PowerShell command to grant permissions

Pablo Glomby 186 Reputation points
2021-07-27T18:03:08.92+00:00

Hi.
I have a generic powershell script that creates an application and it tries to grant permissions... but the grant permission logic does not work (at the end, although there is no exception, the permissions are not granted).

This is what I get after the script is run:
118339-image.png

This is the script... I suspect the problem is in the "resourceId" or in the "clientId" since both have the same value although in the samples I found in internet the values should be different. The script contains redundant information and is still in draft mode.

# first install Azure Ad module in PowerShell  
write-output 'Installing AzureAD module...'  
Install-module AzureAD  
   
#Store the credential and use these credentials to connect to Azure AD.  
$Credentials = Get-Credential  
Connect-AzureAD -Credential $Credentials | Out-Null  
   
# This is the application name  
$appName = "MySample Registered App"  
   
# Provide the Reply URI  
$replyURI ="https://www.contoso.com/Login"  
  
# Now check if App with this name already created ? If it is not created then create it otherwise do not create it.  
if(!($myApp = Get-AzureADApplication -Filter "DisplayName eq '$($appName)'" -ErrorAction SilentlyContinue))  
{  
  write-output 'Creating application'  
  #Create the application using New-AzureADMSApplication in order to be able to (among other things) specify the -SignInAudience parameter (else it's read only). Then get the app using Get-AzureADApplication since else Set-AzureADApplication will fail  
  $myApp = New-AzureADMSApplication -DisplayName $appName -SignInAudience AzureADMultipleOrgs  
  $msalonly = 'msal'+$myApp.AppId+'://auth'  
  Set-AzureADMSApplication -ObjectId $myApp.Id -PublicClient @{RedirectUris = $replyURI, $msalonly }  
  $myApp = Get-AzureADApplication -Filter "DisplayName eq '$($appName)'"  
} else {  
  $myApp = Get-AzureADApplication -Filter "DisplayName eq '$($appName)'"  
}  
  
#Get the Microsoft Graph service   
$svcPrincipalGraph = Get-AzureADServicePrincipal -All $true | Where-Object { $_.DisplayName -eq "Microsoft Graph" };  
  
#Create the Graph object that will be used to add the needed permissions  
$Graph = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess"  
$Graph.ResourceAppId = $svcPrincipalGraph.AppId;  
  
$servicePrincipalNameOauth2Permissions = @("Directory.AccessAsUser.All", "Directory.Read.All", "profile", "Sites.FullControl.All", "Team.ReadBasic.All", "TeamSettings.Read.All");  
$svcPrincipalGraph.Oauth2Permissions | Where-Object { $_.Value -in $servicePrincipalNameOauth2Permissions} | ForEach-Object {  
    $permission = $_  
    $delPermission = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList $permission.Id,"Scope" #delegate permission (oauth) are always "Scope"  
    $Graph.ResourceAccess += $delPermission  
}  
$Graph.ResourceAppId = $svcPrincipalGraph.AppId;  
  
  
#Now add the permissions to the application  
Set-AzureADApplication -ObjectId $myApp.ObjectId -RequiredResourceAccess $Graph  
write-output '$Graph='+$Graph  
  
  
  
  
$requiredResourcesAccess=(Get-AzureADApplication -ObjectId $myApp.ObjectId).RequiredResourceAccess  
write-output '$requiredResourcesAccess='+$requiredResourcesAccess  
#$servicePrincipal = Get-AzureADServicePrincipal -All $true | Where-Object {$_.AppId -eq $myApp.AppId}  
$servicePrincipal = $svcPrincipalGraph  
write-output '$servicePrincipal=' + $servicePrincipal  
ForEach ($resourceAppAccess in $requiredResourcesAccess)  
{  
  $resourceApp = Get-AzureADServicePrincipal -All $true | Where-Object {$_.AppId -eq $resourceAppAccess.ResourceAppId}  
  write-output '$resourceApp='+$resourceApp  
  write-output '$resourceAppAccess='+$resourceAppAccess  
  ForEach ($permission in $resourceAppAccess.ResourceAccess)  
  {  
    if ($permission.Type -eq "Role")  
    {  
      New-AzureADServiceAppRoleAssignment -ObjectId $servicePrincipal.ObjectId -PrincipalId $servicePrincipal.ObjectId -ResourceId $resourceApp.ObjectId -Id $permission.Id  
    }  
  }  
}  
  
# Set ADAL (Microsoft.IdentityModel.Clients.ActiveDirectory.dll) assembly path from Azure AD module location  
$AADModule = Import-Module -Name AzureAD -ErrorAction Stop -PassThru  
$adalPath = Join-Path $AADModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.dll"  
$adalformPath = Join-Path $AADModule.ModuleBase "Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll"  
[System.Reflection.Assembly]::LoadFrom($adalPath) | Out-Null  
[System.Reflection.Assembly]::LoadFrom($adalformPath) | Out-Null   
        
# Azure AD PowerShell client id.   
$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2"  
$RedirectUri = "urn:ietf:wg:oauth:2.0:oob"  
$resourceURI = "https://graph.microsoft.com"  
$authority = "https://login.microsoftonline.com/common"  
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority       
   
# Get token by prompting login window.  
$platformParameters = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters" -ArgumentList "Always"  
$authResult = $authContext.AcquireTokenAsync($resourceURI, $ClientID, $RedirectUri, $platformParameters)  
$accessToken = $authResult.Result.AccessToken  
  
$GrantConsnetForAllUsers=$true #Set $true to give consent for all users and set $false to give consent for individual user  
if ($GrantConsnetForAllUsers) {  
  #Grant consent for all users  
  $consentType = "AllPrincipals"  
  $principalId = $null  
} else {  
  #Grant consent for the required user alone  
  $consentType = "Principal"  
  #Get or provide object id for the required Azure AD user  
  $principalId = (Get-AzureADUser -SearchString "******@contoso.com").ObjectId  
  #$principalId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"  
}  
   
ForEach ($resourceAppAccess in $requiredResourcesAccess)  
{  
  $delegatedPermissions = @()  
  $resourceApp = Get-AzureADServicePrincipal -All $true | Where-Object {$_.AppId -eq $resourceAppAccess.ResourceAppId}  
  ForEach ($permission in $resourceAppAccess.ResourceAccess)  
  {  
    if ($permission.Type -eq "Scope")  
    {  
      $permissionObj = $resourceApp.OAuth2Permissions | Where-Object {$_.Id -contains $permission.Id}  
      $delegatedPermissions += $permissionObj.Value  
    }  
  }  
   
  if($delegatedPermissions)  
  {  
    #Get existing grant entry  
    $existingGrant = Get-AzureADOAuth2PermissionGrant -All $true | Where { $_.ClientId -eq $servicePrincipal.ObjectId -and $_.ResourceId -eq $resourceApp.ObjectId -and  $_.PrincipalId -eq $principalId}  
    #$existingGrant = Get-AzureADOAuth2PermissionGrant -All $true | Where { $_.ClientId -eq $myApp.AppId -and $_.ResourceId -eq $resourceApp.ObjectId -and  $_.PrincipalId -eq $principalId}  
   
    if(!$existingGrant){  
      #Create new grant entry  
      $postContent = @{  
        clientId = $servicePrincipal.ObjectId  
        #clientId = $myApp.ObjectId  
        consentType = $consentType  
        principalId = $principalId  
        resourceId  = $resourceApp.ObjectId  
        scope       = $delegatedPermissions -Join " "  
      }  
   
      $requestBody = $postContent | ConvertTo-Json  
      Write-Host "Grant consent for $delegatedPermissions ($($resourceApp.DisplayName))" -ForegroundColor Green  
      $headers = @{Authorization = "Bearer $accessToken"}  
      write-output '$requestBody='+$requestBody  
      $response = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/oauth2PermissionGrants" -Body $requestBody -Method POST -Headers $headers -ContentType "application/json"  
      write-output '$response='+$response  
    } else {  
      #Update existing grant entry  
      $delegatedPermissions+=$existingGrant.Scope -Split " "  
      $delegatedPermissions = $delegatedPermissions | Select -Unique  
#      $patchContent = @{  
#        scope       = $delegatedPermissions -Join " "  
#      }  
      $patchContent = @{  
        clientId = $servicePrincipal.ObjectId  
        consentType = $consentType  
        principalId = $principalId  
        resourceId  = $resourceApp.ObjectId  
        scope       = $delegatedPermissions -Join " "  
      }  
     
      $requestBody = $patchContent | ConvertTo-Json  
      Write-Host "Update consent for $delegatedPermissions ($($resourceApp.DisplayName))" -ForegroundColor Green  
      $headers = @{Authorization = "Bearer $accessToken"}  
      $response = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/oauth2PermissionGrants/$($existingGrant.ObjectId)" -Body $requestBody -Method PATCH -Headers $headers -ContentType "application/json"  
      write-output '$requestBody='+$requestBody  
      write-output '$response='+$response  
     
    }  
  }  
}  
  
  
write-output 'Application successfully created'  

Thanks

Windows for business Windows Server User experience PowerShell
Microsoft Security Microsoft Entra Microsoft Entra ID
0 comments No comments
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.