Ejemplos de consultas avanzadas de Resource Graph

El primer paso para entender las consultas con Azure Resource Graph es el reconocimiento básico del lenguaje de consultas. Si aún no está familiarizado con Azure Data Explorer, se recomienda repasar los conceptos básicos para entender cómo componer solicitudes para los recursos que está buscando.

Le guiaremos por las siguientes consultas avanzadas:

Si no tiene una suscripción a Azure, cree una cuenta gratuita antes de empezar.

Compatibilidad con idiomas

La CLI de Azure (mediante una extensión) y Azure PowerShell (mediante un módulo) admiten Azure Resource Graph. Antes de ejecutar cualquiera de las siguientes consultas, compruebe que el entorno está listo. Consulte la CLI de Azure y Azure PowerShell para conocer los pasos para instalar y validar el entorno de shell que prefiera.

Mostrar tipos de recurso y versiones de API

Resource Graph usa mayormente la versión no preliminar más reciente de una API de proveedor de recursos para obtener las propiedades de los recursos durante una actualización (instrucción GET). En algunos casos, la versión de la API usada se ha invalidado para proporcionar propiedades más actuales o ampliamente utilizadas en los resultados. La siguiente consulta detalla la versión de API que se usa para recopilar propiedades en cada tipo de recurso:

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"

Obtener la capacidad y el tamaño del conjunto de escalado de máquinas virtuales

Esta consulta busca los recursos del conjunto de escalado de máquinas virtuales y obtiene varios detalles, incluido el tamaño de la máquina virtual y la capacidad del conjunto de escalado. La consulta usa la función toint() para convertir la capacidad en un número para que se pueda ordenar. Por último, se cambia el nombre de las columnas por propiedades con nombre personalizadas.

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"

Eliminación de columnas de los resultados

En la consulta siguiente se usa summarize para contar los recursos por suscripción, join para combinarlos con los detalles de la suscripción de la tabla summarize y, después, project-away para quitar algunas de las columnas.

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"

Enumeración de todos los nombres de etiquetas

Esta consulta comienza con la etiqueta y crea un objeto JSON que enumera todos los nombres de etiqueta únicos y sus tipos correspondientes.

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

Máquinas virtuales que coinciden con regex

Esta consulta busca las máquinas virtuales que coincidan con una expresión regular (conocida como regex). matches regex @ nos permite definir regex para coincidir, que es ^Contoso(.*)[0-9]+$. Esa definición de regex se explica como:

  • ^ - La coincidencia debe empezar al principio de la cadena.
  • Contoso: la cadena distingue mayúsculas de minúsculas.
  • (.*): una coincidencia de subexpresión:
    • . - Coincide con cualquier carácter individual (excepto saltos de línea).
    • * - Coincide con el elemento anterior cero o más veces.
  • [0-9] - Coincidencia de grupo caracteres para los números del 0 al 9.
  • + - Coincide con el elemento anterior una o más veces.
  • $ - La coincidencia del elemento anterior se debe producir al final de la cadena.

Después de la coincidencia del nombre, la consulta proyecta el nombre y ordena por nombre de forma ascendente.

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"

Enumeración de Azure Cosmos DB con ubicaciones de escritura concretas

Los siguientes límites de consultas para los recursos de Azure Cosmos DB usan mv-expand para expandir la bolsa de propiedades para mv-expand, después proyectan campos específicos y limitan los resultados a valores de properties.writeLocations.locationName que coinciden con "Este de EE. UU." u "Oeste de EE. UU.".

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"

Almacenes de claves con el nombre de la suscripción

En la consulta siguiente se muestra un uso complejo de join con join como leftouter. La consulta limita la tabla combinada a los recursos de suscripciones y con project para incluir solo el campo original project y el campo name con el nombre cambiado a SubName. El cambio de nombre del campo evita join agregarlo como join, ya que el campo ya existe en resources . La tabla original se filtra por where y el project siguiente incluye columnas de ambas tablas. El resultado de la consulta son todos los almacenes de claves que muestran el tipo, el nombre del almacén de claves y el nombre de la suscripción en la que se encuentra.

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"

Enumeración de bases de datos SQL y sus grupos elásticos

En la consulta siguiente se usa leftouterjoin para reunir los recursos de SQL Database y sus grupos elásticos relacionados, si existen.

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"

Enumeración de máquinas virtuales con su interfaz de red y dirección IP pública

Esta consulta usa dos comandos leftouterjoin para reunir las máquinas virtuales creadas con el modelo de implementación de Resource Manager, sus interfaces de red relacionadas y todas las direcciones IP públicas relacionadas con esas interfaces.

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"

Enumeración de todas las extensiones instaladas en una máquina virtual

En primer lugar, esta consulta usa extend en el tipo de recurso de máquinas virtuales para obtener el identificador en mayúsculas (toupper() el identificador), el nombre y el tipo del sistema operativo y el tamaño de la máquina virtual. Obtener el identificador de recurso en mayúsculas es una ayuda en la preparación para unirse a otra propiedad. A continuación, la consulta utiliza join con leftouter como tipo para obtener las extensiones de máquina virtual mediante la coincidencia de una substring en mayúsculas del ID. de extensión. La parte del identificador antes de "/extensions/<NombreDeLaExtensión>" tiene el mismo formato que el identificador de las máquinas virtuales, por lo que se usa esta propiedad para join. summarize se usa entonces con make_list en el nombre de la extensión de máquina virtual para combinar el nombre de cada extensión, donde ID, OSName, OSTypey VMSize son iguales en una única propiedad de matriz. Por último, se aplica order by a OSName en minúsculas con asc. De forma predeterminada, el valor predeterminado de order by es descendente.

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"

Búsqueda de cuentas de almacenamiento con una etiqueta concreta en el grupo de recursos

En la consulta siguiente se usa innerjoin para conectar cuentas de almacenamiento con grupos de recursos que tienen especificados un nombre y un valor de etiqueta que distinguen mayúsculas de minúsculas.

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"

Si es necesario buscar un nombre de etiqueta y un valor de etiqueta que no distingan entre mayúsculas y minúsculas, utilice mv-expand con el parámetro bagexpansion. Esta consulta usa más cuota que la consulta anterior, por lo que solo debe utilizar mv-expand si es necesario.

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"

Combinación de los resultados de dos consultas para formar un solo resultado

La siguiente consulta utiliza union para obtener los resultados de la tabla ResourceContainers y agregarlos a los resultados de la tabla 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)"

Obtención de redes virtuales y subredes de interfaces de red

Use una expresión regular parse para obtener los nombres de red virtual y de subred de la propiedad de identificador de recurso. Aunque parse permite obtener datos de un campo complejo, es óptimo acceder directamente a las propiedades si existen, en lugar de usar 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"

Resumen de la máquina virtual mediante la propiedad extendida de estados de energía

Esta consulta usa las propiedades extendidas de las máquinas virtuales para hacer un resumen por estados de energía.

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

Pasos siguientes