azurepowershellazure-active-directorymicrosoft-graph-apientra

HTTP request to update Service Principal Entra


I'm trying to write a script to update the permissions for a managed identity using Powershell and the REST API, but I'm running into a problem and I don't know how to troubleshoot it any further.

My script connects to an App Registration with App ID and Secret, generates a token and I use that token in my "Invoke-RestMethod" command.

Connecting works fine, and I can run GET commands against the endpoints, but trying to update it using a POST gives me an error of "Not a valid reference update".

This is the 'bit of code:

# Payload in Hashtable
$POSTBody = @{
    principalID = "$($MIDData.id)"
    resourceID = "$ObjectID"
    appRoleId = "$($TEMProle.id)"
}


# check if Hashtable converts to JSON
$POSTBody | convertto-json

$AppRoleAssignment = "https://graph.microsoft.com/beta/servicePrincipals/$ObjectID/appRoleAssignedTo"

Invoke-RestMethod -Uri $AppRoleAssignment -Headers @{Authorization = "Bearer $($TokenAccess)" }  -Method POST -Body $($POSTBody | convertto-json) -ContentType "application/json"

I'm confident my variables are correct. I've tried hard-coding them as well, but I get the same result.

Any wisdom or guidance would be most appreciated.


Solution

  • Note that, you need to pass Object ID of Microsoft Graph Enterprise Application for resourceID parameter.

    In my case, I ran below API call to get the object ID of Microsoft Graph service principal:

    GET https://graph.microsoft.com/v1.0/servicePrincipals?$filter=appId eq '00000003-0000-0000-c000-000000000000'
    

    enter image description here

    Now I ran below PowerShell script to generate token and call API to add User.Read.All permission of Application type to managed identity:

    $AppId = "appID"
    $ClientSecret = "secret"
    $TenantId = "tenantID"
    
    $TokenEndpoint = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token"
    $Body = @{
        client_id     = $AppId
        scope         = "https://graph.microsoft.com/.default"
        client_secret = $ClientSecret
        grant_type    = "client_credentials"
    }
    
    $TokenResponse = Invoke-RestMethod -Uri $TokenEndpoint -Method Post -Body $Body -ContentType "application/x-www-form-urlencoded"
    $AccessToken = $TokenResponse.access_token
    
    $PrincipalId = "fd0e0b8b-53f6-4bcd-a723-xxxxx"   # Managed identity Object ID
    $ResourceId = "c68a82f4-ecea-4f65-8047-xxxxx"     # Microsoft Graph Enterprise App Object ID
    $AppRoleId = "df021288-bdef-4463-88db-98f22de89214"      # User.Read.All permission App Role ID
    
    $POSTBody = @{
        principalId = $PrincipalId
        resourceId  = $ResourceId
        appRoleId   = $AppRoleId
    }
    
    $POSTBodyJSON = $POSTBody | ConvertTo-Json 
    
    $AppRoleAssignment = "https://graph.microsoft.com/beta/servicePrincipals/$ResourceId/appRoleAssignedTo"
    
    try {
        $Response = Invoke-RestMethod -Uri $AppRoleAssignment `
            -Headers @{Authorization = "Bearer $AccessToken"} `
            -Method POST `
            -Body $POSTBodyJSON `
            -ContentType "application/json"
    
        Write-Host "App Role Assignment Successful:"
        Write-Host ($Response | ConvertTo-Json -Depth 10 -Compress)
    } catch {
        Write-Error "Error assigning App Role: $($_.Exception.Message)"
    }
    

    Response:

    enter image description here

    To confirm that, I checked the same in Azure Portal where User.Read.All permission of Application type added successfully to managed identity like this:

    enter image description here

    Reference:

    Grant an appRoleAssignment for a service principal - Microsoft Graph