Retrieve And Mail Azure Resource Manager Virtual Machine Status Using PowerShell

Azure originally provided only the classic deployment model. In this model, each resource existed independently; there was no way to group related resources together. In 2014, Azure introduced Resource Manager which added the concept of a resource group. A resource group is a container for resources that share a common lifecycle. Virtual Machines that are created using ARM Templates can be monitored using PowerShell and status can be mailed to business users to monitor Azure VMs. It can happen that the Azure VMs are not shut down after use which can incur considerable costs for non-usage.

Currently, there are two VMs in the subscription out of which one is stopped and another one is in a running state. Let’s connect to Azure using PowerShell to retrieve the VM status.

Azure

Connect to Azure from PowerShell

PowerShell requires Azure PowerShell module to be installed in the machine so that we can connect to Azure using the ‘Login-azureRMAccount’ cmdlet. If the Azure module is not installed, we will get the below error message when we try to login to Azure.

Azure

We can download the Azure PowerShell module from here.Once downloaded, install Azure PowerShell.

Azure

Post installation of Azure PowerShell, we can connect to Azure using the below cmdlet :

Login-AzureRmAccount

Azure

Now, we can specify the Azure Subscription credentials in the pop up authentication window to connect to Azure.

Azure

Thus, we have connected to the Azure and it returns the Azure Subscription details.

Azure

Retrieve Azure Resource Manager Virtual Machine Status

Resource Group acts as a container for the Azure resources. The Virtual Machines will be created within Resource groups. We will use ‘Get-AzureRMResourceGroup’ cmdlet to get all the resource groups within the Azure Subscription. We will, then, iterate through the VM within each resource group to get the status of the VMs. 

  1. $ResourceGroupColl = Get-AzureRMResourceGroup  
  2. foreach($ResourceGroup in $ResourceGroupColl)  
  3. {  
  4.     $VirtualMachines = Get-AzureRmVM -ResourceGroupName $ResourceGroup.ResourceGroupName  
  5.     foreach($VirtualMachine in $VirtualMachines)  
  6.     {  
  7.         $VMInfo = Get-AzureRmVM -ResourceGroupName $ResourceGroup.ResourceGroupName -Name $VirtualMachine.Name -Status  
  8.         foreach ($Status in $VMInfo.Statuses)  
  9.         {   
  10.           
  11.             if($Status.Code -like "PowerState/*")  
  12.             {  
  13.                 $VMDetails = $Status.DisplayStatus  
  14.             }  
  15.         }  
  16.         $VMName = $VirtualMachine.Name     
  17.     Write-Host "VM Name : $VMName    -----  $VMDetails "  
  18.         $Body = $Body + " <br /> VM Name : $VMName    -----  $VMDetails "   
  19.     }  
  20. }   

Send Mail using PowerShell

Once the information is retrieved, we can use the Gmail SMTP Mail Server to send the details as emails to the business users. In order to send an E-mail from PowerShell, we need to specify the SMTP Server. We will be using Gmail SMTP to relay the mails. We will have to fill out couple of parameters before triggering the ‘Send-MailMessage’ command, which will relay the email.

  • $SmtpServer = 'smtp.gmail.com' – This is the address of Gmail SMTP Server, which we will be using.
  • $SmtpUser = ‘[email protected]’ – Specify your Gmail User ID.
  • $smtpPassword = ‘<Input Gmail Account Password Here>’ – Specify your Gmail account password.
  • $MailtTo = ‘[email protected] ' – Specify the users to which the mails should be sent.
  • $MailFrom = ‘[email protected]’ – Specify the source Email ID.
  • $MailSubject = "Test using $SmtpServer" – This is the mail subject line.

Finally, create a credential object, using the user name and the password, which we have entered above.

  • $Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SmtpUser, $($smtpPassword | ConvertTo-SecureString -AsPlainText -Force)

    Azure

    Ensure that the credentials are correct, else we will get the error given above. Thus, we have set up the parameters. Now, we can call the Send-MailMessage command to send the mail to the users, as shown below,

  • Send-MailMessage -To "$MailtTo" -from "$MailFrom" -Subject $MailSubject -Body "$Body" -SmtpServer $SmtpServer -BodyAsHtml -UseSsl -Credential $Credentials

Full code to Retrieve the VM Status (This does not apply to Classic VMs) 

  1. $Body =''  
  2. $ResourceGroupColl = Get-AzureRMResourceGroup  
  3. foreach($ResourceGroup in $ResourceGroupColl)  
  4. {  
  5.     $VirtualMachines = Get-AzureRmVM -ResourceGroupName $ResourceGroup.ResourceGroupName  
  6.     foreach($VirtualMachine in $VirtualMachines)  
  7.     {  
  8.         $VMInfo = Get-AzureRmVM -ResourceGroupName $ResourceGroup.ResourceGroupName -Name $VirtualMachine.Name -Status  
  9.         foreach ($Status in $VMInfo.Statuses)  
  10.         {   
  11.           
  12.             if($Status.Code -like "PowerState/*")  
  13.             {  
  14.                 $VMDetails = $Status.DisplayStatus  
  15.             }  
  16.         }  
  17.         $VMName = $VirtualMachine.Name     
  18.     Write-Host "VM Name : $VMName    -----  $VMDetails "  
  19.         $Body = $Body + " <br /> VM Name : $VMName    -----  $VMDetails "   
  20.     }  
  21. }  
  22.   
  23. $SmtpServer = 'smtp.gmail.com'    
  24. $SmtpUser = '[email protected]'    
  25. $smtpPassword = ‘<Input Gmail Account Password Here >’    
  26. $MailtTo = '[email protected]'    
  27. $MailFrom = '[email protected]'    
  28. $MailSubject = "Azure VM Status"    
  29. $Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SmtpUser, $($smtpPassword | ConvertTo-SecureString -AsPlainText -Force)    
  30. Send-MailMessage -To "$MailtTo" -from "$MailFrom" -Subject $MailSubject -Body "$Body" -SmtpServer $SmtpServer -BodyAsHtml -UseSsl -Credential $Credentials    
  31. write-Output " `r`n Custom Message : Azure VM Status Email Sent to Business Users"    

PowerShell Output

Running the above script will display the VM Status, as shown below.

Azure

It has sent the status as an Email to business users as well.

Azure

Automate the Script

As a part of extending functionality, we can automate the running of the script by setting PowerShell script using Task Scheduler. This way, the script will run at the specified intervals and it will read the Azure Resource Manager Virtual Machine status and email it to the business users. This will help in cost savings as unintended Virtual Machine running in the cloud incurs considerable cost.

Summary

Thus, we saw how to get the Azure Resource Manager VM Status using PowerShell and mail it to business users