Introduction



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 2 VMs in the subscription out of which one is stopped and another one is in running state. Let’s connect to Azure using PowerShell to retrieve the VM status.


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.

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

 


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

Login-AzureRmAccount

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

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



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 the ‘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.

$ResourceGroupColl = Get-AzureRMResourceGroup
foreach($ResourceGroup in $ResourceGroupColl)
{
    $VirtualMachines = Get-AzureRmVM -ResourceGroupName $ResourceGroup.ResourceGroupName
    foreach($VirtualMachine in $VirtualMachines)
    {
        $VMInfo = Get-AzureRmVM -ResourceGroupName $ResourceGroup.ResourceGroupName -Name $VirtualMachine.Name -Status
        foreach ($Status in $VMInfo.Statuses)
        {                           
 
            if($Status.Code -like "PowerState/*")
            {
                $VMDetails = $Status.DisplayStatus
            }
        }
        $VMName = $VirtualMachine.Name 
                Write-Host "VM Name : $VMName    -----  $VMDetails "
 
        $Body = $Body + " <br /> VM Name : $VMName    -----  $VMDetails "
    }
}


Send Mail using PowerShell

Once the information is retrieved we can use the Gmail SMTP mail server to send the details to the business users as email. In order to send an E-mail from PowerShell, we will need to specify SMPTP 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 = ‘kspriyaranjan@gmail.com’ – Specify your Gmail User ID.
  • $smtpPassword = ‘<Input Gmail Account Password Here>’ – Specify your Gmail account password.
  • $MailtTo = ‘priyaranjan.ks@hotmail.com ' – Specify the users to which the mails should be sent.
  • $MailFrom = ‘kspriyaranjan@gmail.com’ – 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.

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



    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:
  1. 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)

$Body =''
 
$ResourceGroupColl = Get-AzureRMResourceGroup
 
foreach($ResourceGroup in $ResourceGroupColl)
 
{
 
    $VirtualMachines = Get-AzureRmVM -ResourceGroupName $ResourceGroup.ResourceGroupName
 
    foreach($VirtualMachine in $VirtualMachines)
 
    { 
        $VMInfo = Get-AzureRmVM -ResourceGroupName $ResourceGroup.ResourceGroupName -Name $VirtualMachine.Name -Status 
        foreach ($Status in $VMInfo.Statuses) 
        {                                 
             if($Status.Code -like "PowerState/*") 
            { 
                $VMDetails = $Status.DisplayStatus 
            } 
        } 
        $VMName = $VirtualMachine.Name  
                Write-Host "VM Name : $VMName    -----  $VMDetails " 
        $Body = $Body + " <br /> VM Name : $VMName    -----  $VMDetails " 
    } 
}
  
 
$SmtpServer = 'smtp.gmail.com' 
$SmtpUser = 'kspriyaranjan@gmail.com' 
$smtpPassword = '<Input Gmail Account Password Here >'
$MailtTo = 'priyaranjan.ks@hotmail.com' 
$MailFrom = 'kspriyaranjan@gmail.com' 
$MailSubject = "Azure VM Status"
 
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SmtpUser, $($smtpPassword | ConvertTo-SecureString -AsPlainText -Force)
 
Send-MailMessage -To "$MailtTo" -from "$MailFrom" -Subject $MailSubject -Body "$Body" -SmtpServer $SmtpServer -BodyAsHtml -UseSsl -Credential $Credentials
 
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:

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


Automate the Script

As a part of extending the functionality, we can automate the running of the script by setting the PowerShell script using Task Scheduler. This way the script will run at 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 un intended 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