Azure / azure-cli

Azure Command-Line Interface
MIT License
3.96k stars 2.94k forks source link

`az ad group member list` outputs far less information than before the Graph API migration. How to retrieve those additional attributes? #23017

Open jonfuller opened 2 years ago

jonfuller commented 2 years ago

This is autogenerated. Please review and update as needed.

Describe the issue

We use the outputs of az ad group member list to drive other data-backed process within our company. Many of the attributes that used to be available as outputs from this command are longer output.

What is the migration path to access those other pieces of information from the azcli?

Command Name az ad group member list

To Reproduce:

Steps to reproduce the behavior. Note that argument values have been redacted, as they may contain sensitive information.

partial JSON snippet

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
  "businessPhones": [
    "5555"
  ],
  "displayName": "Name Last",
  "givenName": "Name",
  "id": "GUID",
  "jobTitle": "Some Title",
  "mail": "example@example.org",
  "mobilePhone": "555-555-5555",
  "officeLocation": null,
  "preferredLanguage": null,
  "surname": "Last",
  "userPrincipalName": "example@example.org"
}

Expected Behavior

Prior to 2.37 an example output might look like:

partial JSON snippet

  {
    "accountEnabled": true,
    "ageGroup": null,
    "assignedLicenses": [
      {
        "disabledPlans": [],
        "skuId": "GUID"
      },
...
    ],
    "assignedPlans": [
   {
        "assignedTimestamp": "2020-05-20T22:06:46Z",
        "capabilityStatus": "Enabled",
        "service": "ServiceName",
        "servicePlanId": "GUID"
      }
...
    ],
    "city": null,
    "companyName": null,
    "consentProvidedForMinor": null,
    "country": null,
    "createdDateTime": "date",
    "creationType": "EmailVerified",
    "deletionTimestamp": null,
    "department": null,
    "dirSyncEnabled": true,
    "displayName": "Name Last",
    "employeeId": null,
    "extension_b8017f7b65834f229dfc5057389a227a_extensionAttribute1": "value",
    "extension_b8017f7b65834f229dfc5057389a227a_extensionAttribute2": "date",
    "facsimileTelephoneNumber": null,
    "givenName": "Nickname",
    "immutableId": "NotGuid",
    "isCompromised": null,
    "jobTitle": "Title",
    "lastDirSyncTime": "Date",
    "legalAgeGroupClassification": null,
    "mail": "example@example.org",
    "mailNickname": "example",
    "mobile": "555-555-5555",
    "objectId": "GUID",
    "objectType": "User",
    "odata.type": "Microsoft.DirectoryServices.User",
    "onPremisesDistinguishedName": "CN/OU information",
    "onPremisesSecurityIdentifier": "...",
    "otherMails": [
      "otherexample@example.org"
    ],
...
    "userPrincipalName": "example@example.org",
    "userState": null,
    "userStateChangedOn": null,
    "userType": "Member"
  },

Environment Summary

macOS-12.4-x86_64-i386-64bit, Darwin 21.5.0
Python 3.10.4
Installer: HOMEBREW

azure-cli 2.37.0

This is also happening on github actions, after upgrading to azure-cli 2.37.0

Additional Context

Any help would be much appreciated! Thanks in advance!

yonzhan commented 2 years ago

@jiasli for awareness

jiasli commented 2 years ago

Actually, I am little bit curious why your result has "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity". Running az ad group member list on my machine shows

> az ad group member list --group 796cd246-84fa-468d-a8ef-97b80b0943da
[
  {
    "@odata.type": "#microsoft.graph.user",
    "businessPhones": [],
    "displayName": "Admin",
    "givenName": "Admin",
    "id": "7a938a30-4226-420e-996f-4d48bca6d537",
    "jobTitle": null,
    "mail": null,
    "mobilePhone": null,
    "officeLocation": null,
    "preferredLanguage": null,
    "surname": null,
    "userPrincipalName": "admin@AzureSDKTeam.onmicrosoft.com"
  }
]

Even the raw HTTP response of az ad user list --verbose only has "@odata.context":"https://graph.microsoft.com/v1.0/$metadata#users".

Anyway, az ad user list also has this behavior change

> az ad user list
[
  {
    "businessPhones": [],
    "displayName": "2021-12-02-08-52-55-azps-demo-user1",
    "givenName": null,
    "id": "549e5db4-5f11-48c6-a646-bb515a19785d",
    "jobTitle": null,
    "mail": null,
    "mobilePhone": null,
    "officeLocation": null,
    "preferredLanguage": null,
    "surname": null,
    "userPrincipalName": "2021-12-02-08-52-55-azps-demo-user_microsoft.com#EXT#@AzureSDKTeam.onmicrosoft.com"
  },

This is described by https://docs.microsoft.com/en-us/graph/api/user-list?view=graph-rest-1.0&tabs=http:

By default, only a limited set of properties are returned (businessPhones, displayName, givenName, id, jobTitle, mail, mobilePhone, officeLocation, preferredLanguage, surname, and userPrincipalName). To return an alternative property set, specify the desired set of user properties using the OData $select query parameter. For example, to return displayName, givenName, and postalCode, add the following to your query $select=displayName,givenName,postalCode.

I will mark this issue as a feature request to support $select query parameter.

For now, you may directly call az rest (https://github.com/Azure/azure-cli/issues/22580) to use $select query parameter.

thiagottss commented 2 years ago

Hi there,

Which permission is required to show these properties when using the az ad group member list command?

I can successfully get the properties when running with my account but when running it with an app principal all the properties return null values.

{ "@odata.type": "#microsoft.graph.user", "businessPhones": [], "displayName": null, "givenName": null, "id": "dc119ab6-74b6-461c-959e-bc170ece87ae", "jobTitle": null, "mail": null, "mobilePhone": null, "officeLocation": null, "preferredLanguage": null, "surname": null, "userPrincipalName": null }

image

PS.: it was working fine before but now the Azure AD API is deprecated and we have to use Graph API.

Thanks,

timja commented 2 years ago

If anyone is on Azure DevOps and stuck with this issue I downgraded it with:

  - script: |
      AZ_REPO=$(lsb_release -cs)
      echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $AZ_REPO main" |
        sudo tee /etc/apt/sources.list.d/azure-cli.list
      sudo apt-get update
      sudo apt-cache madison azure-cli
      sudo apt-get install -y --allow-downgrades azure-cli=2.36.0-1~bionic
    displayName: Downgrade Azure CLI
theonesuperdave commented 2 years ago

I see issues similar to @thiagottss in that Postman and the Graph Explorer work just fine, but az CLI and Azure AD PowerShell always return the same JSON object in the response. $select has no effect on the output.

using az rest with the following URI: https://graph.microsoft.com/v1.0/users/[UPN]?$select=id,displayName,userPrincipalName,accountEnabled,onPremisesDistinguishedName.

Maybe az CLI and PowerShell are missing some scopes when requesting the token? I see the following scopes in the access token from Graph Explorer and it's working as expected.

"scp": "DeviceManagementApps.Read.All DeviceManagementApps.ReadWrite.All DeviceManagementConfiguration.Read.All DeviceManagementConfiguration.ReadWrite.All DeviceManagementManagedDevices.PrivilegedOperations.All DeviceManagementManagedDevices.Read.All DeviceManagementManagedDevices.ReadWrite.All DeviceManagementRBAC.Read.All DeviceManagementRBAC.ReadWrite.All DeviceManagementServiceConfig.Read.All DeviceManagementServiceConfig.ReadWrite.All Directory.AccessAsUser.All Directory.ReadWrite.All IdentityRiskEvent.Read.All openid Organization.Read.All People.Read People.Read.All profile User.Read User.Read.All User.ReadBasic.All User.ReadWrite User.ReadWrite.All UserActivity.ReadWrite.CreatedByApp

az CLi version - 2.38.0

@jiasli - please advise when you can.

theonesuperdave commented 2 years ago

Just curious if anyone has gotten the az rest workaround to work with $select or if it's just me?

@jiasli - do you have any advice, please?

timja commented 1 year ago

We have switched to az rest:

previously:

$ az ad user list > users/aad.json

now:


NEXT_LINK=
counter=0

until [[ "${NEXT_LINK}" == "null" ]]; do
  echo "Working on users-${counter}.json"

  if [[ ${counter} == 0 ]]; then
    az rest --method get --uri 'https://graph.microsoft.com/beta/users?$top=999&filter=accountEnabled+eq+true&select=accountEnabled,displayName,mail,otherMails,mailNickname' > users/users-${counter}.json
  else
    az rest --method get --uri "${NEXT_LINK}" > users/users-${counter}.json
  fi

  NEXT_LINK=$(jq -r '."@odata.nextLink"' users/users-${counter}.json)

  counter=$(( counter + 1 ))

done

jq -s 'map(.value[])' users/users-?.json > users/aad.json
rm -rf users/users-${counter}.json