{"id":51543,"date":"2010-01-18T00:01:00","date_gmt":"2010-01-18T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/01\/18\/hey-scripting-guy-tell-me-about-modules-in-windows-powershell-2-0\/"},"modified":"2010-01-18T00:01:00","modified_gmt":"2010-01-18T00:01:00","slug":"hey-scripting-guy-tell-me-about-modules-in-windows-powershell-2-0","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-tell-me-about-modules-in-windows-powershell-2-0\/","title":{"rendered":"Hey, Scripting Guy! Tell Me About Modules in Windows PowerShell 2.0"},"content":{"rendered":"<p class=\"MsoNormal\"><a class=\"addthis_button\" href=\"http:\/\/www.addthis.com\/bookmark.php?v=250&amp;pub=scriptingguys\"><img decoding=\"async\" alt=\"Bookmark and Share\" src=\"http:\/\/s7.addthis.com\/static\/btn\/v2\/lg-share-en.gif\" width=\"125\" height=\"16\"><\/a><\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p><img decoding=\"async\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"><\/p>\n<p class=\"MsoNormal\">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?<\/p>\n<p class=\"MsoNormal\">&#8212; MH<\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\">Hello MH, <\/p>\n<p class=\"MsoNormal\">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 <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\"><font face=\"Segoe\">scripter@microsoft.com<\/font><\/a> e-mail inbox, and checked for updates on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\">Twitter<\/a>. 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&mdash;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. <\/p>\n<p class=\"MsoNormal\">Pete and I went scuba diving off <a href=\"http:\/\/wikitravel.org\/en\/Montague_Island\"><font face=\"Segoe\">Montague Island<\/font><\/a> in <a href=\"http:\/\/en.wikipedia.org\/wiki\/New_South_Wales\"><font face=\"Segoe\">New South Wales<\/font><\/a>, Australia, when Lou swam over to see what was going on. The following picture is the one I took of Lou. <\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of Lou\" alt=\"Image of Lou\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/january\/hey0118\/hsg-01-18-10-01.jpg\" width=\"600\" height=\"450\"><\/p>\n<p class=\"Fig-Graphic\">\n<p>&nbsp;<\/p>\n<\/p>\n<blockquote>\n<p class=\"Readeraidonly\">Note: Portions of today&#8217;s Hey, Scripting Guy! Blog post are excerpted from the Microsoft Press book, <i>Windows PowerShell 2.0 Best Practices<\/i> by Ed Wilson, which is <a href=\"http:\/\/bit.ly\/BestPractice\">now available<\/a>.<\/p>\n<\/blockquote>\n<p class=\"MsoNormal\">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&#8217; 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&#8217; home directory is not present by default. The modules directory will only exist in the users&#8217; home directory if it has been created. The creation of the modules directory in the users&#8217; 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&#8217;s module directory does not exist, the modules directory within the Windows PowerShell home directory is used. <\/p>\n<p class=\"MsoNormal\">Windows PowerShell modules exist in two states: loaded and unloaded. To display a list of all loaded modules, use the <b>Get-Module<\/b> cmdlet without any parameters. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Get-Module<\/p>\n<p>ModuleType Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>ExportedCommands<br \/>&#8212;&#8212;&#8212;- &#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8212;&#8212;&#8212;-<br \/>Script<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>helloworld<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{Hello-World, Hello-User}<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">If there are multiple modules loaded when the <b>Get-Module<\/b> cmdlet is run, each module and its accompanying exported commands will appear on their own individual lines. This is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Get-Module<\/p>\n<p>ModuleType Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>ExportedCommands<br \/>&#8212;&#8212;&#8212;- &#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span>&#8212;&#8212;&#8212;&#8212;&#8212;-<br \/>Script<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>GetFreeDiskSpace<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Get-FreeDiskSpace<br \/>Script<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>HelloWorld<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{Hello-World, Hello-User}<br \/>Script<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>TextFunctions<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{New-Line, Get-TextStats}<br \/>Manifest<span>&nbsp;&nbsp; <\/span>BitsTransfer<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{Start-BitsTransfer, Remove-BitsTransfe&#8230;<br \/>Script<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>PSDiagnostics<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{Enable-PSTrace, Enable-WSManTr\nace, Sta&#8230;<\/p>\n<p>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">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:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Get-Module<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">To obtain a list of all modules that are available on the system but are not loaded, use the <b>Get-Module<\/b> cmdlet with the <b>&ndash;ListAvailable<\/b> parameter, which lists all modules that are available regardless of whether the modules are loaded into the Windows PowerShell console. This is seen here: <\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Get-Module -ListAvailable<\/p>\n<p>ModuleType Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>ExportedCommands<br \/>&#8212;&#8212;&#8212;- &#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8212;&#8212;&#8212;-<br \/>Manifest<span>&nbsp;&nbsp; <\/span>GetFreeDiskSpace<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Get-FreeDiskSpace<br \/>Script<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>HelloWorld<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{}<br \/>Script<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>TextFunctions<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{}<br \/>Manifest<span>&nbsp;&nbsp; <\/span>BitsTransfer<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{}<br \/>Manifest<span>&nbsp;&nbsp; <\/span>PSDiagnostics<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{Enable-PSTrace, Enable-WSManTrace, Sta&#8230;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">After you have identified a module you wish to load, you use the <b>Import-Module<\/b> cmdlet to load the module into the current Windows PowerShell session: <\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Import-Module -Name GetFreeDiskSpace<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">If the module exists, the <b>Import-Module<\/b> 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 <b>Import-Module<\/b> command is run three times:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Import-Module -Name GetFreeDiskSpace<br \/>PS C:&gt; Import-Module -Name GetFreeDiskSpace<br \/>PS C:&gt; Import-Module -Name GetFreeDiskSpace<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">Once you import the module, you may want to use the <b>Get-Module<\/b> cmdlet to quickly see which functions are exposed by the module. This is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Get-Module -Name GetFreeDiskSpace<\/p>\n<p>ModuleType Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>ExportedCommands<br \/>&#8212;&#8212;&#8212;- &#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span>&#8212;&#8212;&#8212;&#8212;&#8212;-<br \/>Script<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>GetFreeDiskSpace<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Get-FreeDiskSpace<\/p>\n<p>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">As seen above, the <b>GetFreeDiskSpace<\/b> module exports a single command, the <b>Get-FreeDiskSpace<\/b> function. The one problem with using the <b>Get-Module<\/b> cmdlet is that it does not include other information that could be exported by the module. It only lists commands. <\/p>\n<p class=\"MsoNormal\">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:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Import-Module -Name GetFree*<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"Readeraidonly\">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. <\/p>\n<p class=\"MsoNormal\">If you want to load all of the modules that are available on your system, you can use the <b>Get-Module<\/b> cmdlet with the <b>&ndash;ListAvailable<\/b> parameter and pipe the resulting <b>PSModuleInfo<\/b><i> <\/i>objects to the <b>Import-Module<\/b> cmdlet. This is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Get-Module -ListAvailable | Import-Module<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">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:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Get-Module -ListAvailable | Import-Module<br \/>WARNING: Some imported command names include unapproved verbs which might make<br \/>them less discoverable.<span>&nbsp; <\/span>Use the Verbose parameter for more detail or type<br \/>Get-Verb to see the list of approved verbs.<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">To obtain more information about which unapproved verbs are being used, use the <b>&ndash;verbose<\/b> parameter of the <b>Import-Module<\/b> cmdlet. This command is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Get-Module -ListAvailable | Import-Module &ndash;Verbose<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The results of the <b>Import-Module<\/b> <b>&ndash;Verbose<\/b> command are seen in the following image. <\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of results of Import-Module -Verbose command\" alt=\"Image of results of Import-Module -Verbose command\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/january\/hey0118\/hsg-01-18-10-02.jpg\" width=\"600\" height=\"459\"><\/p>\n<p class=\"Fig-Graphic\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\">Well, MH, that is a quick overview of using Windows PowerShell 2.0 modules. Windows PowerShell Module Week will continue tomorrow. <\/p>\n<p class=\"MsoNormal\">If you want to know exactly what we will be looking at tomorrow, follow us on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\"><font face=\"Segoe\">Facebook<\/font><\/a>. If you have any questions, send e-mail to us at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\"><font face=\"Segoe\">scripter@microsoft.com<\/font><\/a> or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\"><font face=\"Segoe\">Official Scripting Guys Forum<\/font><\/a>. See you tomorrow. Until then, peace.<\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<\/p>\n<p><b><span>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/p>\n<p><\/span><\/b><\/p>\n<p><p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; 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? &#8212; MH &nbsp; Hello MH, Microsoft Scripting Guy Ed Wilson here. I spent [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[51,52,3,4,45],"class_list":["post-51543","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-modules","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; 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? &#8212; MH &nbsp; Hello MH, Microsoft Scripting Guy Ed Wilson here. I spent [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/51543","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\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=51543"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/51543\/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=51543"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=51543"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=51543"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}