SHELL/5.3.2.ps1
|
$CheckId = "5.3.2" $Title = "Ensure 'Access reviews' for Guest Users are configured" $Level = "L1" $BenchmarkType = "Automated" $Uri = "https://graph.microsoft.com/v1.0/identityGovernance/accessReviews/definitions" function Get-PropValue { param( [AllowNull()]$Object, [string]$Name ) if ($null -eq $Object) { return $null } if ($Object -is [hashtable]) { foreach ($Key in $Object.Keys) { if ([string]$Key -ieq $Name) { return $Object[$Key] } } } if ($Object.PSObject -and $Object.PSObject.Properties) { foreach ($Property in $Object.PSObject.Properties) { if ([string]$Property.Name -ieq $Name) { return $Property.Value } } } return $null } function Get-GuestScopeQueries { param([AllowNull()]$Review) $Queries = @() $Scope = Get-PropValue -Object $Review -Name "scope" if ($Scope) { $DirectScopeQuery = Get-PropValue -Object $Scope -Name "query" if ($DirectScopeQuery) { $Queries += [string]$DirectScopeQuery } $PrincipalScopes = Get-PropValue -Object $Scope -Name "principalScopes" foreach ($PrincipalScope in @($PrincipalScopes)) { $PrincipalQuery = Get-PropValue -Object $PrincipalScope -Name "query" if ($PrincipalQuery) { $Queries += [string]$PrincipalQuery } } } return @($Queries | Where-Object { $_ }) } try { $Response = Invoke-MgGraphRequest -Uri $Uri -Method GET -ErrorAction Stop $Definitions = @() if ($Response) { $Definitions = @(Get-PropValue -Object $Response -Name "value") } if ($Definitions.Count -eq 0) { [pscustomobject]@{ CheckId = $CheckId Title = $Title Level = $Level BenchmarkType = $BenchmarkType Status = "FAIL" Pass = $false Evidence = [pscustomobject]@{ ReviewCount = 0 GuestReviewCount = 0 CompliantGuestReviewCount = 0 AccessReviewReport = @() SourceDocument = "CIS_Microsoft_365_Foundations_Benchmark_v6.0.1" } Error = "No access review definitions were returned." Timestamp = Get-Date } return } $GuestReviews = @() foreach ($Review in $Definitions) { $Queries = Get-GuestScopeQueries -Review $Review if (($Queries -join " || ") -match "(?i)userType\s+eq\s+'Guest'|guest") { $GuestReviews += $Review } } $AccessReviewReport = foreach ($Review in $GuestReviews) { $Settings = Get-PropValue -Object $Review -Name "settings" $Recurrence = Get-PropValue -Object $Settings -Name "recurrence" $Pattern = Get-PropValue -Object $Recurrence -Name "pattern" $RecurrenceType = [string](Get-PropValue -Object $Pattern -Name "type") $Status = [string](Get-PropValue -Object $Review -Name "status") $Mail = [bool](Get-PropValue -Object $Settings -Name "mailNotificationsEnabled") $Reminder = [bool](Get-PropValue -Object $Settings -Name "reminderNotificationsEnabled") $Justification = [bool](Get-PropValue -Object $Settings -Name "justificationRequiredOnApproval") $AutoApply = [bool](Get-PropValue -Object $Settings -Name "autoApplyDecisionsEnabled") $DefaultDecision = [string](Get-PropValue -Object $Settings -Name "defaultDecision") $RecurrencePass = $RecurrenceType -eq "absoluteMonthly" -or $RecurrenceType -eq "weekly" $IsCISCompliant = $Status -eq "InProgress" -and $Mail -and $Reminder -and $Justification -and $RecurrencePass -and $AutoApply -and ($DefaultDecision -eq "Deny") [pscustomobject]@{ Name = [string](Get-PropValue -Object $Review -Name "displayName") Status = $Status mailNotificationsEnabled = $Mail Reminders = $Reminder justificationRequiredOnApproval = $Justification Frequency = $RecurrenceType autoApplyDecisionsEnabled = $AutoApply defaultDecision = $DefaultDecision IsCISCompliant = $IsCISCompliant } } $CompliantCount = @($AccessReviewReport | Where-Object { $_.IsCISCompliant }).Count $Pass = $CompliantCount -gt 0 $Status = if ($Pass) { "PASS" } else { "FAIL" } if ($GuestReviews.Count -eq 0) { $Pass = $false $Status = "FAIL" } [pscustomobject]@{ CheckId = $CheckId Title = $Title Level = $Level BenchmarkType = $BenchmarkType Status = $Status Pass = $Pass Evidence = [pscustomobject]@{ ReviewCount = $Definitions.Count GuestReviewCount = $GuestReviews.Count CompliantGuestReviewCount = $CompliantCount AccessReviewReport = @($AccessReviewReport) SourceDocument = "CIS_Microsoft_365_Foundations_Benchmark_v6.0.1" } Error = if ($Pass) { $null } else { "No guest-user access review matched all CIS-required settings, or no guest-user access review was found." } Timestamp = Get-Date } } catch { [pscustomobject]@{ CheckId = $CheckId Title = $Title Level = $Level BenchmarkType = $BenchmarkType Status = "ERROR" Pass = $null Evidence = [pscustomobject]@{ RequestUri = $Uri SourceDocument = "CIS_Microsoft_365_Foundations_Benchmark_v6.0.1" } Error = $_.Exception.Message Timestamp = Get-Date } } |