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.
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 ‘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 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)
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)
- $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 = '[email protected]'
- $smtpPassword = ‘<Input Gmail Account Password Here >’
- $MailtTo = '[email protected]'
- $MailFrom = '[email protected]'
- $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 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