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
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
I see I am missing the scope permissions.
Thank you all.
UPDATE: Scoped assigned in correct area
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
Initially, I created one app registration and uploaded certificate in it like this:
Now, I added Directory.Read.All
permission of Application type in it with admin consent as below:
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:
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
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:
You need to move it to Configured permissions of your application by clicking below option:
In Portal, permission should appear under Configured permissions like this:
Now, connect to MS Graph via client certificate authentication again and check Get-MgContext
. Now, it should work.