Using PowerShell to add custom properties to Hyper-V virtual machines

One of the more underrated features in System Center Virtual Machine Manager is the ability to associate custom properties with virtual machines. Custom properties allow you to store your own key/value pairs within a VM’s attributes. For example, I recently heard of someone using custom properties as a mechanism for storing an expiration date for virtual machines. Similarly, a custom property might be used to store the name of the person or department who created the virtual machines, to differentiate between a production and a lab VM, or to list the VM’s guest OS or the applications that the VM runs.

You can, of course, create or manage custom properties from within the Virtual Machine Manager console. To do so, go to the VMs and Services workspace, right click on a virtual machine, and select the Properties command from the shortcut menu. The custom properties are listed on the virtual machine’s properties sheet on the Custom Properties tab, which you can see in the figure below.

As you look at the figure above, you will notice a button labeled Manage Custom Properties. Clicking on this button takes you to a screen that allows you to create your own named custom properties. If you look at the screen capture shown below, you will notice that the Manage Custom Properties screen contains an available property named Owner. I created this property by clicking the Create button and typing Owner. If I wanted to assign this custom property to virtual machines, I would simply select it, and click Add.

Upon adding the Owner property to the VM, it is listed on the VM’s list of custom properties, as shown below. Now I can add a value to the property if I want.

Custom properties in PowerShell

So now that I have shown you how custom properties work, let’s take a look at how to use custom properties in PowerShell. It is worth noting that I am working from the Virtual Machine Manager Command Shell.

If I wanted to see a list of all of the custom properties that exist within Virtual Machine Manager, I could use this command:

Get-SCCustomProperty | Select-Object Name

As you can see in the figure below, the Select-Object Name portion of the command filters the output so that PowerShell displays only the name of the custom property.

Now let’s suppose that we want to create a brand new custom property called GuestOS. To do so, we could use the New-SCCustomProperty cmdlet. The cmdlet requires us to specify the name of the new custom property, and to specify the type of object that the custom property should apply to. Because we are assigning the custom property to VMs, the object type (which we will specify through the AddMember parameter) will be set to VM. The command used for doing so is:

New-SCCustomProperty -Name “GuestOS” -AddMember “VM”

The figure below shows this command in action. In the figure, I have used the Get-SCCustomProperty command to verify that the new GuestOS custom property has indeed been added.

Associating the custom property with virtual machines

Although I have created a new custom property called GuestOS, none of my VMs are currently using this custom property. If I want to associate the custom property with a VM and populate the custom property with a value, I will have to use the Set-SCCustomPropertyValue cmdlet. This cmdlet requires you to specify the input object (the name of a VM), the name of the custom property, and the value that you want to assign to the custom property. However, there is a catch.

For whatever reason, this cmdlet will not allow you to enter the name of a virtual machine directly. Instead, you are going to need to assign the virtual machine name to a variable. Actually, to be more technically precise, you are not assigning just the virtual machine’s name, but rather an entire System Center Virtual Machine Manager virtual machine object.

Similarly, you can’t just list the custom property by name either. Instead, you have to reference it through the Get-SCCustomProperty command, and then assign it to a variable.

Suppose for example, that I want to assign a value of “Windows” to the GuestOS property on a VM named Sentinel. The first thing that I would have to do is to set up a variable, in this case, $VM, to contain the virtual machine object for Sentinel. Next, I need to set up another variable (I’m using $CustomProperty) and associate it with the Get-SCCustomProperty cmdlet. Finally, I could then reference those variables, along with the desired value of Windows in the last line of code. Here is what it all looks like:

$VM = Get-SCVirtualMachine -Name “Sentinel”
$CustomProperty = Get-SCCustomProperty -Name “GuestOS”
Set-SCCustomPropertyValue -InputObject $VM -CustomProperty $CustomProperty -Value “Windows”

You can see these commands in action in the figure below.

As you can see in the figure, PowerShell generates a relatively verbose output. But what if some time has passed, and I want to see the value of the GuestOS property? Well, remember those variables that I just created? As it turns out, I can reuse those variables. Here is the command:

Get-SCCustomPropertyValue -InputObject $VM -CustomProperty $CustomProperty | Select-Object Name, Value

You can see the command’s output below:

Custom properties are admittedly a little bit tough to work within PowerShell, and so you probably would not use PowerShell if you only needed to set up a property or two on your virtual machines. If however, you needed to bulk assign custom properties or wanted to populate custom properties as a part of the VM creation process, PowerShell is the way to go.

Photo credit: Shutterstock