{"id":13501,"date":"2011-06-27T00:01:00","date_gmt":"2011-06-27T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/06\/27\/dont-write-scripts-write-powershell-modules\/"},"modified":"2011-06-27T00:01:00","modified_gmt":"2011-06-27T00:01:00","slug":"dont-write-scripts-write-powershell-modules","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/dont-write-scripts-write-powershell-modules\/","title":{"rendered":"Don&#039;t Write Scripts, Write PowerShell Modules"},"content":{"rendered":"<p><b>Summary<\/b>: The Microsoft Scripting Guys talk about turning three scripts into a single module to configure basic desktop tasks. <br \/>&nbsp;<\/p>\n<p>Microsoft Scripting Guy Ed Wilson here. I have spent the last several days building a new computer. The following photo shows me working on my new computer.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5861.hsg-6-27-11-1.jpg\"><img decoding=\"async\" style=\"border-width: 0px\" title=\"The Scripting Guy down in the mines...rather, building a new computer\" alt=\"The Scripting Guy down in the mines...rather, building a new computer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5861.hsg-6-27-11-1.jpg\" \/><\/a><\/p>\n<p>It actually took me only a couple of hours to move from a dozen boxes to a working computer, but it has taken the last few days installing software and the accompanying hundreds of software updates. This time I started a list of all the things I do after I have the operating system installed to configure it the way I like. My list contains 30 items, and it includes things such as changing Windows Explorer to display file extensions, and changing Internet Explorer to allow 15 downloads at the same time. Over the years, I have written a number of scripts to automate these sort of tasks, but unfortunately, over the years I have written more than 6,000 scripts and the scripts are spread out over dozens of computers and hundreds of folders. Therefore, when I am building a new computer, I still end up performing the 30 post configuration tasks manually.<\/p>\n<p>It dawned on me that, instead of writing scripts, I should be writing modules. With a module, I have an easy-to-store location, it has an easy to remember name, and it can combine the functionality of numerous scripts into a single entity.<\/p>\n<p>I decided to try out my new idea by locating three scripts to move me along my goal of having a new system that works the way that I like to work. Because I am working on a new computer, it means that the Script Execution policy has not been set, nor has my quick launch for the Windows PowerShell ISE been configured. I therefore have to navigate to All Programs &gt; Accessories &gt; Windows PowerShell to find the Windows PowerShell ISE, as shown in the following image.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1425.HSG-06-27-11-02.png\"><img decoding=\"async\" title=\"Image showing the location of the Windows PowerShell ISE\" border=\"0\" alt=\"Image showing the location of the Windows PowerShell ISE\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1425.HSG-06-27-11-02.png\" width=\"458\" height=\"517\" \/><\/a><\/p>\n<p>The three things I want to do today are increase my Internet Explorer downloads, set start pages on Internet Explorer, and remove the hidden file extensions in Windows Explorer. I wrote a Hey, Scripting Guy! Blog post called <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2009\/01\/06\/how-can-i-modify-registry-settings-that-configure-windows-explorer.aspx\" target=\"_blank\">Hey, Scripting Guy! How Can I Modify Registry Settings That Configure Windows Explorer?<\/a> that included a script that will remove the hidden file extensions in Windows Explorer. I copied the two functions from that script into the Windows PowerShell ISE.<\/p>\n<p>Next, I found <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2009\/01\/07\/how-can-i-change-my-internet-explorer-home-page.aspx\" target=\"_blank\">Hey, Scripting Guy! How Can I Change My Internet Explorer Home Page?<\/a> and copied the two functions from that article as well. The two functions in this article needed a modification to enable them to work in the module. They relied upon a global variable for the value of the computer name. I added a <strong>param<\/strong> statement at the top of each of the functions to populate the <strong>$computer<\/strong> variable. Here is the line of code I added.<\/p>\n<blockquote>\n<p>Param($computer = $env:computername)<\/p>\n<\/blockquote>\n<p>The last thing I want to do is increase the number of Internet Explorer downloads. This is important for a newly create computer because there are always things that need to be downloaded. I found a script from the <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2009\/08\/14\/hey-scripting-guy-can-i-download-multiple-files-at-once-with-internet-explorer-in-windows-7.aspx\" target=\"_blank\">2009 Summer Scripting Games Wrap-Up<\/a> that will do the trick, but it needs to be turned into a function first, which was easy to do. All I do is use the <strong>function<\/strong> keyword and provide a name, and then open and close the curly brackets. It looks like this:<\/p>\n<p style=\"padding-left: 30px\">Function Set-IEDownload<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">} #end function Set-IEDownload<\/p>\n<p>Now I am ready to save the module. To do this, I save it with the .psm1 file extension. I call my module ConfigureDesktop.psm1.<\/p>\n<p>I open a Windows PowerShell console with administrator rights, and set the Script Execution policy to unrestricted:<\/p>\n<p style=\"padding-left: 30px\">Set-ExecutionPolicy unrestricted &ndash;force<\/p>\n<p>Now I open a new tab in the Windows PowerShell ISE, and open my Copy-Modules script to install my newly created ConfigureDesktop.psm1 module file. I talk about the Copy-Modules script in the <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2010\/01\/20\/hey-scripting-guy-january-20-2010.aspx\" target=\"_blank\">Hey, Scripting Guy! How Do I Work with Windows PowerShell Module Paths?<\/a> post. The Copy-Modules script installs the module into the default location on my computer. It creates all needed folders, and it automatically names the folders with the appropriate names. I use this script all the time to copy modules into the appropriate location on my system.<\/p>\n<p>I use the <strong>Get-Modules<\/strong> cmdlet with the <i>listavailable <\/i>parameter to see that the module was &ldquo;installed&rdquo; properly.<\/p>\n<p>Next, I need to import the module. I do this by using the <strong>Import-Module<\/strong> cmdlet. I do not need to type the complete module name. I can use wildcard characters instead.<\/p>\n<p style=\"padding-left: 30px\">Import-Module *desk*<\/p>\n<p>Now, I want to see which commands are exported by the module. I use the <strong>Get-Command<\/strong> cmdlet, and specify the newly imported module. Here is the command and associated output (I use <strong>GCM<\/strong> which is an alias for the <strong>Get-Command<\/strong> cmdlet).<\/p>\n<blockquote>\n<p>PS C:\\Windows\\system32&gt; gcm -Module *desk*<\/p>\n<p>CommandType&nbsp;&nbsp;&nbsp;&nbsp; Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Definition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p>&#8212;&#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p>Function&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Get-ExplorerSettings&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; param()&#8230;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p>Function&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Get-ieStartPage&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p>Function&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set-ExplorerSettings&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; param()&#8230;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p>Function&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set-IEDownload&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p>Function&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set-ieStartPage&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<\/blockquote>\n<p>I open a new tab in the Windows PowerShell ISE, and use the two <strong>Get*<\/strong> functions. The cool thing is that tab expansion works here:<\/p>\n<p style=\"padding-left: 30px\">Get-ExplorerSettings<\/p>\n<p style=\"padding-left: 30px\">Get-ieStartPage<\/p>\n<p>The output associated with this appears here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Windows\\system32&gt; Get-ExplorerSettings<\/p>\n<p style=\"padding-left: 30px\">Get-ieStartPage<\/p>\n<p style=\"padding-left: 30px\">Display hidden files and folders is 0<\/p>\n<p style=\"padding-left: 30px\">Hide File extensions is set to 1<\/p>\n<p style=\"padding-left: 30px\">Show system files and folders is set to<\/p>\n<p style=\"padding-left: 30px\">Hide desktop icons 0<\/p>\n<p style=\"padding-left: 30px\">Use Web view for folders 1<\/p>\n<p style=\"padding-left: 30px\">Display correct file name capitalization 0<\/p>\n<p style=\"padding-left: 30px\">Prevent automatically locate file shares and printers<\/p>\n<p style=\"padding-left: 30px\">about:blank<\/p>\n<p>Cool. Now, I am going to write a script (a series of commands) to configure my desktop. I do this to simplify managing the commands, but I could have typed them directly into the immediate window. I did not even save the &ldquo;script&rdquo; because it took less than a minute to create. Here&rsquo;s the &ldquo;script&rdquo;:<\/p>\n<p style=\"padding-left: 30px\">Set-ExplorerSettings<\/p>\n<p style=\"padding-left: 30px\">Set-IEDownload -connections 15<\/p>\n<p style=\"padding-left: 30px\">Set-ieStartPage<\/p>\n<p>I have uploaded the <a href=\"http:\/\/gallery.technet.microsoft.com\/scriptcenter\/cc98b735-c943-4158-8b66-9c8aa78eafbd?SRC=Home\" target=\"_blank\">Configure Desktop Module to the Script Center Script Repository<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: The Microsoft Scripting Guys talk about turning three scripts into a single module to configure basic desktop tasks. &nbsp; Microsoft Scripting Guy Ed Wilson here. I have spent the last several days building a new computer. The following photo shows me working on my new computer. It actually took me only a couple of [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[16,17,52,3,4,226,45],"class_list":["post-13501","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-desktop-management","tag-internet-explorer","tag-modules","tag-scripting-guy","tag-scripting-techniques","tag-windows-explorer","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: The Microsoft Scripting Guys talk about turning three scripts into a single module to configure basic desktop tasks. &nbsp; Microsoft Scripting Guy Ed Wilson here. I have spent the last several days building a new computer. The following photo shows me working on my new computer. It actually took me only a couple of [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/13501","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=13501"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/13501\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=13501"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=13501"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=13501"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}