Summary: Increase your Windows PowerShell productivity by unleashing the power of parameter aliases.
Microsoft Scripting Guy Ed Wilson here. The more I work with Windows PowerShell the more I enjoy it. On the other hand, there are still some challenges that need to be met in terms of both discoverability and in usability. Quite frankly, some things are still a bit too hard. For example, one of the cool things about Windows PowerShell is the ability to create aliases. If you do not like the name of a command, you can create an alias and effectively change the name of the command. If you do not like the way a command behaves AND you do not like the name of the command you can create a function, and then create an alias for that function. In short, Windows PowerShell is configurable.
On the other hand, some things are already built into the product but the problem is discovering that the feature exists. An example of this is the parameter aliases. The aliases that are associated with the common parameters are documented on MSDN. Unfortunately, the help About_CommonParameters topic that ships with both Windows PowerShell 1.0 and Windows PowerShell 2.0 does not include the aliases for the common parameters, and the Parameter Aliases topic on MSDN talks about creating aliases for Windows PowerShell cmdlet parameters, but it does not list existing aliases. In short, it seems like parameter aliases have fallen through the cracks. The only way I even learned about them was sort of picking them up by osmosis.
I decided to write the following command to produce a listing of Windows PowerShell cmdlets and their associated aliases (it is a single logical command but I broke the command into two lines at the pipe character for display on the blog platform).
gcm -commandtype cmdlet | % {$_.name ; $_.parameters.values | ? { $_.aliases } |
ft name, aliases}
The GCM command is an alias for the Get-Command Windows PowerShell cmdlet that is used to retrieve a listing of all the cmdlets that are available in my current Windows PowerShell environment. This value can change depending on which modules or snap-ins are loaded. The percent sign (%) is an alias for the Foreach-Object Windows PowerShell cmdlet. Inside the Foreach-Object loop, the $_.name command displays the name of the Windows PowerShell cmdlet that is currently on the pipeline. Next the values of the parameters object are pipelined to the Where-Object (the question mark (?) is an alias for the Where-Object Windows PowerShell cmdlet). The Where-Object Windows PowerShell cmdlet looks for parameter values that are aliases. If the aliases are found, they are pipelined to the Format-Table Windows PowerShell cmdlet (ft is an alias for Format-Table) where only the name of the parameter and the alias of the parameter is displayed.
The results from running the script are displayed in the following figure.
The reason the script works is because Windows PowerShell contains an object that is called a cmdletinfo object. This is seen here where I use the Get-Command Windows PowerShell cmdlet to retrieve the cmdletinfo object for the Get-Command cmdlet. I pipeline this object to the Get-Member Windows PowerShell cmdlet to reveal its members. The results are seen here.
PS C:\> Get-Command get-command | Get-Member
TypeName: System.Management.Automation.CmdletInfo
Name MemberType Definition
—- ———- ———-
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
CommandType Property System.Management.Automation.CommandTypes Comm…
DefaultParameterSet Property System.String DefaultParameterSet {get;}
Definition Property System.String Definition {get;}
HelpFile Property System.String HelpFile {get;}
ImplementingType Property System.Type ImplementingType {get;}
Module Property System.Management.Automation.PSModuleInfo Modu…
ModuleName Property System.String ModuleName {get;}
Name Property System.String Name {get;}
Noun Property System.String Noun {get;}
OutputType Property System.Collections.ObjectModel.ReadOnlyCollect…
Parameters Property System.Collections.Generic.Dictionary`2[[Syste…
ParameterSets Property System.Collections.ObjectModel.ReadOnlyCollect…
PSSnapIn Property System.Management.Automation.PSSnapInInfo PSSn…
Verb Property System.String Verb {get;}
Visibility Property System.Management.Automation.SessionStateEntry…
DLL ScriptProperty System.Object DLL {get=$this.ImplementingType….
HelpUri ScriptProperty System.Object HelpUri {get=try…
I see that there is a parameters property, and therefore I decide to access them directly. This is seen here.
PS C:\> (gcm get-command).parameters
Key Value
— —–
Name System.Management.Automation.Parameter…
Verb System.Management.Automation.Parameter…
Noun System.Management.Automation.Parameter…
Module System.Management.Automation.Parameter…
CommandType System.Management.Automation.Parameter…
TotalCount System.Management.Automation.Parameter…
Syntax System.Management.Automation.Parameter…
ArgumentList System.Management.Automation.Parameter…
Verbose System.Management.Automation.Parameter…
Debug System.Management.Automation.Parameter…
ErrorAction System.Management.Automation.Parameter…
WarningAction System.Management.Automation.Parameter…
ErrorVariable System.Management.Automation.Parameter…
WarningVariable System.Management.Automation.Parameter…
OutVariable System.Management.Automation.Parameter…
OutBuffer System.Management.Automation.Parameter…
At this point in the exercise, I have retrieved the parameters for the Get-Command Windows PowerShell cmdlet. The results that are returned are a dictionary object (as evidenced by the key value combinations. I think I would like to see the values. This is seen here.
PS C:\> (gcm get-command).parameters | % {$_.values}
Name : Name
ParameterType : System.String[]
ParameterSets : {[AllCommandSet, System.Management.Automation.ParameterSetMetadata
]}
IsDynamic : False
Aliases : {}
Attributes : {AllCommandSet, System.Management.Automation.ValidateNotNullOrEmpt
yAttribute}
SwitchParameter : False
Name : Verb
ParameterType : System.String[]
ParameterSets : {[CmdletSet, System.Management.Automation.ParameterSetMetadata]}
IsDynamic : False
Aliases : {}
Attributes : {CmdletSet}
SwitchParameter : False
Name : Noun
ParameterType : System.String[]
ParameterSets : {[CmdletSet, System.Management.Automation.ParameterSetMetadata]}
IsDynamic : False
Aliases : {}
Attributes : {CmdletSet}
SwitchParameter : False
Name : Module
ParameterType : System.String[]
ParameterSets : {[__AllParameterSets, System.Management.Automation.ParameterSetMet
adata]}
IsDynamic : False
Aliases : {PSSnapin}
Attributes : {System.Management.Automation.AliasAttribute, __AllParameterSets}
SwitchParameter : False
Name : CommandType
ParameterType : System.Management.Automation.CommandTypes
ParameterSets : {[AllCommandSet, System.Management.Automation.ParameterSetMetadata
]}
IsDynamic : False
Aliases : {Type}
Attributes : {System.Management.Automation.AliasAttribute, AllCommandSet}
SwitchParameter : False
<output truncated>
From this output, I can see that some of the parameters do not have aliases (name, verb, noun) but that some of the parameters do have aliases (module and commandtype). I was able to use the information I discovered at this point to write my command to obtain all of the aliases for each of the Windows PowerShell cmdlets. However, you might be interested in seeing the type of object that the above code is working with. It is called a ParameterSetMetadata object, and it is shown here.
PS C:\> (gcm get-command).parameters | % {$_.values | gm}
TypeName: System.Management.Automation.ParameterMetadata
Name MemberType Definition
—- ———- ———-
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Aliases Property System.Collections.ObjectModel.Collection`1[[System.St…
Attributes Property System.Collections.ObjectModel.Collection`1[[System.At…
IsDynamic Property System.Boolean IsDynamic {get;set;}
Name Property System.String Name {get;set;}
ParameterSets Property System.Collections.Generic.Dictionary`2[[System.String…
ParameterType Property System.Type ParameterType {get;set;}
SwitchParameter Property System.Boolean SwitchParameter {get;}
PS C:\>
One thing I should mention, is that even though two Windows PowerShell cmdlets may contain the same parameter, it does not mean that that both cmdlets will use the same parameter alias. This is the value of the list.
I invite you to follow me on Twitter or Facebook. If you have any questions, send email to me at scripter@microsoft.com or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy
0 comments