Поделиться через


Запрос на получение журналов Управления обновлениями

Внимание

Управление обновлениями службы автоматизации прекращено 31 августа 2024 г. и рекомендуется использовать Диспетчер обновлений Azure. Следуйте рекомендациям по миграции из службы "Управление обновлениями службы автоматизации" в Диспетчер обновлений Azure.

Помимо сведений, предоставленных во время развертывания Управления обновлениями, можно выполнять поиск в журналах, хранящихся в рабочей области Log Analytics. Чтобы выполнить поиск в журналах из учетной записи службы автоматизации, выберите Управление обновлениями и откройте рабочую область Log Analytics, связанную с развертыванием.

Можно также настроить запросы к журналам или использовать их из других клиентов. См. документацию по API поиска Log Analytics.

Запрос записей обновлений

Решение "Управление обновлениями" собирает записи для виртуальных машин Windows и Linux и типов данных, которые приводятся в результатах поиска по журналам. Эти записи описываются в разделах ниже.

Запрос записи обновления

Создается запись с типом Update, которая представляет доступные обновления и состояние их установки для компьютера. У этих записей есть свойства, приведенные в таблице ниже.

Свойство Description
TenantId Уникальный идентификатор, представляющий экземпляр microsoft Entra ID вашей организации.
SourceSystem Исходная система записи. Значение — OperationsManager.
TimeGenerated Дата и время создания записи.
SourceComputerId Уникальный идентификатор, представляющий исходный компьютер.
Заголовок Заголовок обновления.
Классификация Классификация утверждения. Значение — "Обновления".
PublishedDate (UTC) Дата готовности обновления к скачиванию и установке из Центра обновления Windows.
Компьютер Полное доменное имя компьютера.
UpdateState Текущее состояние обновления.
Продукт Продукты, к которым применимо обновление.
OSType Тип операционной системы. Значения: Windows или Linux.
ProductVersion Версия обновления.
Арка продукта Применимой архитектуры компьютера
CVENumbers Распространенные уязвимости и номера уязвимостей
БюллетеньUrl URL-адрес бюллетеня
Идентификатор бюллетеня Номер идентификатора бюллетеня.
PackageRepository Сведения о репозитории пакета.
PackageSeverity Серьезность обновления.
OSName Тип операционной системы. Значения: Windows или Linux.
OSVersion Версия операционной системы.
OSFullName Имя операционной системы.
SubscriptionId Уникальный идентификатор подписки Azure.
ResourceGroup Имя группы ресурсов, к которой принадлежит ресурс.
ResourceProvider Поставщик ресурса.
Ресурс Имя ресурса.
ResourceId Уникальный идентификатор ресурса, связанного с записью.
ResourceType Типа ресурса.
ComputerEnvironment Среда. Возможные значения: "Azure" или "Не относящаяся к Azure".
VMUUID Уникальный идентификатор виртуальной машины.
MG Уникальный идентификатор группы управления или рабочей области Log Analytics.
ManagementGroupName Имя группы управления Operations Manager или рабочей области Log Analytics.
MSRCSeverity Оценка серьезности уязвимости. Значения:
Критически важно
Внимание
Умеренно
Низкая
KBID Идентификатор статьи базы знаний об обновлении Windows.
UpdateID Уникальный идентификатор обновления программного обеспечения.
RevisionNumber Номер определенной редакции обновления.
Необязательно Значение true, если запись является необязательной, или false в противном случае.
RebootBehavior Необходимость в перезагрузке после установки или удаления обновления.
MSRCBulletinID Идентификационный номер бюллетеня по безопасности.
Утвержденная Значение true, если запись утверждена, или false в противном случае.
ApprovalSource Применяется только к операционной системе Windows. Источник утверждения для записи. Значение — Центр обновления Майкрософт.
InstallTimePredictionSeconds
InstallTimeDeviationRangeSeconds
InstallTimeAvailable
Тип Тип записи Значение — "обновление".

Запрос записи о состоянии развертывания обновления

Создается запись типа UpdateRunProgress, которая предоставляет состояние запланированного развертывания обновления на компьютере. У этих записей есть свойства, приведенные в таблице ниже.

Свойство Description
TenantId Уникальный идентификатор, представляющий экземпляр microsoft Entra ID вашей организации.
SourceSystem Исходная система записи. Значение — OperationsManager.
TimeGenerated Дата и время создания записи.
MG Уникальный идентификатор группы управления или рабочей области Log Analytics.
ManagementGroupName Имя группы управления Operations Manager или рабочей области Log Analytics.
SourceComputerId Уникальный идентификатор, представляющий исходный компьютер.
KBID Идентификатор статьи базы знаний об обновлении Windows.
UpdateId Уникальный идентификатор обновления программного обеспечения.
SucceededOnRetry Значение, указывающее, произошла ли ошибка при первой попытке выполнения обновления и является ли текущая операция повторной попыткой.
ErrorResult Код ошибки Центра обновления Windows, генерируемый при сбое установки обновления.
UpdateRunName Имя расписания обновления.
InstallationStatus Возможные состояния установки обновления на клиентском компьютере:
NotStarted — задание еще не активировано.
Failed — задание запущено, но завершилось с исключением.
InProgress — задание выполняется.
MaintenanceWindowExceeded — выполнение не завершилось, но период обслуживания истек.
Succeeded — задание успешно выполнено.
Install Failed — не удалось успешно установить обновление.
NotIncluded — классификация соответствующего обновления не соответствует записям клиента в списке классификации входных данных.
Excluded — пользователь вводит KBID в исключенном списке. При исправлении, если KBID в исключенном списке совпадает с обнаруженным идентификатором базы знаний обновления системы, он помечается как исключенный.
Компьютер Полное доменное имя компьютера.
Заголовок Заголовок обновления.
Продукт Продукты, к которым применимо обновление.
OSType Тип операционной системы. Значения: Windows или Linux.
StartTime (UTC) Запланированное время установки обновления. Это свойство в настоящее время не используется. См. раздел TimeGenerated.
EndTime (UTC) Время завершения процесса синхронизации. Это свойство в настоящее время не используется. См. раздел TimeGenerated.
CorrelationId Уникальный идентификатор выполнения задания runbook для обновления.
SubscriptionId Уникальный идентификатор подписки Azure.
ResourceGroup Имя группы ресурсов, к которой принадлежит ресурс.
ResourceProvider Поставщик ресурса.
Ресурс Имя ресурса.
ResourceId Уникальный идентификатор ресурса, связанного с записью.
ResourceType Тип ресурса.
ComputerEnvironment Среда. Значения: "Azure" или "Не относящаяся к Azure".
VMUUID Уникальный идентификатор виртуальной машины.
Тип Тип обновления. Значение — UpdateRunProgress.
_ResourceId Уникальный идентификатор ресурса, связанного с записью.

Запрос сводной записи обновления

Создается запись типа UpdateSummary, которая предоставляет сводку обновлений по компьютерам. У этих записей есть свойства, приведенные в таблице ниже.

Свойство Description
TenantId Уникальный идентификатор, представляющий экземпляр microsoft Entra ID вашей организации.
SourceSystem Исходная система записи. Значение — OpsManager.
TimeGenerated Дата и время создания записи.
MG Уникальный идентификатор группы управления или рабочей области Log Analytics.
ManagementGroupName Имя группы управления Operations Manager или рабочей области Log Analytics.
SourceComputerId Уникальный идентификатор виртуальной машины.
LastUpdateApplied (UTC)
OldestMissingSecurityUpdateInDays Возраст самого раннего обнаруженного обновления, которое не было установлено.
OldestMissingSecurityUpdateBucket Описатель самого раннего отсутствующего контейнера безопасности. Значения:
"Недавно", если значение меньше 30 дней
30 дн. назад
60 дней назад
90 дней назад
120 дней назад
150 дней назад
180 дней назад
"Старше", если значение больше 180 дней.
WindowsUpdateSetting Состояние агента Центра обновления Windows. Возможны следующие значения:
Scheduled installation
Notify before installation
Error returned from unhealthy WUA agent
WindowsUpdateAgentVersion Версия агента Центра обновления Windows.
WSUSServer Ошибки, помогающие в устранении неполадок с агентом Центра обновления Windows.
Компьютер Полное доменное имя компьютера.
OsVersion Версия операционной системы.
NETRuntimeVersion Версия .NET Framework, установленная на компьютере с ОС Windows.
CriticalUpdatesMissing Число отсутствующих критически важных обновлений, применимых к системе.
SecurityUpdatesMissing Число отсутствующих применимых обновлений для системы безопасности.
OtherUpdatesMissing Число обнаруженных отсутствующих обновлений.
TotalUpdatesMissing Общее число отсутствующих применимых обновлений.
RestartPending Значение true, если ожидается перезапуск, или false в противном случае.
SubscriptionId Уникальный идентификатор подписки Azure.
ResourceGroup Имя группы ресурсов, которая содержит ресурс.
ResourceProvider Поставщик ресурса.
Ресурс Имя ресурса записи.
ResourceId Уникальный идентификатор ресурса, связанного с записью.
ResourceType Тип ресурса.
ComputerEnvironment Среда. Значения: "Azure" или "Не относящаяся к Azure".
VMUUID Уникальный идентификатор виртуальной машины.
Тип Тип записи Значение — UpdateSummary.
_ResourceId Уникальный идентификатор ресурса, связанного с записью.

Примеры запросов

В следующих разделах приведены примеры запросов журнала для записей обновлений, которые собираются для Управления обновлениями.

Подтверждение включения Управления обновлениями для виртуальных машин, не относящихся к Azure

Чтобы подтвердить, что подключенные напрямую виртуальные машины взаимодействуют с журналами Azure Monitor, выполните один из приведенных ниже поисков по журналу.

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

Чтобы проверить подключение агента к журналам Azure Monitor на компьютере с Windows, ознакомьтесь со следующей информацией:

  1. На панели управления откройте Microsoft Monitoring Agent. На вкладке Azure Log Analytics агент отобразит сообщение: The Microsoft Monitoring Agent has successfully connected to Log Analytics (Microsoft Monitoring Agent успешно подключен к Log Analytics).

  2. Откройте журнал событий Windows. Перейдите к журналам приложения и служб или Operations Manager и выполните поиск идентификатора события 3000 или 5002 в исходном соединителе службы. Эти события указывают, что компьютер был зарегистрирован для рабочей области Log Analytics и получает конфигурацию.

Если агент не может взаимодействовать с журналами Azure Monitor и настроен на взаимодействие с Интернетом через брандмауэр или прокси-сервер, подтвердите корректную настройку брандмауэра или прокси-сервера. Чтобы узнать, как проверить это, ознакомьтесь со статьей Подключение компьютеров Windows к службе Log Analytics в Azure или Настройка агента Log Analytics для компьютеров Linux в гибридной среде.

Примечание.

Если при включении Управления обновлениями системы Linux настроены для взаимодействия с прокси-сервером или шлюзом Log Analytics, обновите разрешения proxy.conf, чтобы предоставить группе omiuser разрешение на чтение файла. Для этого выполните следующие команды.

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

Добавленные агенты Linux отобразят состояние обновления после оценки. Этот процесс может занять до 6 часов.

Сведения о том, как подтвердить, что группа управления Operations Manager взаимодействует с журналами Azure Monitor, см. в разделе Проверка интеграции Operations Manager с журналами Azure Monitor.

Запросы оценки одной виртуальной машины Azure (Windows)

Замените значение VMUUID на GUID запрашиваемой виртуальной машины. Вы можете найти нужный VMUUID, выполнив следующий запрос в журналах Azure Monitor: Update | where Computer == "<machine name>" | summarize by Computer, VMUUID

Сводка об отсутствующих обновлениях

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

Список отсутствующих обновлений

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

Запросы оценки одной виртуальной машины Azure (Linux)

В некоторых дистрибутивах Linux наблюдается несоответствие порядка байтов между значениями VMUUID, которое поступает из Azure Resource Manager и хранится в журналах Azure Monitor. Следующий запрос проверяет совпадение по порядку байтов. Чтобы вернулись правильные результаты, замените значения VMUUID форматом GUID с прямым и обратным порядком. Вы можете найти нужный VMUUID, выполнив следующий запрос в журналах Azure Monitor: Update | where Computer == "<machine name>" | summarize by Computer, VMUUID

Сводка об отсутствующих обновлениях

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

Список отсутствующих обновлений

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

Запросы для оценки нескольких виртуальных машин

Сводка по компьютерам

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

Сводка об отсутствующих обновлениях

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

Список компьютеров

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

Список отсутствующих обновлений

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

Следующие шаги