Last active
February 22, 2021 23:00
-
-
Save JustinGrote/a00370731c19188ba00f0d9526d15b7f to your computer and use it in GitHub Desktop.
Configure a Managed Services Identity for O365 Services
This file contains hidden or 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
TestExplorerResults.xml |
This file contains hidden or 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
#requires -module AzureAD | |
<# | |
.LINK | |
https://stackoverflow.com/questions/63953702/access-o365-exchange-online-with-an-azure-managed-identity-or-service-principal | |
https://finarne.wordpress.com/2019/03/17/azure-function-using-a-managed-identity-to-call-sharepoint-online/ | |
#> | |
function New-AzManagedIdentityRoleAssignment { | |
[CmdletBinding(SupportsShouldProcess)] | |
param( | |
#Object ID of the managed service identity you wish to use | |
[Parameter(ValueFromPipelineByPropertyName)][Guid]$ObjectId, | |
#The Object Id of the application that holds the role you want to assign | |
[Guid]$RefObjectId, | |
#The Role that you wish to | |
[Guid]$RoleId, | |
#Specify that you want to use Interactive Mode | |
[Switch]$Interactive, | |
#Choose an Interactive mode. Will use Out-Gridview by default and fallback to console if not available | |
[ValidateSet('GUI','Console')]$InteractiveMode = 'GUI' | |
) | |
$ErrorActionPreference = 'Stop' | |
#Interactive Mode Sanity Check | |
if ($Interactive) { | |
if ($InteractiveMode -eq 'GUI' -and -not (Get-Command 'Out-GridView' -ErrorAction SilentlyContinue)) { | |
if ($PSVersionTable.PSVersion -ge '6.2.0' -and (Get-Command 'Out-ConsoleGridView' -ErrorAction SilentlyContinue)) { | |
$InteractiveMode = 'Console' | |
} else { | |
throw [NotSupportedException]'-Interactive was specified but neither Out-Gridview or Out-ConsoleGridview was found. Hint: Install-Module Microsoft.Powershell.ConsoleGuiTools' | |
} | |
} | |
$InteractiveCommand = switch ($InteractiveMode) { | |
'GUI' { | |
'Out-GridView' | |
} | |
'Console' { | |
'Out-ConsoleGridView' | |
} | |
} | |
} | |
if (-not $ObjectId) { | |
if ($Interactive) { | |
$targetSP = Get-AzureADServicePrincipal -filter "servicePrincipalType eq 'ManagedIdentity'" -Top ([int]::MaxValue) | | |
& $InteractiveCommand -Title 'Select the target Service Principal for role assignment' -OutputMode Single | |
$objectId = $targetSP.ObjectId | |
} | |
} | |
if (-not $ObjectId) {throw 'You must select a service principal to which the new roles will be assigned'} | |
if (-not $RefObjectId) { | |
if ($Interactive) { | |
$RefSP = Get-AzureADServicePrincipal -All:$true | | |
Where-Object approles | | |
Sort-Object DisplayName | | |
& $InteractiveCommand -Title 'Select the app that has the role you wish to assign' -OutputMode Single | |
$RefObjectId = $RefSP.ObjectId | |
} | |
} | |
if (-not $RefObjectId) {throw [InvalidOperationException]'You must select a service principal to which the new roles will be assigned'} | |
if (-not $RoleId) { | |
if ($Interactive) { | |
$RoleItem = $RefSP.approles | | |
Where-Object AllowedMemberTypes | | |
Select-Object Id,@{N='AppName';E={$RefSP.DisplayName}},DisplayName,Description,Value,IsEnabled | | |
Sort-Object DisplayName | | |
& $InteractiveCommand -Title 'Select the role to assign to the app' -OutputMode Single | |
$RoleId = $RoleItem.Id | |
} | |
} | |
if (-not $RoleId) {throw [InvalidOperationException]'You must select a service principal to which the new roles will be assigned'} | |
if ($PSCmdlet.ShouldProcess($ObjectId,"Add Application Role")) { | |
New-AzureAdServiceAppRoleAssignment -ObjectId $ObjectId -PrincipalId $ObjectId -ResourceId $RefObjectId -Id $RoleId | |
} else { | |
New-AzureAdServiceAppRoleAssignment -ObjectId $ObjectId -PrincipalId $ObjectId -ResourceId $RefObjectId -Id $RoleId -WhatIf | |
} | |
} |
This file contains hidden or 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
Describe 'Set-AzManagedIdentityRoleAssignment' { | |
BeforeAll { | |
. $PSScriptRoot/New-AzManagedIdentityRoleAssignment.ps1 | |
} | |
It "Fails if no identity provided and interactive not specified" { | |
{New-AzManagedIdentityRoleAssignment} | | |
Should -Throw 'You must provide a service identity to act upon, either by its objectID, via the pipeline, or via the -Interactive switch' | |
} | |
It "Fails if Interactive specified but no interactive options exist" { | |
Mock Get-Command {} | |
{New-AzManagedIdentityRoleAssignment -Interactive} | | |
Should -Throw '-Interactive was specified but neither Out-Gridview or Out-ConsoleGridview was found. Hint: Install-Module Microsoft.Powershell.ConsoleGuiTools' | |
} | |
It "Object ID" { | |
$TestGuid = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' | |
Mock Get-AzureADServicePrincipal -ParameterFilter {$ObjectId -eq $TestGuid} { | |
throw 'MatchedTestGuid' | |
} | |
{New-AzManagedIdentityRoleAssignment -ObjectID $TestGuid} | Should -Throw 'MatchedTestGuid' | |
} | |
It "GUI Interactive Path" { | |
function Out-Gridview {} | |
Mock Out-Gridview {} | |
Mock Get-AzureADServicePrincipal -ParameterFilter {$Filter -eq "servicePrincipalType eq 'ManagedIdentity'"} { | |
throw 'OutGridViewPathTaken' | |
} | |
{New-AzManagedIdentityRoleAssignment -Interactive -InteractiveMode GUI} | | |
Should -Throw 'OutGridViewPathTaken' | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment