Query Update Management logs
Important
Automation Update Management has retired on 31 August 2024 and we recommend that you use Azure Update Manager. Follow the guidelines for migration from Automation Update Management to Azure Update Manager.
In addition to the details that are provided during Update Management deployment, you can search the logs stored in your Log Analytics workspace. To search the logs from your Automation account, select Update management and open the Log Analytics workspace associated with your deployment.
You can also customize the log queries or use them from different clients. See Log Analytics search API documentation.
Query update records
Update Management collects records for Windows and Linux VMs and the data types that appear in log search results. The following sections describe those records.
Query Update record
A record with a type of Update
is created that represents updates available and their installation status for a machine. These records have the properties in the following table:
Property | Description |
---|---|
TenantId | Unique identifier representing your organization's instance of Microsoft Entra ID. |
SourceSystem | The source system for the record. The value is OperationsManager . |
TimeGenerated | Date and time of record creation. |
SourceComputerId | Unique identifier representing the source computer. |
Title | The title of the update. |
Classification | Approval classification. The value is Updates. |
PublishedDate (UTC) | The date when the update is ready to be downloaded and installed from Windows Update. |
Computer | Fully-qualified domain name of reporting machine. |
UpdateState | The current state of the update. |
Product | The products for which the update is applicable. |
OSType | Type of operating system. Values are Windows or Linux. |
ProductVersion | Version of the update. |
Product Arch | Applicable machine architecture |
CVENumbers | Common Vulnerabilities and Exposures number |
BulletinUrl | URL of the Bulletin |
BulletinID | Bulletin ID number. |
PackageRepository | Repository info of the package. |
PackageSeverity | Severity of the update. |
OSName | Type of operating system. Values are Windows or Linux. |
OSVersion | The version of the operating system. |
OSFullName | Name of operating system. |
SubscriptionId | Unique identifier for the Azure subscription. |
ResourceGroup | Name of the resource group to which the resource belongs. |
ResourceProvider | The resource provider. |
Resource | Name of the resource. |
ResourceId | Unique identifier for the resource associated with the record. |
ResourceType | The resource type. |
ComputerEnvironment | Environment. Possible values are Azure or Non-Azure. |
VMUUID | Unique identifier for the virtual machine. |
MG | Unique identifier for the management group or Log Analytics workspace. |
ManagementGroupName | Name of the Operations Manager management group or the Log Analytics workspace. |
MSRCSeverity | Severity rating for the vulnerability. Values are: Critical Important Moderate Low |
KBID | Knowledge base article ID for the Windows update. |
UpdateID | Unique identifier of the software update. |
RevisionNumber | The revision number of a specific revision of an update. |
Optional | True if the record is optional, or False otherwise. |
RebootBehavior | The reboot behavior after installing/uninstalling an update. |
MSRCBulletinID | Security bulletin ID number. |
Approved | True if the record is approved, or False otherwise. |
ApprovalSource | Applies to Windows operating system only. Source of approval for the record. The value is Microsoft Update. |
InstallTimePredictionSeconds | |
InstallTimeDeviationRangeSeconds | |
InstallTimeAvailable | |
Type | Record type. The value is Update. |
Query Update Deployment Status record
A record with a type of UpdateRunProgress
is created that provides update deployment status of a scheduled deployment by machine. These records have the properties in the following table:
Property | Description |
---|---|
TenantId | Unique identifier representing your organization's instance of Microsoft Entra ID. |
SourceSystem | Source system for the record. The value is OperationsManager . |
TimeGenerated | Date and time of record creation. |
MG | Unique identifier for the management group or Log Analytics workspace. |
ManagementGroupName | Name of the Operations Manager management group or Log Analytics workspace. |
SourceComputerId | Unique identifier representing the source computer. |
KBID | Knowledge base article ID for the Windows update. |
UpdateId | Unique identifier of the software update. |
SucceededOnRetry | Value indicating if the update execution failed on the first attempt and the current operation is a retry attempt. |
ErrorResult | Windows Update error code generated if an update fails to install. |
UpdateRunName | Name of the update schedule. |
InstallationStatus | The possible installation states of an update on the client computer,NotStarted - job not triggered yet.Failed - job started but failed with an exception.InProgress - job in progress.MaintenanceWindowExceeded - if execution was remaining but maintenance window interval reached.Succeeded - job succeeded.Install Failed - update failed to install successfully.NotIncluded - the corresponding update's classification doesn't match with customer's entries in input classification list.Excluded - user enters a KBID in excluded list. While patching, if KBID in excluded list matches with the system detected update KB ID, it is marked as excluded. |
Computer | Fully-qualified domain name of reporting machine. |
Title | The title of the update. |
Product | The products for which the update is applicable. |
OSType | Type of operating system. Values are Windows or Linux. |
StartTime (UTC) | Time when the update is scheduled to be installed. This property is currently not used. See TimeGenerated. |
EndTime (UTC) | The time when the synchronization process ended. This property is currently not used. See TimeGenerated. |
CorrelationId | Unique identifier of the runbook job run for the update. |
SubscriptionId | Unique identifier for the Azure subscription. |
ResourceGroup | Name of the resource group to which the resource belongs. |
ResourceProvider | The resource provider. |
Resource | Name of the resource. |
ResourceId | Unique identifier for the resource associated with the record. |
ResourceType | Resource type. |
ComputerEnvironment | Environment. Values are Azure or Non-Azure. |
VMUUID | Unique identifier for the virtual machine. |
Type | The type of update. The value is UpdateRunProgress . |
_ResourceId | Unique identifier for the resource associated with the record. |
Query Update Summary record
A record with a type of UpdateSummary
is created that provides update summary by machine. These records have the properties in the following table:
Property | Description |
---|---|
TenantId | Unique identifier representing your organization's instance of Microsoft Entra ID. |
SourceSystem | Source system for the record. The value is OpsManager . |
TimeGenerated | Date and time of record creation. |
MG | Unique identifier for the management group or Log Analytics workspace. |
ManagementGroupName | Name of the Operations Manager management group or Log Analytics workspace. |
SourceComputerId | Unique identifier for the virtual machine. |
LastUpdateApplied (UTC) | |
OldestMissingSecurityUpdateInDays | Total number of days for the oldest update detected as applicable that has not been installed. |
OldestMissingSecurityUpdateBucket | Specifier of the oldest missing security bucket. Values are: Recent if value is less than 30 days 30 days ago 60 days ago 90 days ago 120 days ago 150 days ago 180 days ago Older when value is greater than 180 days. |
WindowsUpdateSetting | Status of the Windows Update agent. Possible values are:Scheduled installation Notify before installation Error returned from unhealthy WUA agent |
WindowsUpdateAgentVersion | Version of the Windows Update agent. |
WSUSServer | Errors if the Windows Update agent has a problem, to assist with troubleshooting. |
Computer | Fully-qualified domain name of reporting machine. |
OsVersion | The version of the operating system. |
NETRuntimeVersion | Version of .NET Framework installed on the Windows computer. |
CriticalUpdatesMissing | Number of applicable critical updates that are missing. |
SecurityUpdatesMissing | Count of missing security updates that are applicable. |
OtherUpdatesMissing | Count of detected updates missing. |
TotalUpdatesMissing | Total number of missing updates that are applicable. |
RestartPending | True if a restart is pending, or False otherwise. |
SubscriptionId | Unique identifier for the Azure subscription. |
ResourceGroup | Name of the resource group containing the resource. |
ResourceProvider | The resource provider. |
Resource | Name of the resource for the record. |
ResourceId | Unique identifier for the resource associated with the record. |
ResourceType | Resource type. |
ComputerEnvironment | Environment. Values are Azure or Non-Azure. |
VMUUID | Unique identifier for the virtual machine. |
Type | Record type. The value is UpdateSummary . |
_ResourceId | Unique identifier for the resource associated with the record. |
Sample queries
The following sections provide sample log queries for update records that are collected for Update Management.
Confirm that non-Azure machines are enabled for Update Management
To confirm that directly connected machines are communicating with Azure Monitor logs, run one of the following log searches.
Linux
Heartbeat
| where OSType == "Linux" | summarize arg_max(TimeGenerated, *) by SourceComputerId | top 500000 by Computer asc | render table
Windows
Heartbeat
| where OSType == "Windows" | summarize arg_max(TimeGenerated, *) by SourceComputerId | top 500000 by Computer asc | render table
On a Windows computer, you can review the following information to verify agent connectivity with Azure Monitor logs:
In Control Panel, open Microsoft Monitoring Agent. On the Azure Log Analytics tab, the agent displays the following message: The Microsoft Monitoring Agent has successfully connected to Log Analytics.
Open the Windows Event Log. Go to Application and Services Logs\Operations Manager and search for Event ID 3000 and Event ID 5002 from the source Service Connector. These events indicate that the computer has registered with the Log Analytics workspace and is receiving configuration.
If the agent can't communicate with Azure Monitor logs and the agent is configured to communicate with the internet through a firewall or proxy server, confirm the firewall or proxy server is properly configured. To learn how to verify the firewall or proxy server is properly configured, see Network configuration for Windows agent or Network configuration for Linux agent.
Note
If your Linux systems are configured to communicate with a proxy or Log Analytics Gateway and you're enabling Update Management, update the proxy.conf
permissions to grant the omiuser group read permission on the file by using the following commands:
sudo chown omsagent:omiusers /etc/opt/microsoft/omsagent/proxy.conf
sudo chmod 644 /etc/opt/microsoft/omsagent/proxy.conf
Newly added Linux agents show a status of Updated after an assessment has been performed. This process can take up to 6 hours.
To confirm that an Operations Manager management group is communicating with Azure Monitor logs, see Validate Operations Manager integration with Azure Monitor logs.
Single Azure VM Assessment queries (Windows)
Replace the VMUUID value with the VM GUID of the virtual machine you're querying. You can find the VMUUID that should be used by running the following query in Azure Monitor logs: Update | where Computer == "<machine name>" | summarize by Computer, VMUUID
Missing updates summary
Update
| where TimeGenerated>ago(14h) and OSType!="Linux" and (Optional==false or Classification has "Critical" or Classification has "Security") and VMUUID=~"b08d5afa-1471-4b52-bd95-a44fea6e4ca8"
| summarize hint.strategy=partitioned arg_max(TimeGenerated, UpdateState, Classification, Approved) by Computer, SourceComputerId, UpdateID
| where UpdateState=~"Needed" and Approved!=false
| summarize by UpdateID, Classification
| summarize allUpdatesCount=count(), criticalUpdatesCount=countif(Classification has "Critical"), securityUpdatesCount=countif(Classification has "Security"), otherUpdatesCount=countif(Classification !has "Critical" and Classification !has "Security")
Missing updates list
Update
| where TimeGenerated>ago(14h) and OSType!="Linux" and (Optional==false or Classification has "Critical" or Classification has "Security") and VMUUID=~"8bf1ccc6-b6d3-4a0b-a643-23f346dfdf82"
| summarize hint.strategy=partitioned arg_max(TimeGenerated, UpdateState, Classification, Title, KBID, PublishedDate, Approved) by Computer, SourceComputerId, UpdateID
| where UpdateState=~"Needed" and Approved!=false
| project-away UpdateState, Approved, TimeGenerated
| summarize computersCount=dcount(SourceComputerId, 2), displayName=any(Title), publishedDate=min(PublishedDate), ClassificationWeight=max(iff(Classification has "Critical", 4, iff(Classification has "Security", 2, 1))) by id=strcat(UpdateID, "_", KBID), classification=Classification, InformationId=strcat("KB", KBID), InformationUrl=iff(isnotempty(KBID), strcat("https://support.microsoft.com/kb/", KBID), ""), osType=2
| sort by ClassificationWeight desc, computersCount desc, displayName asc
| extend informationLink=(iff(isnotempty(InformationId) and isnotempty(InformationUrl), toobject(strcat('{ "uri": "', InformationUrl, '", "text": "', InformationId, '", "target": "blank" }')), toobject('')))
| project-away ClassificationWeight, InformationId, InformationUrl
Single Azure VM assessment queries (Linux)
For some Linux distros, there is an endianness mismatch with the VMUUID value that comes from Azure Resource Manager and what is stored in Azure Monitor logs. The following query checks for a match on either endianness. Replace the VMUUID values with the big-endian and little-endian format of the GUID to properly return the results. You can find the VMUUID that should be used by running the following query in Azure Monitor logs: Update | where Computer == "<machine name>" | summarize by Computer, VMUUID
Missing updates summary
Update
| where TimeGenerated>ago(5h) and OSType=="Linux" and (VMUUID=~"625686a0-6d08-4810-aae9-a089e68d4911" or VMUUID=~"a0865662-086d-1048-aae9-a089e68d4911")
| summarize hint.strategy=partitioned arg_max(TimeGenerated, UpdateState, Classification) by Computer, SourceComputerId, Product, ProductArch
| where UpdateState=~"Needed"
| summarize by Product, ProductArch, Classification
| summarize allUpdatesCount=count(), criticalUpdatesCount=countif(Classification has "Critical"), securityUpdatesCount=countif(Classification has "Security"), otherUpdatesCount=countif(Classification !has "Critical" and Classification !has "Security")
Missing updates list
Update
| where TimeGenerated>ago(5h) and OSType=="Linux" and (VMUUID=~"625686a0-6d08-4810-aae9-a089e68d4911" or VMUUID=~"a0865662-086d-1048-aae9-a089e68d4911")
| summarize hint.strategy=partitioned arg_max(TimeGenerated, UpdateState, Classification, BulletinUrl, BulletinID) by Computer, SourceComputerId, Product, ProductArch
| where UpdateState=~"Needed"
| project-away UpdateState, TimeGenerated
| summarize computersCount=dcount(SourceComputerId, 2), ClassificationWeight=max(iff(Classification has "Critical", 4, iff(Classification has "Security", 2, 1))) by id=strcat(Product, "_", ProductArch), displayName=Product, productArch=ProductArch, classification=Classification, InformationId=BulletinID, InformationUrl=tostring(split(BulletinUrl, ";", 0)[0]), osType=1
| sort by ClassificationWeight desc, computersCount desc, displayName asc
| extend informationLink=(iff(isnotempty(InformationId) and isnotempty(InformationUrl), toobject(strcat('{ "uri": "', InformationUrl, '", "text": "', InformationId, '", "target": "blank" }')), toobject('')))
| project-away ClassificationWeight, InformationId, InformationUrl
Multi-VM assessment queries
Computers summary
Heartbeat
| where TimeGenerated>ago(12h) and OSType=~"Windows" and notempty(Computer)
| summarize arg_max(TimeGenerated, Solutions) by SourceComputerId
| where Solutions has "updates"
| distinct SourceComputerId
| join kind=leftouter
(
Update
| where TimeGenerated>ago(14h) and OSType!="Linux"
| summarize hint.strategy=partitioned arg_max(TimeGenerated, UpdateState, Approved, Optional, Classification) by SourceComputerId, UpdateID
| distinct SourceComputerId, Classification, UpdateState, Approved, Optional
| summarize WorstMissingUpdateSeverity=max(iff(UpdateState=~"Needed" and (Optional==false or Classification has "Critical" or Classification has "Security") and Approved!=false, iff(Classification has "Critical", 4, iff(Classification has "Security", 2, 1)), 0)) by SourceComputerId
)
on SourceComputerId
| extend WorstMissingUpdateSeverity=coalesce(WorstMissingUpdateSeverity, -1)
| summarize computersBySeverity=count() by WorstMissingUpdateSeverity
| union (Heartbeat
| where TimeGenerated>ago(12h) and OSType=="Linux" and notempty(Computer)
| summarize arg_max(TimeGenerated, Solutions) by SourceComputerId
| where Solutions has "updates"
| distinct SourceComputerId
| join kind=leftouter
(
Update
| where TimeGenerated>ago(5h) and OSType=="Linux"
| summarize hint.strategy=partitioned arg_max(TimeGenerated, UpdateState, Classification) by SourceComputerId, Product, ProductArch
| distinct SourceComputerId, Classification, UpdateState
| summarize WorstMissingUpdateSeverity=max(iff(UpdateState=~"Needed", iff(Classification has "Critical", 4, iff(Classification has "Security", 2, 1)), 0)) by SourceComputerId
)
on SourceComputerId
| extend WorstMissingUpdateSeverity=coalesce(WorstMissingUpdateSeverity, -1)
| summarize computersBySeverity=count() by WorstMissingUpdateSeverity)
| summarize assessedComputersCount=sumif(computersBySeverity, WorstMissingUpdateSeverity>-1), notAssessedComputersCount=sumif(computersBySeverity, WorstMissingUpdateSeverity==-1), computersNeedCriticalUpdatesCount=sumif(computersBySeverity, WorstMissingUpdateSeverity==4), computersNeedSecurityUpdatesCount=sumif(computersBySeverity, WorstMissingUpdateSeverity==2), computersNeedOtherUpdatesCount=sumif(computersBySeverity, WorstMissingUpdateSeverity==1), upToDateComputersCount=sumif(computersBySeverity, WorstMissingUpdateSeverity==0)
| summarize assessedComputersCount=sum(assessedComputersCount), computersNeedCriticalUpdatesCount=sum(computersNeedCriticalUpdatesCount), computersNeedSecurityUpdatesCount=sum(computersNeedSecurityUpdatesCount), computersNeedOtherUpdatesCount=sum(computersNeedOtherUpdatesCount), upToDateComputersCount=sum(upToDateComputersCount), notAssessedComputersCount=sum(notAssessedComputersCount)
| extend allComputersCount=assessedComputersCount+notAssessedComputersCount
Missing updates summary
Update
| where TimeGenerated>ago(5h) and OSType=="Linux" and SourceComputerId in ((Heartbeat
| where TimeGenerated>ago(12h) and OSType=="Linux" and notempty(Computer)
| summarize arg_max(TimeGenerated, Solutions) by SourceComputerId
| where Solutions has "updates"
| distinct SourceComputerId))
| summarize hint.strategy=partitioned arg_max(TimeGenerated, UpdateState, Classification) by Computer, SourceComputerId, Product, ProductArch
| where UpdateState=~"Needed"
| summarize by Product, ProductArch, Classification
| union (Update
| where TimeGenerated>ago(14h) and OSType!="Linux" and (Optional==false or Classification has "Critical" or Classification has "Security") and SourceComputerId in ((Heartbeat
| where TimeGenerated>ago(12h) and OSType=~"Windows" and notempty(Computer)
| summarize arg_max(TimeGenerated, Solutions) by SourceComputerId
| where Solutions has "updates"
| distinct SourceComputerId))
| summarize hint.strategy=partitioned arg_max(TimeGenerated, UpdateState, Classification, Approved) by Computer, SourceComputerId, UpdateID
| where UpdateState=~"Needed" and Approved!=false
| summarize by UpdateID, Classification )
| summarize allUpdatesCount=count(), criticalUpdatesCount=countif(Classification has "Critical"), securityUpdatesCount=countif(Classification has "Security"), otherUpdatesCount=countif(Classification !has "Critical" and Classification !has "Security")
Computers list
Heartbeat
| where TimeGenerated>ago(12h) and OSType=="Linux" and notempty(Computer)
| summarize arg_max(TimeGenerated, Solutions, Computer, ResourceId, ComputerEnvironment, VMUUID) by SourceComputerId
| where Solutions has "updates"
| extend vmuuId=VMUUID, azureResourceId=ResourceId, osType=1, environment=iff(ComputerEnvironment=~"Azure", 1, 2), scopedToUpdatesSolution=true, lastUpdateAgentSeenTime=""
| join kind=leftouter
(
Update
| where TimeGenerated>ago(5h) and OSType=="Linux" and SourceComputerId in ((Heartbeat
| where TimeGenerated>ago(12h) and OSType=="Linux" and notempty(Computer)
| summarize arg_max(TimeGenerated, Solutions) by SourceComputerId
| where Solutions has "updates"
| distinct SourceComputerId))
| summarize hint.strategy=partitioned arg_max(TimeGenerated, UpdateState, Classification, Product, Computer, ComputerEnvironment) by SourceComputerId, Product, ProductArch
| summarize Computer=any(Computer), ComputerEnvironment=any(ComputerEnvironment), missingCriticalUpdatesCount=countif(Classification has "Critical" and UpdateState=~"Needed"), missingSecurityUpdatesCount=countif(Classification has "Security" and UpdateState=~"Needed"), missingOtherUpdatesCount=countif(Classification !has "Critical" and Classification !has "Security" and UpdateState=~"Needed"), lastAssessedTime=max(TimeGenerated), lastUpdateAgentSeenTime="" by SourceComputerId
| extend compliance=iff(missingCriticalUpdatesCount > 0 or missingSecurityUpdatesCount > 0, 2, 1)
| extend ComplianceOrder=iff(missingCriticalUpdatesCount > 0 or missingSecurityUpdatesCount > 0 or missingOtherUpdatesCount > 0, 1, 3)
)
on SourceComputerId
| project id=SourceComputerId, displayName=Computer, sourceComputerId=SourceComputerId, scopedToUpdatesSolution=true, missingCriticalUpdatesCount=coalesce(missingCriticalUpdatesCount, -1), missingSecurityUpdatesCount=coalesce(missingSecurityUpdatesCount, -1), missingOtherUpdatesCount=coalesce(missingOtherUpdatesCount, -1), compliance=coalesce(compliance, 4), lastAssessedTime, lastUpdateAgentSeenTime, osType=1, environment=iff(ComputerEnvironment=~"Azure", 1, 2), ComplianceOrder=coalesce(ComplianceOrder, 2)
| union(Heartbeat
| where TimeGenerated>ago(12h) and OSType=~"Windows" and notempty(Computer)
| summarize arg_max(TimeGenerated, Solutions, Computer, ResourceId, ComputerEnvironment, VMUUID) by SourceComputerId
| where Solutions has "updates"
| extend vmuuId=VMUUID, azureResourceId=ResourceId, osType=2, environment=iff(ComputerEnvironment=~"Azure", 1, 2), scopedToUpdatesSolution=true, lastUpdateAgentSeenTime=""
| join kind=leftouter
(
Update
| where TimeGenerated>ago(14h) and OSType!="Linux" and SourceComputerId in ((Heartbeat
| where TimeGenerated>ago(12h) and OSType=~"Windows" and notempty(Computer)
| summarize arg_max(TimeGenerated, Solutions) by SourceComputerId
| where Solutions has "updates"
| distinct SourceComputerId))
| summarize hint.strategy=partitioned arg_max(TimeGenerated, UpdateState, Classification, Title, Optional, Approved, Computer, ComputerEnvironment) by Computer, SourceComputerId, UpdateID
| summarize Computer=any(Computer), ComputerEnvironment=any(ComputerEnvironment), missingCriticalUpdatesCount=countif(Classification has "Critical" and UpdateState=~"Needed" and Approved!=false), missingSecurityUpdatesCount=countif(Classification has "Security" and UpdateState=~"Needed" and Approved!=false), missingOtherUpdatesCount=countif(Classification !has "Critical" and Classification !has "Security" and UpdateState=~"Needed" and Optional==false and Approved!=false), lastAssessedTime=max(TimeGenerated), lastUpdateAgentSeenTime="" by SourceComputerId
| extend compliance=iff(missingCriticalUpdatesCount > 0 or missingSecurityUpdatesCount > 0, 2, 1)
| extend ComplianceOrder=iff(missingCriticalUpdatesCount > 0 or missingSecurityUpdatesCount > 0 or missingOtherUpdatesCount > 0, 1, 3)
)
on SourceComputerId
| project id=SourceComputerId, displayName=Computer, sourceComputerId=SourceComputerId, scopedToUpdatesSolution=true, missingCriticalUpdatesCount=coalesce(missingCriticalUpdatesCount, -1), missingSecurityUpdatesCount=coalesce(missingSecurityUpdatesCount, -1), missingOtherUpdatesCount=coalesce(missingOtherUpdatesCount, -1), compliance=coalesce(compliance, 4), lastAssessedTime, lastUpdateAgentSeenTime, osType=2, environment=iff(ComputerEnvironment=~"Azure", 1, 2), ComplianceOrder=coalesce(ComplianceOrder, 2) )
| order by ComplianceOrder asc, missingCriticalUpdatesCount desc, missingSecurityUpdatesCount desc, missingOtherUpdatesCount desc, displayName asc
| project-away ComplianceOrder
Missing updates list
Update
| where TimeGenerated>ago(5h) and OSType=="Linux" and SourceComputerId in ((Heartbeat
| where TimeGenerated>ago(12h) and OSType=="Linux" and notempty(Computer)
| summarize arg_max(TimeGenerated, Solutions) by SourceComputerId
| where Solutions has "updates"
| distinct SourceComputerId))
| summarize hint.strategy=partitioned arg_max(TimeGenerated, UpdateState, Classification, BulletinUrl, BulletinID) by SourceComputerId, Product, ProductArch
| where UpdateState=~"Needed"
| project-away UpdateState, TimeGenerated
| summarize computersCount=dcount(SourceComputerId, 2), ClassificationWeight=max(iff(Classification has "Critical", 4, iff(Classification has "Security", 2, 1))) by id=strcat(Product, "_", ProductArch), displayName=Product, productArch=ProductArch, classification=Classification, InformationId=BulletinID, InformationUrl=tostring(split(BulletinUrl, ";", 0)[0]), osType=1
| union(Update
| where TimeGenerated>ago(14h) and OSType!="Linux" and (Optional==false or Classification has "Critical" or Classification has "Security") and SourceComputerId in ((Heartbeat
| where TimeGenerated>ago(12h) and OSType=~"Windows" and notempty(Computer)
| summarize arg_max(TimeGenerated, Solutions) by SourceComputerId
| where Solutions has "updates"
| distinct SourceComputerId))
| summarize hint.strategy=partitioned arg_max(TimeGenerated, UpdateState, Classification, Title, KBID, PublishedDate, Approved) by Computer, SourceComputerId, UpdateID
| where UpdateState=~"Needed" and Approved!=false
| project-away UpdateState, Approved, TimeGenerated
| summarize computersCount=dcount(SourceComputerId, 2), displayName=any(Title), publishedDate=min(PublishedDate), ClassificationWeight=max(iff(Classification has "Critical", 4, iff(Classification has "Security", 2, 1))) by id=strcat(UpdateID, "_", KBID), classification=Classification, InformationId=strcat("KB", KBID), InformationUrl=iff(isnotempty(KBID), strcat("https://support.microsoft.com/kb/", KBID), ""), osType=2)
| sort by ClassificationWeight desc, computersCount desc, displayName asc
| extend informationLink=(iff(isnotempty(InformationId) and isnotempty(InformationUrl), toobject(strcat('{ "uri": "', InformationUrl, '", "text": "', InformationId, '", "target": "blank" }')), toobject('')))
| project-away ClassificationWeight, InformationId, InformationUrl
Next steps
- For details of Azure Monitor logs, see Azure Monitor logs.
- For help with alerts, see Configure alerts.