Hey, Scripting Guy! I have been reading on Twitter and on various Web sites about Windows PowerShell 2.0 modules. However, I am not sure what a module is. Or why I would want to use one. Can you shed some light?
— MH
Hello MH,
Microsoft Scripting Guy Ed Wilson here. I spent much of the morning in a meeting. It was a really cool meeting with a clear-cut agenda, timeframe, the whole ball of wax. Meetings are an important collaboration tool, and when they are properly organized, they are much more efficient than wrestling with hundreds of e-mails. When I got out of the meeting, I started going through the scripter@microsoft.com e-mail inbox, and checked for updates on Twitter. I have been discussing the Scripting Games with several people on Twitter, and I am beginning to get impatient for the Games to begin. It will be an awesome event this year. As I was looking through some of the Scripting Games material from last year, I noticed a folder that had been misplaced on my large storage drive—scuba pictures from my last trip to Australia. I was in the land down under doing a train-the-trainer session for a Windows PowerShell workshop that I wrote, and while I was there, Pete and I took the opportunity to jump in the water. Luckily, I just so happened to have my dry suit and underwater camera gear with me.
Pete and I went scuba diving off Montague Island in New South Wales, Australia, when Lou swam over to see what was going on. The following picture is the one I took of Lou.
Note: Portions of today’s Hey, Scripting Guy! Blog post are excerpted from the Microsoft Press book, Windows PowerShell 2.0 Best Practices by Ed Wilson, which is now available.
MH, a Windows PowerShell module is like a Windows PowerShell script. It can store functions, variables, and other things. One advantage of using a Windows PowerShell module is you can create a manifest that specifies exactly which elements from the module to export. There are two default locations for Windows PowerShell modules. The first location is located in the users’ home directory and the second is located in the Windows PowerShell home directory. The modules directory in the Windows PowerShell home directory always exists. However, the modules directory in the users’ home directory is not present by default. The modules directory will only exist in the users’ home directory if it has been created. The creation of the modules directory in the users’ home directory does not normally happen until someone has decided to create and to store modules there. A nice feature of the module directory is that when it exists, it is the first place Windows PowerShell uses when it searches for a module. If the user’s module directory does not exist, the modules directory within the Windows PowerShell home directory is used.
Windows PowerShell modules exist in two states: loaded and unloaded. To display a list of all loaded modules, use the Get-Module cmdlet without any parameters. This is shown here:
PS C:> Get-Module
ModuleType Name ExportedCommands
———- —- —————-
Script helloworld {Hello-World, Hello-User}
If there are multiple modules loaded when the Get-Module cmdlet is run, each module and its accompanying exported commands will appear on their own individual lines. This is seen here:
PS C:> Get-Module
ModuleType Name ExportedCommands
———- —- —————-
Script GetFreeDiskSpace Get-FreeDiskSpace
Script HelloWorld {Hello-World, Hello-User}
Script TextFunctions {New-Line, Get-TextStats}
Manifest BitsTransfer {Start-BitsTransfer, Remove-BitsTransfe…
Script PSDiagnostics {Enable-PSTrace, Enable-WSManTr
ace, Sta…
PS C:>
If no modules are loaded, nothing will be displayed on the Windows PowerShell console. No errors are displayed, nor is there any confirmation that the command actually ran. This is seen here:
PS C:> Get-Module
PS C:>
To obtain a list of all modules that are available on the system but are not loaded, use the Get-Module cmdlet with the –ListAvailable parameter, which lists all modules that are available regardless of whether the modules are loaded into the Windows PowerShell console. This is seen here:
PS C:> Get-Module -ListAvailable
ModuleType Name ExportedCommands
———- —- —————-
Manifest GetFreeDiskSpace Get-FreeDiskSpace
Script HelloWorld {}
Script TextFunctions {}
Manifest BitsTransfer {}
Manifest PSDiagnostics {Enable-PSTrace, Enable-WSManTrace, Sta…
After you have identified a module you wish to load, you use the Import-Module cmdlet to load the module into the current Windows PowerShell session:
PS C:> Import-Module -Name GetFreeDiskSpace
PS C:>
If the module exists, the Import-Module cmdlet completes without displaying any information. If the module is already loaded, no error message is displayed. This is seen here where I use the up arrow key to retrieve the previous command and press ENTER to execute the command. The Import-Module command is run three times:
PS C:> Import-Module -Name GetFreeDiskSpace
PS C:> Import-Module -Name GetFreeDiskSpace
PS C:> Import-Module -Name GetFreeDiskSpace
PS C:>
Once you import the module, you may want to use the Get-Module cmdlet to quickly see which functions are exposed by the module. This is seen here:
PS C:> Get-Module -Name GetFreeDiskSpace
ModuleType Name ExportedCommands
———- —- —————-
Script GetFreeDiskSpace Get-FreeDiskSpace
PS C:>
As seen above, the GetFreeDiskSpace module exports a single command, the Get-FreeDiskSpace function. The one problem with using the Get-Module cmdlet is that it does not include other information that could be exported by the module. It only lists commands.
When working with modules that have long names, you are not limited to typing the entire module name. You are allowed to use wildcard characters. It is a best practice when using wildcard characters to load modules to type a significant portion of the module name so that you only match a single module from the list of modules that are available to you. This is seen here:
PS C:> Import-Module -Name GetFree*
PS C:>
Important: If you use a wildcard character pattern that matches more than one module name, the first matched module is loaded and the remaining matches are discarded. This can lead to inconsistent and unpredictable results. No error message is displayed when more than one module matches a wildcard character pattern.
If you want to load all of the modules that are available on your system, you can use the Get-Module cmdlet with the –ListAvailable parameter and pipe the resulting PSModuleInfo objects to the Import-Module cmdlet. This is seen here:
PS C:> Get-Module -ListAvailable | Import-Module
PS C:>
If you have a module that uses a verb that is not on the allowed verb list, a warning message is displayed when you import the module. The functions in the module still work and the module will work, but the warning is displayed to remind you to check the authorized verb list. This is seen here:
PS C:> Get-Module -ListAvailable | Import-Module
WARNING: Some imported command names include unapproved verbs which might make
them less discoverable. Use the Verbose parameter for more detail or type
Get-Verb to see the list of approved verbs.
PS C:>
To obtain more information about which unapproved verbs are being used, use the –verbose parameter of the Import-Module cmdlet. This command is seen here:
PS C:> Get-Module -ListAvailable | Import-Module –Verbose
The results of the Import-Module –Verbose command are seen in the following image.
Well, MH, that is a quick overview of using Windows PowerShell 2.0 modules. Windows PowerShell Module Week will continue tomorrow.
If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson and Craig Liebendorfer, Scripting Guys
0 comments