Created
July 8, 2022 22:03
-
-
Save JustinGrote/47ee8e0c6336235d628e0952dcea4f52 to your computer and use it in GitHub Desktop.
Add a Role to a SAML-only Enterprise Application that you can then provide as a claim for user assignment (there is no GUI for this)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using namespace Microsoft.Azure.PowerShell.Cmdlets.Resources.MSGraph.Models.ApiV10 | |
using namespace System.Management.Automation | |
using namespace System.Collections.Generic | |
function Add-JAzADServicePrincipalRole { | |
[CmdletBinding(DefaultParameterSetName='ByObject', SupportsShouldProcess)] | |
param( | |
#The display name of the role. This is the name that will be displayed in the app portal when assigning the role to a user or group. | |
[Parameter(Mandatory)]$Name, | |
#The value that will be added to the SAML roles claim for the user. Make this something that is appropriate to signal to your application what role the user should have, e.g. admin, owner, etc., your App may have specific documentation for this effect, for example Palo Alto defines specific values like superuser and superreader | |
[ValidateNotNullOrEmpty()]$Value = $Name, | |
#The description of the role. This should provide guidance as to what rights the role grants to the application | |
[string]$Description = $Name, | |
#Create the role as disabled. By default roles are created as enabled | |
[switch]$Disabled, | |
#Update any existing Roles with the same claim values. The roles will retain their ID | |
[Switch]$Update, | |
#The ID of the role. This is usually automatically generated and does not need to be specified | |
[ValidateNotNullOrEmpty()][Guid]$RoleId = $(New-Guid), | |
#What kind of resources can be assigned to the role. Options are User (which allows both users and groups) and Application (which allows Service Principals). Default is to allow all types. | |
[ValidateSet('User', 'Application')][string[]]$AllowedMemberType = @('Application','User'), | |
[Parameter(Mandatory,ParameterSetName='ById',ValueFromPipelineByPropertyName)][String]$Id, | |
[Parameter(Mandatory,ParameterSetName='ByObject',ValueFromPipeline)][MicrosoftGraphServicePrincipal]$InputObject | |
) | |
if (-not $InputObject) { | |
if (-not ($id -as [guid])) {throw 'The -Id Parameter must be a valid GUID'} | |
$InputObject = Get-AzADApplication -ObjectId $Id | |
} | |
$roles = [List[MicrosoftGraphAppRole]]$InputObject.AppRole | |
[MicrosoftGraphAppRole]$existingRole = $roles | Where-Object Value -eq $Value | |
if ($existingRole) { | |
if (-not $Update) { | |
$InputObject | Write-CmdletError "$($InputObject.DisplayName)`: A role with the claim value '$Value' already exists. Use -Update to update the existing role with new changes." | |
return | |
} | |
Write-Verbose "An existing role was found but -Force was specified, updating the existing role." | |
$roles.Remove($existingRole) | |
#We want to keep the ID otherwise we have to go thru a whole disablement process | |
$RoleId = $existingRole.Id | |
} | |
$newRole = [MicrosoftGraphAppRole]@{ | |
IsEnabled = !$Disabled | |
Description = $Description | |
DisplayName = $Name | |
AllowedMemberType = $AllowedMemberType | |
Value = $Value | |
Id = [string]$RoleId | |
} | |
if (-not $PSCmdlet.ShouldProcess( | |
"$($InputObject.DisplayName) [$($InputObject.Id)]", | |
"Add New Role $($newRole.DisplayName) with role claim value: $($newRole.Value)" | |
)) {return} | |
$roles.Add($newRole) | |
$inputObject | Update-AzADServicePrincipal -AppRole $roles | |
} | |
function Get-ParamBlock ([String[]]$Name) { | |
[hashset[string]]$params = $PSCmdlet.MyInvocation.MyCommand.Parameters.Keys | |
$params.ExceptWith([string[]]([PSCmdlet]::CommonParameters + [PSCmdlet]::OptionalCommonParameters)) | |
$result = @{} | |
if ($Name) {$params = $params -in $Name} | |
foreach ($name in $params) { | |
$result.$name = $PSCmdlet.GetVariableValue($name) | |
} | |
return $result | |
} | |
function Write-CmdletError { | |
param( | |
[Exception]$Message = 'An Error Occured in the cmdlet', | |
[String]$ErrorId, | |
[ErrorCategory]$Category = 'InvalidOperation', | |
$TargetObject = $PSItem, | |
$cmdlet = $PSCmdlet, | |
[Switch]$Terminating | |
) | |
process { | |
$errorRecord = [ErrorRecord]::new( | |
$Message, | |
$ErrorId, | |
$Category, | |
$TargetObject | |
) | |
if ($Terminating) { | |
$cmdlet.ThrowTerminatingError( | |
$ErrorRecord | |
) | |
} else { | |
$cmdlet.WriteError( | |
$ErrorRecord | |
) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment