January 15th, 2011

Weekend Scripter: Discovering PowerShell Cmdlet Parameter Aliases

  

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

Author

0 comments

Discussion are closed.