Last active
April 8, 2024 14:37
-
-
Save m8r1us/2b97604b6dd42809a52ca31315a4998a to your computer and use it in GitHub Desktop.
Find foreign service principals
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
# The script is part of the following article: https://www.scip.ch/en/?labs.20240404 | |
# -------------- | |
# Find foreign service principals with application permissions | |
# -------------- | |
Write-Host "[*] Log in with a user that has at least the Application.Read.All right `n" -ForegroundColor Green | |
Connect-MgGraph -scopes "Application.Read.All" -NoWelcome | |
Write-Host "[*] Output the connection context `n" -ForegroundColor Green | |
$mgcontext = Get-MgContext | |
$mgcontext | |
$foreignsp = Get-MgServicePrincipal -All | Where-Object { $_.AppOwnerOrganizationId -ne $mgcontext.TenantId -and $_.AppOwnerOrganizationId -ne $null } | |
$collSpAppRolePermissions = "" | |
$collSpAppRolePermissions = New-Object System.Collections.ArrayList | |
$progress = 0 | |
$TotalCount = $foreignsp.Count | |
# Query for AppRoles once and store in a hashtable | |
$appRolesHashTable = @{} | |
$allAppRoles = Get-MgServicePrincipal -All | Select-Object Id,AppRoles | |
foreach ($appRole in $allAppRoles) { | |
foreach ($role in $appRole.AppRoles) { | |
$appRolesHashTable["$($appRole.Id)-$($role.Id)"] = $role | |
} | |
} | |
foreach ($sp in $foreignsp) | |
{ | |
$DisplayName = $sp.DisplayName | |
$Progress += 1 | |
$ProgressPercentage = (($Progress / $TotalCount) * 100) -As [Int] | |
If ($Progress -eq $TotalCount) { | |
Write-Host "[*] Processing Service Principals: [${Progress}/${TotalCount}][${ProgressPercentage}%] Current Service Principals: ${DisplayName}`n" -ForegroundColor Green | |
} else { | |
If (($Progress % 100) -eq 0) { | |
Write-Host "[*] Processing Service Principals: [${Progress}/${TotalCount}][${ProgressPercentage}%] Current Service Principals: ${DisplayName}" -ForegroundColor Green | |
} | |
} | |
# AppPermission - What application permissions have been assigned to the service principal? | |
$spAppRolePermissions = Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $sp.id -All | Select-Object PrincipalId,PrincipalType,ResourceId,ResourceDisplayName,Id,PrincipalDisplayName,AppRoleId | |
foreach ($spAppRolePermission in $spAppRolePermissions) | |
{ | |
#Translate Rights | |
$getAppRole = $appRolesHashTable["$($spAppRolePermission.ResourceId)-$($spAppRolePermission.AppRoleId)"] | |
$customObject = [PSCustomObject]@{ | |
mytenant = $mgcontext.TenantId | |
foreigntenant = $sp.AppOwnerOrganizationId | |
principalDisplayName = $spAppRolePermission.PrincipalDisplayName | |
principalId = $spAppRolePermission.PrincipalId | |
principalType = $spAppRolePermission.PrincipalType | |
resourceId = $spAppRolePermission.ResourceId | |
resourceDisplayName = $spAppRolePermission.ResourceDisplayName | |
appRoleId = $spAppRolePermission.AppRoleId | |
appRoleIdd = $getAppRole.Id | |
appRoleValue = $getAppRole.Value -replace '\.', '' | |
appDisplayname = $getAppRole.DisplayName | |
appDescription = $getAppRole.Description | |
} | |
$null = $CollSpAppRolePermissions.Add($customObject) | |
} | |
} | |
Write-Host "[*] All foreign service principals found are displayed below for review `n" -ForegroundColor Green | |
$CollSpAppRolePermissions | select mytenant, foreigntenant, principalDisplayName, principalId, appRoleValue | |
$CollSpAppRolePermissions | Out-GridView -Title "Foreign Service Principal with AppRoles" | |
Disconnect-MgGraph | Out-null |
Hi @mezzofix thanks for your question. I think it should be Application.Read.All
. I updated the script and also fixed the tenantid variable which was only set by the POC powershell (https://gist.github.com/m8r1us/86434d2fb7b9e31a71ba4295d6cb2a3a).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@m8r1us thank you for the script! Question, since the recommended approach with Graph PowerShell SDK it to be precise about the permissions needed for a script and to state those permissions when connecting to the Grap API, what would be the minimum required permissions that one could pass with the scope’s parameter , .eg.
Connect-MgGraph -Scopes
for this to work?