Skip to content

Commit 488a5ee

Browse files
authored
Add resiliency for getting app's new SP
Add retry for getting and adding app owner.
2 parents 14ea2b7 + cfdecc9 commit 488a5ee

File tree

1 file changed

+67
-20
lines changed

1 file changed

+67
-20
lines changed

SOA/SOA-Prerequisites.psm1

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ Function Install-EntraApp {
483483
# Create the Entra application
484484
Write-Verbose "$(Get-Date) Install-EntraApp Installing App"
485485
$Params = @{
486-
'displayName' = 'Microsoft Security Assessment'
486+
'displayName' = 'Microsoft 365 Security Assessment'
487487
'SignInAudience' = 'AzureADMyOrg'
488488
'web' = @{
489489
'redirectUris' = @("https://security.optimization.assessment.local","https://o365soa.github.io/soa/")
@@ -499,14 +499,19 @@ Function Install-EntraApp {
499499
Set-EntraAppPermission -App $EntraApp -PerformConsent:$True -CloudEnvironment $CloudEnvironment
500500

501501
# Add service principal (enterprise app) as owner of its app registration
502-
$appSp = Invoke-MgGraphRequest -Method GET -Uri "$GraphHost/v1.0/servicePrincipals(appId=`'$($EntraApp.AppId)`')" -OutputType PSObject
503-
$Params = @{
504-
'@odata.id' = "https://graph.microsoft.com/v1.0/directoryObjects/$($appSp.Id)"
502+
$appSp = Get-SOAAppServicePrincipal -EntraApp $EntraApp
503+
if ($appSp) {
504+
if (Add-SOAAppOwner -NewOwnerObjectId $appSp.Id -EntraApp $EntraApp) {
505+
$script:appSelfOwner = $true
506+
} else {
507+
$script:appSelfOwner = $false
508+
}
509+
} else {
510+
$script:appSelfOwner = $false
505511
}
506-
Invoke-MgGraphRequest -Method POST -Uri "$GraphHost/v1.0/applications(appId=`'$($EntraApp.AppId)`')/owners/`$ref" -body $Params
507-
512+
508513
# Return the newly created application
509-
Return (Invoke-MgGraphRequest -Method GET -Uri "$GraphHost/v1.0/applications/$($EntraApp.Id)")
514+
return (Invoke-MgGraphRequest -Method GET -Uri "$GraphHost/v1.0/applications/$($EntraApp.Id)")
510515

511516
}
512517

@@ -1653,28 +1658,28 @@ function Get-SOAEntraApp {
16531658
$EntraApp = (Invoke-MgGraphRequest -Method GET -Uri "$GraphHost/v1.0/applications?`$filter=web/redirectUris/any(p:p eq 'https://security.optimization.assessment.local')&`$count=true" -Headers @{'ConsistencyLevel' = 'eventual'} -OutputType PSObject).Value
16541659

16551660
if ($EntraApp -and $RemoveExistingEntraApp -and $DoNotRemediate -eq $false) {
1656-
Write-Host "$(Get-Date) Removing existing Microsoft Entra application..."
1661+
Write-Host "$(Get-Date) Deleting existing Microsoft Entra application..."
16571662
try {
16581663
Invoke-MgGraphRequest -Method DELETE -Uri "$GraphHost/v1.0/applications/$($EntraApp.Id)"
16591664
$EntraApp = $null
16601665
}
16611666
catch {
1662-
Write-Warning "$(Get-Date) Unable to remove existing Microsoft Entra application. Please remove it manually."
1667+
Write-Warning "$(Get-Date) Unable to delete existing Microsoft Entra app registration. Please remove it manually."
16631668
}
16641669
}
16651670

16661671
if (!$EntraApp) {
16671672
if ($DoNotRemediate -eq $false) {
1668-
Write-Host "$(Get-Date) Creating Microsoft Entra enterprise application..."
1673+
Write-Host "$(Get-Date) Creating Microsoft Entra app registration..."
16691674
$EntraApp = Install-EntraApp -CloudEnvironment $CloudEnvironment
16701675
Write-Verbose "$(Get-Date) Get-SOAEntraApp App $($EntraApp.Id)"
16711676
}
16721677
}
16731678
else {
16741679
# Check whether the application name should be updated
1675-
if ($EntraApp.displayName -eq 'Office 365 Security Optimization Assessment') {
1680+
if ($EntraApp.displayName -ne 'Microsoft 365 Security Assessment') {
16761681
Write-Verbose "$(Get-Date) Renaming the display name of the Microsoft Entra application..."
1677-
$Body = @{'displayName' = 'Microsoft Security Assessment'}
1682+
$Body = @{'displayName' = 'Microsoft 365 Security Assessment'}
16781683
Invoke-MgGraphRequest -Method PATCH -Uri "$GraphHost/v1.0/applications/$($EntraApp.Id)" -Body $Body
16791684
}
16801685

@@ -1712,22 +1717,60 @@ function Get-SOAEntraApp {
17121717
}
17131718
# Check if service principal (enterprise app) is owner of its app registration
17141719
$appOwners = (Invoke-MgGraphRequest -Method GET -Uri "$GraphHost/v1.0/applications/$($EntraApp.Id)/owners" -OutputType PSObject).Value
1715-
$appSp = Invoke-MgGraphRequest -Method GET -Uri "$GraphHost/v1.0/servicePrincipals(appId=`'$($EntraApp.AppId)`')" -OutputType PSObject
1716-
if ($appOwners.Id -notcontains $appSp.Id) {
1717-
if ($DoNotRemediate -eq $false) {
1718-
Write-Verbose "$(Get-Date) Adding Microsoft Entra application as owner of its app registration..."
1719-
$Params = @{
1720-
'@odata.id' = "https://graph.microsoft.com/v1.0/directoryObjects/$($appSp.Id)"
1720+
$appSp = Get-SOAAppServicePrincipal -EntraApp $EntraApp
1721+
if ($appSp) {
1722+
if ($appOwners.Id -notcontains $appSp.Id) {
1723+
if ($DoNotRemediate -eq $false) {
1724+
if (Add-SOAAppOwner -NewOwnerObjectId $appSp.Id -EntraApp $EntraApp) {
1725+
$script:appSelfOwner = $true
1726+
} else {
1727+
$script:appSelfOwner = $false
1728+
}
17211729
}
1722-
Invoke-MgGraphRequest -Method POST -Uri "$GraphHost/v1.0/applications(appId=`'$($EntraApp.AppId)`')/owners/`$ref" -body $Params
1730+
} else {
1731+
$script:appSelfOwner = $true
17231732
}
1724-
}
1733+
} else {
1734+
$script:appSelfOwner = $false
1735+
}
17251736
}
17261737

17271738
Return $EntraApp
17281739

17291740
}
17301741

1742+
function Get-SOAAppServicePrincipal {
1743+
param (
1744+
$EntraApp
1745+
)
1746+
$connCount = 0
1747+
$connLimit = 5
1748+
do {
1749+
try {
1750+
$connCount++
1751+
Write-Verbose "$(Get-Date) Get-SOAAppServicePrincipal: Getting app service principal attempt #$connCount"
1752+
$sp = Invoke-MgGraphRequest -Method GET -Uri "$GraphHost/v1.0/servicePrincipals(appId=`'$($EntraApp.AppId)`')" -OutputType PSObject
1753+
return $sp
1754+
} catch {
1755+
Write-Verbose $_.Exception.Message
1756+
Start-Sleep -Seconds 2
1757+
}
1758+
} until ($connCount -eq $connLimit)
1759+
}
1760+
1761+
function Add-SOAAppOwner {
1762+
param (
1763+
$NewOwnerObjectId,
1764+
$EntraApp
1765+
)
1766+
$params = @{
1767+
'@odata.id' = "https://graph.microsoft.com/v1.0/directoryObjects/$NewOwnerObjectId"
1768+
}
1769+
Write-Verbose "$(Get-Date) Adding Microsoft Entra application as owner of its app registration..."
1770+
Invoke-MgGraphRequest -Method POST -Uri "$GraphHost/v1.0/applications(appId=`'$($EntraApp.AppId)`')/owners/`$ref" -Body $params
1771+
if ($?) {return $true} else {return $false}
1772+
}
1773+
17311774
Function Test-SOAApplication
17321775
{
17331776
Param
@@ -2300,6 +2343,10 @@ Function Install-SOAPrerequisites {
23002343
Pass=$true
23012344
}
23022345
}
2346+
$CheckResults += New-Object -Type PSObject -Property @{
2347+
Check="Entra Application Owner"
2348+
Pass=$script:appSelfOwner
2349+
}
23032350

23042351
if ($PromptForApplicationSecret -eq $True) {
23052352
# Prompt for the client secret needed to connect to the application

0 commit comments

Comments
 (0)