Create VM annotation based on deployed template name

I was recently looking to create a virtual machine annotation type to include the template name to which a virtual machine was deployed from.

I was able to achieve this by using the Get-VIEvent cmdlet to return a match for a virtual machine where the event was equal to “VmBeingDeployedEvent” and formatting the output string to only include the template name.

As I plan to run the above as a scheduled task, I will load the PowerCLI snap-in in the current powershell session and connect to a vcenter server (in this example, server1.domain.local).

If (-not (Get-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue)) 
   Add-PSSnapin VMware.VimAutomation.Core

Connect-VIServer server1.domain.local

Firstly, I wanted to return a collection of virtual machines and to check from the first virtual machine if the annotation ‘Template’ exists and if not create this object

$VMS = Get-VM 
$VM = $VMs | Select -First 1
If (-not $vm.CustomFields.ContainsKey("Template")) 
   New-CustomAttribute -TargetType VirtualMachine -Name Template | Out-Null

Now, that we have created the annotation if this currently did not exist, we will now query each virtual machine in the collection to determine if an event is returned for “VmBeingDeployedEvent”.

ForEach ($VM in $VMs)
   $Event = $VM | Get-VIEvent -Types Info | Where-Object {$_.Gettype().Name-eq "VmBeingDeployedEvent"}

The FullFormatMessage property returned will have a string relating to the “VmBeingDeployedEvent” which will identity the template used for the VM, the string is expected as below:

"Deploying <virtual machine> on host <Host> in <Cluster> from template <template name>"

If the $Event.FullFormatMessage contains ‘template’ in the returned string, the string will be manipulated to only return characters after the word template, which will allow for the template name to be stored as a variable. The returned variable will then be used to set the value for the annotation using the Set-CustomField cmdlet.

If ($Event.FullFormattedMessage -like "*template*") 
   $Template = $Event.FullFormattedMessage  | select-string -pattern '(?<=template)(.*)'  |  select -expa matches | select -expa value |  % { $_.trim() }
   $VM | Set-CustomField -Name "Template" -Value $Template

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s