Query's uitvoeren op Azure CLI-opdrachtuitvoer met behulp van een JMESPath-query

In de Azure CLI wordt het argument --query gebruikt om een JMESPath-query uit te voeren op de opdrachtresultaten. JMESPath is een querytaal voor JSON, zodat u gegevens uit CLI-uitvoer kunt selecteren en wijzigen. Query's worden uitgevoerd op de JSON-uitvoer vóór weergaveopmaak.

Het argument --query wordt ondersteund door alle opdrachten in Azure CLI. In dit artikel wordt beschreven hoe u de functies van JMESPath gebruikt met een reeks kleine, eenvoudige voorbeelden.

Notitie

Wanneer u Azure CLI gebruikt in PowerShell Windows, is er mogelijk extra escape-informatie nodig voor het queryargument. Zie Quoting issues with PowerShell (Problemen met PowerShell aan quoten) voor meer informatie.

CLI-resultaten in woordenlijst en lijst

Zelfs wanneer u een andere uitvoerindeling dan JSON gebruikt, worden cli-opdrachtresultaten eerst behandeld als JSON voor query's. CLI-resultaten zijn een JSON-matrix of -woordenlijst. Matrices zijn reeksen objecten die kunnen worden geïndexeerd en woordenlijsten zijn niet-ordebare objecten die toegankelijk zijn met sleutels. Opdrachten die meer dan één object kunnen retourneren, retourneren een matrix en opdrachten die altijd slechts één object retourneren, retourneren een woordenlijst.

Eigenschappen in een woordenlijst op halen

Als u met woordenlijstresultaten werkt, hebt u met alleen de sleutel toegang tot eigenschappen op het hoogste niveau. Het . teken (subexpressie) wordt gebruikt voor toegang tot eigenschappen van geneste woordenlijsten. Voordat u query's introduceert, bekijkt u de ongewijzigde uitvoer van de az vm show opdracht:

az vm show -g QueryDemo -n TestVM -o json

Met de opdracht wordt een woordenlijst uitgevoerd. Sommige inhoud is weggelaten.

{
  "additionalCapabilities": null,
  "availabilitySet": null,
  "diagnosticsProfile": {
    "bootDiagnostics": {
      "enabled": true,
      "storageUri": "https://xxxxxx.blob.core.windows.net/"
    }
  },
  ...
  "osProfile": {
    "adminPassword": null,
    "adminUsername": "azureuser",
    "allowExtensionOperations": true,
    "computerName": "TestVM",
    "customData": null,
    "linuxConfiguration": {
      "disablePasswordAuthentication": true,
      "provisionVmAgent": true,
      "ssh": {
        "publicKeys": [
          {
            "keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso",
            "path": "/home/azureuser/.ssh/authorized_keys"
          }
        ]
      }
    },
    "secrets": [],
    "windowsConfiguration": null
  },
  ....
}

Met de volgende opdracht worden de openbare SSH-sleutels die zijn gemachtigd om verbinding te maken met de VM, opgevraagd door een query toe te voegen:

az vm show -g QueryDemo -n TestVM --query osProfile.linuxConfiguration.ssh.publicKeys -o json
[
  {
    "keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso",
    "path": "/home/azureuser/.ssh/authorized_keys"
  }
]

Eén waarde krijgen

Een veelvoorkomende case is dat u slechts één waarde uit een CLI-opdracht hoeft op te halen, zoals een Azure-resource-id, een resourcenaam, een gebruikersnaam of een wachtwoord. In dat geval wilt u de waarde ook vaak opslaan in een lokale omgevingsvariabele. Als u één eigenschap wilt krijgen, moet u er eerst voor zorgen dat u slechts één eigenschap uit de query krijgt. Wijzig het laatste voorbeeld om alleen de gebruikersnaam van de beheerder op te halen:

az vm show -g QueryDemo -n TestVM --query 'osProfile.adminUsername' -o json
"azureuser"

Dit ziet eruit als een geldige enkele waarde, maar houd er rekening mee dat de " tekens worden geretourneerd als onderdeel van de uitvoer. Dit geeft aan dat het object een JSON-tekenreeks is. Het is belangrijk te weten dat wanneer u deze waarde rechtstreeks als uitvoer van de opdracht toewijst aan een omgevingsvariabele, de aanhalingstekens mogelijk niet worden geïnterpreteerd door de shell:

USER=$(az vm show -g QueryDemo -n TestVM --query 'osProfile.adminUsername' -o json)
echo $USER
"azureuser"

Dit is bijna zeker niet wat u wilt. In dit geval wilt u een uitvoerindeling gebruiken die geen geretourneerde waarden insluit met typegegevens. De beste uitvoeroptie die de CLI voor dit doel biedt, is tsv door tabs gescheiden waarden. Met name bij het ophalen van een waarde die slechts één waarde is (niet een woordenlijst of lijst), is de uitvoer gegarandeerd tsv niet-aan te halen.

az vm show -g QueryDemo -n TestVM --query 'osProfile.adminUsername' -o tsv
azureuser

Zie Uitvoerindelingen tsv - TSV-uitvoerindeling voor meer informatie over de uitvoerindeling

Booleaanse waarden opvragen

Het uitvoeren van query's op Booleaanse waarden is iets anders. Er zijn twee opties:

# Boolean values are assumed to be true, so this syntax returns the current default subscription.
az account list --query "[?isDefault]"

# If you want a false value, use an escape character.
az account list --query "[?isDefault == \`false\`]"

Meerdere waarden op halen

Als u meer dan één eigenschap wilt op halen, zet u expressies tussen vierkante haken (een lijst met meerdere [ ] selecties) als een door komma's gescheiden lijst. Gebruik de opdracht om de VM-naam, de gebruiker met beheerdersrechten en de SSH-sleutel in één keer op te halen:

az vm show -g QueryDemo -n TestVM --query '[name, osProfile.adminUsername, osProfile.linuxConfiguration.ssh.publicKeys[0].keyData]' -o json
[
  "TestVM",
  "azureuser",
  "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso"
]

Deze waarden worden weergegeven in de resultaat matrix in de volgorde waarin ze zijn opgegeven in de query. Omdat het resultaat een matrix is, zijn er geen sleutels gekoppeld aan de resultaten.

De naam van eigenschappen in een query wijzigen

Als u een woordenlijst wilt opvragen in plaats van een matrix bij het opvragen van meerdere waarden, gebruikt u de { } operator (multiselect hash). De indeling voor een hash met meerdere selecties is {displayName:JMESPathExpression, ...} . displayName wordt de tekenreeks die wordt weergegeven in de uitvoer en JMESPathExpression is de JMESPath-expressie die moet worden geëvalueerd. Wijzig het voorbeeld uit de laatste sectie door de lijst met meervoudige selecties te wijzigen in een hash:

az vm show -g QueryDemo -n TestVM --query '{VMName:name, admin:osProfile.adminUsername, sshKey:osProfile.linuxConfiguration.ssh.publicKeys[0].keyData }' -o json
{
  "VMName": "TestVM",
  "admin": "azureuser",
  "ssh-key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso"
}

Eigenschappen in een matrix op te halen

Een matrix heeft geen eigen eigenschappen, maar kan wel worden geïndexeerd. Deze functie wordt weergegeven in het laatste voorbeeld met de expressie , waarmee het eerste element van publicKeys[0] de matrix wordt publicKeys weergegeven. Er is geen garantie dat DE CLI-uitvoer is geordend, dus vermijd het gebruik van indexering, tenzij u zeker bent van de volgorde of het niet belangrijk is welk element u krijgt. Voor toegang tot de eigenschappen van elementen in een matrix, moet u een van de volgende twee bewerkingen uitvoeren: plat maken en filteren. In deze sectie wordt be lezen hoe u een matrix plat maakt.

Het plat maken van een matrix wordt uitgevoerd met de [] JMESPath-operator. Alle expressies na de [] operator worden toegepast op elk element in de huidige matrix. Als wordt weergegeven aan het begin van de query, wordt het RESULTAAT van de [] CLI-opdracht plat gemaakt. De resultaten van az vm list kunnen met deze functie worden geïnspecteerd. De naam, het besturingssysteem en de beheerdersnaam voor elke VM in een resourcegroep op te halen:

az vm list -g QueryDemo --query '[].{Name:name, OS:storageProfile.osDisk.osType, admin:osProfile.adminUsername}' -o json
[
  {
    "Name": "Test-2",
    "OS": "Linux",
    "admin": "sttramer"
  },
  {
    "Name": "TestVM",
    "OS": "Linux",
    "admin": "azureuser"
  },
  {
    "Name": "WinTest",
    "OS": "Windows",
    "admin": "winadmin"
  }
]

In combinatie met de --output table uitvoerindeling komen de kolomnamen overeen met de displayKey waarde van de hash met meerdere selecties:

az vm list -g QueryDemo --query '[].{Name:name, OS:storageProfile.osDisk.osType, Admin:osProfile.adminUsername}' --output table
Name     OS       Admin
-------  -------  ---------
Test-2   Linux    sttramer
TestVM   Linux    azureuser
WinTest  Windows  winadmin

Notitie

Bepaalde sleutels worden eruit gefilterd en niet opgenomen in de tabelweergave. Deze sleutels zijn id, type en etag. Als u deze waarden wilt zien, kunt u de sleutelnaam wijzigen in een hash met meerdere selecties.

az vm show -g QueryDemo -n TestVM --query "{objectID:id}" -o table

Elke matrix kan plat worden gemaakt, niet alleen het resultaat op het hoogste niveau dat wordt geretourneerd door de opdracht . In de laatste sectie is de expressie gebruikt om de openbare SSH-sleutel voor osProfile.linuxConfiguration.ssh.publicKeys[0].keyData aanmelding op te halen. Om elke openbare SSH-sleutel op te halen, kan de expressie in plaats daarvan worden geschreven als osProfile.linuxConfiguration.ssh.publicKeys[].keyData . Met deze queryexpressie wordt de osProfile.linuxConfiguration.ssh.publicKeys matrix afgevlakt en wordt vervolgens de keyData expressie voor elk element uitgevoerd:

az vm show -g QueryDemo -n TestVM --query '{VMName:name, admin:osProfile.adminUsername, sshKeys:osProfile.linuxConfiguration.ssh.publicKeys[].keyData }' -o json
{
  "VMName": "TestVM",
  "admin": "azureuser",
  "sshKeys": [
    "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso\n"
  ]
}

Matrices filteren

De andere bewerking die wordt gebruikt om gegevens op te halen uit een matrix is filteren. Filteren wordt uitgevoerd met de [?...] JMESPath-operator. Deze operator neemt een predicaat als inhoud. Een predicaat is een instructie die kan worden geëvalueerd als true of false . Expressies waarbij het predicaat als wordt true geëvalueerd, worden opgenomen in de uitvoer.

JMESPath biedt de standaardvergelijking en logische operators. Deze omvatten < , , , , en <= > >= == != . JMESPath ondersteunt ook logical and ( && ), or ( ) en niet ( || ! ). Expressies kunnen worden gegroepeerd tussen haakjes, waardoor complexere predicaatexpressie mogelijk is. Zie de JMESPath-specificatievoor meer informatie over predicaten en logische bewerkingen.

In de laatste sectie hebben we een matrix plat gemaakt om de volledige lijst met alle VM's in een resourcegroep op te halen. Met behulp van filters kan deze uitvoer worden beperkt tot alleen Linux-VM's:

az vm list -g QueryDemo --query "[?storageProfile.osDisk.osType=='Linux'].{Name:name,  admin:osProfile.adminUsername}" --output table
Name    Admin
------  ---------
Test-2  sttramer
TestVM  azureuser

Belangrijk

In JMESPath worden tekenreeksen altijd omgeven door enkele aanhalingstekens ( ' ). Als u dubbele aanhalingstekens gebruikt als onderdeel van een tekenreeks in een filterpredicaat, krijgt u lege uitvoer.

JMESPath heeft ook ingebouwde functies die u kunnen helpen bij het filteren. Een van deze functies is ? contains(string, substring) , waarmee wordt gecontroleerd of een tekenreeks een subtekenreeks bevat. Expressies worden geëvalueerd voordat de functie wordt aanroepen, zodat het eerste argument een volledige JMESPath-expressie kan zijn. In het volgende voorbeeld worden alle VM's gevonden die SSD-opslag gebruiken voor hun besturingssysteemschijf:

az vm list -g QueryDemo --query "[? contains(storageProfile.osDisk.managedDisk.storageAccountType,'SSD')].{Name:name, Storage:storageProfile.osDisk.managedDisk.storageAccountType}" -o json
[
  {
    "Name": "TestVM",
    "Storage": "StandardSSD_LRS"
  },
  {
    "Name": "WinTest",
    "Storage": "StandardSSD_LRS"
  }
]

Deze query is een beetje lang. De storageProfile.osDisk.managedDisk.storageAccountType sleutel wordt twee keer genoemd en opnieuw in de uitvoer. U kunt het filter onder andere inkorten door het filter toe te passen na het plat maken en selecteren van gegevens.

az vm list -g QueryDemo --query "[].{Name:name, Storage:storageProfile.osDisk.managedDisk.storageAccountType}[? contains(Storage,'SSD')]" -o json
[
  {
    "Name": "TestVM",
    "Storage": "StandardSSD_LRS"
  },
  {
    "Name": "WinTest",
    "Storage": "StandardSSD_LRS"
  }
]

Voor grote matrices is het mogelijk sneller om het filter toe te passen voordat u gegevens selecteert.

Zie de JMESPath-specificatie - Ingebouwde functies voor de volledige lijst met functies.

Uitvoer wijzigen

JMESPath-functies hebben ook een ander doel: het uitvoeren van de resultaten van een query. Elke functie die een niet-Booleaanse waarde retourneert, wijzigt het resultaat van een expressie. U kunt bijvoorbeeld gegevens sorteren op een eigenschapswaarde met sort_by(array, &sort_expression) . JMESPath maakt gebruik van een speciale operator, , voor expressies die later moeten worden geëvalueerd & als onderdeel van een functie. In het volgende voorbeeld ziet u hoe u een lijst met VM's kunt sorteren op grootte van de besturingssysteemschijf:

az vm list -g QueryDemo --query "sort_by([].{Name:name, Size:storageProfile.osDisk.diskSizeGb}, &Size)" --output table
Name     Size
-------  ------
TestVM   30
Test-2   32
WinTest  127

Zie de JMESPath-specificatie - Ingebouwde functies voor de volledige lijst met functies.

Interactief experimenteren met query’s

Als u wilt experimenteren met JMESPath, biedt het Python-pakket JMESPath-terminal een interactieve omgeving om met query's te werken. Gegevens worden doorspijpt als invoer en vervolgens worden query's geschreven en uitgevoerd in de editor.

pip install jmespath-terminal
az vm list --output json | jpterm