Summary: In preparation for creating a Windows PowerShell ISE add-on to automatically remove aliases, Scripting Guy Ed Wilson builds a hash table with alias definitions.

Microsoft Scripting Guy, Ed Wilson, here. It has finally happened, I unveiled the last event of the 2011 Windows PowerShell Scripting Games on Friday. Contestants still have a week to deliver their solutions for the remaining events, but the games are drawing to a conclusion.

The judging criteria for the 2011 Scripting Games are not arbitrary, but they actually represent best practices to incorporate when writing enterprise production scripts. One of those guidelines is to not use Windows PowerShell cmdlet aliases in a script. This causes a few problems for people, because when working interactively from the Windows PowerShell console, the use of aliases is encouraged because it simplifies typing and allows one to get the task accomplished more quickly.

Because I use the Windows PowerShell console for prototyping commands prior to incorporating them into the Windows PowerShell ISE, I often copy code from the console and paste it into the Windows PowerShell ISE. This causes a dilemma—I like to use aliases in the Windows PowerShell console, but in a script, I should not use aliases. Therefore, when prototyping a command, I have two choices: do not use aliases, or rewrite all my code after I paste it into the Windows PowerShell ISE. Neither choice is great, but until recently those were my two options.

While I was grading some of the scripts for the 2011 Scripting Games, a third option to the problem of aliases came to me: Write a script and have it replace all aliases with the full cmdlet names.

Today’s blog is the first of a series of four that will discuss the parts of my solution to the problem of working with aliases. In this blog, I want to create a hash table and populate it with all of the available aliases. The code that accomplishes this task is shown here.

New-HashTableWithAliases.ps1

Get-Alias |

 Select-object name, definition |

 Foreach-object -begin {$a = @{} } `

                -process { $a.add($_.name,$_.definition)} `

                -end {$a}

The Get-Alias cmdlet returns a list of aliases and their associated definitions. Each alias that is returned by this cmdlet is an instance of an aliasinfo object. The members of that object are shown here.

PS C:\> Get-Alias | Get-Member

 

TypeName: System.Management.Automation.AliasInfo

 

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...

Definition          Property       System.String Definition {get;}

Description         Property       System.String Description {get;set;}

Module              Property       System.Management.Automation.PSModuleInfo Modu...

ModuleName          Property       System.String ModuleName {get;}

Name                Property       System.String Name {get;}

Options             Property       System.Management.Automation.ScopedItemOptions...

OutputType          Property       System.Collections.ObjectModel.ReadOnlyCollect...

Parameters          Property       System.Collections.Generic.Dictionary`2[[Syste...

ParameterSets       Property       System.Collections.ObjectModel.ReadOnlyCollect...

ReferencedCommand   Property       System.Management.Automation.CommandInfo Refer...

ResolvedCommand     Property       System.Management.Automation.CommandInfo Resol...

Visibility          Property       System.Management.Automation.SessionStateEntry...

HelpUri             ScriptProperty System.Object HelpUri {get=try...

ResolvedCommandName ScriptProperty System.Object ResolvedCommandName {get=$this.R...

There are two properties from the aliasinfo object that I want to retrieve: the name and the definition. The name property is the actual alias itself; the definition property is the full cmdlet name that resolves to the alias. The following code illustrates this concept by using the Get-Alias cmdlet to retrieve the alias named gps.

PS C:\> Get-Alias gps

 

CommandType     Name                               Definition

-----------     ----                               ----------

Alias           gps                                Get-Process

To retrieve only the name and the definition from all of the aliases, I use the code seen here.

Get-Alias |

 Select-Object name, definition

The command to retrieve aliases and definitions and the associated output are shown here.

Image of command output

When I have the aliases and their associated definition, I create a hash table for storage. The name will be the key property because all aliases have to be unique. The definition will be the value that is associated with the key because there could be several aliases for a single cmdlet.

To create an empty hash table, I use the syntax shown here where I store the empty hash table in the $a variable. I only need to perform this action once, so I place this command in the begin portion of the Foreach-Object cmdlet.

-begin {$a = @{} }}

To add to the hash table, I use the add method. The first item is the key, and the second item is the value. In this example, I am adding the name as the key and the definition as the value. I will add each alias and its associated definition as they flow through the Foreach-Object cmdlet. Therefore, this section goes into the process portion of the command. Here is that portion of the script.

-process { $a.add($_.name,$_.definition)}

The last thing I do here, is to display the contents of the hash table that is stored in the $a variable. This action will occur after everything else has completed; and therefore, it appears in the end portion of the ForEach-Object cmdlet.

-end {$a}

The script and its associated output are shown in the following image.

Image of command output

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy