Display number of running Azure VM's on a dashboard - azure

I'd like to create a dashboard in the Azure Portal that displays the number of active virtual machines per resource group. In this case I'm not interested in any deallocated or stopped VM's.
Since filtering the virtual machines blade doesn't work for the VM's power state, I turned to the Resource Graph. From there the solution gets close, but it doesn't seem possible to filter on power state (yet).
resources
| where type == "microsoft.compute/virtualmachines"
| summarize count() by resourceGroup
| order by resourceGroup asc
Is there a way to combine this data with another data table to be able to filter on power state and get only the running virtual machines? Or maybe a different solution altogether to just display the number of running VM's on a dashboard?

There doesn't seem to be a table that holds the PowerState of the VM in the Resource Graph schema (at least I couldn't find it)
Since you had stated that you would also like to hear about altogether a different approach, I want to suggest the PowerShell route
You can get the PowerState of the VM using the below command
Get-AzVM -Status
This output you may write to a Azure table storage. (this link has details of how to use PowerShell to interact with Azure Storage Accounts [https://learn.microsoft.com/en-us/azure/storage/tables/table-storage-how-to-use-powershell]
You can build a Power BI report on top of this table storage filtering only for PowerState == running and light up your report.
Now to schedule this, you will need to
a) Create an Automation Account. Details on how to create automation account can be found here [https://learn.microsoft.com/en-us/azure/automation/automation-create-standalone-account]
b) Create a PowerShell runbook which get the VM status and inserts rows to table storage
c) Create a schedule and link the runbook to it.
Details on how to schedule can be found here [https://learn.microsoft.com/en-us/azure/automation/shared-resources/schedules]
Thus, using Azure Automation Account and a Runbook (point b) you can setup a schedule and link the runbook with that schedule. Whenever the runbook executes it gets the current powerstatus and uploads it to Azure Table storage as per the schedule which would keep the PowerBI updated.
Hope this helps

hope the example below works for you
resources
| where type == "microsoft.compute/virtualmachines"
| where properties.extended.instanceView.powerState.displayStatus=="VM running"
| summarize count() by resourceGroup
| order by resourceGroup asc
Cheers,

Related

How do you see the availabilty zones of an Azure Data Explorer Cluster?

It's mentioned in the Microsoft Docs that an Azure Data Explorer Cluster can be created with availablity zones, but not edited after creation.
We have an existing cluster where I am trying to see if it was created with availablity zones selected, however I cannot work out where to find this within the Azure Portal. Maybe a very dumb question but where can I go to check if my instance has availability zones set up?
Thanks
You see the availability zones of a particular Adx cluster either from portal, PowerShell cmdlets or through by using Azure management Rest API's.
Using Get-AzKustoCluster cmdlet to list the properties of the cluster.
get-azkustocluster -ResourceGroupName <ResourceGroupName> -Name <ClusterName> | select -Property Name,Zone
Cluster-Get REST API to get the information about cluster and it's properties.
https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Kusto/clusters/{clusterName}?api-version=2022-07-07
From Azure Portal in the overview page under instance count as shown in below image

Unable to get Cost details for right-sizing Azure VMs using get-azadvisoreecommendations Powershell cmdlet

I'm trying to build a custom report showing the cost savings figures from Azure Cost Advisor, using the get-azadvisorrecommendation cmdlet. I can get the VM reservation savings amount, but for right-sizing advice it doesn't give me the savings amounts, however these show in the portal.
There is an extendedproperties value, but this only gives:
--- -----
MaxCpuP95 9
MaxTotalNetworkP95 0
MaxMemoryP95 38
deploymentId 02538ce8-c03d-4fa9-b2bc-136096896b64
roleName GW-BRS-2ivi
currentSku Standard_F4s
targetSku Standard_B4ms
How can I get the Savings amount values?
We have tested our local environment, our local environment has the azure advisor recommendations for cosmos db.
Based on the azure advisor recommendations we have used the below PowerShell cmdlet to pull the saving cost using the get-azureadvisorrecommendations cmdlet
Get-AzAdvisorRecommendation -Category Cost | Where-Object {$_.ImpactedField -eq "microsoft.documentdb/databaseaccounts"} | Select-Object -ExpandProperty ExtendedProperties
Here is the sample output for reference :
Alternatively, You can use use MSGraph to accomplish this.
Azure Advisor API documentation contains Reccomendations Operation Category which will give you ability to programmatically get Azure Advisor Recommendations.
There is also an official Microsoft.Graph module available on the PowerShell Gallery.
Here is the reference output pulling the savings cost using the resource graph explorer from portal.
Here is the reference SO Thread.
Note : If my answer is helpful for you, you can accept it as answer( click on the check mark beside the answer to toggle it from greyed out to filled in.). This can be beneficial to other community members. Thank you

KQL Query to retrieve Azure Subscription Name, Resource Group, Resource Name, Resource Type, Tags and Location

I would like to retrieve all the resource names along with their types belonging to a particular subscription and resource group, along with the tags of the resources.
I should be able to dump them in a CSV file where the first column would be subscription, then resource group followed by resource name, type and tags. I should be able to filter the CSV as to what i need to see.
I need to run this for all my subscriptions in a particular tenant so that i get this information for all subscriptions in my tenant.
Can anyone please help me writing a KQL query for this so that i can run from the portal.
Thanks
had a similar challenge with KQL to provide a user friendly names for Subscriptions in Azure Workbooks. I found a solution on link
The trick is to list the subscriptionnames from the table resourcecontainers and then join the results with your resources query
The answer to your question will look like this:
resources
| join kind=inner (
resourcecontainers
| where type == 'microsoft.resources/subscriptions'
| project subscriptionId, subscriptionName = name)
on subscriptionId
| project subscriptionName, resourceGroup, name, type, tags
Using KQL in Azure Resource Graph is actually an ideal way to retrieve this information. You can run the KQL queries from the Azure Portal using Resource Graph Explorer then export (or use PowerShell with the Search-AzGraph cmdlet and pipe to Export-Csv).
Resource Graph allows queries to the ARM graph backend using KQL, which is an extremely powerful and preferred method to access Azure configuration data. All subscriptions in the tenant are in scope by default (if checked off).
Please review Resource Graph concepts and query samples in Microsoft's docs:
Explore your Azure resources with Resource Graph
Starter Resource Graph query samples
Advanced Resource Graph query samples
Query below; if you choose to export all subscriptions and RGs at once just remove the subscriptionId and resourceGroup where clauses:
resources | where subscriptionId == "subscription-id-here" | where resourceGroup == "rg-name-here" | project subscriptionId, resourceGroup, name, type, tags
Yes, #Ivan is right. KQL is certainly not meant for this purpose. Kusto query language, or KQL is the primary means of interaction with Azure Data Explorer and work with log data on Azure.
The simplest way to get this information about your Azure resources is from the Azure Portal itself, by viewing and filtering Azure resource information.
As your query spans across your Subscriptions, you could also run queries from Azure Resource Graph.
Azure PowerShell and Azure CLI would be other great ways to get detailed information about your Azure resources. Here is another post with a similar ask.

Get Azure VM creation date

Is there a possible way to get the VM creation date ?
I've tried the following by now
AzureActivity
| where TimeGenerated > ago(90d)
| where ResourceProvider == "Microsoft.Compute" and OperationName == "Create or Update Virtual Machine"
| project Resource ,Datum = format_datetime(EventSubmissionTimestamp, 'MM') ,Caller
| distinct Datum , Resource , Caller
| order by Datum
This kusto query will read the logs from the VM's connected to it. and get all the Create or update virtual machine operations from a vm and its caller ID.
But this is create and update So it gives me double values every time an VM is being updated.
I tried also in PowerShell
$GetVM = Get-AzureRMVM
Foreach ($vms in $GetVM)
{
$vm = get-azurermvm -name $vms.Name -ResourceGroupName $vms.ResourceGroupName
$log = Get-AzureRmLog -ResourceId $vm.Id -StartTime (Get-Date).AddDays(-90) -WarningAction silentlyContinue
Write-Output "- Found VM creation at $($log.EventTimestamp) for VM $($log.Id.split("/")[8]) in Resource Group $($log.ResourceGroupName) found in Azure logs"
}
But Can't seem to find the creation date inside the log files either. Does anyone have a clue if it is possible to find the creation date of a Virtual Machine inside a scripting language , Kusto , Powershell , ...
The easiest way that worked for me to get the Azure VM creation date was to look at the creation date of the OS Disk
Browse to your VM on Azure Portal
On Left Hand side, click on the blade "Disks"
Under OS Disk section, click on your OS Disk.
In the Overview blade of your OS Disk, you can see Time Created field.
Note: All my Azure VMs were created with the OS Disk and were never changed.
Hope it helps. Cheers.
There is no direct way to find out the creation date if it's later than 90 days. But here is a nice workaround solution: https://savilltech.com/2018/02/13/checking-the-creation-time-of-an-azure-iaas-vm/
You can use azure cli
use below command
az vm list
This will list json data with fields and you can filter
date = vm['timeCreated']
//"timeCreated": "2022-06-24T14:13:00.326985+00:00",
The portal does show Created for a cloud service in the Dashboard of a Cloud Service, but that is not shown for a specific VM (which you can see with Azure PowerShell with Get-AzureService <cloud service name> | select DateCreated).
When you do a Quick Create of a VM, that will always create a new cloud service, so the time created would be the same for VM and cloud service. But since you can add multiple VMs to a cloud service, you can't always rely on that.
On the VM's Dashboard in the portal, at the bottom if you look at the VHD column, the VHD name includes the date the disk was created as part of the name, though this is only true for VMs created from an image. If the VM was created from a disk, the name could be anything. You can get that OS disk name in Azure PowerShell with Get-AzureVM <cloud service name> <VM name> | Get-AzureOSDisk | select medialink.
Operation Logs under Management Services in the portal lets you search the last 30 days for operations, so if the VM was created in the last month, you can find evidence of the operation there (for example CreateHostedService and CreateDeployment operations).
For Windows VMs created from an image, the timestamp on WaSetup.log and WaSetup.xml in C:\Windows\panther\ reflect when the VM was provisioned.
Hope it helps.
If you check Deployments in the respective resource group, you will see Last Modified date for each of the deployment in that RG.
I found another way to get it working for me by tweaking your ActivityLog query instead of Powershell. Using the HTTPRequest property seemed to give me what I needed.
AzureActivity
| where TimeGenerated > ago(7d)
| where ResourceProvider contains "Microsoft.Compute" and OperationName == "Create or Update Virtual Machine"
| where HTTPRequest contains "PUT"
| project VMName = Resource, Created_On = format_datetime(EventSubmissionTimestamp,'dd-MM-yyyy-HHtt'), User = Caller
| distinct Created_On, VMName, User
| order by Created_On
In my case, I was trying to get the VMs deleted in the last 7 days. For some reason the time wasn't displaying properly for the query below, hence I had to convert it to my timezone.
AzureActivity
| where TimeGenerated > ago(7d)
| where ResourceProvider == "Microsoft.Compute" and OperationName == "Delete Virtual Machine"
| where HTTPRequest contains "DELETE"
| extend MyTimeZone = EventSubmissionTimestamp + 8h
| project VM_Name = Resource, Deleted_On = format_datetime(MyTimeZone, 'dd-MM-yyyy-HHtt'), User = Caller
| distinct Deleted_On , VM_Name , User
| order by Deleted_On

Azure resource to check orphan resource

I am looking solution to find out Stopped | Deallocated resources Orphan Resources in Azure. I grab the VM data. But if someone spins the VM and VM showing running, How to check owner not used that VM since 30 Days.
az vm list -d --output table
Any automation suggestion will be welcome.
az vm list -d --output table
TESTSXG VM running
I see multiple queries here.
To identify if someone created any resource (say VM) and has forgot to deallocate it.
To check last login in VM if it is older than 30 days.
To check owner not used the VM(s) in the last 30 days.
If we don’t login to VM since a while and if some services (like Jenkins, etc.) are running and untouched.
To audit actions on resources and to determine the operations that were taken on resources, you may use Activity Logs. For more information refer this (https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-audit) link.
For #1, You may execute the below command.
Get-AzureRmVM -Status|select Name, PowerState
For #2 and #3, below is the command which you can run manually in the VM.
Get-WmiObject -Class Win32_NetworkLoginProfile |
Sort-Object -Property LastLogon -Descending |
Select-Object -Property * -First 1 |
Where-Object {$_.LastLogon -match "(\d{14})"} |
Foreach-Object { New-Object PSObject -Property #{ Name=$_.Name;LastLogon=[datetime]::ParseExact($matches[0], "yyyyMMddHHmmss", $null)}}
But I know that we are looking for an automated way to validate all the VM’s under your subscription. So here the requirement is to automatically (i.e., remotely) connect to all the ‘running’ VM’s from Azure portal and then get the required output. If i am not wrong, most probably we can achieve this requirement in multiple ways i.e.,
i. Log Analytics
ii. DSC
iii. Functions
iv. Runbook
v. Logic App
i. Create a Log Analytics OMS workspace and install OMS agent on the VM(s) as instructed here (https://learn.microsoft.com/en-us/azure/azure-monitor/learn/quick-collect-azurevm). Then add Azure Security Center (Security and Audit) solution in OMS so that the security events will be pushed to OMS repository. Then goto Log Analytics -> OMSworkspaceName -> Logs and run the below Kusto query to get the required output.
SecurityEvent
| where EventID == 4624
| sort by TimeGenerated desc
Note that the Event ID 4624 is the ID for the event log of any account logged on to a machine.
ii. Onboard Azure DSC on the VM(s) as instructed here (https://learn.microsoft.com/en-us/azure/automation/automation-dsc-onboarding) and write a DSC configuration script using ‘script’ DSC resource which will run the above mentioned Get-WmiObject…. command remotely on the DSC nodes (i.e., VM’s) and fetch us the required output.
iii. Write a HTTP trigger PowerShell function which will run the above mentioned Get-WmiObject…. command remotely (i.e., may be try a new ps session and invoke command) on the VM’s and fetch us the required output. You may refer this (https://learn.microsoft.com/en-us/azure/azure-functions/functions-create-first-azure-function) link to learn about Functions.
iv. Write a PowerShell runbook which will run the above mentioned Get-WmiObject…. command remotely (i.e., may be try new ps session and invoke command) on the VM’s and fetch us the required output.
v. Currently Azure Logic Apps seems not support to run PowerShell and CLI script. However, we may try to use available Logic Apps Functions connector or any similar connector and internally try to call PowerShell to execute above mentioned Get-WmiObject…. command remotely. Just FYI here (https://feedback.azure.com/forums/287593-logic-apps/suggestions/33913552-run-a-powershell-code-within-a-logic-app-action) is a voice in Azure feedback regarding running PowerShell code within a Logic App, you could vote if you are interested in this option.
For #4, Install OMS agent on the VM’s so that the events details get stored in OMS repository. For example, if no one is logging in to a VM but Jenkins service is running on that VM then in that case you may want to not disturb that VM. So, to validate if Jenkins service is running on a VM or not you may have to run a Kusto query something like this.
Event
| where (EventLog == "System")
| where (RenderedDescription has "jenkins" and RenderedDescription has "stopped")
Hope this helps!!

Resources