So you can probably guess that importing a module is just loading someone else's code. A module, when professionally written is most likely "compiled" code. Code written C# or another .NET language and compiled into a DLL. In Visual Studio you can create PowerShell projects. Does that mean, if you want you own module, you need to start learning Visual Studio and C# ? Hell no, you can create your own module in matter of minutes with nothing more that just plain old PowerShell.
This isn't going to be a PowerShell course, but I will need to teach you some of PowerShell's best practices if you want to create . One of them is writing a little help for your own powershell cmdlets. The other is add cmdlet-binding.
Use PowerShell ISE
If you are coding in PowerShell, you should at least use a proper PowerShell Editor, there are many out there, powerful ones too and expensive ones. But Windows comes with a default one, called PowerShell ISE. So start that one. The screen can be divided in 3 parts.- The Shell (where your code is run)
- The Script Pane (the editor)
- The Command Add-on (where you can search modules & cmdlets)
Your script
Let's use a simple script for this example. It will write a text in color and underline it.Function Underline{ Param( [string]$Text, [string]$Color="Cyan" ) Begin{} Process{ if($Text){ Write-Host "`n$Text" -ForegroundColor $Color Write-Host "".PadRight($Text.Length,"-") } } }
Now we want this to be a module so we can use it everywhere we want.
Use ISE Snippet
The first thing I always do when I write a module is making sure my function has all the required elements.- Help text
- Cmdlet binding
- Pipeline input (optional)
<# .Synopsis Short description .DESCRIPTION Long description .EXAMPLE Example of how to use this cmdlet .EXAMPLE Another example of how to use this cmdlet #> function Verb-Noun { [CmdletBinding()] [Alias()] [OutputType([int])] Param ( # Param1 help description [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] $Param1, # Param2 help description [int] $Param2 ) Begin { } Process { } End { } }
Notice it has help at the top, it has the "CmdletBinding" and it's showing me how to implement pipeline input. Now this is not a powershell course, so I do assume you know what pipeline input is.
Now, also notice that its says your function should have the format Verb-Noun ! This is important. You want to know all the possible verbs ? (like : new-, add-,invoke-, get-, ...), just type "get-verb" in the console.
So now I merge these 2 into my final script
<# .Synopsis Underlines your text .DESCRIPTION Underlines your text .EXAMPLE Underline "Hoo" .EXAMPLE "Hoo" | Underline -Color Magenta #> Function Add-Underline{ [CmdletBinding()] Param( # Your input text [Parameter(Mandatory=$true,ValueFromPipeline=$true,Position=0)] [string]$Text, # Your color [Parameter(Mandatory=$false,Position=1)] [string]$Color="Cyan" ) Begin{} Process{ if($Text){ Write-Host "`n$Text" -ForegroundColor $Color Write-Host "".PadRight($Text.Length,"-") } } }If you run this, notice you will now have a function "Add-Underline". Notice if you type "Get-Help Underline -Full", it will actually show you help information, directly extracted from your code, and check out the pipeline input. Just do something like "date | Underline".
PS C:\jumpstart> date | Add-Underline
12/15/2016 09:35:37
-------------------
PS C:\jumpstart> get-help Add-Underline -Full
NAME
Add-Underline
SYNOPSIS
Underlines your text
SYNTAX
Add-Underline [-Text] <String> [[-Color] <String>] [<CommonParameters>]
DESCRIPTION
Underlines your text
PARAMETERS
-Text <String>
Your input text
Required? true
Position? 1
Default value
Accept pipeline input? true (ByValue)
Accept wildcard characters? false
-Color <String>
Your color
Required? false
Position? 2
Default value Cyan
Accept pipeline input? false
Accept wildcard characters? false
<CommonParameters>
This cmdlet supports the common parameters: Verbose, Debug,
ErrorAction, ErrorVariable, WarningAction, WarningVariable,
OutBuffer, PipelineVariable, and OutVariable. For more information, see
about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
INPUTS
OUTPUTS
-------------------------- EXAMPLE 1 --------------------------
PS C:\>Add-Underline "Hoo"
-------------------------- EXAMPLE 2 --------------------------
PS C:\>"Hoo" | Add-Underline -Color Magenta
Create a simple module
You want a simple module huh ? Well, just do this :Step 1 : Add this at the bottom of your script : Export-ModuleMember Add-Underline
This added line of code tells the module which functions should be cmdlets, all other functions (if any) are internal use only, and are not "exported" to the module.
So your script now looks like :
<# .Synopsis Underlines your text .DESCRIPTION Underlines your text .EXAMPLE Underline "Hoo" .EXAMPLE "Hoo" | Underline -Color Magenta #> Function Add-Underline{ [CmdletBinding()] Param( # Your input text [Parameter(Mandatory=$true,ValueFromPipeline=$true,Position=0)] [string]$Text, # Your color [Parameter(Mandatory=$false,Position=1)] [string]$Color="Cyan" ) Begin{} Process{ if($Text){ Write-Host "`n$Text" -ForegroundColor $Color Write-Host "".PadRight($Text.Length,"-") } } } Export-ModuleMember Add-Underline
Create a folder called "Underline"
Save your script (.psm1) in that directory as "Underline.psm1".
Now your module "Underline" is ready. You can now already import it locally like :
import-module .\Underline
(.\Underline is the path of your directory, powershell will assume that there is a subdirectory called Underline with an underline.psm1 in that directory).
PS C:\jumpstart\Underline> cd.. PS C:\jumpstart> Import-Module .\Underline PS C:\jumpstart> Get-Module ModuleType Version Name ExportedCommands ---------- ------- ---- ---------------- Script 1.0.0.0 ISE {Get-IseSnippet, Import-IseSnippet, New-IseSnippet} Manifest 3.1.0.0 Microsoft.PowerShell.Management {Add-Computer, Add-Content, Checkpoint-Computer, Clear-Content...} Manifest 3.0.0.0 Microsoft.PowerShell.Security {ConvertFrom-SecureString, ConvertTo-SecureString, Get-Acl, Get-Aut... Manifest 3.1.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object...} Manifest 3.0.0.0 Microsoft.WSMan.Management {Connect-WSMan, Disable-WSManCredSSP, Disconnect-WSMan, Enable-WSMa... Script 0.0 Underline Add-Underline PS C:\jumpstart> Get-Command -Module Underline CommandType Name Version Source ----------- ---- ------- ------ Function Add-Underline 0.0 Underline
Move your module to the module repository
Now, to make sure you don't have to know the path of your module, just move it to the repository. There are 2 of them :%USERPROFILE%\Documents\WindowsPowerShell\Modules\ (create this if needed)
%WINDOWS%\System32\WindowsPowerShell\v1.0\Modules\
The first is user-bound, the second is global. As soon as you've copied your module (the directory) to one of these locations, you will now always be able to call it just by typing "import-module Underline". And don't forget : your .psm1 file must be in a directory with the same name (\Underline\Underline.psm1).
Create a Manifest
Now you probably noticed that your module didn't have a "Version number" and maybe you want to add some "Author" information, or your want to add dependencies, like the powershell version, or you want to make sure another module is loaded/installed. Now, again, this isn't a powershell course and I won't tell you everthing about manifests (hell, I don't know everything about manifests), but I can show you the very basics.First : remove the line "Export-ModuleMember" again from your .psm1 file. We will add that information in the manifest file instead.
Now before we start : there is NOTHING fancy about this manifest. It's just a plain text file in a specific format, containing some information about your module, like Author, company, version, exported functions, ... The file must be in your module-directory and the extension of the file is .psd1
Now, to create such a manifest file, there is actually a cmdlet called "New-ModuleManifest", but it has A LOT of parameters. Luckily, the PowerShell ISE application has a CmdLet GUI !
In your PowerShell ISE application, show the Command Add-On (in the view menu). And search for manifest. Select "New-ModuleManifest" and notice a GUI appear for all parameters.
Now, here is the difficult part, for the manifest to work properly, you need to fill in the right parameters and in the right format. This is the part were I lost time the first time. In fact, I always open one of my previous working manifest files to have a peep how to do it.
This is my method
Fill in these fields, leave the rest blank if you want :
- Path = c:\jumpstart\underline\Underline.psd1
- RootModule = Underline.psm1
- ModuleVersion = 1.0
- Author = The Wfa Guy
- CompanyName = NetApp
- Description = A cool function
- FunctionsToExport = 'Add-Underline'
- ModuleList = 'Underline.psm1'
- FileList = 'Underline.psm1'
Moduleversion : start with something, you could change versions once you modify stuff
FunctionsToExport, ModuleList & FileList : This is a tricky one, you must wrap them in single-quotes and comma separate them as these parameters are of type "string[]".

Once you run the cmdlet, your psd1 file is created. If you open it, you'll see it will have added more things, like copyright, a GUID (this is a unique ID and guarantees that versioning works, in case your module name is not unique).
In case your module has extra files, maybe an ini-file or an xml-file or some other dll, then add them in the "filelist" too.
Also note that I use "functions to export" not "cmdlets to export" !!
That's it. Let me know if this was useful !
No comments :
Post a Comment