- Manage Azure PowerShell global settings - Fri, Sep 22 2023
- Create and manage append blobs with PowerShell - Wed, Oct 12 2022
- Permanently delete a Key Vault in Azure using PowerShell - Fri, Feb 4 2022
Defining Azure resources
Even though you've set your Azure resource limits to high values, it might still be critical to create consumption reports regularly. This is especially true for organizations that frequently create large numbers of resources in a dynamic way.
First, I'd like to list my current resources in a particular subscription:
Get-AzureRmResource | select name
This command shows us all resources in a subscription. However, this does not give us a complete report of all resource types and usage details.
In case we need to see how many virtual machines (VMs) are already in use, we can execute this command:
(get-azurermvm).count
However, this command does not give us the maximum number of allowed VMs. You can view the limit for each resource available in Azure. But this is a huge list showing each resource with details for limits and quotas. The Azure PowerShell Module version 4.1.0 (or later) has the ability to list all resources with corresponding limit values.
Resource usage reports
Three cmdlets allow us to get a usage report for a particular Azure location. This point is important because each Azure location has its own separate limits, which may differ from one location to another. This is why we need to specify a value for the -Location parameter.
$location="WestEurope" Get-AzureRmVMUsage -Location $location
Get-AzureRmStorageUsage | select name,currentvalue,limit
Current usage of Azure RM storage accounts, location independent
Get-AzureRmNetworkUsage -Location $location | select resourcetype,currentvalue,limit
Combining reports
Now we should combine all three of the cmdlets above using custom formatting. We need to make sure the output for each cmdlet has the same column structure so we can have a single table showing all results in it. To achieve this, we'll get them aligned in a single view by giving columns identical names.
The column names are Name, CurrentValue, and Limit:
$location="westeurope" $vms=Get-AzureRmVMUsage -Location $location | select @{label="Name";expression={$_.name.LocalizedValue}},currentvalue,limit $storages=Get-AzureRmStorageUsage | select name,currentvalue,limit $networks=Get-AzureRmNetworkUsage -Location $location | select @{label="Name";expression={$_.resourcetype}},currentvalue,limit $result=$vms+$storages+$networks $result
Now we are able to see all the results in a single table:
Combination of VM, storage, and network resource usage reports
With the help of the Out-Gridview cmdlet, we can display the output in an interactive table:
$result | Out-gridview
Grid view of the consumption report
By doing this, we've created a complete table listing all details we need in terms of resource limits and consumptions.
Reporting usage limits
Let's take this one step further by adding a usage check feature. For instance, you may want to get notified in case you start running out of VMs before you hit the limit. Even though Azure limits are not that restricted, we can make sure we have a sufficient amount of resources to use before it's too late. It makes sense to send a notification when 80 percent of a certain resource has been consumed. The script below checks the values and sends you a daily report with resource details using the Send-MailMessage cmdlet.
The code below will do the trick. Note: I've set the limit to 4% to be able to test it. You can change it to any value you like.
cls $location="westeurope" $vms=Get-AzureRmVMUsage -Location $location | select @{label="Name";expression={$_.name.LocalizedValue}},currentvalue,limit,@{label="PercentageUsed";expression={[math]::Round(($_.currentvalue/$_.limit)*100,1)}} $storages=Get-AzureRmStorageUsage | select name,currentvalue,limit,@{label="PercentageUsed";expression={[math]::Round(($_.currentvalue/$_.limit)*100,1)}} $networks=Get-AzureRmNetworkUsage -Location $location | select @{label="Name";expression={$_.resourcetype}},currentvalue,limit,@{label="PercentageUsed";expression={[math]::Round(($_.currentvalue/$_.limit)*100,1)}} $result=$vms+$storages+$networks $warning=@() foreach($resource in $result){ if($resource.percentageused -gt 4){ $Warning+=$resource } } $body=$warning | convertto-html $bodyhtml=@" <P> ------------------------------------------- The resources that are about to hit their warning levels ------------------------------------------- <P> $body "@ if($warning.count -gt 0){ Send-MailMessage -BodyAsHtml -body $bodyhtml -Subject "Azure Resource Consumption Report" -SmtpServer smtp.office365.com -UseSsl -From onur.okutucu@clouderz.com -to onur.okutucu@clouderz.com -Credential (get-credential) -Port 587 }
The script sends you a consumption report showing the resources that are hitting their limits.
Hi,
This script is fantastic, but I have problem in my scenario. I want to capture the Number of NSG Rules within the NSG. The command
Get-AzureRmNetworkUsage -Location $location | select resourcetype,currentvalue,limit
Result: I am NOT getting the actual currentvalue on the number of rules instead I get zero. But in portal I have 146 rules.
Any help…
Thanks,
K. Hasan
Hi Hasan,
Please use the following command to get the number of rules defined within a Network Security group
((Get-AzureRmNetworkSecurityGroup -Name “NSGName” -ResourceGroupName “ResourceGroupName”).securityrules).count
To be more specific, you can also narrow down the result specifying the direction (Inbound or Outbound)
for Inbound Rules
((Get-AzureRmNetworkSecurityGroup -Name “NSGName” -ResourceGroupName “ResourceGroupName”).securityrules | where{$_.direction -eq “Inbound”}).count
for Outbound Rules
((Get-AzureRmNetworkSecurityGroup -Name “NSGName” -ResourceGroupName “ResourceGroupName”).securityrules | where{$_.direction -eq “Outbound”}).count
thanks
Onur
It works. Thanks
Hi,
Great article.
One question, with syntax for Get-AzureRmStorageUsage it is not possible to set location/region. Accordin to MS docs it states ” The Get-AzureRmStorageUsage cmdlet gets the resource usage for Azure Storage for the current subscription.” However I’ve noticed that this is not true, and the current value doesn’t match the actuall value of storage accounts across several regions, and since the limitation for storage account is per region, this would have been great.
Do you have any idea, how to secure that you get present with the correct value per region for storage accounts?
Regards,
+ fun fact
I’ve also noticed that CurrentValue you get from running Get-AzureRmStorageUsage does not match that actuall items I see if i go to Storage Account blade in the Azure portal.
Hi, I want to see idle time of all azure resources running ( preferably by day/hour ) How can i achieve this?