azureazure-powershell

Azure Portal PowerShell Read Global Admins Certificate


I am trying to read global admins out of a portal using PowerShell. I know I am very close, I can read VMs and other information out.

I connect in with this:

Connect-AzAccount -CertificateThumbprint $certThumbPrint -ApplicationId $applicationID -Tenant $tenantID -ServicePrincipal
# Verify connection
if (-not (Get-AzContext)) {
    Write-Host "Failed to connect to Azure. Please check your credentials and try again." -ForegroundColor Red
    return
}

I read VMs with this:

# Get a list of VMs
$vms = Get-AzVM 

# Display VM information
foreach ($vm in $vms) {
    Write-Host "VM Name: $($vm.Name), Resource Group: $($vm.ResourceGroupName)"
    # Add more details as needed
}

I try to read global admins with this but get unauthorized error:

Connect-MgGraph -ClientId $applicationID -TenantId $tenantID -CertificateThumbprint $certThumbPrint
# Connect-MgGraph -ClientId $appId -TenantId $tenantId -CertificateThumbprint $thumbprint

$adminRole = Get-MgDirectoryRole -Filter "DisplayName eq '$roleName'"

if ($adminRole) {
    $roleMembers = Get-MgDirectoryRoleMember -DirectoryRoleId $adminRole.Id

    if ($roleMembers) {
        $roleMembers | ForEach-Object {
            [PSCustomObject]@{
                DisplayName = $_.AdditionalProperties["displayName"]
                Id          = $_.Id
            }
        } | Format-Table DisplayName, Id
    } else {
        Write-Host "No members found for the role: $roleName"
    }
} else {
    Write-Host "Role '$roleName' not found"
}

Get-MgDirectoryRole_List: Line | 4 | $adminRole = Get-MgDirectoryRole -Filter "DisplayName eq '$roleName'" | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | Insufficient privileges to complete the operation.

Status: 403 (Forbidden) ErrorCode: Authorization_RequestDenied Date: 2024-11-06T22:30:03

Headers: Cache-Control : no-cache Vary : Accept-Encoding Strict-Transport-Security : max-age=31536000

App registration permissions: enter image description here

I feel like I'm missing something small and simple here.

UPDATE:

So these are the permissions I add with my code:

$app = Get-AzADApplication  -ApplicationId $sp.AppId
$appObjectId = $app.Id

Write-Host "ApplicationID: $($sp.AppId)" -ForegroundColor Magenta
# Write-Host $appObjectId -ForegroundColor Magenta

# Assign Reader role to the Service Principal under specific subscription
$spId = (Get-AzADServicePrincipal -DisplayName $applicationName).Id
New-AzRoleAssignment -ObjectId $spId `
    -RoleDefinitionName "Reader" `
    -Scope "/"

# Add Microsoft Graph Directory.Read.All permission of Application type
Add-AzADAppPermission -ObjectId $appObjectId `
-ApiId "00000003-0000-0000-c000-000000000000" `
-PermissionId "7ab1d382-f21e-4acd-a863-ba3e13f7da61" `
-Type Role

I go and manually grant admin consent

enter image description here

AFter running Get-MgContext enter image description here

I see I am missing the scope permissions.

Thank you all.

UPDATE: Scoped assigned in correct area enter image description here

enter image description here

CODE:

Connect-MgGraph -ClientId $applicationID -TenantId $tenantID -CertificateThumbprint $certThumbPrint
Get-MgContext 
$roleName = "Global Administrator"

$adminRole = Get-MgDirectoryRole -Filter "DisplayName eq '$roleName'"

if ($adminRole) {
    $roleMembers = Get-MgDirectoryRoleMember -DirectoryRoleId $adminRole.Id

    if ($roleMembers) {
        $roleMembers | ForEach-Object {
            [PSCustomObject]@{
                DisplayName = $_.AdditionalProperties["displayName"]
                Id          = $_.Id
            }
        } | Format-Table DisplayName, Id
    } else {
        Write-Host "No members found for the role: $roleName"
    }
} else {
    Write-Host "Role '$roleName' not found"
}

ERROR:

Get-MgDirectoryRole_List: 
Line |
   7 |  $adminRole = Get-MgDirectoryRole -Filter "DisplayName eq '$roleName'"
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Insufficient privileges to complete the operation.

Status: 403 (Forbidden)
ErrorCode: Authorization_RequestDenied
Date: 2024-11-11T18:21:55

Solution

  • Initially, I created one app registration and uploaded certificate in it like this:

    enter image description here

    Now, I added Directory.Read.All permission of Application type in it with admin consent as below:

    enter image description here

    When I ran same script in my environment, I got the response with list of users having "Global Administrator" role successfully as below:

    $applicationID = "appId"
    $tenantID = "tenantId"
    $certThumbPrint = "65876F7BB07xxxxxxxx4848DDE"
    $roleName = "Global Administrator"
    
    Connect-MgGraph -ClientId $applicationID -TenantId $tenantID -CertificateThumbprint $certThumbPrint -Scopes "Directory.Read.All"
    
    $adminRole = Get-MgDirectoryRole -Filter "DisplayName eq '$roleName'"
    
    if ($adminRole) {
        $roleMembers = Get-MgDirectoryRoleMember -DirectoryRoleId $adminRole.Id
    
        if ($roleMembers) {
            $roleMembers | ForEach-Object {
                [PSCustomObject]@{
                    DisplayName = $_.AdditionalProperties["displayName"]
                    Id          = $_.Id
                }
            } | Format-Table DisplayName, Id
        } else {
            Write-Host "No members found for the role: $roleName"
        }
    } else {
        Write-Host "Role '$roleName' not found"
    }
    

    Response:

    enter image description here

    In your case, try running below PowerShell command after connecting to MS Graph and confirm whether it has Directory.Read.All permission in Scopes parameter or not:

    Get-MgContext 
    

    enter image description here

    If the permission is not present in Scopes parameter, try removing the added permission in app registration and add it again by granting admin consent.

    UPDATE:

    The added permission won't come in Scopes of Get-MgContext command if it is present under "Other permissions granted" tab in Portal:

    enter image description here

    You need to move it to Configured permissions of your application by clicking below option:

    enter image description here

    In Portal, permission should appear under Configured permissions like this:

    enter image description here

    Now, connect to MS Graph via client certificate authentication again and check Get-MgContext. Now, it should work.