Don't Write Scripts, Write PowerShell Modules
Summary: The Microsoft Scripting Guys talk about turning three scripts into a single module to configure basic desktop tasks.
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 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.
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.
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 > Accessories > Windows PowerShell to find the Windows PowerShell ISE, as shown in the following image.
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 Hey, Scripting Guy! How Can I Modify Registry Settings That Configure Windows Explorer? 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.
Next, I found Hey, Scripting Guy! How Can I Change My Internet Explorer Home Page? 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 param statement at the top of each of the functions to populate the $computer variable. Here is the line of code I added.
Param($computer = $env:computername)
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 2009 Summer Scripting Games Wrap-Up 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 function keyword and provide a name, and then open and close the curly brackets. It looks like this:
} #end function Set-IEDownload
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.
I open a Windows PowerShell console with administrator rights, and set the Script Execution policy to unrestricted:
Set-ExecutionPolicy unrestricted –force
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 Hey, Scripting Guy! How Do I Work with Windows PowerShell Module Paths? 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.
I use the Get-Modules cmdlet with the listavailable parameter to see that the module was “installed” properly.
Next, I need to import the module. I do this by using the Import-Module cmdlet. I do not need to type the complete module name. I can use wildcard characters instead.
Now, I want to see which commands are exported by the module. I use the Get-Command cmdlet, and specify the newly imported module. Here is the command and associated output (I use GCM which is an alias for the Get-Command cmdlet).
PS C:\Windows\system32> gcm -Module *desk*
CommandType Name Definition
———– —- ———-
Function Get-ExplorerSettings param()…
Function Get-ieStartPage …
Function Set-ExplorerSettings param()…
Function Set-IEDownload …
Function Set-ieStartPage …
I open a new tab in the Windows PowerShell ISE, and use the two Get* functions. The cool thing is that tab expansion works here:
The output associated with this appears here:
PS C:\Windows\system32> Get-ExplorerSettings
Display hidden files and folders is 0
Hide File extensions is set to 1
Show system files and folders is set to
Hide desktop icons 0
Use Web view for folders 1
Display correct file name capitalization 0
Prevent automatically locate file shares and printers
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 “script” because it took less than a minute to create. Here’s the “script”:
Set-IEDownload -connections 15
I have uploaded the Configure Desktop Module to the Script Center Script Repository.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy