PSGISP.MicrosoftGraph.psm1
#--------------------------------------------- #------------------ Classes ------------------ #--------------------------------------------- #--------------------------------------------- #------------- Private Functions ------------- #--------------------------------------------- Function Approve-MgSessionPermission { <# .SYNOPSIS Checks if Connection is established with correct permissions .DESCRIPTION Checks if Connection is established with correct permissions .PARAMETER Permission Permissions which are needed in this session .INPUTS System.String[] .OUTPUTS none .EXAMPLE Approve-MgSessionPermission -Permission "User.ReadWrite.All","Application.ReadWrite.All" .LINK https://github.com/gisp497/psgisp #> [CmdletBinding()] param ( [Parameter( Mandatory = $true, HelpMessage = "Permissions which are needed in this session" )] [System.String[]]$Scope ) Begin { $Session = Get-MgContext } Process { if ($null -ne $Session) { $Scope | ForEach-Object { $ScopeVar = $_ if ($null -eq ($Session.Scopes | Where-Object {$_ -eq $ScopeVar})){ Throw "Not all Scope Permissions are granted! Please add this one to the Session: $Scope" } } }else { Throw "You are not connected to the Microsoft Graph API." } } End { } } #--------------------------------------------- #-------------- Public Functions ------------- #--------------------------------------------- Function Add-MgApplicationAPIPermission { <# .SYNOPSIS This function adds API permission to azure ad application. .DESCRIPTION This function adds application API permission to a azure ad application. It also automatically grants the permission. .PARAMETER ClientId ID of the application which will get new permissions. .PARAMETER APIPermissionId ID of the new permission. You can find those permissions with this command: Find-MgGraphPermission .PARAMETER APIPermissionType Type of API Permission. Role is used by default. .PARAMETER Wait The wait parameter must be used in loops and scripts. If you do not use this parameter the function will exceed before the new permissions are set in azure ad. Otherwise the new permissions aren't set successfully. .INPUTS System.String System.Management.Automation.SwitchParameter .OUTPUTS None .EXAMPLE Add-MgApplicationAPIPermission -ClientId $Application.Id -APIPermissionId $_.Id -Wait $true .LINK https://github.com/gisp497/psgisp #> [CmdletBinding()] param ( [Parameter( Mandatory = $true, HelpMessage = 'ID of the application which will get new permissions.' )] [System.String]$ClientId, [Parameter( Mandatory = $true, HelpMessage = 'ID of the new permission. You can find those permissions with this command: Find-MgGraphPermission' )] [System.String]$APIPermissionId, [Parameter( Mandatory = $false, HelpMessage = 'Type of API Permission. Role is used by default.' )] [ValidateSet('Role', 'Scope')] [System.String]$APIPermissionType = 'Role', [Parameter( Mandatory = $false, HelpMessage = "The wait parameter must be used in loops and scripts. If you do not use this parameter the function will exceed before the new permissions are set in azure ad Otherwise the new permissions aren't set successfully." )] [System.Management.Automation.SwitchParameter]$Wait = $false ) Begin { #check authentication status Approve-MgSessionPermission -Scope @('Application.ReadWrite.All','Directory.ReadWrite.All') #Get Application existing Permisisons $Application = Get-MgApplication -ApplicationId $ClientId -ErrorAction Stop #Get Service Principal for App Role $MGServicePrincipal = Get-MgServicePrincipal -All -Property Id,DisplayName,AppId,Approles | Where-Object{$_.AppRoles.Id -eq $APIPermissionId} if ($null -eq $MGServicePrincipal) { Throw ('The Application API Permissions Id: ' + $APIPermissionId + ' cannot be found. This function can only use Application Permission Type') } #Get Service Principal of App $Application $ApplicationServicePrincipal = Get-MgServicePrincipal -All | Where-Object {$_.AppId -eq $Application.AppId} if ($null -eq $ApplicationServicePrincipal) { Throw ('The Application does no have a Service Principal. Create one before try to grant any permissions.') } } Process { ############################################# ######Add API permission to application###### ############################################# #create new permissions [Microsoft.Graph.PowerShell.Models.MicrosoftGraphResourceAccess]$NewResourceAccess = @{ id = $APIPermissionId type = $APIPermissionType } [Microsoft.Graph.PowerShell.Models.IMicrosoftGraphRequiredResourceAccess[]]$NewRequiredResourceAccess = @{ ResourceAppId = $MGServicePrincipal.AppId ResourceAccess = @($NewResourceAccess) } #edit app object switch ($Application) { {$null -ne ($_ | Where-Object {$_.RequiredResourceAccess.ResourceAccess.Id -eq $APIPermissionId})}{ Write-Warning ("API Permission " + $APIPermissionId + " exists already.") } {$null -ne ($_ | Where-Object {$_.RequiredResourceAccess.ResourceAppId -eq $MGServicePrincipal.AppId})} { ($Application.RequiredResourceAccess | Where-Object {$_.ResourceAppId -eq $MGServicePrincipal.AppId}).ResourceAccess += $NewResourceAccess } Default { $Application.RequiredResourceAccess += $NewRequiredResourceAccess } } #Update Application settings Update-MgApplication -ApplicationId $Application.Id -BodyParameter $Application ################################################ ######Grant API permission for application###### ################################################ #Create hashtable for new ServicePrincipalAppRoleAssignedTo $Params = @{ PrincipalId = $ApplicationServicePrincipal.Id ResourceId = $MgServicePrincipal.Id AppRoleId = $APIPermissionId } #check if assigment already exists if ($null -eq (Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $Params.ResourceId | Where-Object {$_.PrincipalId -eq $Params.PrincipalId -and $_.ResourceId -eq $Params.ResourceId -and $_.AppRoleId -eq $Params.AppRoleId})) { New-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $MgServicePrincipal.Id -BodyParameter $Params > $null }else { Write-Warning ('Grant Permission ' + $APIPermissionId + ' exists already.') } #if Wait parameter is used, wait until new application permission are set before exiting funtion while ($true) { if ($null -ne (Get-MgApplication -ApplicationId $Application.Id | Where-Object {$_.RequiredResourceAccess.ResourceAccess.Id -eq $APIPermissionId})) { Break }else { Start-Sleep -Seconds 1 } } } End { } } Function Remove-MgApplicationAPIPermission { <# .SYNOPSIS This function removes API permission to azure ad application. .DESCRIPTION This function removes application API permission to a azure ad application. It also automatically ungrants the permission. .PARAMETER ClientId ID of the application which will get lose permissions. .PARAMETER APIPermissionId ID of the removed permission. You can find those permissions with this command: Find-MgGraphPermission .PARAMETER Wait The wait parameter must be used in loops and scripts. If you do not use this parameter the function will exceed before the new permissions are set in azure ad. Otherwise the new permissions aren't set successfully. .INPUTS System.String System.Management.Automation.SwitchParameter .OUTPUTS None .EXAMPLE Remove-MgApplicationAPIPermission -ClientId $Application.Id -APIPermissionId $_.Id -Wait .LINK https://github.com/gisp497/psgisp #> [CmdletBinding()] param ( [Parameter( Mandatory = $true, HelpMessage = 'ID of the application which will get lose permissions.' )] [System.String]$ClientId, [Parameter( Mandatory = $true, HelpMessage = 'ID of the removed permission. You can find those permissions with this command: Find-MgGraphPermission' )] [System.String]$APIPermissionId, [Parameter( Mandatory = $false, HelpMessage = "The wait parameter must be used in loops and scripts. If you do not use this parameter the function will exceed before the new permissions are set in azure ad. Otherwise the new permissions aren't set successfully." )] [System.Management.Automation.SwitchParameter]$Wait = $false ) Begin { #check authentication status Approve-MgSessionPermission -Scope @('Application.ReadWrite.All','Directory.ReadWrite.All') #Get Application existing Permisisons $Application = Get-MgApplication -ApplicationId $ClientId -ErrorAction Stop #Get Service Principal for App Role $MGServicePrincipal = Get-MgServicePrincipal -All -Property Id,DisplayName,AppId,Approles | Where-Object{$_.AppRoles.Id -eq $APIPermissionId} if ($null -eq $MGServicePrincipal) { Throw ('The Application API Permissions Id: ' + $APIPermissionId + ' cannot be found. This function can only use Application Permission Type') } #Get Service Principal of App $Application $ApplicationServicePrincipal = Get-MgServicePrincipal -All | Where-Object {$_.AppId -eq $Application.AppId} } Process { ############################################# ####remove API permission to application##### ############################################# #remove the specififc resourceaccess object $ActiveResourceAccess = $application.RequiredResourceAccess | Where-Object {$_.ResourceAppId -eq $MGServicePrincipal.AppId} $RemovedResourceAccess = $ActiveResourceAccess.ResourceAccess | Where-Object {$_.Id -ne $APIPermissionId} #if this object wasn't the only one in the RequiredResourceObject add the other ResourceAccess Objects again if ($null -ne $RemovedResourceAccess) { ($Application.RequiredResourceAccess | Where-Object {$_.ResourceAppId -eq $MGServicePrincipal.AppId}).ResourceAccess = $RemovedResourceAccess } #if the object was the last, remove the whole RequiredResourceAccess Object else { #if there is any other RequiredResourceAccess just add the other again if ($Application.RequiredResourceAccess.Count -gt 1) { $Application.RequiredResourceAccess = $Application.RequiredResourceAccess | Where-Object {$_.ResourceAppId -ne $MGServicePrincipal.AppId} } #if there is no other RequiredResourceAccess just add an empty object else{ $Application.RequiredResourceAccess = [Microsoft.Graph.PowerShell.Models.IMicrosoftGraphRequiredResourceAccess[]]@{} } } #Update Application settings Update-MgApplication -ApplicationId $ClientId -BodyParameter $Application ################################################ ##remove Grant API permission for application### ################################################ #Get Exsiting ServicePrincipalAppRoleAssignment $ServicePrincipalAppRoleAssignment = Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $MgServicePrincipal.Id | Where-Object {$_.PrincipalId -eq $ApplicationServicePrincipal.Id -and $_.ResourceId -eq $MgServicePrincipal.Id -and $_.AppRoleId -eq $APIPermissionId} #check if assigment already exists if ($null -ne $ServicePrincipalAppRoleAssignment) { Remove-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $MgServicePrincipal.Id -AppRoleAssignmentId $ServicePrincipalAppRoleAssignment.Id > $null }else { Write-Warning ('Permission ' + $APIPermissionId + ' was not granted') } #if Wait parameter is used, wait until new application permission are set before exiting funtion while ($true) { if ($null -eq (Get-MgApplication -ApplicationId $Application.Id | Where-Object {$_.RequiredResourceAccess.ResourceAccess.Id -eq $APIPermissionId})) { Break }else { Start-Sleep -Seconds 1 } } } End { } } Function Add-MgApplicationCertificate { <# .SYNOPSIS Add a Certificate to Azure AD Application .DESCRIPTION Add a Certificate to Azure AD Application .PARAMETER ClientId ID of the application which will get new permissions. .PARAMETER Certificate Certificate which will be added to the azure ad application .INPUTS System.String System.Security.Cryptography.X509Certificates.X509Certificate2 .OUTPUTS None .EXAMPLE Add-MgAppCertificate -Application $Application -Certificate $Certificate .LINK https://github.com/gisp497/psgisp #> [CmdletBinding()] param ( [Parameter( Mandatory = $true, HelpMessage = 'ID of the application which will get new permissions.' )] [System.String]$ClientId, [Parameter( Mandatory = $true, HelpMessage = "Certificate which will be added to the azure ad application" )] [System.Security.Cryptography.X509Certificates.X509Certificate2]$Certificate ) Begin { #Approve Permissions of current Session Approve-MGSessionPermission -Scope 'Application.ReadWrite.All' #Get Application existing Permisisons $Application = Get-MgApplication -ApplicationId $ClientId -ErrorAction Stop } Process { [Microsoft.Graph.PowerShell.Models.IMicrosoftGraphKeyCredential]$NewKeyCredentials = @{ Type = "AsymmetricX509Cert"; Usage = "Verify"; key = $Certificate.RawData } #add new permissions to the existing application $Application.KeyCredentials += $NewKeyCredentials #Update new Application with the correct certificate Update-MgApplication -ApplicationId $Application.Id -BodyParameter $Application -ErrorAction Stop } End { } } #--------------------------------------------- #--------- Export Public Functions ----------- #--------------------------------------------- $PublicFunctions = @( 'Add-MgApplicationAPIPermission', 'Remove-MgApplicationAPIPermission', 'Add-MgApplicationCertificate' ) Export-ModuleMember -Function $PublicFunctions |