In today's tutorial, I assume you have already installed and configured Azure PowerShell on your administrative workstation. Our goal is simple: we need "at-a-glance" details concerning the running state of all VMs in our current Azure context.
First, you should open an elevated PowerShell session. Second, you should authenticate to Azure by running Add-AzureRmAccount or its alias, Login-AzureRmAccount. Third, you should run Set-AzureRmContext to ensure you're using the proper Azure subscription.
Now we're ready to get down to business!
The default output of the Get-AzureRmVM cmdlet is okay, but it doesn't give you the running state by default. Check out the following screenshot:
We can do better than that! Let's start our experimentation by creating a variable named $dc to hold a reference to my dc VM:
$dc = Get-AzureRmVM -ResourceGroupName 4sysops -Name 'dc' -Status
That -Status switch parameter is actually crucially important, by the way. Now then: if we pipe that variable to Get-Member, we can examine the property data exposed by the PSVirtualMachineInstanceView object:
If you left off -Status in the $dc variable declaration and then piped it to Get-Member, you'd see the properties associated with the PSVirtualMachine object, which doesn't give us enough detail.
The property we're after here is DisplayStatus, which is tucked underneath the Statuses property. Here, let me demonstrate:
PS C:\> $dc.Statuses.DisplayStatus
Are you with me so far? Let's write a simple PowerShell function to give us the run state of all VMs in our current subscription context.
Our script ^
Fire up Visual Studio Code, the PowerShell ISE, or your favorite code editor, and add the following function definition. (For your convenience, you can get the source code by viewing my GitHub Gist.) In this example, I adapted my Pluralsight colleague John Savill's code from an ITProtoday.com article.
$RGs = Get-AzureRMResourceGroup
foreach($RG in $RGs)
$VMs = Get-AzureRmVM -ResourceGroupName $RG.ResourceGroupName
foreach($VM in $VMs)
$VMDetail = Get-AzureRmVM -ResourceGroupName $RG.ResourceGroupName -Name $VM.Name -Status
$RGN = $VMDetail.ResourceGroupName
foreach ($VMStatus in $VMDetail.Statuses)
$VMStatusDetail = $VMStatus.DisplayStatus
Write-Output "Resource Group: $RGN", ("VM Name: " + $VM.Name), "Status: $VMStatusDetail" `n
Let me explain each code line so you understand exactly what's happening:
- 1: I've defined a simple PowerShell function here, but you can make the function much more powerful by making it an advanced function.
- 3: Enumerate all resource groups in the current subscription context.
- 4: Loop through each resource group.
- 6: Define a collection of all VMs across all resource groups.
- 7: Loop through each VM in the collection.
- 9: Obtain the status data for each VM.
- 10: Grab the resource group name for each VM.
- 11: Loop through the status information for each VM.
- 13: Obtain the specific runtime status property information.
- 15: Print the output to the screen in a reader-friendly format.
You can see my function results in the following screenshot. Note that I have one running VM and another one shut down and deallocated.
Extra credit : Obtain Azure VM uptime ^
What if we want to determine how long a particular Windows Server VM in Azure has been up? We can use PowerShell and Azure PowerShell to solve this problem as long as the VM is enabled for WinRM/WS-Man remoting and your network security group (NSG) has an exception for TCP 5985 and 5986.
Given that, we can start by defining a PowerShell remoting session object, specifying the VM's public IPv4 address, and authenticating with a local administrator account:
$sess = New-CimSession -ComputerName '126.96.36.199' -Credential Get-Credential
Next, we obtain a reference to the system's Win32_OperatingSystem CIM class:
$os = Get-CimInstance -CimSession $sess -ClassName Win32_OperatingSystem
Notice in the previous code we plug in our $sess session data. Once there, we can pluck CIM data from the Azure VM seamlessly.
Given that action, we can perform simple subtraction from the current date/time to get the system uptime; the system's last startup time is stored in the LastBootUpTime property:
$uptime = (Get-Date) - $os.LastBootUpTime
Lastly, we can use simple string concatenation to display our output:
$Display = "Uptime: "+ $uptime.Days + " days, " + $uptime.Hours + " hours, " + $uptime.Minutes + " minutes"
The output will look something like the following:
Uptime: 0 days, 6 hours, 9 minutes
Your homework assignment is to integrate this uptime routine into the original Get-ARMVM code. Feel free to put your results in the comments so we can all benefit. Happy coding!