Whereas *.ps1 scripts are cheaky little useful scripts that get things done, Modules are the modular building blocks of a maintainable and reusable strategy.
Essentially, a module is just a new namespace. Any data member or function that you declare inside of the module will be accessible by other module members. But, it’s out of scope for your interactive session. So, you just have to export the members that you’d like to be publicly accessible. (Basically just like Python’s import statement.)
There is some set up cost though.
The process of creating powershell modules approximately is
* converting the extension from *.ps1 to *.psm1,
* adding to the bottom of the script a declaration of what methods in the script you are exposing as callable.
* installing in a WellKnown/ Modules directory.
* debugging is a little harder due to a feature of *.psm1 files in that reloading doesn't refresh the script – you have to unload/reload before you see the changes applied…a bit annoying.
* It's optional to add a description of the script's functionality as a *.psd1 in the same directory as the *.psm1
Modules are controlled by the same security as Scripts.
So if you haven't already
Set-ExecutionPolicy Unrestricted
*.psm1 rather than a *.ps1 file.You'll have to be stricter with the way you name files.
But once addressed, complete the file, with the following exporting of methods as the last lines of the file.
export-modulemember -function Show-Calendar
until you do, consider turning off import warnings: import-module <path-to-module> -DisableNameChecking
you can also export methods using wildcards, as shown here:
http://www.itidea.nl/index.php/powershell-export-functions-variables-and-aliases-with-wildcards/
Modules are saved in a folder under one of the “Powershell Module Root Paths”. By default there are 2 – one per User, one System wide one.
You can get your current “Powershell Module Root Paths” as follows:
# works much the same as the PATH Environment Variable: $env:PSModulePath
The default will be something like:
WindowsPowerShell\Modules;C:\windows\system32\WindowsPowerShell\v1.0\Modules\
In other words:
C:\windows\system32\WindowsPowerShell\v1.0\Modules\%userprofile%\documents\windowspowershell\modules\mymoduleDocument folder:%userprofile%\windowspowershell\modules\mymodule
* WRONG:`%userprofile%\documents\windowspowershell\modules\mymodule` * CORRECT: `%userprofile%\windowspowershell\modules\mymodule` * `windows\system32\windowspowershell\V1.0\modules\mymodule`
You are not limited to use only those paths… You can update your environment as follows:
In those root dirs, you create a folder with the same name (eg: “xact”) as the Module filename (eg: “xact”)
In that folder you place your xact.psm1 file, that is export-modulemember methods from it.
/{root}/
/{root}/xact/
/{root}/xact/xact.psm1
Whereas Scripts one just loads with 'dot' loading, *.psm1 files have to be loaded/unloaded.
# all following forms are valid:
import-module {path-needed-if-not-module-root}/untitled1.psm1
import-module untitled1.ps1
import-module untitled1
import-module <path-to-module> -DisableNameChecking #if you want it to shut up about not adhering to Get-Verb
It's easy.
But there's a catch … if you load A, which imports B and C, and B imports C as well, then the file is only loaded once. Makes sense. But it makes debugging harder than with *ps.1 files which you can just reload/refresh after every edit.
You have to unload files before you can reload them.
remove-module untitled1
See http://la11111.wordpress.com/2012/10/25/how-to-create-a-powershell-module-the-easy-way/
for an elegant solution.
If we're talking about *.ps1 script functions, one can document them by putting extended comments at the bottom of the function.
Something like:
<# .SYNOPSIS --TODO:Summary .DESCRIPTION --TODO:Describe .PARAMETER --TODO:ParamName-- --TODO: Describe .EXAMPLE .LINK http://skysigal.com .NOTES #>
Then you can
get-help myFunc
Alternatively, for modules, consider:
New-ModuleManifest
See: https://www.simple-talk.com/sysadmin/powershell/an-introduction-to-powershell-modules/
http://msdn.microsoft.com/en-us/library/dd878343(v=vs.85).aspx
By default Scripts are not loaded.
You have to import-module... them into the IDE.
But Powershell looks for file in its $profile variable (it's going to be %userprofile\$profile – which ends up being
# per user $useprofile\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1. # All users (notice different filename) C:\Windows\System32\WindowsPowerShell\V1.0\Microsoft.PowerShell_profile.ps1
It's just the first script that's run when the IDE is loaded.
So you can just create the file, and add
import-module mytest
get-command -type cmdlet *-*module* | select name
Get-Module patternImport-ModuleRemove-ModuleExport-ModuleMemberNew-ModuleManifestTest-ModuleManifestNew-Module