Azure Graph query to get VM Agent status for all VMs - azure

I'm trying to get a query to check the VM Agent status in Azure. Currently I'm using RestAPI, but I need one call to the API for each machine, and I want to do it with Azure Graph to list all the VMs with the Azure Agent status in a single request.
This is the query in Azure Graph
Resources
| where type in~ ("microsoft.compute/virtualmachines","microsoft.classiccompute/virtualmachines")
But under properties the STATUS of the agent is not available. Any ideas?
I tried listing the extensions but it is also not helping, with this query:
Resources
| where type == 'microsoft.compute/virtualmachines'
| extend
JoinID = toupper(id),
OSName = tostring(properties.osProfile.computerName),
OSType = tostring(properties.storageProfile.osDisk.osType),
VMSize = tostring(properties.hardwareProfile.vmSize)
| join kind=leftouter(
Resources
| where type == 'microsoft.compute/virtualmachines/extensions'
| extend
VMId = toupper(substring(id, 0, indexof(id, '/extensions'))),
ExtensionName = name
) on $left.JoinID == $right.VMId
| summarize Extensions = make_list(ExtensionName) by id, OSName, OSType, VMSize
| order by tolower(OSName) asc
I can only see the extensions but I need the Azure Agent STATUS.

After trying many approaches, Agent Status cannot be retrieved directly from the VM properties but ProvisioningState as well as powerstate can be retrieved.
This ProvisionVMAgent property is there for marketplace images that have the agent installed on creation as mentioned here.
To identify the exact health check of the VM, we can use the "ProvisioningState" attribute rather than the "Agent status".
I've done these changes to your code:
Resources
| where type == 'microsoft.compute/virtualmachines'
| extend
JoinID = toupper(id),
OSName = tostring(properties.osProfile.computerName),
OSType = tostring(properties.storageProfile.osDisk.osType),
VMSize = tostring(properties.hardwareProfile.vmSize),
powerState = tostring(properties.extended.instanceView.powerState.displayStatus),
ProvisioningState = tostring(properties.provisioningState)
| join kind=leftouter(
Resources
| where type == 'microsoft.compute/virtualmachines/extensions'
| extend
VMId = toupper(substring(id, 0, indexof(id, '/extensions'))),
ExtensionName = name
) on $left.JoinID == $right.VMId
| summarize Extensions = make_list(ExtensionName) by id, OSName, OSType, VMSize, powerState, ProvisioningState
| order by tolower(OSName) asc
Output:
Note: All statuses of VM's can be received by calling PowerShell command Get-AzVM -status
Reference: AzureVMAgent, Finding VM Agent-Powershell
given by #rakhesh sasidharan

Related

how to get Azure VM last reboot using azure resource graph

I'm using azure resource graph to create dashboard and need the VM last reboot or Power-Off date.
Need your helps please.
Thank you
I tried to reproduce the same in my environment:
Graph query:
Resources
| where type == 'microsoft.compute/virtualmachines'
| summarize count() by PowerState = tostring(properties.extended.instanceView.powerState.code)
Checked the powerstate :
Tried below query :
resources
| where type has 'microsoft.compute/virtualmachines/extensions'
| where name has 'MicrosoftMonitoringAgent' or name has 'AzureMonitorWindowsAgent'
| extend AzureVM = extract('virtualMachines/(.*)/extensions',1,id), ArcVM = extract('machines/(.*)/extensions',1,id)
|summarize count() by name=tolower(AzureVM), ArcVM=tolower(ArcVM), subscriptionId, resourceGroup, AgentType=name
| extend hasBoth = iff(count_ > 0, 'Yes', 'No')
| join
(
resources
| where type =~ 'Microsoft.Compute/virtualMachines'
| project name, properties.extended.instanceView.powerState.displayStatus,
properties.extended.instanceView.powerState.code,
created_ = properties.timeCreated
| order by name desc
) on name
where i got created time of azure vm running and deallocation time.
If you want the alert when the vm stpped you can check this : azureportal - Azure alert to notify when a vm is stopped - Stack Overflow
Reference: resource-graph-samples | Microsoft Learn

KQL join query to extract compliance report from resource

I am trying to get left outer join or join with extend or mv-expand on Graph API to list all non-compliant disk with specific path (non-comp reason). In other words, extracting fields from policy and fields from resource e.g.-
resources
| where type == "microsoft.compute/disks"  and subscriptionId == '3mmmmm333333####e35'
    | join kind=leftouter (policyresources
        | where type == "microsoft.policyinsights/policystates"
  
Some resource I am going through are https://www.youtube.com/watch?v=r_3Ydr6fCHQ and https://github.com/globalbao/azure-resource-graph/blob/master/README.md but the join statement to correlate resource query are not working with both outer or join. Maybe I need to narrow down to related item under the resource and resource policy?
Azure Management Talk: Azure Resource Graph Zero to Hero - YouTube
In this session, Microsoft Consultant Billy York will go over the basics of Azure Resource Graph, including how Kusto Query Language (KQL) is used and its li...
If anyone has similar report extraction code with leftouter join between policy with compute resource that would be helpful
KQL join query to extract compliance report from resource. To get some fields from resource and some from compliance related to resource
To achieve, KQL query to extract compliance disk resources:
By referring MSDoc, I've included the relevant part of the query and tried by changing the resource type
"resourceType = "microsoft.compute/disks" , I was able to receive the expected results.
PolicyResources
| where type =~ 'Microsoft.PolicyInsights/PolicyStates'
| extend complianceState = tostring(properties.complianceState)
| extend
resourceId = tostring(properties.resourceId),
resourceType = "microsoft.compute/disks",
policyAssignmentId = tostring(properties.policyAssignmentId),
policyDefinitionId = tostring(properties.policyDefinitionId),
policyDefinitionReferenceId = tostring(properties.policyDefinitionReferenceId),
stateWeight = iff(complianceState == 'NonCompliant', int(300), iff(complianceState == 'Compliant', int(200), iff(complianceState == 'Conflict', int(100), iff(complianceState == 'Exempt', int(50), int(0)))))
| summarize max(stateWeight) by resourceId, resourceType
| summarize counts = count() by resourceType, max_stateWeight
| summarize overallStateWeight = max(max_stateWeight),
nonCompliantCount = sumif(counts, max_stateWeight == 300),
compliantCount = sumif(counts, max_stateWeight == 200),
conflictCount = sumif(counts, max_stateWeight == 100),
exemptCount = sumif(counts, max_stateWeight == 50) by resourceType
| extend totalResources = todouble(nonCompliantCount + compliantCount + conflictCount + exemptCount)
| extend compliancePercentage = iff(totalResources == 0, todouble(100), 100 * todouble(compliantCount + exemptCount) / totalResources)
| project resourceType,
overAllComplianceState = iff(overallStateWeight == 300, 'noncompliant', iff(overallStateWeight == 200, 'compliant', iff(overallStateWeight == 100, 'conflict', iff(overallStateWeight == 50, 'exempt', 'notstarted')))),
compliancePercentage,
compliantCount,
nonCompliantCount,
conflictCount,
exemptCount
Output:
I've pulled up all the relevant fields here, but you can extend and project the fields you want based on your requirements.

Connector name from Kusto query

I am very new with the sintaxis of Kusto query. My goal is to create a kusto query to retreive which Logic App has a system error and in which action the error was located. Additionally, I would like to know which connector, this failed action belongs. For example, If the action "Move Email" failed I would like to have the connector name, in this case, Office 365 Outlook or something similar in order to classify the action.
My query to achieve this goal was based on the Table "AzureDiagnostics":
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.LOGIC"
| where Category == "WorkflowRuntime"
| where status_s == "Failed"
| where code_s !has 'ActionFailed'
| where OperationName has "workflowActionCompleted" or OperationName has "workflowTriggerCompleted"
| extend ResourceName = coalesce(resource_actionName_s, resource_triggerName_s)
| extend ResourceCategory = substring(OperationName, 34, strlen(OperationName) - 43)
| project
LogicAppName = resource_workflowName_s,
ResourceCategory,
ResourceName,
LogicAppId = resource_runId_s,
ErrorCode = code_s,
ErrorMessage = error_message_s,
ErrorTime = format_datetime(startTime_t,'dd.MM.yyyy')
The connector name will give me the possibility to classify the failed logic apps and this way I can create a report to show which type of connector we are having issues.
Thanks in advance for your help or another workarround to classify the failed logic apps.
After reproducing from our end, One of the workarounds is that we can fetch the action name of the failed step along with the status using the below query.
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.LOGIC"
| where Category == "WorkflowRuntime"
| where status_s == "Failed"
| extend Status = code_s
| project
LogicAppName = resource_workflowName_s,
ResourceRunID = resource_runId_s,
Operation = OperationName,
ActionName = coalesce(resource_actionName_s, resource_triggerName_s),
Status
RESULTS:
Updated Answer
There is no direct way to get the connector's name. One of the workarounds would be using tracked properties to save the connector name and retrieve it through logs. Not a perfect way but this is one of the workarounds that achieves the requirement.
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.LOGIC"
| where OperationName == "Microsoft.Logic/workflows/workflowActionCompleted"
| where status_s == "Failed"
| extend Status = code_s
| project
LogicAppName = resource_workflowName_s,
ResourceRunID = resource_runId_s,
Operation = OperationName,
ActionName = coalesce(resource_actionName_s, resource_triggerName_s),
Status,
ConnectorName = trackedProperties_ConnectorName_s
Below is the flow in my logic app
Failed Run
In logs

KQL to identify which vm has CustomScript extension

I want how many and what VMs have "CustomScript"extension enabled along with the “properties” of that extensions and I have tried this query but didn't extract the custom-extension
Resources
| where type == 'microsoft.compute/virtualmachines'
| extend
JoinID = toupper(id),
OSName = tostring(properties.osProfile.computerName),
OSType = tostring(properties.storageProfile.osDisk.osType),
VMSize = tostring(properties.hardwareProfile.vmSize)
| join kind=leftouter(
Resources
| where type == 'microsoft.compute/virtualmachines/extensions'
| extend
VMId = toupper(substring(id, 0, indexof(id, '/extensions'))),
ExtensionName =~ 'custom-script'
) on $left.JoinID == $right.VMId
| top 5 by name asc
For the custom script extensions, for Windows and Linux, they have slightly different names. This query will return a list of VM with custom script extension and the properties for the VM and the extension.
resources
| where type == 'microsoft.compute/virtualmachines'
| extend
JoinID = toupper(id),
OSName = tostring(properties.osProfile.computerName),
OSType = tostring(properties.storageProfile.osDisk.osType),
VMSize = tostring(properties.hardwareProfile.vmSize)
| join kind=leftouter(
resources
| where type == 'microsoft.compute/virtualmachines/extensions'
| where name in ("CustomScriptExtension", "CustomScriptForLinux")
| extend VMId = toupper(substring(id,0,indexof(id,"/",0,-1,9)))
)
on $left.JoinID == $right.VMId

Azure Resource Graph Explorer - Query Azure VM descriptions, OS, sku - I need to join to columns (OS and sku in one)

I have a issue. I want to know how can I join two columns in one.
I want to join the "OS" and "sku" columns in one with the name "OS"
This is my KQL:
Kusto Query on Azure Resource Graph
Resources
| where type == "microsoft.compute/virtualmachines"
| extend OS = properties.storageProfile.imageReference.offer
| extend sku = properties.storageProfile.imageReference.sku
| project OS, sku, name, nic = (properties.networkProfile.networkInterfaces)
| mvexpand nic
| project OS, sku, name, nic_id = tostring(nic.id)
| join (
    Resources 
    | where type == "microsoft.network/networkinterfaces" 
    | project nic_id = tostring(id), properties) on nic_id
    | mvexpand ipconfig = (properties.ipConfigurations)
    | extend subnet_resource_id = split(tostring(ipconfig.properties.subnet.id), '/'), ipAddress = ipconfig.properties.privateIPAddress
    | order by name desc
| project vmName=(name), OS, sku, vnetName=subnet_resource_id[8], subnetName=subnet_resource_id[10], ipAddress
This is my result:
I need like this:
Can anyone help me, thanks so much.
I've tried to use the "union" operator, but I can't make it work.
I have used these reference link:
Azure Docs Link 1
Azure Docs Link 2
Azure Docs Link 3
If you want to combine two strings - you can use strcat() function:
Resources
| where type == "microsoft.compute/virtualmachines"
| extend OS = properties.storageProfile.imageReference.offer
| extend sku = properties.storageProfile.imageReference.sku
| project OS, sku, name, nic = (properties.networkProfile.networkInterfaces)
| mvexpand nic
| project OS, sku, name, nic_id = tostring(nic.id)
| join (
Resources
| where type == "microsoft.network/networkinterfaces"
| project nic_id = tostring(id), properties) on nic_id
| mvexpand ipconfig = (properties.ipConfigurations)
| extend subnet_resource_id = split(tostring(ipconfig.properties.subnet.id), '/'), ipAddress = ipconfig.properties.privateIPAddress
| order by name desc
| project vmName=(name), OS = strcat(OS, ' ', sku), vnetName=subnet_resource_id[8], subnetName=subnet_resource_id[10], ipAddress

Resources