PowerShell: Add Unique IDs to Your Objects

If you’re developing interactive PowerShell scripts, that frequently prompt for user input, it is often desirable to uniquely identify objects. Enabling the end user to select the object that they wish to operate on, in a simple fashion, reduces the amount of end user effort required to operate the script.

For example, if you are working with the Azure PowerShell module, and are performing operations on Azure virtual machines, you will frequently find that you must specify the Cloud Service container’s name, and the virtual machine’s name. This is inherent to the existing Azure architecture, because virtual machines must be contained inside of a Cloud Service object.

2015-02-18 19_08_49-Windows PowerShell ISE Rather than requiring the end user of your PowerShell script to type the Cloud Service name and the virtual machine name, you might want to simplify things for the user, by allowing them to easily specify a unique identifier. The default output of the Get-AzureVM command provides the Cloud Service Name, the virtual machine name, and the state of the virtual machine. But what if we added a custom, unique identifier to each object, to simplify the end user’s process of selecting a specific VM to operate on?

PowerShell has always provided a command called Add-Member, which allows us to dynamically add properties and methods to PowerShell objects. We can use this command to our advantage, to simplify the object selection process. By augmenting each object output from the Get-AzureVM command, using Add-Member, we can add a simple integer that uniquely identifies each virtual machine.

The following code shows how to achieve this, using the shorthand for the ForEach-Object command, the percent sign %.

### Get a list of virtual machines and add a unique ID to each one
$VMList = Get-AzureVM | % { Add-Member -InputObject $PSItem -MemberType NoteProperty -Name Id -Value ($i++) -PassThru; };

### Output the list of virtual machines
$VMList | Format-Table -Property ServiceName,Name,Id -AutoSize;

2015-02-18 19_13_37-Windows PowerShell ISE Now, rather than seeing the default output from Get-AzureVM, we have augmented the objects with a custom Id property. The end user can be prompted for the unique ID of the VM rather than having to type the Cloud Service and virtual machine name.

Using the Read-Host command, we can prompt the end user for the unique ID of the object they want to operate on, and then perform some function on that particular object. We can use PowerShell 4.0’s Where() method syntax to select only the virtual machine that the user specifies, based on its unique ID. Finally, we can call a command, such as Get-AzureRemoteDesktopFile, and pass in the virtual machine’s Cloud Service name, and the virtual machine name, resulting in a much easier end user experience.

### Prompt the user for the ID of the virtual machine to operate on
$VMNumber = Read-Host -Prompt 'Which VM should we operate on?';

### Retrieve the virtual machine with the specified unique ID
$VM = $VMList.Where({ $PSItem.Id -eq $VMNumber; }, 'First');
Write-Host -Object ('Operating on VM {0} in cloud service {1}' -f $VM.Name, $VM.ServiceName) -ForegroundColor Green;

### Invoke a RDP session to the virtual machine
Get-AzureRemoteDesktopFile -ServiceName $VM.ServiceName -Name $VM.Name -Launch;

2015-02-18 19_19_46-Windows PowerShell ISE