Interroger les journaux Update Management

Outre les détails fournis pendant le déploiement d’Update Management, vous pouvez effectuer des recherches dans les journaux stockés dans votre espace de travail Log Analytics. Pour effectuer des recherches dans les journaux à partir de votre compte Automation, sélectionnez Update Management, puis ouvrez l’espace de travail Log Analytics associé à votre déploiement.

Vous pouvez également personnaliser les requêtes de journal ou les utiliser à partir de différents clients. Voir Documentation de l’API de recherche Log Analytics.

Interroger des enregistrements de mises à jour

Update Management collecte les enregistrements des machines virtuelles Windows et Linux et les types de données qui apparaissent dans les résultats de la recherche dans les journaux. Les sections suivantes décrivent ces enregistrements.

Interroger un enregistrement de mise à jour

Un enregistrement du type Update est créé, qui représente les mises à jour disponibles et leur état d’installation pour un ordinateur. Les propriétés de ces enregistrements sont décrites dans le tableau suivant :

Propriété Description
TenantId Identificateur unique représentant l’instance Microsoft Entra ID de votre organisation.
SourceSystem Système source de l’enregistrement. La valeur est OperationsManager.
TimeGenerated Date et heure de création de l’enregistrement.
SourceComputerId Identificateur unique représentant l’ordinateur source.
Titre Titre de la mise à jour.
Classification Classification de l’approbation. La valeur est Updates.
PublishedDate (UTC) Date à laquelle la mise à jour est prête à être téléchargée et installée à partir de Windows Update.
Ordinateur Nom de domaine complet de la machine qui rend compte.
UpdateState État actuel de la mise à jour.
Produit Produits pour lesquels la mise à jour est applicable.
OSType Type de système d'exploitation. Les valeurs sont Windows ou Linux.
Productversion Version de la mise à jour.
Product Arch Architecture de machine applicable
CVENumbers Nombre de vulnérabilités et menaces courantes
BulletinUrl URL du bulletin
BulletinID Numéro d’ID du bulletin.
PackageRepository Informations de référentiel du package.
PackageSeverity Gravité de la mise à jour.
OSName Type de système d'exploitation. Les valeurs sont Windows ou Linux.
OSVersion Version du système d’exploitation.
OSFullName Nom du système d’exploitation.
SubscriptionId Identificateur unique de l’abonnement Azure.
ResourceGroup Nom du groupe de ressources auquel appartient la ressource.
ResourceProvider Fournisseur de ressources.
Ressource Nom de la ressource.
ResourceId Identificateur unique de la ressource associée à l’enregistrement.
ResourceType Type de ressource.
ComputerEnvironment L’environnement. Les valeurs possibles sont Azure ou non-Azure.
VMUUID Identificateur unique de la machine virtuelle.
MG Identificateur unique du groupe d’administration ou de l’espace de travail Log Analytics.
ManagementGroupName Nom du groupe d’administration Operations Manager ou de l’espace de travail Log Analytics.
MSRCSeverity Degré de gravité de la vulnérabilité. Les valeurs sont les suivantes :
Critique
Important
Modéré
Faible
KBID ID d’article de la base de connaissances pour la mise à jour Windows.
UpdateID Identificateur unique de la mise à jour de logiciel.
RevisionNumber Numéro de révision d’une révision spécifique d’une mise à jour.
Facultatif True si l’enregistrement est facultatif, False dans le cas contraire.
RebootBehavior Comportement de redémarrage après l’installation ou la désinstallation d’une mise à jour.
MSRCBulletinID Numéro d’identification du bulletin de sécurité.
Approved True si l’enregistrement est approuvé, False dans le cas contraire.
ApprovalSource S’applique au système d’exploitation Windows uniquement. Source d’approbation de l’enregistrement. La valeur est Microsoft Update.
InstallTimePredictionSeconds
InstallTimeDeviationRangeSeconds
InstallTimeAvailable
Type Type d’enregistrement. La valeur est Update.

Interroger un enregistrement d’état du déploiement des mises à jour

Un enregistrement du type UpdateRunProgress est créé, qui fournit l’état du déploiement des mises à jour d’un déploiement planifié par ordinateur. Les propriétés de ces enregistrements sont décrites dans le tableau suivant :

Propriété Description
TenantId Identificateur unique représentant l’instance Microsoft Entra ID de votre organisation.
SourceSystem Système source de l’enregistrement. La valeur est OperationsManager.
TimeGenerated Date et heure de création de l’enregistrement.
MG Identificateur unique du groupe d’administration ou de l’espace de travail Log Analytics.
ManagementGroupName Nom du groupe d’administration Operations Manager ou de l’espace de travail Log Analytics.
SourceComputerId Identificateur unique représentant l’ordinateur source.
KBID ID d’article de la base de connaissances pour la mise à jour Windows.
UpdateId Identificateur unique de la mise à jour de logiciel.
SucceededOnRetry Valeur indiquant si l’exécution de la mise à jour a échoué lors de la première tentative et si l’opération en cours est une nouvelle tentative.
ErrorResult Code d’erreur Windows Update généré en cas d’échec de l’installation d’une mise à jour.
UpdateRunName Nom de la planification de mise à jour.
InstallationStatus Les états d’installation possibles d’une mise à jour sur l’ordinateur client sont :
NotStarted : la tâche n’a pas encore été déclenchée.
Failed : la tâche a démarré, mais a échoué avec une exception.
InProgress : tâche en cours.
MaintenanceWindowExceeded : si l’exécution était encore en cours, mais que l’intervalle de la fenêtre de maintenance a été atteint.
Succeeded : la tâche a réussi.
Install Failed : échec de l’installation de la mise à jour.
NotIncluded : la classification de la mise à jour correspondante ne correspond pas aux entrées du client dans la liste de classification d’entrées.
Excluded : l’utilisateur entre un KBID dans la liste d’exclusion. Pendant la mise à jour corrective, si le KBID de la liste d’exclusion correspond à l’ID de base de connaissances mis à jour détecté par le système, il est marqué comme étant exclu.
Ordinateur Nom de domaine complet de la machine qui rend compte.
Titre Titre de la mise à jour.
Produit Produits pour lesquels la mise à jour est applicable.
OSType Type de système d'exploitation. Les valeurs sont Windows ou Linux.
StartTime (UTC) Heure à laquelle l’installation de la mise à jour est planifiée. Cette propriété n’est pas utilisée actuellement. Consultez TimeGenerated.
EndTime (UTC) Heure de fin du processus de synchronisation. Cette propriété n’est pas utilisée actuellement. Consultez TimeGenerated.
CorrelationId Identificateur unique de la tâche runbook à exécuter pour la mise à jour.
SubscriptionId Identificateur unique de l’abonnement Azure.
ResourceGroup Nom du groupe de ressources auquel appartient la ressource.
ResourceProvider Fournisseur de ressources.
Ressource Nom de la ressource.
ResourceId Identificateur unique de la ressource associée à l’enregistrement.
ResourceType Type de ressource.
ComputerEnvironment L’environnement. Les valeurs sont Azure ou non-Azure.
VMUUID Identificateur unique de la machine virtuelle.
Type Le type de mise à jour. La valeur est UpdateRunProgress.
_ResourceId Identificateur unique de la ressource associée à l’enregistrement.

Interroger un enregistrement de résumé des mises à jour

Un enregistrement du type UpdateSummary est créé, qui fournit un résumé des mises à jour par ordinateur. Les propriétés de ces enregistrements sont décrites dans le tableau suivant :

Propriété Description
TenantId Identificateur unique représentant l’instance Microsoft Entra ID de votre organisation.
SourceSystem Système source de l’enregistrement. La valeur est OpsManager.
TimeGenerated Date et heure de création de l’enregistrement.
MG Identificateur unique du groupe d’administration ou de l’espace de travail Log Analytics.
ManagementGroupName Nom du groupe d’administration Operations Manager ou de l’espace de travail Log Analytics.
SourceComputerId Identificateur unique de la machine virtuelle.
LastUpdateApplied (UTC)
OldestMissingSecurityUpdateInDays Nombre total de jours pour la mise à jour la plus ancienne ayant été détectée comme applicable mais n’ayant pas été installée.
OldestMissingSecurityUpdateBucket Spécificateur du plus ancien compartiment de sécurité manquant. Les valeurs sont les suivantes :
Récent si la valeur est inférieure à 30 jours
Il y a 30 jours
Il y a 60 jours
Il y a 90 jours
Il y a 120 jours
Il y a 150 jours
Il y a 180 jours
Plus ancien lorsque la valeur est supérieure à 180 jours
WindowsUpdateSetting État de l’agent Windows Update. Les valeurs possibles sont les suivantes :
Scheduled installation
Notify before installation
Error returned from unhealthy WUA agent
WindowsUpdateAgentVersion Version de l’agent Windows Update.
WSUSServer Erreurs si l’agent Windows Update a un problème, pour faciliter la résolution des problèmes.
Ordinateur Nom de domaine complet de la machine qui rend compte.
OsVersion Version du système d’exploitation.
NETRuntimeVersion Version de .NET Framework installée sur l’ordinateur Windows.
CriticalUpdatesMissing Nombre de mises à jour critiques applicables qui font défaut.
SecurityUpdatesMissing Nombre de correctifs de sécurité manquants qui sont applicables.
OtherUpdatesMissing Nombre de mises à jour détectées manquantes.
TotalUpdatesMissing Nombre total de mises à jour manquantes qui sont applicables.
RestartPending True si un redémarrage est en attente, False dans le cas contraire.
SubscriptionId Identificateur unique de l’abonnement Azure.
ResourceGroup Nom du groupe de ressources contenant la ressource.
ResourceProvider Fournisseur de ressources.
Ressource Nom de la ressource pour l’enregistrement.
ResourceId Identificateur unique de la ressource associée à l’enregistrement.
ResourceType Type de ressource.
ComputerEnvironment L’environnement. Les valeurs sont Azure ou non-Azure.
VMUUID Identificateur unique de la machine virtuelle.
Type Type d’enregistrement. La valeur est UpdateSummary.
_ResourceId Identificateur unique de la ressource associée à l’enregistrement.

Exemples de requêtes

Les sections suivantes présentent des exemples de requêtes sur les journaux d’enregistrements des mises à jour qui sont collectés pour Update Management.

Vérifier que les machines non-Azure sont activées pour Update Management

Pour vérifier que les machines directement connectées communiquent avec les journaux Azure Monitor, exécutez l’une des recherches suivantes dans les journaux.

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

Sur un ordinateur Windows, vous pouvez vérifier les informations suivantes pour tester la connectivité de l’agent avec les journaux Azure Monitor :

  1. Dans le Panneau de configuration, ouvrez Microsoft Monitoring Agent. Ouvrez l’onglet Azure Log Analytics. L’agent affiche un message indiquant : Microsoft Monitoring Agent est bien connecté à Log Analytics.

  2. Ouvrez le journal des événements Windows. Accédez à Application and Services Logs\Operations Manager, puis recherchez l’ID d’événement 3000 et 5002 à partir du connecteur de service source. Ces événements indiquent que l’ordinateur est enregistré sur l’espace de travail Log Analytics et qu’il reçoit la configuration.

Si l’agent ne parvient pas à communiquer avec les journaux Azure Monitor et s’il est configuré pour communiquer avec Internet par le biais d’un pare-feu ou d’un serveur proxy, vérifiez que le pare-feu ou le serveur proxy est correctement configuré. Pour savoir comment vérifier la configuration du pare-feu ou du serveur proxy, consultez Configuration réseau de l’agent Windows ou Configuration réseau de l’agent Linux.

Remarque

Si vos systèmes Linux sont configurés pour communiquer avec un proxy ou Log Analytics Gateway et que vous activez Update Management, vous devez mettre à jour les autorisations proxy.conf pour accorder au groupe omiuser une autorisation d’accès en lecture sur le fichier. Pour cela, exécutez les commandes suivantes :

sudo chown omsagent:omiusers /etc/opt/microsoft/omsagent/proxy.conf sudo chmod 644 /etc/opt/microsoft/omsagent/proxy.conf

Les nouveaux agents Linux ajoutés affichent l’état Mis à jour après l’exécution d’une évaluation. Ce processus peut prendre jusqu’à 6 heures.

Pour vérifier qu’un groupe d’administration Operations Manager communique avec les journaux Azure Monitor, consultez Valider l’intégration d’Operations Manager aux journaux Azure Monitor.

Requêtes d’évaluation de la machine virtuelle Azure unique (Windows)

Remplacez la valeur VMUUID par le GUID VM de la machine virtuelle que vous interrogez. Pour trouver le VMUUID à utiliser, exécutez la requête suivante dans les journaux Azure Monitor : Update | where Computer == "<machine name>" | summarize by Computer, VMUUID

Récapitulatif des mises à jour manquantes

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")

Liste des mises à jour manquantes

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

Requêtes d’évaluation de la machine virtuelle Azure unique (Linux)

Pour certaines distributions de Linux, il existe une incompatibilité de mode Endian entre la valeur VMUUID qui provient d’Azure Resource Manager et ce qui est stocké dans les journaux d’activité Azure Monitor. La requête suivante recherche une correspondance sur l’un des modes Endian. Remplacez les valeurs VMUUID avec le format big-endian et little-endian du GUID afin de retourner correctement les résultats. Pour trouver le VMUUID à utiliser, exécutez la requête suivante dans les journaux Azure Monitor : Update | where Computer == "<machine name>" | summarize by Computer, VMUUID

Récapitulatif des mises à jour manquantes

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")

Liste des mises à jour manquantes

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

Requêtes d’évaluation sur plusieurs VM

Récapitulatif des ordinateurs

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

Récapitulatif des mises à jour manquantes

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")

Liste des ordinateurs

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

Liste des mises à jour manquantes

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

Étapes suivantes