Get Azure VM Uptime – sorta

Let’s say you have a few virtual machines in Azure, that should only be running for a limited period of time. You want to ensure that they are stopped after that period of time, but you aren’t the one responsible for the service running on the VMs, and as such, want to empower the owner(s) with both the responsibility and capability to determine when that period of time is finished; perhaps with just a bit of nudging…

Thinking about this scenario had me determine, “what if I could find out when a VM uptime exceeds a set value (say 14 days)” and notify someone that “hey, maybe you forgot to turn this off”.

Turns out there isn’t an accessible “uptime” property for an Azure VM. However, there is a time stamp property from the last state change, and that’s what we can use to enable this logic.

The key is to use “Get-AzVM” with the -Status switch. When you run Get-AzVM, you can either return the “model view” or the “instance view” of a collection of virtual machines, or an individual VM. The Microsoft Doc page for this cmdlet describes using the -Status switch to provide the “instance view” which is where we get the properties we’re after.

If you run it for a collection of VMs you can retrieve the PowerState property:

For an individual VM, you get the “Statuses” property, which contains a collection of items:

The first item within the “Statuses” collection is the “ProvisioningState”, which displays (from what I can gather) the most recent provisioning action taken on the VM (starting it, stopping/deallocating it), along with a Time property. The second item is the current PowerState of the VM.

Using this information, I’ve built the PowerShell below to grab all VMs within a subscription, and for each of them evaluate the status against a point-in-time, outputting results for those which are running and where the successful provisioning exceeds the age of that point-in-time.

$comparedate = (get-date).AddDays(-14)
$rg = "resourcegroup"
#Get the Instance view of a collection of virtual machines (returns the PowerState property)
$vms = get-azvm -status -resourcegroup $rg
#Iterate through the collection
foreach ($vm in $vms)
	# only check if the VM is running, because if it's off we don't care
	if ($vm.powerstate -ceq "VM running")
		# Get the instance view of a single virtual machine (returns the "statuses" object)
		$foundvm = get-azvm -resourcegroup $vm.ResourceGroupName -name $vm.Name -status
                # check if time since it was provisioned (in Statuses[0]) is greater than a value
		if ($foundvm.Statuses.Time -le $comparedate)
			write-output "$($ : running longer than 14 days"

Using this PowerShell, you could modify the results to populate an array, and email it to a recipient. This could be placed into an Azure Automation runbook and ran on a schedule.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.