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.

The Scripting Guy down in the mines...rather, building a 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.

Image showing the location of the Windows PowerShell ISE

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:

Function Set-IEDownload


} #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.

Import-Module *desk*

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, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Comments (3)

  1. mredwilson says:

    @Klaus thanks for the comment. I hope to have an Invoke-ConfigureNewComputer module before too long. Even after having written this series of articles, I still have a way to go before I have everything configured the way I like. The cool thing about Windows PowerShell, is that it allows for this type of attempt (or effort). What I come up will work for me, but may not reflect what you want to do. This is where it really begins to be a lot of work … making what works for me, also work for you. This is where command line parameters, switches, etc. come into play.

  2. Klaus Schulte says:

    WOW! Well done, Ed!!

    It would be wonderful, if we culd script all parts of the software installation!

    It's true, that it takes nearly no time to buy or even assemble a new computer,

    but it usually takes me three days to get to the point I've been before!!!

    So let's plan an Invoke-ConfigureNewComputer module for the near future 🙂


  3. Ralph Frampton says:

    I think there is an error in your article as there is no Get-Modules Cmdlet in my PS. Being a PS neophyte, it took me awhile to figure out that there is a Get-Module Cmdlet (mostly because I’m used to using /? for usage/help and now it looks like -? is
    the PS way).

Skip to main content