In PowerShell V2 CTP3, you can create Advanced Functions which are, in effect, cmdlets written in script. I’ve already blogged about some of the cool features, particularly AutoHelp, which I find utterly cool! One neat aspect is the ability to define the parameters that your script accepts. Thus you can get PowerShell to do at least some of the validation of the parameter for you automagically. With Advanced Functions, you can do two things: you can define the parameter details in your script and have Get-Help provide them as documentation and you can decorate your script with Attributes telling PowerShell how to treat each parameter.
For many PowerShell users, the terms “decorate” and “attribute” may be new. By decorate, I mean just adding in extra text. Attributes are text that tell PowerShell how to do something. In CTP3, you can specify the [Parameter] attribute – decorating your script with these attributes (i.e. adding in the text to your script) enables you to tell PowerShell just how it should handle parameters to your script. I believe this is an important feature – and takes PowerShell further down the road towards being a full .NET language.
Here’s a snipped of code, a param block, showing the use of [Parameter] attributes:
- param (
- [Parameter(Position=0, Mandatory=$false)]
- [string] $Domain = "Cookham" ,
- [Parameter(Position=1, Mandatory=$false)]
- [string] $Computer = "Cookham8",
- [Parameter(Position=2, Mandatory=$false]
- [string] $User = "tfl"
- )
This parameter (param) block defines three script parameters ($domain, $computer, $user). The Parameter attributes are also specified using named attributes (eg Mandatory, Position, etc) to ensure PowerShell knows how to handle them. The documentation thus far on these parameter attributes is limited. Well, limited in terms of PowerShell documentation. The MSDN Library has a ton of documentation on how to write PowerShell Cmdlet, but these are written for C# programmers. I’m assuming that, in due course, there will be additional documentation that is more PowerShell focused.
If this script fragment were from a script called Get-Foo (ok bad name but work with me!), then you might call this script as follows:
PS C:\foo> Get-Foo NWTraders MyWorkstation BillyBob
In terms of Parameter attributes, http://msdn.microsoft.com/en-us/library/ms714348(VS.85).aspx contains a list of the name attributes you can use. These are:
- Mandatory - a boolean saying whether the parameter is required or not. A mandatory parameter that is not specified generates a run time exception.
- ParameterSetName – a string naming the parameter set a parameter belongs to. You can use this name in your script to handle different sets of parameters (that result in different behaviour of your script).
- Position – an integer specifying where parameter’s order. As you can see in the above example, the $User paramater is the third parameter, while $domain is the first and $computer the second.
- ValueFromPipeline – a boolean indicating if the parameter can come from the pipeline.
- ValueFromPipelineByPropertyName - a boolean indicating whether the parameter is filled from a property of the piped-in object that has either the same name or the same alias as this parameter.
- ValueFromRemainingArguments – a Boolean indicating whether this cmdlet accepts all the remaining arguments passed. This is a good way to pickup any overspecified parameters.
- HelpMessage – a string containing a short description of this parameter.
- HelpMessageBaseName – the base name of the help message resource.
- HelpMessageResourceId – an identifier used when a help message is localised.
Here is a slightly longer script demonstrating some of these:
- <#
- .SYNOPSIS
- Shows Parameter attributes
- .DESCRIPTION
- Script is decorated with Parameter attributes to demostrate the use of them
- .NOTES
- File Name : Get-ParameterAttribute1.ps1
- Author : Thomas Lee - tfl@psp.co.uk
- Requires : PowerShell V2 CTP3
- .LINK
- To be posted at:
- http://www.pshscripts.blogspot.com
- .EXAMPLE
- Simple usage, with partial parameters specified
- PS C:\foo> .\Get-ParameterAttribute1.ps1 abc
- ----
- Domain : abc
- Computer : Cookham8
- User : tfl
- ----
- .EXAMPLE
- Simple usage, with all parameters specified
- PS C:\foo> .\Get-ParameterAttribute1.ps1 kapoho, kapoho1, BigKahuna
- ----
- Domain : kapoho
- Computer : kapoho1
- User : BigKahuna
- ----
- .EXAMPLE
- Showing getting first parameter from the pipeline
- PS C:\foo> "abc", "def", "GHI" |.\Get-ParameterAttribute1.ps1
- ----
- Domain : abc
- Computer : Cookham8
- User : tfl
- ----
- ----
- Domain : def
- Computer : Cookham8
- User : tfl
- ----
- ----
- Domain : GHI
- Computer : Cookham8
- User : tfl
- ----
- EXAMPLE
- Shows getting all Value From Remaining Arguments
- PS C:\foo> .\Get-ParameterAttribute1.ps1 abc def ghi xxx xxx xxx xxx
- ----
- Domain : abc
- Compuyter : def
- User : ghi xxx xxx xxx xxx
- .PARAMETER Domain
- A domain name - must be a string
- .PARAMETER Computer
- A computer Name - must be a string
- .PARAMETER User
- A user name - must be a string
- #>
- param (
- [Parameter(Position=0, Mandatory=$true,ValueFromPipeLine=$true)]
- [string] $Domain = "Cookham" ,
- [Parameter(Position=1, Mandatory=$false)]
- [string] $Computer = "Cookham8",
- [Parameter(Position=2, Mandatory=$false, ValueFromRemainingArguments=$true)]
- [string] $User = "tfl"
- )
- Process {
- "----"
- "Domain : {0}" -f $domain
- "Computer : {0}" -f $computer
- "User : {0}" -f $user
- "----"
- }
1 comment:
Hello Thomas,
thanks a lot for this info. I was wondering, how to migrate plain $args to the new syntax.
I just wrote a starter for ISE, which works good, but get-help doesn't use the comment. Code at
http://poshcode.org/774.
By the way which tools do you use to post your listings. It looks really good
Happy scripting
Bernd
Post a Comment