Примеры расширенных запросов к Resource Graph

Первым шагом на пути к пониманию запросов к Azure Resource Graph является общее понимание языка запросов. Если вы еще не знакомы с обозревателем данных Azure, рекомендуется просмотреть основные сведения, чтобы понять, как составлять запросы к ресурсам, которые вы ищете.

Мы рассмотрим следующие продвинутые запросы:

Если у вас нет подписки Azure, создайте бесплатную учетную запись, прежде чем приступить к работе.

Поддержка языков

Azure CLI (с помощью расширения) и Azure PowerShell (с помощью модуля) поддерживают Azure Resource Graph. Перед выполнением любого из следующих запросов убедитесь, что среда готова. В разделах об Azure CLI и Azure PowerShell приведены инструкции по установке и проверке выбранной вами среды оболочки.

Отображение типов ресурсов и версий API

Resource Graph в основном использует самую новую не предварительную версию API поставщика ресурсов для получения (GET) свойств ресурсов во время обновления. В некоторых случаях используемая версия API была переопределена, чтобы предоставить больше текущих или широко используемых свойств в результатах. Следующий запрос содержит сведения о версии API, используемой для сбора свойств каждого типа ресурсов:

Resources
| distinct type, apiVersion
| where isnotnull(apiVersion)
| order by type asc
az graph query -q "Resources | distinct type, apiVersion | where isnotnull(apiVersion) | order by type asc"

Получение сведений о емкости и производительности масштабируемого набора виртуальных машин

Этот запрос выполняет поиск ресурсов масштабируемого набора виртуальных машин и возвращает разные сведения, включая размер виртуальной машины и емкость масштабируемого набора. В запросе используется функция toint() для приведения значения емкости в число для сортировки. Наконец, столбцы переименовываются в пользовательские именованные свойства.

Resources
| where type=~ 'microsoft.compute/virtualmachinescalesets'
| where name contains 'contoso'
| project subscriptionId, name, location, resourceGroup, Capacity = toint(sku.capacity), Tier = sku.name
| order by Capacity desc
az graph query -q "Resources | where type=~ 'microsoft.compute/virtualmachinescalesets' | where name contains 'contoso' | project subscriptionId, name, location, resourceGroup, Capacity = toint(sku.capacity), Tier = sku.name | order by Capacity desc"

Удаление столбцов из результатов

Следующий запрос использует summarize для подсчета ресурсов по подписке, join — для их объединения с данными о подписке из таблицы ResourceContainers, а затем project-away — для удаления некоторых столбцов.

Resources
| summarize resourceCount=count() by subscriptionId
| join (ResourceContainers | where type=='microsoft.resources/subscriptions' | project SubName=name, subscriptionId) on subscriptionId
| project-away subscriptionId, subscriptionId1
az graph query -q "Resources | summarize resourceCount=count() by subscriptionId | join (ResourceContainers | where type=='microsoft.resources/subscriptions' | project SubName=name, subscriptionId) on subscriptionId| project-away subscriptionId, subscriptionId1"

Вывод списка всех названий тегов

Этот запрос начинается с тега и строит объект JSON, перечисляющий все уникальные имена тегов и их соответствующие типы.

Resources
| project tags
| summarize buildschema(tags)
az graph query -q "Resources | project tags | summarize buildschema(tags)"

Виртуальные машины, сопоставленные по регулярному выражению

Этот запрос выполняет поиск виртуальных машин, которые соответствуют регулярному выражению (известному как регулярное выражение). matches regex @ позволяет определить регулярное выражение для сопоставления, которое равно ^Contoso(.*)[0-9]+$. Дополнительные сведения об определении регулярного выражения см. в разделе:

  • ^ — Сопоставление должно начаться в начале строки.
  • Contoso — Строка с учетом регистра.
  • (.*) — совпадение подэкспрессии:
    • . — Сопоставляется с любым единичным символом (кроме новой строки).
    • * — Сопоставляется с предыдущим элементом ноль или более раз.
  • [0-9] — Сопоставление группы символ для чисел от 0 до 9.
  • + — Сопоставляется с предыдущим элементом один или более раз.
  • $ — Сопоставление предыдущего элемента должно находиться в конце строки.

После сопоставления по имени запрос проектирует имя и порядок по возрастанию имени.

Resources
| where type =~ 'microsoft.compute/virtualmachines' and name matches regex @'^Contoso(.*)[0-9]+$'
| project name
| order by name asc
az graph query -q "Resources | where type =~ 'microsoft.compute/virtualmachines' and name matches regex @'^Contoso(.*)[0-9]+\$' | project name | order by name asc"

Вывод списка Azure Cosmos DB с указанием определенных расположений записи

Следующий запрос ограничивает ресурсы Azure Cosmos DB, использует mv-expand для расширения пакета свойств для properties.writeLocations, а затем проецирует конкретные поля и ограничивает результаты до значения properties.writeLocations.locationName, совпадающего с "Восточная часть США" или "Западная часть США".

Resources
| where type =~ 'microsoft.documentdb/databaseaccounts'
| project id, name, writeLocations = (properties.writeLocations)
| mv-expand writeLocations
| project id, name, writeLocation = tostring(writeLocations.locationName)
| where writeLocation in ('East US', 'West US')
| summarize by id, name
az graph query -q "Resources | where type =~ 'microsoft.documentdb/databaseaccounts' | project id, name, writeLocations = (properties.writeLocations) | mv-expand writeLocations | project id, name, writeLocation = tostring(writeLocations.locationName) | where writeLocation in ('East US', 'West US') | summarize by id, name"

Хранилища ключей с именем подписки

В следующем запросе показано сложное использование join с kind в качестве leftouter. Запрос ограничивает объединенную таблицу до ресурсов подписки, а project включает только исходное поле subscriptionId и поле name, переименованное в SubName. Переименование полей позволяет избежать join, добавляя его как name1, так как поле уже существует в resources. Исходная таблица фильтруется с where, а следующая project включает столбцы из обеих таблиц. Результатом запроса являются все хранилища ключей, отображающие тип, имя хранилища ключей и имя подписки, в которой оно находится.

Resources
| join kind=leftouter (ResourceContainers | where type=='microsoft.resources/subscriptions' | project SubName=name, subscriptionId) on subscriptionId
| where type == 'microsoft.keyvault/vaults'
| project type, name, SubName
az graph query -q "Resources | join kind=leftouter (ResourceContainers | where type=='microsoft.resources/subscriptions' | project SubName=name, subscriptionId) on subscriptionId | where type == 'microsoft.keyvault/vaults' | project type, name, SubName"

Вывод списка баз данных SQL и их эластичных пулов

В следующем запросе для объединения ресурсов Базы данных SQL и связанных с ними эластичных пулов (если имеются) используется leftouterjoin.

Resources
| where type =~ 'microsoft.sql/servers/databases'
| project databaseId = id, databaseName = name, elasticPoolId = tolower(tostring(properties.elasticPoolId))
| join kind=leftouter (
    Resources
    | where type =~ 'microsoft.sql/servers/elasticpools'
    | project elasticPoolId = tolower(id), elasticPoolName = name, elasticPoolState = properties.state)
on elasticPoolId
| project-away elasticPoolId1
az graph query -q "Resources | where type =~ 'microsoft.sql/servers/databases' | project databaseId = id, databaseName = name, elasticPoolId = tolower(tostring(properties.elasticPoolId)) | join kind=leftouter ( Resources | where type =~ 'microsoft.sql/servers/elasticpools' | project elasticPoolId = tolower(id), elasticPoolName = name, elasticPoolState = properties.state) on elasticPoolId | project-away elasticPoolId1"

Вывод списка виртуальных машин с их сетевым интерфейсом и общедоступным IP-адресом

В этом запросе для объединения виртуальных машин, которые созданы с помощью модели развертывания Resource Manager, связанных с ними сетевых интерфейсов и любых общедоступных IP-адресов, связанных с этими сетевыми интерфейсами, используются две команды leftouterjoin.

Resources
| where type =~ 'microsoft.compute/virtualmachines'
| extend nics=array_length(properties.networkProfile.networkInterfaces)
| mv-expand nic=properties.networkProfile.networkInterfaces
| where nics == 1 or nic.properties.primary =~ 'true' or isempty(nic)
| project vmId = id, vmName = name, vmSize=tostring(properties.hardwareProfile.vmSize), nicId = tostring(nic.id)
| join kind=leftouter (
    Resources
    | where type =~ 'microsoft.network/networkinterfaces'
    | extend ipConfigsCount=array_length(properties.ipConfigurations)
    | mv-expand ipconfig=properties.ipConfigurations
    | where ipConfigsCount == 1 or ipconfig.properties.primary =~ 'true'
    | project nicId = id, publicIpId = tostring(ipconfig.properties.publicIPAddress.id))
on nicId
| project-away nicId1
| summarize by vmId, vmName, vmSize, nicId, publicIpId
| join kind=leftouter (
    Resources
    | where type =~ 'microsoft.network/publicipaddresses'
    | project publicIpId = id, publicIpAddress = properties.ipAddress)
on publicIpId
| project-away publicIpId1
az graph query -q "Resources | where type =~ 'microsoft.compute/virtualmachines' | extend nics=array_length(properties.networkProfile.networkInterfaces) | mv-expand nic=properties.networkProfile.networkInterfaces | where nics == 1 or nic.properties.primary =~ 'true' or isempty(nic) | project vmId = id, vmName = name, vmSize=tostring(properties.hardwareProfile.vmSize), nicId = tostring(nic.id) | join kind=leftouter ( Resources | where type =~ 'microsoft.network/networkinterfaces' | extend ipConfigsCount=array_length(properties.ipConfigurations) | mv-expand ipconfig=properties.ipConfigurations | where ipConfigsCount == 1 or ipconfig.properties.primary =~ 'true' | project nicId = id, publicIpId = tostring(ipconfig.properties.publicIPAddress.id)) on nicId | project-away nicId1 | summarize by vmId, vmName, vmSize, nicId, publicIpId | join kind=leftouter ( Resources | where type =~ 'microsoft.network/publicipaddresses' | project publicIpId = id, publicIpAddress = properties.ipAddress) on publicIpId | project-away publicIpId1"

Список всех расширений, установленных на виртуальной машине

Сначала этот запрос применяет extend к типу ресурса виртуальных машин, чтобы получить идентификатор, указанный прописными буквами (toupper()), имя и тип операционной системы, а также размер виртуальной машины. Получение идентификатора ресурса, указанного прописными буквами, очень удобно при подготовке к объединению с другим свойством. Затем этот запрос применяет join со значением leftouter для параметра kind, чтобы получить список расширений виртуальной машины по сопоставлению с substring идентификатора расширения, указанного прописными буквами. Сегмент идентификатора перед строкой "/extensions/<ExtensionName>" имеет тот же формат, что и идентификатор виртуальных машин, поэтому мы используем это свойство для join. Затем применяется summarize в сочетании с make_list для имени расширения виртуальной машины, чтобы объединить в одно свойство массива все имена расширений, у которых совпадают значения ID, OSName, OSType и VMSize. Наконец, мы применим order by к значению OSName (строчными буквами) с параметром asc. По умолчанию order by использует порядок по убыванию.

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
az graph query -q "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"

Поиск учетных записей хранения с указанным тегом в группе ресурсов

В приведенном ниже запросе используется innerjoin для подключения учетных записей хранения к группам ресурсов с указанными именем с учетом регистра и значением тега.

Resources
| where type =~ 'microsoft.storage/storageaccounts'
| join kind=inner (
    ResourceContainers
    | where type =~ 'microsoft.resources/subscriptions/resourcegroups'
    | where tags['Key1'] =~ 'Value1'
    | project subscriptionId, resourceGroup)
on subscriptionId, resourceGroup
| project-away subscriptionId1, resourceGroup1
az graph query -q "Resources | where type =~ 'microsoft.storage/storageaccounts' | join kind=inner ( ResourceContainers | where type =~ 'microsoft.resources/subscriptions/resourcegroups' | where tags['Key1'] =~ 'Value1' | project subscriptionId, resourceGroup) on subscriptionId, resourceGroup | project-away subscriptionId1, resourceGroup1"

Если вам необходимо найти нечувствительное к регистру имя и значение тега, используйте mv-expand с параметром bagexpansion. Этот запрос использует больше квот, чем предыдущий, поэтому используйте mv-expand только при необходимости.

Resources
| where type =~ 'microsoft.storage/storageaccounts'
| join kind=inner (
    ResourceContainers
    | where type =~ 'microsoft.resources/subscriptions/resourcegroups'
    | mv-expand bagexpansion=array tags
    | where isnotempty(tags)
    | where tags[0] =~ 'key1' and tags[1] =~ 'value1'
    | project subscriptionId, resourceGroup)
on subscriptionId, resourceGroup
| project-away subscriptionId1, resourceGroup1
az graph query -q "Resources | where type =~ 'microsoft.storage/storageaccounts' | join kind=inner ( ResourceContainers | where type =~ 'microsoft.resources/subscriptions/resourcegroups' | mv-expand bagexpansion=array tags | where isnotempty(tags) | where tags[0] =~ 'key1' and tags[1] =~ 'value1' | project subscriptionId, resourceGroup) on subscriptionId, resourceGroup | project-away subscriptionId1, resourceGroup1"

Объединение результатов из двух запросов в один результат

Следующий запрос использует union, чтобы получить результаты из таблицы ResourceContainers и добавить их в результаты из таблицы Resources.

ResourceContainers
| where type=='microsoft.resources/subscriptions/resourcegroups' | project name, type  | limit 5
| union  (Resources | project name, type | limit 5)
az graph query -q "ResourceContainers | where type=='microsoft.resources/subscriptions/resourcegroups' | project name, type  | limit 5 | union  (Resources | project name, type | limit 5)"

Получение виртуальных сетей и подсетей сетевых интерфейсов

Используйте регулярное выражение parse для получения имен виртуальной сети и подсети из свойства "ИД ресурса". Хотя parse позволяет получать данные из сложного поля, доступ к свойствам, если они существуют, лучше всего осуществлять напрямую, а не с помощью parse.

Resources
| where type =~ 'microsoft.network/networkinterfaces'
| project id, ipConfigurations = properties.ipConfigurations
| mvexpand ipConfigurations
| project id, subnetId = tostring(ipConfigurations.properties.subnet.id)
| parse kind=regex subnetId with '/virtualNetworks/' virtualNetwork '/subnets/' subnet
| project id, virtualNetwork, subnet
az graph query -q "Resources | where type =~ 'microsoft.network/networkinterfaces' | project id, ipConfigurations = properties.ipConfigurations | mvexpand ipConfigurations | project id, subnetId = tostring(ipConfigurations.properties.subnet.id) | parse kind=regex subnetId with '/virtualNetworks/' virtualNetwork '/subnets/' subnet | project id, virtualNetwork, subnet"

Суммирование виртуальных машин по расширенному свойству состояния питания

Этот запрос использует расширенные свойства на виртуальных машинах для суммирования по состоянию питания.

Resources
| where type == 'microsoft.compute/virtualmachines'
| summarize count() by tostring(properties.extended.instanceView.powerState.code)
az graph query -q "Resources | where type == 'microsoft.compute/virtualmachines' | summarize count() by tostring(properties.extended.instanceView.powerState.code)"

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