diff --git a/source/Private/Format-MissingActions.ps1 b/source/Private/Format-MissingActions.ps1 new file mode 100644 index 0000000..b9efa97 --- /dev/null +++ b/source/Private/Format-MissingActions.ps1 @@ -0,0 +1,26 @@ +function Format-MissingActions { + param ([array]$missingActions) + + $actionGroups = @{ + "Admin" = @() + "Delegate" = @() + "Owner" = @() + } + + foreach ($action in $missingActions) { + if ($action -match "(Admin|Delegate|Owner) action '([^']+)' missing") { + $type = $matches[1] + $actionName = $matches[2] + $actionGroups[$type] += $actionName + } + } + + $formattedResults = @() + foreach ($type in $actionGroups.Keys) { + if ($actionGroups[$type].Count -gt 0) { + $formattedResults += "$($type) actions missing: $($actionGroups[$type] -join ', ')" + } + } + + return $formattedResults -join '; ' +} \ No newline at end of file diff --git a/source/Private/Initialize-CISAuditResult.ps1 b/source/Private/Initialize-CISAuditResult.ps1 index b1e2e09..3b2cc94 100644 --- a/source/Private/Initialize-CISAuditResult.ps1 +++ b/source/Private/Initialize-CISAuditResult.ps1 @@ -1,19 +1,23 @@ function Initialize-CISAuditResult { + [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$Rec, - [Parameter(Mandatory = $true)] + [Parameter(Mandatory = $true, ParameterSetName = 'Full')] [bool]$Result, - [Parameter(Mandatory = $true)] + [Parameter(Mandatory = $true, ParameterSetName = 'Full')] [string]$Status, - [Parameter(Mandatory = $true)] + [Parameter(Mandatory = $true, ParameterSetName = 'Full')] [string]$Details, - [Parameter(Mandatory = $true)] - [string]$FailureReason + [Parameter(Mandatory = $true, ParameterSetName = 'Full')] + [string]$FailureReason, + + [Parameter(ParameterSetName = 'Error')] + [switch]$Failure ) # Import the test definitions CSV file @@ -22,6 +26,10 @@ function Initialize-CISAuditResult { # Find the row that matches the provided recommendation (Rec) $testDefinition = $testDefinitions | Where-Object { $_.Rec -eq $Rec } + if (-not $testDefinition) { + throw "Test definition for recommendation '$Rec' not found." + } + # Create an instance of CISAuditResult and populate it $auditResult = [CISAuditResult]::new() $auditResult.Rec = $Rec @@ -36,10 +44,18 @@ function Initialize-CISAuditResult { $auditResult.Automated = [bool]::Parse($testDefinition.Automated) $auditResult.Connection = $testDefinition.Connection $auditResult.CISControlVer = 'v8' - $auditResult.Result = $Result - $auditResult.Status = $Status - $auditResult.Details = $Details - $auditResult.FailureReason = $FailureReason + + if ($PSCmdlet.ParameterSetName -eq 'Full') { + $auditResult.Result = $Result + $auditResult.Status = $Status + $auditResult.Details = $Details + $auditResult.FailureReason = $FailureReason + } elseif ($PSCmdlet.ParameterSetName -eq 'Error') { + $auditResult.Result = $false + $auditResult.Status = 'Fail' + $auditResult.Details = "An error occurred while processing the test." + $auditResult.FailureReason = "Initialization error: Failed to process the test." + } return $auditResult } diff --git a/source/tests/Test-AdministrativeAccountCompliance.ps1 b/source/tests/Test-AdministrativeAccountCompliance.ps1 index 21ab959..05b3796 100644 --- a/source/tests/Test-AdministrativeAccountCompliance.ps1 +++ b/source/tests/Test-AdministrativeAccountCompliance.ps1 @@ -1,83 +1,89 @@ function Test-AdministrativeAccountCompliance { [CmdletBinding()] param ( - # Aligned # Parameters can be added if needed ) begin { - #. .\source\Classes\CISAuditResult.ps1 + # Initialize the valid licenses $validLicenses = @('AAD_PREMIUM', 'AAD_PREMIUM_P2') + $recnum = "1.1.1" } process { - $adminRoles = Get-MgRoleManagementDirectoryRoleDefinition | Where-Object { $_.DisplayName -like "*Admin*" } - $adminRoleUsers = @() + try { + $adminRoles = Get-MgRoleManagementDirectoryRoleDefinition | Where-Object { $_.DisplayName -like "*Admin*" } + $adminRoleUsers = @() - foreach ($role in $adminRoles) { - $roleAssignments = Get-MgRoleManagementDirectoryRoleAssignment -Filter "roleDefinitionId eq '$($role.Id)'" + foreach ($role in $adminRoles) { + $roleAssignments = Get-MgRoleManagementDirectoryRoleAssignment -Filter "roleDefinitionId eq '$($role.Id)'" - foreach ($assignment in $roleAssignments) { - $userDetails = Get-MgUser -UserId $assignment.PrincipalId -Property "DisplayName, UserPrincipalName, Id, OnPremisesSyncEnabled" -ErrorAction SilentlyContinue - if ($userDetails) { - $licenses = Get-MgUserLicenseDetail -UserId $assignment.PrincipalId -ErrorAction SilentlyContinue - $licenseString = if ($licenses) { ($licenses.SkuPartNumber -join '|') } else { "No Licenses Found" } + foreach ($assignment in $roleAssignments) { + $userDetails = Get-MgUser -UserId $assignment.PrincipalId -Property "DisplayName, UserPrincipalName, Id, OnPremisesSyncEnabled" -ErrorAction SilentlyContinue + if ($userDetails) { + $licenses = Get-MgUserLicenseDetail -UserId $assignment.PrincipalId -ErrorAction SilentlyContinue + $licenseString = if ($licenses) { ($licenses.SkuPartNumber -join '|') } else { "No Licenses Found" } - $adminRoleUsers += [PSCustomObject]@{ - UserName = $userDetails.UserPrincipalName - RoleName = $role.DisplayName - UserId = $userDetails.Id - HybridUser = $userDetails.OnPremisesSyncEnabled - Licenses = $licenseString + $adminRoleUsers += [PSCustomObject]@{ + UserName = $userDetails.UserPrincipalName + RoleName = $role.DisplayName + UserId = $userDetails.Id + HybridUser = $userDetails.OnPremisesSyncEnabled + Licenses = $licenseString + } } } } - } - $uniqueAdminRoleUsers = $adminRoleUsers | Group-Object -Property UserName | ForEach-Object { - $first = $_.Group | Select-Object -First 1 - $roles = ($_.Group.RoleName -join ', ') - $licenses = (($_.Group | Select-Object -ExpandProperty Licenses) -join ',').Split(',') | Select-Object -Unique + $uniqueAdminRoleUsers = $adminRoleUsers | Group-Object -Property UserName | ForEach-Object { + $first = $_.Group | Select-Object -First 1 + $roles = ($_.Group.RoleName -join ', ') + $licenses = (($_.Group | Select-Object -ExpandProperty Licenses) -join ',').Split(',') | Select-Object -Unique - $first | Select-Object UserName, UserId, HybridUser, @{Name = 'Roles'; Expression = { $roles } }, @{Name = 'Licenses'; Expression = { $licenses -join '|' } } - } + $first | Select-Object UserName, UserId, HybridUser, @{Name = 'Roles'; Expression = { $roles } }, @{Name = 'Licenses'; Expression = { $licenses -join '|' } } + } - $nonCompliantUsers = $uniqueAdminRoleUsers | Where-Object { - $_.HybridUser -or - -not ($_.Licenses -split '\|' | Where-Object { $validLicenses -contains $_ }) - } + $nonCompliantUsers = $uniqueAdminRoleUsers | Where-Object { + $_.HybridUser -or + -not ($_.Licenses -split '\|' | Where-Object { $validLicenses -contains $_ }) + } - $failureReasons = $nonCompliantUsers | ForEach-Object { - $accountType = if ($_.HybridUser) { "Hybrid" } else { "Cloud-Only" } - $missingLicenses = $validLicenses | Where-Object { $_ -notin ($_.Licenses -split '\|') } - "$($_.UserName)|$($_.Roles)|$accountType|Missing: $($missingLicenses -join ',')" - } - $failureReasons = $failureReasons -join "`n" - $details = if ($nonCompliantUsers) { - "Non-Compliant Accounts: $($nonCompliantUsers.Count)`nDetails:`n" + ($nonCompliantUsers | ForEach-Object { $_.UserName }) -join "`n" - } - else { - "Compliant Accounts: $($uniqueAdminRoleUsers.Count)" - } + $failureReasons = $nonCompliantUsers | ForEach-Object { + $accountType = if ($_.HybridUser) { "Hybrid" } else { "Cloud-Only" } + $missingLicenses = $validLicenses | Where-Object { $_ -notin ($_.Licenses -split '\|') } + "$($_.UserName)|$($_.Roles)|$accountType|Missing: $($missingLicenses -join ',')" + } + $failureReasons = $failureReasons -join "`n" + $details = if ($nonCompliantUsers) { + "Non-Compliant Accounts: $($nonCompliantUsers.Count)`nDetails:`n" + ($nonCompliantUsers | ForEach-Object { $_.UserName }) -join "`n" + } + else { + "Compliant Accounts: $($uniqueAdminRoleUsers.Count)" + } - $result = $nonCompliantUsers.Count -eq 0 - $status = if ($result) { 'Pass' } else { 'Fail' } - $failureReason = if ($nonCompliantUsers) { "Non-compliant accounts: `nUsername | Roles | HybridStatus | Missing Licence`n$failureReasons" } else { "N/A" } + $result = $nonCompliantUsers.Count -eq 0 + $status = if ($result) { 'Pass' } else { 'Fail' } + $failureReason = if ($nonCompliantUsers) { "Non-compliant accounts: `nUsername | Roles | HybridStatus | Missing Licence`n$failureReasons" } else { "N/A" } - # Create the parameter splat - $params = @{ - Rec = "1.1.1" - Result = $result - Status = $status - Details = $details - FailureReason = $failureReason + # Create the parameter splat + $params = @{ + Rec = $recnum + Result = $result + Status = $status + Details = $details + FailureReason = $failureReason + } + + $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" - $auditResult = Initialize-CISAuditResult @params + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } } - end { - # Output the result return $auditResult } } diff --git a/source/tests/Test-AntiPhishingPolicy.ps1 b/source/tests/Test-AntiPhishingPolicy.ps1 index 88b103e..ccbf02f 100644 --- a/source/tests/Test-AntiPhishingPolicy.ps1 +++ b/source/tests/Test-AntiPhishingPolicy.ps1 @@ -10,66 +10,75 @@ function Test-AntiPhishingPolicy { #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed #$auditResults = @() + $recnum = "2.1.7" } process { - # 2.1.7 Ensure that an anti-phishing policy has been created - # Retrieve and validate the anti-phishing policies - $antiPhishPolicies = Get-AntiPhishPolicy - $validatedPolicies = $antiPhishPolicies | Where-Object { - $_.Enabled -eq $true -and - $_.PhishThresholdLevel -ge 2 -and - $_.EnableMailboxIntelligenceProtection -eq $true -and - $_.EnableMailboxIntelligence -eq $true -and - $_.EnableSpoofIntelligence -eq $true - } + try { + # 2.1.7 Ensure that an anti-phishing policy has been created - # Check if there is at least one policy that meets the requirements - $nonCompliantItems = $antiPhishPolicies | Where-Object { - $_.Enabled -ne $true -or - $_.PhishThresholdLevel -lt 2 -or - $_.EnableMailboxIntelligenceProtection -ne $true -or - $_.EnableMailboxIntelligence -ne $true -or - $_.EnableSpoofIntelligence -ne $true - } - $compliantItems = $validatedPolicies - $isCompliant = $compliantItems.Count -gt 0 + # Retrieve and validate the anti-phishing policies + $antiPhishPolicies = Get-AntiPhishPolicy + $validatedPolicies = $antiPhishPolicies | Where-Object { + $_.Enabled -eq $true -and + $_.PhishThresholdLevel -ge 2 -and + $_.EnableMailboxIntelligenceProtection -eq $true -and + $_.EnableMailboxIntelligence -eq $true -and + $_.EnableSpoofIntelligence -eq $true + } - # Prepare failure reasons for non-compliant items - $nonCompliantNames = $nonCompliantItems | ForEach-Object { $_.Name } - $failureReasons = if ($nonCompliantNames.Count -gt 0) { - "Reason: Does not meet one or more compliance criteria.`nNon-compliant Policies:`n" + ($nonCompliantNames -join "`n") - } - else { - "N/A" - } + # Check if there is at least one policy that meets the requirements + $nonCompliantItems = $antiPhishPolicies | Where-Object { + $_.Enabled -ne $true -or + $_.PhishThresholdLevel -lt 2 -or + $_.EnableMailboxIntelligenceProtection -ne $true -or + $_.EnableMailboxIntelligence -ne $true -or + $_.EnableSpoofIntelligence -ne $true + } + $compliantItems = $validatedPolicies + $isCompliant = $compliantItems.Count -gt 0 - # Prepare details for non-compliant items - $nonCompliantDetails = $nonCompliantItems | ForEach-Object { - "Policy: $($_.Name)" - } - $nonCompliantDetails = $nonCompliantDetails -join "`n" + # Prepare failure reasons for non-compliant items + $nonCompliantNames = $nonCompliantItems | ForEach-Object { $_.Name } + $failureReasons = if ($nonCompliantNames.Count -gt 0) { + "Reason: Does not meet one or more compliance criteria.`nNon-compliant Policies:`n" + ($nonCompliantNames -join "`n") + } + else { + "N/A" + } - # Prepare details based on compliance - $details = if ($nonCompliantItems) { - "Non-Compliant Items: $($nonCompliantItems.Count)`nDetails:`n$nonCompliantDetails" - } - else { - "Compliant Items: $($compliantItems.Count)" - } + # Prepare details for non-compliant items + $nonCompliantDetails = $nonCompliantItems | ForEach-Object { + "Policy: $($_.Name)" + } + $nonCompliantDetails = $nonCompliantDetails -join "`n" - # Parameter splat for Initialize-CISAuditResult function - $params = @{ - Rec = "2.1.7" - Result = $nonCompliantItems.Count -eq 0 - Status = if ($isCompliant) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons - } + # Prepare details based on compliance + $details = if ($nonCompliantItems) { + "Non-Compliant Items: $($nonCompliantItems.Count)`nDetails:`n$nonCompliantDetails" + } + else { + "Compliant Items: $($compliantItems.Count)" + } - # Create and populate the CISAuditResult object - $auditResult = Initialize-CISAuditResult @params + # Parameter splat for Initialize-CISAuditResult function + $params = @{ + Rec = $recnum + Result = $nonCompliantItems.Count -eq 0 + Status = if ($isCompliant) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + + # Create and populate the CISAuditResult object + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } } end { diff --git a/source/tests/Test-AuditDisabledFalse.ps1 b/source/tests/Test-AuditDisabledFalse.ps1 index 3f91a83..c2c2dcc 100644 --- a/source/tests/Test-AuditDisabledFalse.ps1 +++ b/source/tests/Test-AuditDisabledFalse.ps1 @@ -9,39 +9,48 @@ function Test-AuditDisabledFalse { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "6.1.1" } process { - # 6.1.1 (L1) Ensure 'AuditDisabled' organizationally is set to 'False' - # Retrieve the AuditDisabled configuration - $auditDisabledConfig = Get-OrganizationConfig | Select-Object AuditDisabled - $auditNotDisabled = -not $auditDisabledConfig.AuditDisabled + try { + # 6.1.1 (L1) Ensure 'AuditDisabled' organizationally is set to 'False' - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $auditNotDisabled) { - "AuditDisabled is set to True" - } - else { - "N/A" - } + # Retrieve the AuditDisabled configuration + $auditDisabledConfig = Get-OrganizationConfig | Select-Object AuditDisabled + $auditNotDisabled = -not $auditDisabledConfig.AuditDisabled - $details = if ($auditNotDisabled) { - "Audit is not disabled organizationally" - } - else { - "Audit is disabled organizationally" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $auditNotDisabled) { + "AuditDisabled is set to True" + } + else { + "N/A" + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "6.1.1" - Result = $auditNotDisabled - Status = if ($auditNotDisabled) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + $details = if ($auditNotDisabled) { + "Audit is not disabled organizationally" + } + else { + "Audit is disabled organizationally" + } + + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $auditNotDisabled + Status = if ($auditNotDisabled) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-AuditLogSearch.ps1 b/source/tests/Test-AuditLogSearch.ps1 index 023f569..69f2c8f 100644 --- a/source/tests/Test-AuditLogSearch.ps1 +++ b/source/tests/Test-AuditLogSearch.ps1 @@ -9,40 +9,49 @@ function Test-AuditLogSearch { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "3.1.1" } process { - # 3.1.1 (L1) Ensure Microsoft 365 audit log search is Enabled - # Retrieve the audit log configuration - $auditLogConfig = Get-AdminAuditLogConfig | Select-Object UnifiedAuditLogIngestionEnabled - $auditLogResult = $auditLogConfig.UnifiedAuditLogIngestionEnabled + try { + # 3.1.1 (L1) Ensure Microsoft 365 audit log search is Enabled - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $auditLogResult) { - "Audit log search is not enabled" - } - else { - "N/A" - } + # Retrieve the audit log configuration + $auditLogConfig = Get-AdminAuditLogConfig | Select-Object UnifiedAuditLogIngestionEnabled + $auditLogResult = $auditLogConfig.UnifiedAuditLogIngestionEnabled - $details = if ($auditLogResult) { - "UnifiedAuditLogIngestionEnabled: True" - } - else { - "UnifiedAuditLogIngestionEnabled: False" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $auditLogResult) { + "Audit log search is not enabled" + } + else { + "N/A" + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "3.1.1" - Result = $auditLogResult - Status = if ($auditLogResult) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons - } - $auditResult = Initialize-CISAuditResult @params + $details = if ($auditLogResult) { + "UnifiedAuditLogIngestionEnabled: True" + } + else { + "UnifiedAuditLogIngestionEnabled: False" + } + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $auditLogResult + Status = if ($auditLogResult) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } } end { diff --git a/source/tests/Test-BlockChannelEmails.ps1 b/source/tests/Test-BlockChannelEmails.ps1 index c8ed086..39884d7 100644 --- a/source/tests/Test-BlockChannelEmails.ps1 +++ b/source/tests/Test-BlockChannelEmails.ps1 @@ -9,9 +9,12 @@ function Test-BlockChannelEmails { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "8.1.2" } process { + + try { # 8.1.2 (L1) Ensure users can't send emails to a channel email address # Retrieve Teams client configuration @@ -35,13 +38,20 @@ function Test-BlockChannelEmails { # Create and populate the CISAuditResult object $params = @{ - Rec = "8.1.2" + Rec = $recnum Result = -not $allowEmailIntoChannel Status = if (-not $allowEmailIntoChannel) { "Pass" } else { "Fail" } Details = $details FailureReason = $failureReasons } $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } } end { diff --git a/source/tests/Test-BlockMailForwarding.ps1 b/source/tests/Test-BlockMailForwarding.ps1 index 8039d06..5554b32 100644 --- a/source/tests/Test-BlockMailForwarding.ps1 +++ b/source/tests/Test-BlockMailForwarding.ps1 @@ -12,37 +12,45 @@ function Test-BlockMailForwarding { } process { - # 6.2.1 (L1) Ensure all forms of mail forwarding are blocked and/or disabled + try { + # 6.2.1 (L1) Ensure all forms of mail forwarding are blocked and/or disabled - # Retrieve the transport rules that redirect messages - $transportRules = Get-TransportRule | Where-Object { $null -ne $_.RedirectMessageTo } - $forwardingBlocked = $transportRules.Count -eq 0 + # Retrieve the transport rules that redirect messages + $transportRules = Get-TransportRule | Where-Object { $null -ne $_.RedirectMessageTo } + $forwardingBlocked = $transportRules.Count -eq 0 - # Prepare failure reasons and details based on compliance - $failureReasons = if ($transportRules.Count -gt 0) { - "Mail forwarding rules found: $($transportRules.Name -join ', ')" - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if ($transportRules.Count -gt 0) { + "Mail forwarding rules found: $($transportRules.Name -join ', ')" + } + else { + "N/A" + } - $details = if ($transportRules.Count -gt 0) { - $transportRules | ForEach-Object { - "$($_.Name) redirects to $($_.RedirectMessageTo)" - } -join " | " - } - else { - "Step 1: No forwarding rules found. Please proceed with Step 2 described in CIS Benchmark." - } + $details = if ($transportRules.Count -gt 0) { + $transportRules | ForEach-Object { + "$($_.Name) redirects to $($_.RedirectMessageTo)" + } -join " | " + } + else { + "Step 1: No forwarding rules found. Please proceed with Step 2 described in CIS Benchmark." + } - $params = @{ - Rec = "6.2.1" - Result = $forwardingBlocked - Status = if ($forwardingBlocked) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + $params = @{ + Rec = "6.2.1" + Result = $forwardingBlocked + Status = if ($forwardingBlocked) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec "6.2.1" -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-BlockSharedMailboxSignIn.ps1 b/source/tests/Test-BlockSharedMailboxSignIn.ps1 index 7f4711b..a8d763a 100644 --- a/source/tests/Test-BlockSharedMailboxSignIn.ps1 +++ b/source/tests/Test-BlockSharedMailboxSignIn.ps1 @@ -9,41 +9,51 @@ function Test-BlockSharedMailboxSignIn { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "1.2.2" } process { - # 1.2.2 (L1) Ensure sign-in to shared mailboxes is blocked - # Retrieve shared mailbox details - $MBX = Get-EXOMailbox -RecipientTypeDetails SharedMailbox - $sharedMailboxDetails = $MBX | ForEach-Object { Get-AzureADUser -ObjectId $_.ExternalDirectoryObjectId } - $enabledMailboxes = $sharedMailboxDetails | Where-Object { $_.AccountEnabled } | ForEach-Object { $_.DisplayName } - $allBlocked = $enabledMailboxes.Count -eq 0 + try { + # 1.2.2 (L1) Ensure sign-in to shared mailboxes is blocked - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $allBlocked) { - "Some mailboxes have sign-in enabled: $($enabledMailboxes -join ', ')" - } - else { - "N/A" - } + # Retrieve shared mailbox details + $MBX = Get-EXOMailbox -RecipientTypeDetails SharedMailbox + $sharedMailboxDetails = $MBX | ForEach-Object { Get-AzureADUser -ObjectId $_.ExternalDirectoryObjectId } + $enabledMailboxes = $sharedMailboxDetails | Where-Object { $_.AccountEnabled } | ForEach-Object { $_.DisplayName } + $allBlocked = $enabledMailboxes.Count -eq 0 - $details = if ($allBlocked) { - "All shared mailboxes have sign-in blocked." - } - else { - "Enabled Mailboxes: $($enabledMailboxes -join ', ')" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $allBlocked) { + "Some mailboxes have sign-in enabled: $($enabledMailboxes -join ', ')" + } + else { + "N/A" + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "1.2.2" - Result = $allBlocked - Status = if ($allBlocked) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + $details = if ($allBlocked) { + "All shared mailboxes have sign-in blocked." + } + else { + "Enabled Mailboxes: $($enabledMailboxes -join ', ')" + } + + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $allBlocked + Status = if ($allBlocked) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-CommonAttachmentFilter.ps1 b/source/tests/Test-CommonAttachmentFilter.ps1 index 9b60797..b328491 100644 --- a/source/tests/Test-CommonAttachmentFilter.ps1 +++ b/source/tests/Test-CommonAttachmentFilter.ps1 @@ -9,39 +9,48 @@ function Test-CommonAttachmentFilter { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "2.1.2" } process { - # 2.1.2 (L1) Ensure the Common Attachment Types Filter is enabled + try { + # 2.1.2 (L1) Ensure the Common Attachment Types Filter is enabled - # Retrieve the attachment filter policy - $attachmentFilter = Get-MalwareFilterPolicy -Identity Default | Select-Object EnableFileFilter - $result = $attachmentFilter.EnableFileFilter + # Retrieve the attachment filter policy + $attachmentFilter = Get-MalwareFilterPolicy -Identity Default | Select-Object EnableFileFilter + $result = $attachmentFilter.EnableFileFilter - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $result) { - "Common Attachment Types Filter is disabled" - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $result) { + "Common Attachment Types Filter is disabled" + } + else { + "N/A" + } - $details = if ($result) { - "File Filter Enabled: True" - } - else { - "File Filter Enabled: False" - } + $details = if ($result) { + "File Filter Enabled: True" + } + else { + "File Filter Enabled: False" + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "2.1.2" - Result = $result - Status = if ($result) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $result + Status = if ($result) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-CustomerLockbox.ps1 b/source/tests/Test-CustomerLockbox.ps1 index c0723f9..a540f1b 100644 --- a/source/tests/Test-CustomerLockbox.ps1 +++ b/source/tests/Test-CustomerLockbox.ps1 @@ -9,9 +9,12 @@ function Test-CustomerLockbox { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "1.3.6" } process { + + try { # 1.3.6 (L2) Ensure the customer lockbox feature is enabled # Retrieve the organization configuration @@ -35,13 +38,20 @@ function Test-CustomerLockbox { # Create and populate the CISAuditResult object # $params = @{ - Rec = "1.3.6" + Rec = $recnum Result = $customerLockboxEnabled Status = if ($customerLockboxEnabled) { "Pass" } else { "Fail" } Details = $details FailureReason = $failureReasons } $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } } end { diff --git a/source/tests/Test-DialInBypassLobby.ps1 b/source/tests/Test-DialInBypassLobby.ps1 index dd2a47b..efd83fa 100644 --- a/source/tests/Test-DialInBypassLobby.ps1 +++ b/source/tests/Test-DialInBypassLobby.ps1 @@ -9,39 +9,49 @@ function Test-DialInBypassLobby { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "8.5.4" } process { - # 8.5.4 (L1) Ensure users dialing in can't bypass the lobby - # Retrieve Teams meeting policy for PSTN users - $CsTeamsMeetingPolicyPSTN = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AllowPSTNUsersToBypassLobby - $PSTNBypassDisabled = -not $CsTeamsMeetingPolicyPSTN.AllowPSTNUsersToBypassLobby + try { + # 8.5.4 (L1) Ensure users dialing in can't bypass the lobby - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $PSTNBypassDisabled) { - "Users dialing in can bypass the lobby" - } - else { - "N/A" - } + # Retrieve Teams meeting policy for PSTN users + $CsTeamsMeetingPolicyPSTN = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AllowPSTNUsersToBypassLobby + $PSTNBypassDisabled = -not $CsTeamsMeetingPolicyPSTN.AllowPSTNUsersToBypassLobby - $details = if ($PSTNBypassDisabled) { - "AllowPSTNUsersToBypassLobby is set to False" - } - else { - "AllowPSTNUsersToBypassLobby is set to True" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $PSTNBypassDisabled) { + "Users dialing in can bypass the lobby" + } + else { + "N/A" + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "8.5.4" - Result = $PSTNBypassDisabled - Status = if ($PSTNBypassDisabled) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + $details = if ($PSTNBypassDisabled) { + "AllowPSTNUsersToBypassLobby is set to False" + } + else { + "AllowPSTNUsersToBypassLobby is set to True" + } + + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $PSTNBypassDisabled + Status = if ($PSTNBypassDisabled) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-DisallowInfectedFilesDownload.ps1 b/source/tests/Test-DisallowInfectedFilesDownload.ps1 index 3ce9b3a..963813d 100644 --- a/source/tests/Test-DisallowInfectedFilesDownload.ps1 +++ b/source/tests/Test-DisallowInfectedFilesDownload.ps1 @@ -10,40 +10,49 @@ function Test-DisallowInfectedFilesDownload { #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "7.3.1" } process { - # 7.3.1 (L2) Ensure Office 365 SharePoint infected files are disallowed for download - # Retrieve the SharePoint tenant configuration - $SPOTenantDisallowInfectedFileDownload = Get-SPOTenant | Select-Object DisallowInfectedFileDownload - $isDisallowInfectedFileDownloadEnabled = $SPOTenantDisallowInfectedFileDownload.DisallowInfectedFileDownload + try { + # 7.3.1 (L2) Ensure Office 365 SharePoint infected files are disallowed for download - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $isDisallowInfectedFileDownloadEnabled) { - "Downloading infected files is not disallowed." - } - else { - "N/A" - } + # Retrieve the SharePoint tenant configuration + $SPOTenantDisallowInfectedFileDownload = Get-SPOTenant | Select-Object DisallowInfectedFileDownload + $isDisallowInfectedFileDownloadEnabled = $SPOTenantDisallowInfectedFileDownload.DisallowInfectedFileDownload - $details = if ($isDisallowInfectedFileDownloadEnabled) { - "DisallowInfectedFileDownload: True" - } - else { - "DisallowInfectedFileDownload: False" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $isDisallowInfectedFileDownloadEnabled) { + "Downloading infected files is not disallowed." + } + else { + "N/A" + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "7.3.1" - Result = $isDisallowInfectedFileDownloadEnabled - Status = if ($isDisallowInfectedFileDownloadEnabled) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons - } - $auditResult = Initialize-CISAuditResult @params + $details = if ($isDisallowInfectedFileDownloadEnabled) { + "DisallowInfectedFileDownload: True" + } + else { + "DisallowInfectedFileDownload: False" + } + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $isDisallowInfectedFileDownloadEnabled + Status = if ($isDisallowInfectedFileDownloadEnabled) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } } end { diff --git a/source/tests/Test-EnableDKIM.ps1 b/source/tests/Test-EnableDKIM.ps1 index db7bac6..7661073 100644 --- a/source/tests/Test-EnableDKIM.ps1 +++ b/source/tests/Test-EnableDKIM.ps1 @@ -9,9 +9,12 @@ function Test-EnableDKIM { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "2.1.9" } process { + + try { # 2.1.9 (L1) Ensure DKIM is enabled for all Exchange Online Domains # Retrieve DKIM configuration for all domains @@ -36,13 +39,20 @@ function Test-EnableDKIM { # Create and populate the CISAuditResult object $params = @{ - Rec = "2.1.9" + Rec = $recnum Result = $dkimResult Status = if ($dkimResult) { "Pass" } else { "Fail" } Details = $details FailureReason = $failureReasons } $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } } end { diff --git a/source/tests/Test-ExternalNoControl.ps1 b/source/tests/Test-ExternalNoControl.ps1 index 8d52da7..0afec63 100644 --- a/source/tests/Test-ExternalNoControl.ps1 +++ b/source/tests/Test-ExternalNoControl.ps1 @@ -10,9 +10,12 @@ function Test-ExternalNoControl { #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "8.5.7" } process { + + try { # 8.5.7 (L1) Ensure external participants can't give or request control # Retrieve Teams meeting policy for external participant control @@ -36,13 +39,20 @@ function Test-ExternalNoControl { # Create and populate the CISAuditResult object $params = @{ - Rec = "8.5.7" + Rec = $recnum Result = $externalControlRestricted Status = if ($externalControlRestricted) { "Pass" } else { "Fail" } Details = $details FailureReason = $failureReasons } $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } } end { diff --git a/source/tests/Test-ExternalSharingCalendars.ps1 b/source/tests/Test-ExternalSharingCalendars.ps1 index 9053bbb..2685a5c 100644 --- a/source/tests/Test-ExternalSharingCalendars.ps1 +++ b/source/tests/Test-ExternalSharingCalendars.ps1 @@ -10,48 +10,58 @@ function Test-ExternalSharingCalendars { #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "1.3.3" } process { - # 1.3.3 (L2) Ensure 'External sharing' of calendars is not available (Automated) - # Retrieve sharing policies related to calendar sharing - $sharingPolicies = Get-SharingPolicy | Where-Object { $_.Domains -like '*CalendarSharing*' } + try { + # 1.3.3 (L2) Ensure 'External sharing' of calendars is not available (Automated) - # Check if calendar sharing is disabled in all applicable policies - $isExternalSharingDisabled = $true - $sharingPolicyDetails = @() - foreach ($policy in $sharingPolicies) { - if ($policy.Enabled -eq $true) { - $isExternalSharingDisabled = $false - $sharingPolicyDetails += "$($policy.Name): Enabled" + # Retrieve sharing policies related to calendar sharing + $sharingPolicies = Get-SharingPolicy | Where-Object { $_.Domains -like '*CalendarSharing*' } + + # Check if calendar sharing is disabled in all applicable policies + $isExternalSharingDisabled = $true + $sharingPolicyDetails = @() + foreach ($policy in $sharingPolicies) { + if ($policy.Enabled -eq $true) { + $isExternalSharingDisabled = $false + $sharingPolicyDetails += "$($policy.Name): Enabled" + } } - } - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $isExternalSharingDisabled) { - "Calendar sharing with external users is enabled in one or more policies." - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $isExternalSharingDisabled) { + "Calendar sharing with external users is enabled in one or more policies." + } + else { + "N/A" + } - $details = if ($isExternalSharingDisabled) { - "Calendar sharing with external users is disabled." - } - else { - "Enabled Sharing Policies: $($sharingPolicyDetails -join ', ')" - } + $details = if ($isExternalSharingDisabled) { + "Calendar sharing with external users is disabled." + } + else { + "Enabled Sharing Policies: $($sharingPolicyDetails -join ', ')" + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "1.3.3" - Result = $isExternalSharingDisabled - Status = if ($isExternalSharingDisabled) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $isExternalSharingDisabled + Status = if ($isExternalSharingDisabled) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-GlobalAdminsCount.ps1 b/source/tests/Test-GlobalAdminsCount.ps1 index c57110f..ea39bfd 100644 --- a/source/tests/Test-GlobalAdminsCount.ps1 +++ b/source/tests/Test-GlobalAdminsCount.ps1 @@ -10,39 +10,49 @@ function Test-GlobalAdminsCount { #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "1.1.3" } process { - # 1.1.3 (L1) Ensure that between two and four global admins are designated - # Retrieve global admin role and members - $globalAdminRole = Get-MgDirectoryRole -Filter "RoleTemplateId eq '62e90394-69f5-4237-9190-012177145e10'" - $globalAdmins = Get-MgDirectoryRoleMember -DirectoryRoleId $globalAdminRole.Id - $globalAdminCount = $globalAdmins.AdditionalProperties.Count - $globalAdminUsernames = ($globalAdmins | ForEach-Object { $_.AdditionalProperties["displayName"] }) -join ', ' + try { + # 1.1.3 (L1) Ensure that between two and four global admins are designated - # Prepare failure reasons and details based on compliance - $failureReasons = if ($globalAdminCount -lt 2) { - "Less than 2 global admins: $globalAdminUsernames" - } - elseif ($globalAdminCount -gt 4) { - "More than 4 global admins: $globalAdminUsernames" - } - else { - "N/A" - } + # Retrieve global admin role and members + $globalAdminRole = Get-MgDirectoryRole -Filter "RoleTemplateId eq '62e90394-69f5-4237-9190-012177145e10'" + $globalAdmins = Get-MgDirectoryRoleMember -DirectoryRoleId $globalAdminRole.Id + $globalAdminCount = $globalAdmins.AdditionalProperties.Count + $globalAdminUsernames = ($globalAdmins | ForEach-Object { $_.AdditionalProperties["displayName"] }) -join ', ' - $details = "Count: $globalAdminCount; Users: $globalAdminUsernames" + # Prepare failure reasons and details based on compliance + $failureReasons = if ($globalAdminCount -lt 2) { + "Less than 2 global admins: $globalAdminUsernames" + } + elseif ($globalAdminCount -gt 4) { + "More than 4 global admins: $globalAdminUsernames" + } + else { + "N/A" + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "1.1.3" - Result = $globalAdminCount -ge 2 -and $globalAdminCount -le 4 - Status = if ($globalAdminCount -ge 2 -and $globalAdminCount -le 4) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + $details = "Count: $globalAdminCount; Users: $globalAdminUsernames" + + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $globalAdminCount -ge 2 -and $globalAdminCount -le 4 + Status = if ($globalAdminCount -ge 2 -and $globalAdminCount -le 4) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-GuestAccessExpiration.ps1 b/source/tests/Test-GuestAccessExpiration.ps1 index 4a0b2b6..4f4aaca 100644 --- a/source/tests/Test-GuestAccessExpiration.ps1 +++ b/source/tests/Test-GuestAccessExpiration.ps1 @@ -10,9 +10,12 @@ function Test-GuestAccessExpiration { #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "7.2.9" } process { + + try { # 7.2.9 (L1) Ensure guest access to a site or OneDrive will expire automatically # Retrieve SharePoint tenant settings related to guest access expiration @@ -31,13 +34,20 @@ function Test-GuestAccessExpiration { # Create and populate the CISAuditResult object $params = @{ - Rec = "7.2.9" + Rec = $recnum Result = $isGuestAccessExpirationConfiguredCorrectly Status = if ($isGuestAccessExpirationConfiguredCorrectly) { "Pass" } else { "Fail" } Details = $details FailureReason = $failureReasons } $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } } end { diff --git a/source/tests/Test-GuestUsersBiweeklyReview.ps1 b/source/tests/Test-GuestUsersBiweeklyReview.ps1 index 730f039..23b2d74 100644 --- a/source/tests/Test-GuestUsersBiweeklyReview.ps1 +++ b/source/tests/Test-GuestUsersBiweeklyReview.ps1 @@ -10,41 +10,50 @@ function Test-GuestUsersBiweeklyReview { #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "1.1.4" } process { - # 1.1.4 (L1) Ensure Guest Users are reviewed at least biweekly + try { + # 1.1.4 (L1) Ensure Guest Users are reviewed at least biweekly - # Retrieve guest users from Microsoft Graph - # Connect-MgGraph -Scopes "User.Read.All" - $guestUsers = Get-MgUser -All -Filter "UserType eq 'Guest'" + # Retrieve guest users from Microsoft Graph + # Connect-MgGraph -Scopes "User.Read.All" + $guestUsers = Get-MgUser -All -Filter "UserType eq 'Guest'" - # Prepare failure reasons and details based on compliance - $failureReasons = if ($guestUsers) { - "Guest users present: $($guestUsers.Count)" - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if ($guestUsers) { + "Guest users present: $($guestUsers.Count)" + } + else { + "N/A" + } - $details = if ($guestUsers) { - $auditCommand = "Get-MgUser -All -Property UserType,UserPrincipalName | Where {`$_.UserType -ne 'Member'} | Format-Table UserPrincipalName, UserType" - "Manual review required. To list guest users, run: `"$auditCommand`"." - } - else { - "No guest users found." - } + $details = if ($guestUsers) { + $auditCommand = "Get-MgUser -All -Property UserType,UserPrincipalName | Where {`$_.UserType -ne 'Member'} | Format-Table UserPrincipalName, UserType" + "Manual review required. To list guest users, run: `"$auditCommand`"." + } + else { + "No guest users found." + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "1.1.4" - Result = -not $guestUsers - Status = if ($guestUsers) { "Fail" } else { "Pass" } - Details = $details - FailureReason = $failureReasons + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = -not $guestUsers + Status = if ($guestUsers) { "Fail" } else { "Pass" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-IdentifyExternalEmail.ps1 b/source/tests/Test-IdentifyExternalEmail.ps1 index 623d986..e275bc1 100644 --- a/source/tests/Test-IdentifyExternalEmail.ps1 +++ b/source/tests/Test-IdentifyExternalEmail.ps1 @@ -10,34 +10,44 @@ function Test-IdentifyExternalEmail { #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "6.2.3" } process { - # 6.2.3 (L1) Ensure email from external senders is identified - # Retrieve external sender tagging configuration - $externalInOutlook = Get-ExternalInOutlook - $externalTaggingEnabled = ($externalInOutlook | ForEach-Object { $_.Enabled }) -contains $true + try { + # 6.2.3 (L1) Ensure email from external senders is identified - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $externalTaggingEnabled) { - "External sender tagging is disabled" - } - else { - "N/A" + # Retrieve external sender tagging configuration + $externalInOutlook = Get-ExternalInOutlook + $externalTaggingEnabled = ($externalInOutlook | ForEach-Object { $_.Enabled }) -contains $true + + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $externalTaggingEnabled) { + "External sender tagging is disabled" + } + else { + "N/A" + } + + $details = "Enabled: $($externalTaggingEnabled); AllowList: $($externalInOutlook.AllowList)" + + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $externalTaggingEnabled + Status = if ($externalTaggingEnabled) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" - $details = "Enabled: $($externalTaggingEnabled); AllowList: $($externalInOutlook.AllowList)" - - # Create and populate the CISAuditResult object - $params = @{ - Rec = "6.2.3" - Result = $externalTaggingEnabled - Status = if ($externalTaggingEnabled) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-LinkSharingRestrictions.ps1 b/source/tests/Test-LinkSharingRestrictions.ps1 index b117da3..ad106bf 100644 --- a/source/tests/Test-LinkSharingRestrictions.ps1 +++ b/source/tests/Test-LinkSharingRestrictions.ps1 @@ -10,34 +10,44 @@ function Test-LinkSharingRestrictions { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "7.2.7" } process { - # 7.2.7 (L1) Ensure link sharing is restricted in SharePoint and OneDrive + try { + # 7.2.7 (L1) Ensure link sharing is restricted in SharePoint and OneDrive - # Retrieve link sharing configuration for SharePoint and OneDrive - $SPOTenantLinkSharing = Get-SPOTenant | Select-Object DefaultSharingLinkType - $isLinkSharingRestricted = $SPOTenantLinkSharing.DefaultSharingLinkType -eq 'Direct' # Or 'SpecificPeople' as per the recommendation + # Retrieve link sharing configuration for SharePoint and OneDrive + $SPOTenantLinkSharing = Get-SPOTenant | Select-Object DefaultSharingLinkType + $isLinkSharingRestricted = $SPOTenantLinkSharing.DefaultSharingLinkType -eq 'Direct' # Or 'SpecificPeople' as per the recommendation + + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $isLinkSharingRestricted) { + "Link sharing is not restricted to 'Specific people'. Current setting: $($SPOTenantLinkSharing.DefaultSharingLinkType)" + } + else { + "N/A" + } + + $details = "DefaultSharingLinkType: $($SPOTenantLinkSharing.DefaultSharingLinkType)" + + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $isLinkSharingRestricted + Status = if ($isLinkSharingRestricted) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $isLinkSharingRestricted) { - "Link sharing is not restricted to 'Specific people'. Current setting: $($SPOTenantLinkSharing.DefaultSharingLinkType)" - } - else { - "N/A" } + catch { + Write-Error "An error occurred during the test: $_" - $details = "DefaultSharingLinkType: $($SPOTenantLinkSharing.DefaultSharingLinkType)" - - # Create and populate the CISAuditResult object - $params = @{ - Rec = "7.2.7" - Result = $isLinkSharingRestricted - Status = if ($isLinkSharingRestricted) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-MailTipsEnabled.ps1 b/source/tests/Test-MailTipsEnabled.ps1 index 12224c0..d6c2684 100644 --- a/source/tests/Test-MailTipsEnabled.ps1 +++ b/source/tests/Test-MailTipsEnabled.ps1 @@ -11,40 +11,49 @@ function Test-MailTipsEnabled { # Initialization code, if needed $auditResult = [CISAuditResult]::new() + $recnum = "6.5.2" } process { - # 6.5.2 (L2) Ensure MailTips are enabled for end users + try { + # 6.5.2 (L2) Ensure MailTips are enabled for end users - # Retrieve organization configuration for MailTips settings - $orgConfig = Get-OrganizationConfig | Select-Object MailTipsAllTipsEnabled, MailTipsExternalRecipientsTipsEnabled, MailTipsGroupMetricsEnabled, MailTipsLargeAudienceThreshold - $allTipsEnabled = $orgConfig.MailTipsAllTipsEnabled -and $orgConfig.MailTipsGroupMetricsEnabled -and $orgConfig.MailTipsLargeAudienceThreshold -eq 25 - $externalRecipientsTipsEnabled = $orgConfig.MailTipsExternalRecipientsTipsEnabled + # Retrieve organization configuration for MailTips settings + $orgConfig = Get-OrganizationConfig | Select-Object MailTipsAllTipsEnabled, MailTipsExternalRecipientsTipsEnabled, MailTipsGroupMetricsEnabled, MailTipsLargeAudienceThreshold + $allTipsEnabled = $orgConfig.MailTipsAllTipsEnabled -and $orgConfig.MailTipsGroupMetricsEnabled -and $orgConfig.MailTipsLargeAudienceThreshold -eq 25 + $externalRecipientsTipsEnabled = $orgConfig.MailTipsExternalRecipientsTipsEnabled - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not ($allTipsEnabled -and $externalRecipientsTipsEnabled)) { - "One or more MailTips settings are not configured as required." - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not ($allTipsEnabled -and $externalRecipientsTipsEnabled)) { + "One or more MailTips settings are not configured as required." + } + else { + "N/A" + } - $details = if ($allTipsEnabled -and $externalRecipientsTipsEnabled) { - "MailTipsAllTipsEnabled: $($orgConfig.MailTipsAllTipsEnabled); MailTipsExternalRecipientsTipsEnabled: $($orgConfig.MailTipsExternalRecipientsTipsEnabled); MailTipsGroupMetricsEnabled: $($orgConfig.MailTipsGroupMetricsEnabled); MailTipsLargeAudienceThreshold: $($orgConfig.MailTipsLargeAudienceThreshold)" - } - else { - "One or more MailTips settings are not configured as required." - } + $details = if ($allTipsEnabled -and $externalRecipientsTipsEnabled) { + "MailTipsAllTipsEnabled: $($orgConfig.MailTipsAllTipsEnabled); MailTipsExternalRecipientsTipsEnabled: $($orgConfig.MailTipsExternalRecipientsTipsEnabled); MailTipsGroupMetricsEnabled: $($orgConfig.MailTipsGroupMetricsEnabled); MailTipsLargeAudienceThreshold: $($orgConfig.MailTipsLargeAudienceThreshold)" + } + else { + "One or more MailTips settings are not configured as required." + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "6.5.2" - Result = $allTipsEnabled -and $externalRecipientsTipsEnabled - Status = if ($allTipsEnabled -and $externalRecipientsTipsEnabled) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $allTipsEnabled -and $externalRecipientsTipsEnabled + Status = if ($allTipsEnabled -and $externalRecipientsTipsEnabled) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-MailboxAuditingE3.ps1 b/source/tests/Test-MailboxAuditingE3.ps1 index 79373b7..eac96d6 100644 --- a/source/tests/Test-MailboxAuditingE3.ps1 +++ b/source/tests/Test-MailboxAuditingE3.ps1 @@ -19,15 +19,17 @@ function Test-MailboxAuditingE3 { $allFailures = @() $allUsers = Get-AzureADUser -All $true $processedUsers = @{} # Dictionary to track processed users + $recnum = "6.1.2" } process { - foreach ($user in $allUsers) { - if ($processedUsers.ContainsKey($user.UserPrincipalName)) { - Write-Verbose "Skipping already processed user: $($user.UserPrincipalName)" - continue - } - try { + try { + foreach ($user in $allUsers) { + if ($processedUsers.ContainsKey($user.UserPrincipalName)) { + Write-Verbose "Skipping already processed user: $($user.UserPrincipalName)" + continue + } + $licenseDetails = Get-MgUserLicenseDetail -UserId $user.UserPrincipalName $hasOfficeE3 = ($licenseDetails | Where-Object { $_.SkuPartNumber -in $e3SkuPartNumbers }).Count -gt 0 Write-Verbose "Evaluating user $($user.UserPrincipalName) for Office E3 license." @@ -61,24 +63,28 @@ function Test-MailboxAuditingE3 { $processedUsers[$user.UserPrincipalName] = $true } } - catch { - Write-Warning "Could not retrieve license details for user $($user.UserPrincipalName): $_" + + # Prepare failure reasons and details based on compliance + $failureReasons = if ($allFailures.Count -eq 0) { "N/A" } else { "Audit issues detected." } + $details = if ($allFailures.Count -eq 0) { "All Office E3 users have correct mailbox audit settings." } else { $allFailures -join " | " } + + # Populate the audit result + $params = @{ + Rec = $recnum + Result = $allFailures.Count -eq 0 + Status = if ($allFailures.Count -eq 0) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons } - } + $auditResult = Initialize-CISAuditResult @params - # Prepare failure reasons and details based on compliance - $failureReasons = if ($allFailures.Count -eq 0) { "N/A" } else { "Audit issues detected." } - $details = if ($allFailures.Count -eq 0) { "All Office E3 users have correct mailbox audit settings." } else { $allFailures -join " | " } - - # Populate the audit result - $params = @{ - Rec = "6.1.2" - Result = $allFailures.Count -eq 0 - Status = if ($allFailures.Count -eq 0) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons } - $auditResult = Initialize-CISAuditResult @params + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } } end { diff --git a/source/tests/Test-MailboxAuditingE5.ps1 b/source/tests/Test-MailboxAuditingE5.ps1 index 8f6796c..3c5e949 100644 --- a/source/tests/Test-MailboxAuditingE5.ps1 +++ b/source/tests/Test-MailboxAuditingE5.ps1 @@ -20,15 +20,17 @@ function Test-MailboxAuditingE5 { $allFailures = @() $allUsers = Get-AzureADUser -All $true $processedUsers = @{} # Dictionary to track processed users + $recnum = "6.1.3" } process { + try { foreach ($user in $allUsers) { if ($processedUsers.ContainsKey($user.UserPrincipalName)) { continue } - try { + $licenseDetails = Get-MgUserLicenseDetail -UserId $user.UserPrincipalName $hasOfficeE5 = ($licenseDetails | Where-Object { $_.SkuPartNumber -in $e5SkuPartNumbers }).Count -gt 0 Write-Verbose "Evaluating user $($user.UserPrincipalName) for Office E5 license." @@ -66,10 +68,7 @@ function Test-MailboxAuditingE5 { # Adding verbose output to indicate the user does not have an E5 license Write-Verbose "User $($user.UserPrincipalName) does not have an Office E5 license." } - } - catch { - Write-Warning "Could not retrieve license details for user $($user.UserPrincipalName): $_" - } + } # Prepare failure reasons and details based on compliance @@ -78,7 +77,7 @@ function Test-MailboxAuditingE5 { # Populate the audit result $params = @{ - Rec = "6.1.3" + Rec = $recnum Result = $allFailures.Count -eq 0 Status = if ($allFailures.Count -eq 0) { "Pass" } else { "Fail" } Details = $details @@ -86,6 +85,13 @@ function Test-MailboxAuditingE5 { } $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } + } end { return $auditResult diff --git a/source/tests/Test-ManagedApprovedPublicGroups.ps1 b/source/tests/Test-ManagedApprovedPublicGroups.ps1 index 80fb4fa..d471042 100644 --- a/source/tests/Test-ManagedApprovedPublicGroups.ps1 +++ b/source/tests/Test-ManagedApprovedPublicGroups.ps1 @@ -9,40 +9,48 @@ function Test-ManagedApprovedPublicGroups { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed - + $recnum = "1.2.1" } process { - # 1.2.1 (L2) Ensure that only organizationally managed/approved public groups exist (Automated) + try { + # 1.2.1 (L2) Ensure that only organizationally managed/approved public groups exist (Automated) - # Retrieve all public groups - $allGroups = Get-MgGroup -All | Where-Object { $_.Visibility -eq "Public" } | Select-Object DisplayName, Visibility + # Retrieve all public groups + $allGroups = Get-MgGroup -All | Where-Object { $_.Visibility -eq "Public" } | Select-Object DisplayName, Visibility - # Prepare failure reasons and details based on compliance - $failureReasons = if ($null -ne $allGroups -and $allGroups.Count -gt 0) { - "There are public groups present that are not organizationally managed/approved." - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if ($null -ne $allGroups -and $allGroups.Count -gt 0) { + "There are public groups present that are not organizationally managed/approved." + } + else { + "N/A" + } - $details = if ($null -eq $allGroups -or $allGroups.Count -eq 0) { - "No public groups found." - } - else { - $groupDetails = $allGroups | ForEach-Object { $_.DisplayName + " (" + $_.Visibility + ")" } - "Public groups found: $($groupDetails -join ', ')" - } + $details = if ($null -eq $allGroups -or $allGroups.Count -eq 0) { + "No public groups found." + } + else { + $groupDetails = $allGroups | ForEach-Object { $_.DisplayName + " (" + $_.Visibility + ")" } + "Public groups found: $($groupDetails -join ', ')" + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "1.2.1" - Result = $null -eq $allGroups -or $allGroups.Count -eq 0 - Status = if ($null -eq $allGroups -or $allGroups.Count -eq 0) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $null -eq $allGroups -or $allGroups.Count -eq 0 + Status = if ($null -eq $allGroups -or $allGroups.Count -eq 0) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-MeetingChatNoAnonymous.ps1 b/source/tests/Test-MeetingChatNoAnonymous.ps1 index 29428b1..b7f1f98 100644 --- a/source/tests/Test-MeetingChatNoAnonymous.ps1 +++ b/source/tests/Test-MeetingChatNoAnonymous.ps1 @@ -9,36 +9,45 @@ function Test-MeetingChatNoAnonymous { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "8.5.5" } process { - # 8.5.5 (L2) Ensure meeting chat does not allow anonymous users + try { + # 8.5.5 (L2) Ensure meeting chat does not allow anonymous users - # Connect to Teams PowerShell using Connect-MicrosoftTeams + # Connect to Teams PowerShell using Connect-MicrosoftTeams - # Retrieve the Teams meeting policy for meeting chat - $CsTeamsMeetingPolicyChat = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property MeetingChatEnabledType - $chatAnonDisabled = $CsTeamsMeetingPolicyChat.MeetingChatEnabledType -eq 'EnabledExceptAnonymous' + # Retrieve the Teams meeting policy for meeting chat + $CsTeamsMeetingPolicyChat = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property MeetingChatEnabledType + $chatAnonDisabled = $CsTeamsMeetingPolicyChat.MeetingChatEnabledType -eq 'EnabledExceptAnonymous' - # Prepare failure reasons and details based on compliance - $failureReasons = if ($chatAnonDisabled) { - "N/A" - } - else { - "Meeting chat allows anonymous users" + # Prepare failure reasons and details based on compliance + $failureReasons = if ($chatAnonDisabled) { + "N/A" + } + else { + "Meeting chat allows anonymous users" + } + + $details = "MeetingChatEnabledType is set to $($CsTeamsMeetingPolicyChat.MeetingChatEnabledType)" + + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $chatAnonDisabled + Status = if ($chatAnonDisabled) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" - $details = "MeetingChatEnabledType is set to $($CsTeamsMeetingPolicyChat.MeetingChatEnabledType)" - - # Create and populate the CISAuditResult object - $params = @{ - Rec = "8.5.5" - Result = $chatAnonDisabled - Status = if ($chatAnonDisabled) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-ModernAuthExchangeOnline.ps1 b/source/tests/Test-ModernAuthExchangeOnline.ps1 index 811679b..5210b18 100644 --- a/source/tests/Test-ModernAuthExchangeOnline.ps1 +++ b/source/tests/Test-ModernAuthExchangeOnline.ps1 @@ -9,6 +9,7 @@ function Test-ModernAuthExchangeOnline { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "6.5.1" } process { @@ -30,18 +31,22 @@ function Test-ModernAuthExchangeOnline { # Create and populate the CISAuditResult object $params = @{ - Rec = "6.5.1" - Result = $orgConfig.OAuth2ClientProfileEnabled - Status = if ($orgConfig.OAuth2ClientProfileEnabled) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + Rec = $recnum + Result = $orgConfig.OAuth2ClientProfileEnabled + Status = if ($orgConfig.OAuth2ClientProfileEnabled) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons } $auditResult = Initialize-CISAuditResult @params } catch { - Write-Error "An error occurred while testing modern authentication for Exchange Online: $_" + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } + } end { diff --git a/source/tests/Test-ModernAuthSharePoint.ps1 b/source/tests/Test-ModernAuthSharePoint.ps1 index 3f7ae76..cb51f46 100644 --- a/source/tests/Test-ModernAuthSharePoint.ps1 +++ b/source/tests/Test-ModernAuthSharePoint.ps1 @@ -9,32 +9,41 @@ function Test-ModernAuthSharePoint { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "7.2.1" } process { - # 7.2.1 (L1) Ensure modern authentication for SharePoint applications is required - $SPOTenant = Get-SPOTenant | Select-Object -Property LegacyAuthProtocolsEnabled - $modernAuthForSPRequired = -not $SPOTenant.LegacyAuthProtocolsEnabled + try { + # 7.2.1 (L1) Ensure modern authentication for SharePoint applications is required + $SPOTenant = Get-SPOTenant | Select-Object -Property LegacyAuthProtocolsEnabled + $modernAuthForSPRequired = -not $SPOTenant.LegacyAuthProtocolsEnabled - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $modernAuthForSPRequired) { - "Legacy authentication protocols are enabled" - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $modernAuthForSPRequired) { + "Legacy authentication protocols are enabled" + } + else { + "N/A" + } - $details = "LegacyAuthProtocolsEnabled: $($SPOTenant.LegacyAuthProtocolsEnabled)" + $details = "LegacyAuthProtocolsEnabled: $($SPOTenant.LegacyAuthProtocolsEnabled)" - # Create and populate the CISAuditResult object - $params = @{ - Rec = "7.2.1" - Result = $modernAuthForSPRequired - Status = if ($modernAuthForSPRequired) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $modernAuthForSPRequired + Status = if ($modernAuthForSPRequired) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-NoAnonymousMeetingJoin.ps1 b/source/tests/Test-NoAnonymousMeetingJoin.ps1 index fbeb7dd..ce430ca 100644 --- a/source/tests/Test-NoAnonymousMeetingJoin.ps1 +++ b/source/tests/Test-NoAnonymousMeetingJoin.ps1 @@ -9,9 +9,11 @@ function Test-NoAnonymousMeetingJoin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "8.5.1" } process { + try { # 8.5.1 (L2) Ensure anonymous users can't join a meeting # Connect to Teams PowerShell using Connect-MicrosoftTeams @@ -31,7 +33,7 @@ function Test-NoAnonymousMeetingJoin { # Create and populate the CISAuditResult object $params = @{ - Rec = "8.5.1" + Rec = $recnum Result = -not $allowAnonymousUsersToJoinMeeting Status = if (-not $allowAnonymousUsersToJoinMeeting) { "Pass" } else { "Fail" } Details = $details @@ -39,6 +41,13 @@ function Test-NoAnonymousMeetingJoin { } $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } + } end { # Return the audit result diff --git a/source/tests/Test-NoAnonymousMeetingStart.ps1 b/source/tests/Test-NoAnonymousMeetingStart.ps1 index 01c680f..d9d1441 100644 --- a/source/tests/Test-NoAnonymousMeetingStart.ps1 +++ b/source/tests/Test-NoAnonymousMeetingStart.ps1 @@ -9,35 +9,44 @@ function Test-NoAnonymousMeetingStart { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "8.5.2" } process { - # 8.5.2 (L1) Ensure anonymous users and dial-in callers can't start a meeting + try { + # 8.5.2 (L1) Ensure anonymous users and dial-in callers can't start a meeting - # Connect to Teams PowerShell using Connect-MicrosoftTeams + # Connect to Teams PowerShell using Connect-MicrosoftTeams - $CsTeamsMeetingPolicyAnonymous = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AllowAnonymousUsersToStartMeeting - $anonymousStartDisabled = -not $CsTeamsMeetingPolicyAnonymous.AllowAnonymousUsersToStartMeeting + $CsTeamsMeetingPolicyAnonymous = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AllowAnonymousUsersToStartMeeting + $anonymousStartDisabled = -not $CsTeamsMeetingPolicyAnonymous.AllowAnonymousUsersToStartMeeting - # Prepare failure reasons and details based on compliance - $failureReasons = if ($anonymousStartDisabled) { - "N/A" - } - else { - "Anonymous users and dial-in callers can start a meeting" + # Prepare failure reasons and details based on compliance + $failureReasons = if ($anonymousStartDisabled) { + "N/A" + } + else { + "Anonymous users and dial-in callers can start a meeting" + } + + $details = "AllowAnonymousUsersToStartMeeting is set to $($CsTeamsMeetingPolicyAnonymous.AllowAnonymousUsersToStartMeeting)" + + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $anonymousStartDisabled + Status = if ($anonymousStartDisabled) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" - $details = "AllowAnonymousUsersToStartMeeting is set to $($CsTeamsMeetingPolicyAnonymous.AllowAnonymousUsersToStartMeeting)" - - # Create and populate the CISAuditResult object - $params = @{ - Rec = "8.5.2" - Result = $anonymousStartDisabled - Status = if ($anonymousStartDisabled) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-NoWhitelistDomains.ps1 b/source/tests/Test-NoWhitelistDomains.ps1 index 820ff7b..92652be 100644 --- a/source/tests/Test-NoWhitelistDomains.ps1 +++ b/source/tests/Test-NoWhitelistDomains.ps1 @@ -9,39 +9,48 @@ function Test-NoWhitelistDomains { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "6.2.2" } process { - # 6.2.2 (L1) Ensure mail transport rules do not whitelist specific domains + try { + # 6.2.2 (L1) Ensure mail transport rules do not whitelist specific domains - # Retrieve transport rules that whitelist specific domains - $whitelistedRules = Get-TransportRule | Where-Object { $_.SetSCL -eq -1 -and $null -ne $_.SenderDomainIs } + # Retrieve transport rules that whitelist specific domains + $whitelistedRules = Get-TransportRule | Where-Object { $_.SetSCL -eq -1 -and $null -ne $_.SenderDomainIs } - # Prepare failure reasons and details based on compliance - $failureReasons = if ($whitelistedRules) { - "There are transport rules whitelisting specific domains." - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if ($whitelistedRules) { + "There are transport rules whitelisting specific domains." + } + else { + "N/A" + } - $details = if ($whitelistedRules) { - $ruleDetails = $whitelistedRules | ForEach-Object { "{0}: {1}" -f $_.Name, ($_.SenderDomainIs -join ', ') } - "Whitelisted Rules: $($ruleDetails -join '; ')" - } - else { - "No transport rules whitelisting specific domains found." - } + $details = if ($whitelistedRules) { + $ruleDetails = $whitelistedRules | ForEach-Object { "{0}: {1}" -f $_.Name, ($_.SenderDomainIs -join ', ') } + "Whitelisted Rules: $($ruleDetails -join '; ')" + } + else { + "No transport rules whitelisting specific domains found." + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "6.2.2" - Result = -not $whitelistedRules - Status = if ($whitelistedRules) { "Fail" } else { "Pass" } - Details = $details - FailureReason = $failureReasons + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = -not $whitelistedRules + Status = if ($whitelistedRules) { "Fail" } else { "Pass" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-NotifyMalwareInternal.ps1 b/source/tests/Test-NotifyMalwareInternal.ps1 index ba962d6..e09a4b6 100644 --- a/source/tests/Test-NotifyMalwareInternal.ps1 +++ b/source/tests/Test-NotifyMalwareInternal.ps1 @@ -9,9 +9,11 @@ function Test-NotifyMalwareInternal { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "2.1.3" } process { + try { # 2.1.3 Ensure notifications for internal users sending malware is Enabled # Retrieve all 'Custom' malware filter policies and check notification settings @@ -44,7 +46,7 @@ function Test-NotifyMalwareInternal { # Create and populate the CISAuditResult object $params = @{ - Rec = "2.1.3" + Rec = $recnum Result = $result Status = if ($result) { "Pass" } else { "Fail" } Details = $details @@ -52,6 +54,13 @@ function Test-NotifyMalwareInternal { } $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } + } end { # Return the audit result diff --git a/source/tests/Test-OneDriveContentRestrictions.ps1 b/source/tests/Test-OneDriveContentRestrictions.ps1 index 7a69c37..136f951 100644 --- a/source/tests/Test-OneDriveContentRestrictions.ps1 +++ b/source/tests/Test-OneDriveContentRestrictions.ps1 @@ -9,39 +9,48 @@ function Test-OneDriveContentRestrictions { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "7.2.4" } process { - # 7.2.4 (L2) Ensure OneDrive content sharing is restricted + try { + # 7.2.4 (L2) Ensure OneDrive content sharing is restricted - # Retrieve OneDrive sharing capability settings - $SPOTenant = Get-SPOTenant | Select-Object OneDriveSharingCapability - $isOneDriveSharingRestricted = $SPOTenant.OneDriveSharingCapability -eq 'Disabled' + # Retrieve OneDrive sharing capability settings + $SPOTenant = Get-SPOTenant | Select-Object OneDriveSharingCapability + $isOneDriveSharingRestricted = $SPOTenant.OneDriveSharingCapability -eq 'Disabled' - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $isOneDriveSharingRestricted) { - "OneDrive content sharing is not restricted to 'Disabled'. Current setting: $($SPOTenant.OneDriveSharingCapability)" - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $isOneDriveSharingRestricted) { + "OneDrive content sharing is not restricted to 'Disabled'. Current setting: $($SPOTenant.OneDriveSharingCapability)" + } + else { + "N/A" + } - $details = if ($isOneDriveSharingRestricted) { - "OneDrive content sharing is restricted." - } - else { - "OneDriveSharingCapability: $($SPOTenant.OneDriveSharingCapability)" - } + $details = if ($isOneDriveSharingRestricted) { + "OneDrive content sharing is restricted." + } + else { + "OneDriveSharingCapability: $($SPOTenant.OneDriveSharingCapability)" + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "7.2.4" - Result = $isOneDriveSharingRestricted - Status = if ($isOneDriveSharingRestricted) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $isOneDriveSharingRestricted + Status = if ($isOneDriveSharingRestricted) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-OneDriveSyncRestrictions.ps1 b/source/tests/Test-OneDriveSyncRestrictions.ps1 index 5357cda..dbea815 100644 --- a/source/tests/Test-OneDriveSyncRestrictions.ps1 +++ b/source/tests/Test-OneDriveSyncRestrictions.ps1 @@ -9,39 +9,48 @@ function Test-OneDriveSyncRestrictions { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "7.3.2" } process { - # 7.3.2 (L2) Ensure OneDrive sync is restricted for unmanaged devices + try { + # 7.3.2 (L2) Ensure OneDrive sync is restricted for unmanaged devices - # Retrieve OneDrive sync client restriction settings - $SPOTenantSyncClientRestriction = Get-SPOTenantSyncClientRestriction | Select-Object TenantRestrictionEnabled, AllowedDomainList - $isSyncRestricted = $SPOTenantSyncClientRestriction.TenantRestrictionEnabled -and $SPOTenantSyncClientRestriction.AllowedDomainList + # Retrieve OneDrive sync client restriction settings + $SPOTenantSyncClientRestriction = Get-SPOTenantSyncClientRestriction | Select-Object TenantRestrictionEnabled, AllowedDomainList + $isSyncRestricted = $SPOTenantSyncClientRestriction.TenantRestrictionEnabled -and $SPOTenantSyncClientRestriction.AllowedDomainList - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $isSyncRestricted) { - "OneDrive sync is not restricted to managed devices. TenantRestrictionEnabled should be True and AllowedDomainList should contain trusted domains GUIDs." - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $isSyncRestricted) { + "OneDrive sync is not restricted to managed devices. TenantRestrictionEnabled should be True and AllowedDomainList should contain trusted domains GUIDs." + } + else { + "N/A" + } - $details = if ($isSyncRestricted) { - "OneDrive sync is restricted for unmanaged devices." - } - else { - "TenantRestrictionEnabled: $($SPOTenantSyncClientRestriction.TenantRestrictionEnabled); AllowedDomainList: $($SPOTenantSyncClientRestriction.AllowedDomainList -join ', ')" - } + $details = if ($isSyncRestricted) { + "OneDrive sync is restricted for unmanaged devices." + } + else { + "TenantRestrictionEnabled: $($SPOTenantSyncClientRestriction.TenantRestrictionEnabled); AllowedDomainList: $($SPOTenantSyncClientRestriction.AllowedDomainList -join ', ')" + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "7.3.2" - Result = $isSyncRestricted - Status = if ($isSyncRestricted) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $isSyncRestricted + Status = if ($isSyncRestricted) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-OrgOnlyBypassLobby.ps1 b/source/tests/Test-OrgOnlyBypassLobby.ps1 index 7a7e668..1f6a6b3 100644 --- a/source/tests/Test-OrgOnlyBypassLobby.ps1 +++ b/source/tests/Test-OrgOnlyBypassLobby.ps1 @@ -9,41 +9,50 @@ function Test-OrgOnlyBypassLobby { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "8.5.3" } process { - # 8.5.3 (L1) Ensure only people in my org can bypass the lobby + try { + # 8.5.3 (L1) Ensure only people in my org can bypass the lobby - # Connect to Teams PowerShell using Connect-MicrosoftTeams + # Connect to Teams PowerShell using Connect-MicrosoftTeams - # Retrieve the Teams meeting policy for lobby bypass settings - $CsTeamsMeetingPolicyLobby = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AutoAdmittedUsers - $lobbyBypassRestricted = $CsTeamsMeetingPolicyLobby.AutoAdmittedUsers -eq 'EveryoneInCompanyExcludingGuests' + # Retrieve the Teams meeting policy for lobby bypass settings + $CsTeamsMeetingPolicyLobby = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AutoAdmittedUsers + $lobbyBypassRestricted = $CsTeamsMeetingPolicyLobby.AutoAdmittedUsers -eq 'EveryoneInCompanyExcludingGuests' - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $lobbyBypassRestricted) { - "External participants can bypass the lobby" - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $lobbyBypassRestricted) { + "External participants can bypass the lobby" + } + else { + "N/A" + } - $details = if ($lobbyBypassRestricted) { - "Only people in the organization can bypass the lobby." - } - else { - "AutoAdmittedUsers is set to $($CsTeamsMeetingPolicyLobby.AutoAdmittedUsers)" - } + $details = if ($lobbyBypassRestricted) { + "Only people in the organization can bypass the lobby." + } + else { + "AutoAdmittedUsers is set to $($CsTeamsMeetingPolicyLobby.AutoAdmittedUsers)" + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "8.5.3" - Result = $lobbyBypassRestricted - Status = if ($lobbyBypassRestricted) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $lobbyBypassRestricted + Status = if ($lobbyBypassRestricted) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-OrganizersPresent.ps1 b/source/tests/Test-OrganizersPresent.ps1 index 337e671..e0215f5 100644 --- a/source/tests/Test-OrganizersPresent.ps1 +++ b/source/tests/Test-OrganizersPresent.ps1 @@ -9,9 +9,11 @@ function Test-OrganizersPresent { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "8.5.6" } process { + try { # 8.5.6 (L2) Ensure only organizers and co-organizers can present # Connect to Teams PowerShell using Connect-MicrosoftTeams @@ -37,7 +39,7 @@ function Test-OrganizersPresent { # Create and populate the CISAuditResult object $params = @{ - Rec = "8.5.6" + Rec = $recnum Result = $presenterRoleRestricted Status = if ($presenterRoleRestricted) { "Pass" } else { "Fail" } Details = $details @@ -45,6 +47,13 @@ function Test-OrganizersPresent { } $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } + } end { # Return the audit result diff --git a/source/tests/Test-PasswordHashSync.ps1 b/source/tests/Test-PasswordHashSync.ps1 index 583d65e..42afa1c 100644 --- a/source/tests/Test-PasswordHashSync.ps1 +++ b/source/tests/Test-PasswordHashSync.ps1 @@ -9,9 +9,11 @@ function Test-PasswordHashSync { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "5.1.8.1" } process { + try { # 5.1.8.1 (L1) Ensure password hash sync is enabled for hybrid deployments # Pass if OnPremisesSyncEnabled is True. Fail otherwise. @@ -31,7 +33,7 @@ function Test-PasswordHashSync { # Create and populate the CISAuditResult object $params = @{ - Rec = "5.1.8.1" + Rec = $recnum Result = $hashSyncResult Status = if ($hashSyncResult) { "Pass" } else { "Fail" } Details = $details @@ -39,6 +41,13 @@ function Test-PasswordHashSync { } $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } + } end { # Return the audit result diff --git a/source/tests/Test-PasswordNeverExpirePolicy.ps1 b/source/tests/Test-PasswordNeverExpirePolicy.ps1 index 530d481..63f2166 100644 --- a/source/tests/Test-PasswordNeverExpirePolicy.ps1 +++ b/source/tests/Test-PasswordNeverExpirePolicy.ps1 @@ -10,34 +10,43 @@ function Test-PasswordNeverExpirePolicy { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "1.3.1" } process { - # 1.3.1 (L1) Ensure the 'Password expiration policy' is set to 'Set passwords to never expire' - # Pass if PasswordValidityPeriodInDays is 0. Fail otherwise. + try { + # 1.3.1 (L1) Ensure the 'Password expiration policy' is set to 'Set passwords to never expire' + # Pass if PasswordValidityPeriodInDays is 0. Fail otherwise. - # Retrieve password expiration policy - $passwordPolicy = Get-MgDomain -DomainId $DomainName | Select-Object -ExpandProperty PasswordValidityPeriodInDays + # Retrieve password expiration policy + $passwordPolicy = Get-MgDomain -DomainId $DomainName | Select-Object -ExpandProperty PasswordValidityPeriodInDays - # Prepare failure reasons and details based on compliance - $failureReasons = if ($passwordPolicy -ne 0) { - "Password expiration is not set to never expire" - } - else { - "N/A" + # Prepare failure reasons and details based on compliance + $failureReasons = if ($passwordPolicy -ne 0) { + "Password expiration is not set to never expire" + } + else { + "N/A" + } + + $details = "Validity Period: $passwordPolicy days" + + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $passwordPolicy -eq 0 + Status = if ($passwordPolicy -eq 0) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" - $details = "Validity Period: $passwordPolicy days" - - # Create and populate the CISAuditResult object - $params = @{ - Rec = "1.3.1" - Result = $passwordPolicy -eq 0 - Status = if ($passwordPolicy -eq 0) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-ReauthWithCode.ps1 b/source/tests/Test-ReauthWithCode.ps1 index 28ac0f0..5274b46 100644 --- a/source/tests/Test-ReauthWithCode.ps1 +++ b/source/tests/Test-ReauthWithCode.ps1 @@ -9,34 +9,43 @@ function Test-ReauthWithCode { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "7.2.10" } process { - # 7.2.10 (L1) Ensure reauthentication with verification code is restricted + try { + # 7.2.10 (L1) Ensure reauthentication with verification code is restricted - # Retrieve reauthentication settings for SharePoint Online - $SPOTenantReauthentication = Get-SPOTenant | Select-Object EmailAttestationRequired, EmailAttestationReAuthDays - $isReauthenticationRestricted = $SPOTenantReauthentication.EmailAttestationRequired -and $SPOTenantReauthentication.EmailAttestationReAuthDays -le 15 + # Retrieve reauthentication settings for SharePoint Online + $SPOTenantReauthentication = Get-SPOTenant | Select-Object EmailAttestationRequired, EmailAttestationReAuthDays + $isReauthenticationRestricted = $SPOTenantReauthentication.EmailAttestationRequired -and $SPOTenantReauthentication.EmailAttestationReAuthDays -le 15 - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $isReauthenticationRestricted) { - "Reauthentication with verification code does not require reauthentication within 15 days or less." - } - else { - "N/A" + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $isReauthenticationRestricted) { + "Reauthentication with verification code does not require reauthentication within 15 days or less." + } + else { + "N/A" + } + + $details = "EmailAttestationRequired: $($SPOTenantReauthentication.EmailAttestationRequired); EmailAttestationReAuthDays: $($SPOTenantReauthentication.EmailAttestationReAuthDays)" + + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $isReauthenticationRestricted + Status = if ($isReauthenticationRestricted) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" - $details = "EmailAttestationRequired: $($SPOTenantReauthentication.EmailAttestationRequired); EmailAttestationReAuthDays: $($SPOTenantReauthentication.EmailAttestationReAuthDays)" - - # Create and populate the CISAuditResult object - $params = @{ - Rec = "7.2.10" - Result = $isReauthenticationRestricted - Status = if ($isReauthenticationRestricted) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-ReportSecurityInTeams.ps1 b/source/tests/Test-ReportSecurityInTeams.ps1 index f79cf17..cc9c205 100644 --- a/source/tests/Test-ReportSecurityInTeams.ps1 +++ b/source/tests/Test-ReportSecurityInTeams.ps1 @@ -9,44 +9,53 @@ function Test-ReportSecurityInTeams { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "8.6.1" } process { - # 8.6.1 (L1) Ensure users can report security concerns in Teams + try { + # 8.6.1 (L1) Ensure users can report security concerns in Teams - # Retrieve the necessary settings for Teams and Exchange Online - $CsTeamsMessagingPolicy = Get-CsTeamsMessagingPolicy -Identity Global | Select-Object -Property AllowSecurityEndUserReporting - $ReportSubmissionPolicy = Get-ReportSubmissionPolicy | Select-Object -Property ReportJunkToCustomizedAddress, ReportNotJunkToCustomizedAddress, ReportPhishToCustomizedAddress, ReportChatMessageToCustomizedAddressEnabled + # Retrieve the necessary settings for Teams and Exchange Online + $CsTeamsMessagingPolicy = Get-CsTeamsMessagingPolicy -Identity Global | Select-Object -Property AllowSecurityEndUserReporting + $ReportSubmissionPolicy = Get-ReportSubmissionPolicy | Select-Object -Property ReportJunkToCustomizedAddress, ReportNotJunkToCustomizedAddress, ReportPhishToCustomizedAddress, ReportChatMessageToCustomizedAddressEnabled - $securityReportEnabled = $CsTeamsMessagingPolicy.AllowSecurityEndUserReporting -and - $ReportSubmissionPolicy.ReportJunkToCustomizedAddress -and - $ReportSubmissionPolicy.ReportNotJunkToCustomizedAddress -and - $ReportSubmissionPolicy.ReportPhishToCustomizedAddress -and - $ReportSubmissionPolicy.ReportChatMessageToCustomizedAddressEnabled + $securityReportEnabled = $CsTeamsMessagingPolicy.AllowSecurityEndUserReporting -and + $ReportSubmissionPolicy.ReportJunkToCustomizedAddress -and + $ReportSubmissionPolicy.ReportNotJunkToCustomizedAddress -and + $ReportSubmissionPolicy.ReportPhishToCustomizedAddress -and + $ReportSubmissionPolicy.ReportChatMessageToCustomizedAddressEnabled - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $securityReportEnabled) { - "Users cannot report security concerns in Teams due to one or more incorrect settings" - } - else { - "N/A" + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $securityReportEnabled) { + "Users cannot report security concerns in Teams due to one or more incorrect settings" + } + else { + "N/A" + } + + $details = "AllowSecurityEndUserReporting: $($CsTeamsMessagingPolicy.AllowSecurityEndUserReporting); " + + "ReportJunkToCustomizedAddress: $($ReportSubmissionPolicy.ReportJunkToCustomizedAddress); " + + "ReportNotJunkToCustomizedAddress: $($ReportSubmissionPolicy.ReportNotJunkToCustomizedAddress); " + + "ReportPhishToCustomizedAddress: $($ReportSubmissionPolicy.ReportPhishToCustomizedAddress); " + + "ReportChatMessageToCustomizedAddressEnabled: $($ReportSubmissionPolicy.ReportChatMessageToCustomizedAddressEnabled)" + + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $securityReportEnabled + Status = if ($securityReportEnabled) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" - $details = "AllowSecurityEndUserReporting: $($CsTeamsMessagingPolicy.AllowSecurityEndUserReporting); " + - "ReportJunkToCustomizedAddress: $($ReportSubmissionPolicy.ReportJunkToCustomizedAddress); " + - "ReportNotJunkToCustomizedAddress: $($ReportSubmissionPolicy.ReportNotJunkToCustomizedAddress); " + - "ReportPhishToCustomizedAddress: $($ReportSubmissionPolicy.ReportPhishToCustomizedAddress); " + - "ReportChatMessageToCustomizedAddressEnabled: $($ReportSubmissionPolicy.ReportChatMessageToCustomizedAddressEnabled)" - - # Create and populate the CISAuditResult object - $params = @{ - Rec = "8.6.1" - Result = $securityReportEnabled - Status = if ($securityReportEnabled) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-RestrictCustomScripts.ps1 b/source/tests/Test-RestrictCustomScripts.ps1 index 43a8eef..cc3c051 100644 --- a/source/tests/Test-RestrictCustomScripts.ps1 +++ b/source/tests/Test-RestrictCustomScripts.ps1 @@ -9,49 +9,58 @@ function Test-RestrictCustomScripts { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "7.3.4" } process { - # 7.3.4 (L1) Ensure custom script execution is restricted on site collections + try { + # 7.3.4 (L1) Ensure custom script execution is restricted on site collections - # Retrieve all site collections and select necessary properties - $SPOSitesCustomScript = Get-SPOSite -Limit All | Select-Object Title, Url, DenyAddAndCustomizePages + # Retrieve all site collections and select necessary properties + $SPOSitesCustomScript = Get-SPOSite -Limit All | Select-Object Title, Url, DenyAddAndCustomizePages - # Find sites where custom scripts are allowed (DenyAddAndCustomizePages is not 'Enabled') - $customScriptAllowedSites = $SPOSitesCustomScript | Where-Object { $_.DenyAddAndCustomizePages -ne 'Enabled' } + # Find sites where custom scripts are allowed (DenyAddAndCustomizePages is not 'Enabled') + $customScriptAllowedSites = $SPOSitesCustomScript | Where-Object { $_.DenyAddAndCustomizePages -ne 'Enabled' } - # Compliance is true if no sites allow custom scripts - $complianceResult = $customScriptAllowedSites.Count -eq 0 + # Compliance is true if no sites allow custom scripts + $complianceResult = $customScriptAllowedSites.Count -eq 0 - # Gather details for non-compliant sites (where custom scripts are allowed) - $nonCompliantSiteDetails = $customScriptAllowedSites | ForEach-Object { - "$($_.Title) ($($_.Url)): Custom Script Allowed" + # Gather details for non-compliant sites (where custom scripts are allowed) + $nonCompliantSiteDetails = $customScriptAllowedSites | ForEach-Object { + "$($_.Title) ($($_.Url)): Custom Script Allowed" + } + + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $complianceResult) { + "The following site collections allow custom script execution: " + ($nonCompliantSiteDetails -join "; ") + } + else { + "N/A" + } + + $details = if ($complianceResult) { + "All site collections have custom script execution restricted" + } + else { + $nonCompliantSiteDetails -join "; " + } + + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $complianceResult + Status = if ($complianceResult) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $complianceResult) { - "The following site collections allow custom script execution: " + ($nonCompliantSiteDetails -join "; ") + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - else { - "N/A" - } - - $details = if ($complianceResult) { - "All site collections have custom script execution restricted" - } - else { - $nonCompliantSiteDetails -join "; " - } - - # Create and populate the CISAuditResult object - $params = @{ - Rec = "7.3.4" - Result = $complianceResult - Status = if ($complianceResult) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons - } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-RestrictExternalSharing.ps1 b/source/tests/Test-RestrictExternalSharing.ps1 index f1b0568..a974262 100644 --- a/source/tests/Test-RestrictExternalSharing.ps1 +++ b/source/tests/Test-RestrictExternalSharing.ps1 @@ -9,34 +9,43 @@ function Test-RestrictExternalSharing { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "7.2.3" } process { - # 7.2.3 (L1) Ensure external content sharing is restricted + try { + # 7.2.3 (L1) Ensure external content sharing is restricted - # Retrieve the SharingCapability setting for the SharePoint tenant - $SPOTenantSharingCapability = Get-SPOTenant | Select-Object SharingCapability - $isRestricted = $SPOTenantSharingCapability.SharingCapability -in @('ExternalUserSharingOnly', 'ExistingExternalUserSharingOnly', 'Disabled') + # Retrieve the SharingCapability setting for the SharePoint tenant + $SPOTenantSharingCapability = Get-SPOTenant | Select-Object SharingCapability + $isRestricted = $SPOTenantSharingCapability.SharingCapability -in @('ExternalUserSharingOnly', 'ExistingExternalUserSharingOnly', 'Disabled') - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $isRestricted) { - "External content sharing is not adequately restricted. Current setting: $($SPOTenantSharingCapability.SharingCapability)" - } - else { - "N/A" + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $isRestricted) { + "External content sharing is not adequately restricted. Current setting: $($SPOTenantSharingCapability.SharingCapability)" + } + else { + "N/A" + } + + $details = "SharingCapability: $($SPOTenantSharingCapability.SharingCapability)" + + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $isRestricted + Status = if ($isRestricted) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" - $details = "SharingCapability: $($SPOTenantSharingCapability.SharingCapability)" - - # Create and populate the CISAuditResult object - $params = @{ - Rec = "7.2.3" - Result = $isRestricted - Status = if ($isRestricted) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-RestrictOutlookAddins.ps1 b/source/tests/Test-RestrictOutlookAddins.ps1 index 4438b50..1cbcf34 100644 --- a/source/tests/Test-RestrictOutlookAddins.ps1 +++ b/source/tests/Test-RestrictOutlookAddins.ps1 @@ -12,63 +12,72 @@ function Test-RestrictOutlookAddins { $customPolicyFailures = @() $defaultPolicyFailureDetails = @() $relevantRoles = @('My Custom Apps', 'My Marketplace Apps', 'My ReadWriteMailbox Apps') + $recnum = "6.3.1" } process { - # 6.3.1 (L2) Ensure users installing Outlook add-ins is not allowed + try { + # 6.3.1 (L2) Ensure users installing Outlook add-ins is not allowed - # Check all mailboxes for custom policies with unallowed add-ins - $roleAssignmentPolicies = Get-EXOMailbox | Select-Object -Unique RoleAssignmentPolicy + # Check all mailboxes for custom policies with unallowed add-ins + $roleAssignmentPolicies = Get-EXOMailbox | Select-Object -Unique RoleAssignmentPolicy - if ($roleAssignmentPolicies.RoleAssignmentPolicy) { - foreach ($policy in $roleAssignmentPolicies) { - if ($policy.RoleAssignmentPolicy) { - $rolePolicyDetails = Get-RoleAssignmentPolicy -Identity $policy.RoleAssignmentPolicy - $foundRoles = $rolePolicyDetails.AssignedRoles | Where-Object { $_ -in $relevantRoles } - if ($foundRoles) { - $customPolicyFailures += "Policy: $($policy.RoleAssignmentPolicy): Roles: $($foundRoles -join ', ')" + if ($roleAssignmentPolicies.RoleAssignmentPolicy) { + foreach ($policy in $roleAssignmentPolicies) { + if ($policy.RoleAssignmentPolicy) { + $rolePolicyDetails = Get-RoleAssignmentPolicy -Identity $policy.RoleAssignmentPolicy + $foundRoles = $rolePolicyDetails.AssignedRoles | Where-Object { $_ -in $relevantRoles } + if ($foundRoles) { + $customPolicyFailures += "Policy: $($policy.RoleAssignmentPolicy): Roles: $($foundRoles -join ', ')" + } } } } - } - # Check Default Role Assignment Policy - $defaultPolicy = Get-RoleAssignmentPolicy "Default Role Assignment Policy" - $defaultPolicyRoles = $defaultPolicy.AssignedRoles | Where-Object { $_ -in $relevantRoles } - if ($defaultPolicyRoles) { - $defaultPolicyFailureDetails = $defaultPolicyRoles - } + # Check Default Role Assignment Policy + $defaultPolicy = Get-RoleAssignmentPolicy "Default Role Assignment Policy" + $defaultPolicyRoles = $defaultPolicy.AssignedRoles | Where-Object { $_ -in $relevantRoles } + if ($defaultPolicyRoles) { + $defaultPolicyFailureDetails = $defaultPolicyRoles + } - # Prepare result details string - $detailsString = "" - if ($customPolicyFailures) { - $detailsString += "Custom Policy Failures: | " - $detailsString += ($customPolicyFailures -join " | ") - } - else { - $detailsString += "Custom Policy Failures: None | " - } + # Prepare result details string + $detailsString = "" + if ($customPolicyFailures) { + $detailsString += "Custom Policy Failures: | " + $detailsString += ($customPolicyFailures -join " | ") + } + else { + $detailsString += "Custom Policy Failures: None | " + } - $detailsString += "Default Role Assignment Policy: " - if ($defaultPolicyFailureDetails) { - $detailsString += ($defaultPolicyFailureDetails -join ', ') - } - else { - $detailsString += "Compliant" - } + $detailsString += "Default Role Assignment Policy: " + if ($defaultPolicyFailureDetails) { + $detailsString += ($defaultPolicyFailureDetails -join ', ') + } + else { + $detailsString += "Compliant" + } - # Determine result based on findings - $isCompliant = -not ($customPolicyFailures -or $defaultPolicyFailureDetails) + # Determine result based on findings + $isCompliant = -not ($customPolicyFailures -or $defaultPolicyFailureDetails) - # Create and populate the CISAuditResult object - $params = @{ - Rec = "6.3.1" - Result = $isCompliant - Status = if ($isCompliant) { "Pass" } else { "Fail" } - Details = $detailsString - FailureReason = if ($isCompliant) { "N/A" } else { "Unauthorized Outlook add-ins found in custom or default policies." } + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $isCompliant + Status = if ($isCompliant) { "Pass" } else { "Fail" } + Details = $detailsString + FailureReason = if ($isCompliant) { "N/A" } else { "Unauthorized Outlook add-ins found in custom or default policies." } + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-RestrictStorageProvidersOutlook.ps1 b/source/tests/Test-RestrictStorageProvidersOutlook.ps1 index 8400d72..453b367 100644 --- a/source/tests/Test-RestrictStorageProvidersOutlook.ps1 +++ b/source/tests/Test-RestrictStorageProvidersOutlook.ps1 @@ -9,9 +9,11 @@ function Test-RestrictStorageProvidersOutlook { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "6.5.3" } process { + try { # 6.5.3 (L2) Ensure additional storage providers are restricted in Outlook on the web # Retrieve all OwaMailbox policies @@ -38,7 +40,7 @@ function Test-RestrictStorageProvidersOutlook { # Create and populate the CISAuditResult object $params = @{ - Rec = "6.5.3" + Rec = $recnum Result = $allPoliciesRestricted Status = if ($allPoliciesRestricted) { "Pass" } else { "Fail" } Details = $details @@ -46,6 +48,13 @@ function Test-RestrictStorageProvidersOutlook { } $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure + } + } end { # Return the audit result diff --git a/source/tests/Test-RestrictTenantCreation.ps1 b/source/tests/Test-RestrictTenantCreation.ps1 index 96bfb0f..36107ae 100644 --- a/source/tests/Test-RestrictTenantCreation.ps1 +++ b/source/tests/Test-RestrictTenantCreation.ps1 @@ -9,34 +9,43 @@ function Test-RestrictTenantCreation { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "5.1.2.3" } process { - # 5.1.2.3 (L1) Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes' + try { + # 5.1.2.3 (L1) Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes' - # Retrieve the tenant creation policy - $tenantCreationPolicy = (Get-MgPolicyAuthorizationPolicy).DefaultUserRolePermissions | Select-Object AllowedToCreateTenants - $tenantCreationResult = -not $tenantCreationPolicy.AllowedToCreateTenants + # Retrieve the tenant creation policy + $tenantCreationPolicy = (Get-MgPolicyAuthorizationPolicy).DefaultUserRolePermissions | Select-Object AllowedToCreateTenants + $tenantCreationResult = -not $tenantCreationPolicy.AllowedToCreateTenants - # Prepare failure reasons and details based on compliance - $failureReasons = if ($tenantCreationResult) { - "N/A" - } - else { - "Non-admin users can create tenants" + # Prepare failure reasons and details based on compliance + $failureReasons = if ($tenantCreationResult) { + "N/A" + } + else { + "Non-admin users can create tenants" + } + + $details = "AllowedToCreateTenants: $($tenantCreationPolicy.AllowedToCreateTenants)" + + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $tenantCreationResult + Status = if ($tenantCreationResult) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" - $details = "AllowedToCreateTenants: $($tenantCreationPolicy.AllowedToCreateTenants)" - - # Create and populate the CISAuditResult object - $params = @{ - Rec = "5.1.2.3" - Result = $tenantCreationResult - Status = if ($tenantCreationResult) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-SafeAttachmentsPolicy.ps1 b/source/tests/Test-SafeAttachmentsPolicy.ps1 index 48597ce..eafc7ff 100644 --- a/source/tests/Test-SafeAttachmentsPolicy.ps1 +++ b/source/tests/Test-SafeAttachmentsPolicy.ps1 @@ -9,39 +9,48 @@ function Test-SafeAttachmentsPolicy { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "2.1.4" } process { - # 2.1.4 (L2) Ensure Safe Attachments policy is enabled + try { + # 2.1.4 (L2) Ensure Safe Attachments policy is enabled - # Retrieve all Safe Attachment policies where Enable is set to True - $safeAttachmentPolicies = Get-SafeAttachmentPolicy | Where-Object { $_.Enable -eq $true } + # Retrieve all Safe Attachment policies where Enable is set to True + $safeAttachmentPolicies = Get-SafeAttachmentPolicy | Where-Object { $_.Enable -eq $true } - # Determine result and details based on the presence of enabled policies - $result = $null -ne $safeAttachmentPolicies -and $safeAttachmentPolicies.Count -gt 0 - $details = if ($result) { - "Enabled Safe Attachments Policies: $($safeAttachmentPolicies.Name -join ', ')" - } - else { - "No Safe Attachments Policies are enabled." - } + # Determine result and details based on the presence of enabled policies + $result = $null -ne $safeAttachmentPolicies -and $safeAttachmentPolicies.Count -gt 0 + $details = if ($result) { + "Enabled Safe Attachments Policies: $($safeAttachmentPolicies.Name -join ', ')" + } + else { + "No Safe Attachments Policies are enabled." + } - $failureReasons = if ($result) { - "N/A" - } - else { - "Safe Attachments policy is not enabled." - } + $failureReasons = if ($result) { + "N/A" + } + else { + "Safe Attachments policy is not enabled." + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "2.1.4" - Result = $result - Status = if ($result) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $result + Status = if ($result) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-SafeAttachmentsTeams.ps1 b/source/tests/Test-SafeAttachmentsTeams.ps1 index a1cb453..1d9e32b 100644 --- a/source/tests/Test-SafeAttachmentsTeams.ps1 +++ b/source/tests/Test-SafeAttachmentsTeams.ps1 @@ -9,46 +9,55 @@ function Test-SafeAttachmentsTeams { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "2.1.5" } process { - # 2.1.5 (L2) Ensure Safe Attachments for SharePoint, OneDrive, and Microsoft Teams is Enabled + try { + # 2.1.5 (L2) Ensure Safe Attachments for SharePoint, OneDrive, and Microsoft Teams is Enabled - # Retrieve the ATP policies for Office 365 and check Safe Attachments settings - $atpPolicies = Get-AtpPolicyForO365 + # Retrieve the ATP policies for Office 365 and check Safe Attachments settings + $atpPolicies = Get-AtpPolicyForO365 - # Check if the required ATP policies are enabled - $atpPolicyResult = $atpPolicies | Where-Object { - $_.EnableATPForSPOTeamsODB -eq $true -and - $_.EnableSafeDocs -eq $true -and - $_.AllowSafeDocsOpen -eq $false - } + # Check if the required ATP policies are enabled + $atpPolicyResult = $atpPolicies | Where-Object { + $_.EnableATPForSPOTeamsODB -eq $true -and + $_.EnableSafeDocs -eq $true -and + $_.AllowSafeDocsOpen -eq $false + } - # Determine the result based on the ATP policy settings - $result = $null -ne $atpPolicyResult - $details = if ($result) { - "ATP for SharePoint, OneDrive, and Teams is enabled with correct settings." - } - else { - "ATP for SharePoint, OneDrive, and Teams is not enabled with correct settings." - } + # Determine the result based on the ATP policy settings + $result = $null -ne $atpPolicyResult + $details = if ($result) { + "ATP for SharePoint, OneDrive, and Teams is enabled with correct settings." + } + else { + "ATP for SharePoint, OneDrive, and Teams is not enabled with correct settings." + } - $failureReasons = if ($result) { - "N/A" - } - else { - "ATP policy for SharePoint, OneDrive, and Microsoft Teams is not correctly configured." - } + $failureReasons = if ($result) { + "N/A" + } + else { + "ATP policy for SharePoint, OneDrive, and Microsoft Teams is not correctly configured." + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "2.1.5" - Result = $result - Status = if ($result) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $result + Status = if ($result) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-SafeLinksOfficeApps.ps1 b/source/tests/Test-SafeLinksOfficeApps.ps1 index 46ee852..0660da2 100644 --- a/source/tests/Test-SafeLinksOfficeApps.ps1 +++ b/source/tests/Test-SafeLinksOfficeApps.ps1 @@ -9,53 +9,62 @@ function Test-SafeLinksOfficeApps { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed + $recnum = "2.1.1" } process { - # 2.1.1 (L2) Ensure Safe Links for Office Applications is Enabled + try { + # 2.1.1 (L2) Ensure Safe Links for Office Applications is Enabled - # Retrieve all Safe Links policies - $policies = Get-SafeLinksPolicy + # Retrieve all Safe Links policies + $policies = Get-SafeLinksPolicy - # Initialize the details collection - $misconfiguredDetails = @() + # Initialize the details collection + $misconfiguredDetails = @() - foreach ($policy in $policies) { - # Get the detailed configuration of each policy - $policyDetails = Get-SafeLinksPolicy -Identity $policy.Name + foreach ($policy in $policies) { + # Get the detailed configuration of each policy + $policyDetails = Get-SafeLinksPolicy -Identity $policy.Name - # Check each required property and record failures - $failures = @() - if ($policyDetails.EnableSafeLinksForEmail -ne $true) { $failures += "EnableSafeLinksForEmail: False" } - if ($policyDetails.EnableSafeLinksForTeams -ne $true) { $failures += "EnableSafeLinksForTeams: False" } - if ($policyDetails.EnableSafeLinksForOffice -ne $true) { $failures += "EnableSafeLinksForOffice: False" } - if ($policyDetails.TrackClicks -ne $true) { $failures += "TrackClicks: False" } - if ($policyDetails.AllowClickThrough -ne $false) { $failures += "AllowClickThrough: True" } - if ($policyDetails.ScanUrls -ne $true) { $failures += "ScanUrls: False" } - if ($policyDetails.EnableForInternalSenders -ne $true) { $failures += "EnableForInternalSenders: False" } - if ($policyDetails.DeliverMessageAfterScan -ne $true) { $failures += "DeliverMessageAfterScan: False" } - if ($policyDetails.DisableUrlRewrite -ne $false) { $failures += "DisableUrlRewrite: True" } + # Check each required property and record failures + $failures = @() + if ($policyDetails.EnableSafeLinksForEmail -ne $true) { $failures += "EnableSafeLinksForEmail: False" } + if ($policyDetails.EnableSafeLinksForTeams -ne $true) { $failures += "EnableSafeLinksForTeams: False" } + if ($policyDetails.EnableSafeLinksForOffice -ne $true) { $failures += "EnableSafeLinksForOffice: False" } + if ($policyDetails.TrackClicks -ne $true) { $failures += "TrackClicks: False" } + if ($policyDetails.AllowClickThrough -ne $false) { $failures += "AllowClickThrough: True" } + if ($policyDetails.ScanUrls -ne $true) { $failures += "ScanUrls: False" } + if ($policyDetails.EnableForInternalSenders -ne $true) { $failures += "EnableForInternalSenders: False" } + if ($policyDetails.DeliverMessageAfterScan -ne $true) { $failures += "DeliverMessageAfterScan: False" } + if ($policyDetails.DisableUrlRewrite -ne $false) { $failures += "DisableUrlRewrite: True" } - # Only add details for policies that have misconfigurations - if ($failures.Count -gt 0) { - $misconfiguredDetails += "Policy: $($policy.Name); Failures: $($failures -join ', ')" + # Only add details for policies that have misconfigurations + if ($failures.Count -gt 0) { + $misconfiguredDetails += "Policy: $($policy.Name); Failures: $($failures -join ', ')" + } } - } - # Prepare the final result - $result = $misconfiguredDetails.Count -eq 0 - $details = if ($result) { "All Safe Links policies are correctly configured." } else { $misconfiguredDetails -join ' | ' } - $failureReasons = if ($result) { "N/A" } else { "The following Safe Links policies settings do not meet the recommended configuration: $($misconfiguredDetails -join ' | ')" } + # Prepare the final result + $result = $misconfiguredDetails.Count -eq 0 + $details = if ($result) { "All Safe Links policies are correctly configured." } else { $misconfiguredDetails -join ' | ' } + $failureReasons = if ($result) { "N/A" } else { "The following Safe Links policies settings do not meet the recommended configuration: $($misconfiguredDetails -join ' | ')" } - # Create and populate the CISAuditResult object - $params = @{ - Rec = "2.1.1" - Result = $result - Status = if ($result) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + # Create and populate the CISAuditResult object + $params = @{ + Rec = $recnum + Result = $result + Status = if ($result) { "Pass" } else { "Fail" } + Details = $details + FailureReason = $failureReasons + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-SharePointAADB2B.ps1 b/source/tests/Test-SharePointAADB2B.ps1 index a9af0c4..7f1b6fb 100644 --- a/source/tests/Test-SharePointAADB2B.ps1 +++ b/source/tests/Test-SharePointAADB2B.ps1 @@ -11,21 +11,30 @@ function Test-SharePointAADB2B { # Initialization code, if needed $auditResult = [CISAuditResult]::new() + $recnum = "7.2.2" } process { - # 7.2.2 (L1) Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled - $SPOTenantAzureADB2B = Get-SPOTenant | Select-Object EnableAzureADB2BIntegration + try { + # 7.2.2 (L1) Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled + $SPOTenantAzureADB2B = Get-SPOTenant | Select-Object EnableAzureADB2BIntegration - # Populate the auditResult object with the required properties - $params = @{ - Rec = "7.2.2" - Result = $SPOTenantAzureADB2B.EnableAzureADB2BIntegration - Status = if ($SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Pass" } else { "Fail" } - Details = "EnableAzureADB2BIntegration: $($SPOTenantAzureADB2B.EnableAzureADB2BIntegration)" - FailureReason = if (-not $SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Azure AD B2B integration is not enabled" } else { "N/A" } + # Populate the auditResult object with the required properties + $params = @{ + Rec = $recnum + Result = $SPOTenantAzureADB2B.EnableAzureADB2BIntegration + Status = if ($SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Pass" } else { "Fail" } + Details = "EnableAzureADB2BIntegration: $($SPOTenantAzureADB2B.EnableAzureADB2BIntegration)" + FailureReason = if (-not $SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Azure AD B2B integration is not enabled" } else { "N/A" } + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-SharePointExternalSharingDomains.ps1 b/source/tests/Test-SharePointExternalSharingDomains.ps1 index 25f4213..f828ccf 100644 --- a/source/tests/Test-SharePointExternalSharingDomains.ps1 +++ b/source/tests/Test-SharePointExternalSharingDomains.ps1 @@ -11,22 +11,31 @@ function Test-SharePointExternalSharingDomains { # Initialization code, if needed $auditResult = [CISAuditResult]::new() + $recnum = "7.2.6" } process { - # 7.2.6 (L2) Ensure SharePoint external sharing is managed through domain whitelist/blacklists - $SPOTenant = Get-SPOTenant | Select-Object SharingDomainRestrictionMode, SharingAllowedDomainList - $isDomainRestrictionConfigured = $SPOTenant.SharingDomainRestrictionMode -eq 'AllowList' + try { + # 7.2.6 (L2) Ensure SharePoint external sharing is managed through domain whitelist/blacklists + $SPOTenant = Get-SPOTenant | Select-Object SharingDomainRestrictionMode, SharingAllowedDomainList + $isDomainRestrictionConfigured = $SPOTenant.SharingDomainRestrictionMode -eq 'AllowList' - # Populate the auditResult object with the required properties - $params = @{ - Rec = "7.2.6" - Result = $isDomainRestrictionConfigured - Status = if ($isDomainRestrictionConfigured) { "Pass" } else { "Fail" } - Details = "SharingDomainRestrictionMode: $($SPOTenant.SharingDomainRestrictionMode); SharingAllowedDomainList: $($SPOTenant.SharingAllowedDomainList)" - FailureReason = if (-not $isDomainRestrictionConfigured) { "Domain restrictions for SharePoint external sharing are not configured to 'AllowList'. Current setting: $($SPOTenant.SharingDomainRestrictionMode)" } else { "N/A" } + # Populate the auditResult object with the required properties + $params = @{ + Rec = $recnum + Result = $isDomainRestrictionConfigured + Status = if ($isDomainRestrictionConfigured) { "Pass" } else { "Fail" } + Details = "SharingDomainRestrictionMode: $($SPOTenant.SharingDomainRestrictionMode); SharingAllowedDomainList: $($SPOTenant.SharingAllowedDomainList)" + FailureReason = if (-not $isDomainRestrictionConfigured) { "Domain restrictions for SharePoint external sharing are not configured to 'AllowList'. Current setting: $($SPOTenant.SharingDomainRestrictionMode)" } else { "N/A" } + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-SharePointGuestsItemSharing.ps1 b/source/tests/Test-SharePointGuestsItemSharing.ps1 index 6f35325..025951f 100644 --- a/source/tests/Test-SharePointGuestsItemSharing.ps1 +++ b/source/tests/Test-SharePointGuestsItemSharing.ps1 @@ -11,22 +11,31 @@ function Test-SharePointGuestsItemSharing { # Initialization code, if needed $auditResult = [CISAuditResult]::new() + $recnum = "7.2.5" } process { - # 7.2.5 (L2) Ensure that SharePoint guest users cannot share items they don't own - $SPOTenant = Get-SPOTenant | Select-Object PreventExternalUsersFromResharing - $isGuestResharingPrevented = $SPOTenant.PreventExternalUsersFromResharing + try { + # 7.2.5 (L2) Ensure that SharePoint guest users cannot share items they don't own + $SPOTenant = Get-SPOTenant | Select-Object PreventExternalUsersFromResharing + $isGuestResharingPrevented = $SPOTenant.PreventExternalUsersFromResharing - # Populate the auditResult object with the required properties - $params = @{ - Rec = "7.2.5" - Result = $isGuestResharingPrevented - Status = if ($isGuestResharingPrevented) { "Pass" } else { "Fail" } - Details = "PreventExternalUsersFromResharing: $isGuestResharingPrevented" - FailureReason = if (-not $isGuestResharingPrevented) { "Guest users can reshare items they don't own." } else { "N/A" } + # Populate the auditResult object with the required properties + $params = @{ + Rec = $recnum + Result = $isGuestResharingPrevented + Status = if ($isGuestResharingPrevented) { "Pass" } else { "Fail" } + Details = "PreventExternalUsersFromResharing: $isGuestResharingPrevented" + FailureReason = if (-not $isGuestResharingPrevented) { "Guest users can reshare items they don't own." } else { "N/A" } + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-SpamPolicyAdminNotify.ps1 b/source/tests/Test-SpamPolicyAdminNotify.ps1 index 05be9aa..aa2b181 100644 --- a/source/tests/Test-SpamPolicyAdminNotify.ps1 +++ b/source/tests/Test-SpamPolicyAdminNotify.ps1 @@ -11,37 +11,46 @@ function Test-SpamPolicyAdminNotify { # Initialization code, if needed $auditResult = [CISAuditResult]::new() + $recnum = "2.1.6" } process { - # 2.1.6 Ensure Exchange Online Spam Policies are set to notify administrators + try { + # 2.1.6 Ensure Exchange Online Spam Policies are set to notify administrators - # Get the default hosted outbound spam filter policy - $hostedOutboundSpamFilterPolicy = Get-HostedOutboundSpamFilterPolicy | Where-Object { $_.IsDefault -eq $true } + # Get the default hosted outbound spam filter policy + $hostedOutboundSpamFilterPolicy = Get-HostedOutboundSpamFilterPolicy | Where-Object { $_.IsDefault -eq $true } - # Check if both settings are enabled - $bccSuspiciousOutboundMailEnabled = $hostedOutboundSpamFilterPolicy.BccSuspiciousOutboundMail - $notifyOutboundSpamEnabled = $hostedOutboundSpamFilterPolicy.NotifyOutboundSpam - $areSettingsEnabled = $bccSuspiciousOutboundMailEnabled -and $notifyOutboundSpamEnabled + # Check if both settings are enabled + $bccSuspiciousOutboundMailEnabled = $hostedOutboundSpamFilterPolicy.BccSuspiciousOutboundMail + $notifyOutboundSpamEnabled = $hostedOutboundSpamFilterPolicy.NotifyOutboundSpam + $areSettingsEnabled = $bccSuspiciousOutboundMailEnabled -and $notifyOutboundSpamEnabled - # Prepare failure details if any setting is not enabled - $failureDetails = @() - if (-not $bccSuspiciousOutboundMailEnabled) { - $failureDetails += "BccSuspiciousOutboundMail is not enabled." - } - if (-not $notifyOutboundSpamEnabled) { - $failureDetails += "NotifyOutboundSpam is not enabled." + # Prepare failure details if any setting is not enabled + $failureDetails = @() + if (-not $bccSuspiciousOutboundMailEnabled) { + $failureDetails += "BccSuspiciousOutboundMail is not enabled." + } + if (-not $notifyOutboundSpamEnabled) { + $failureDetails += "NotifyOutboundSpam is not enabled." + } + + # Create an instance of CISAuditResult and populate it + $params = @{ + Rec = $recnum + Result = $areSettingsEnabled + Status = if ($areSettingsEnabled) { "Pass" } else { "Fail" } + Details = if ($areSettingsEnabled) { "Both BccSuspiciousOutboundMail and NotifyOutboundSpam are enabled." } else { $failureDetails -join ' ' } + FailureReason = if (-not $areSettingsEnabled) { "One or both spam policies are not set to notify administrators." } else { "N/A" } + } + $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" - # Create an instance of CISAuditResult and populate it - $params = @{ - Rec = "2.1.6" - Result = $areSettingsEnabled - Status = if ($areSettingsEnabled) { "Pass" } else { "Fail" } - Details = if ($areSettingsEnabled) { "Both BccSuspiciousOutboundMail and NotifyOutboundSpam are enabled." } else { $failureDetails -join ' ' } - FailureReason = if (-not $areSettingsEnabled) { "One or both spam policies are not set to notify administrators." } else { "N/A" } + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-TeamsExternalAccess.ps1 b/source/tests/Test-TeamsExternalAccess.ps1 index 8b0cad2..c4ee735 100644 --- a/source/tests/Test-TeamsExternalAccess.ps1 +++ b/source/tests/Test-TeamsExternalAccess.ps1 @@ -11,32 +11,41 @@ function Test-TeamsExternalAccess { # Initialization code, if needed $auditResult = [CISAuditResult]::new() + $recnum = "8.2.1" } process { - # 8.2.1 (L1) Ensure 'external access' is restricted in the Teams admin center + try { + # 8.2.1 (L1) Ensure 'external access' is restricted in the Teams admin center - # Connect to Teams PowerShell using Connect-MicrosoftTeams + # Connect to Teams PowerShell using Connect-MicrosoftTeams - $externalAccessConfig = Get-CsTenantFederationConfiguration + $externalAccessConfig = Get-CsTenantFederationConfiguration - $allowedDomainsLimited = $false - if ($externalAccessConfig.AllowFederatedUsers -and $externalAccessConfig.AllowedDomains -and $externalAccessConfig.AllowedDomains.AllowedDomain.Count -gt 0) { - $allowedDomainsLimited = $true + $allowedDomainsLimited = $false + if ($externalAccessConfig.AllowFederatedUsers -and $externalAccessConfig.AllowedDomains -and $externalAccessConfig.AllowedDomains.AllowedDomain.Count -gt 0) { + $allowedDomainsLimited = $true + } + + # Check if the configurations are as recommended + $isCompliant = -not $externalAccessConfig.AllowTeamsConsumer -and -not $externalAccessConfig.AllowPublicUsers -and (-not $externalAccessConfig.AllowFederatedUsers -or $allowedDomainsLimited) + + # Create an instance of CISAuditResult and populate it + $params = @{ + Rec = $recnum + Result = $isCompliant + Status = if ($isCompliant) { "Pass" } else { "Fail" } + Details = "AllowTeamsConsumer: $($externalAccessConfig.AllowTeamsConsumer); AllowPublicUsers: $($externalAccessConfig.AllowPublicUsers); AllowFederatedUsers: $($externalAccessConfig.AllowFederatedUsers); AllowedDomains limited: $allowedDomainsLimited" + FailureReason = if (-not $isCompliant) { "One or more external access configurations are not compliant." } else { "N/A" } + } + $auditResult = Initialize-CISAuditResult @params } + catch { + Write-Error "An error occurred during the test: $_" - # Check if the configurations are as recommended - $isCompliant = -not $externalAccessConfig.AllowTeamsConsumer -and -not $externalAccessConfig.AllowPublicUsers -and (-not $externalAccessConfig.AllowFederatedUsers -or $allowedDomainsLimited) - - # Create an instance of CISAuditResult and populate it - $params = @{ - Rec = "8.2.1" - Result = $isCompliant - Status = if ($isCompliant) { "Pass" } else { "Fail" } - Details = "AllowTeamsConsumer: $($externalAccessConfig.AllowTeamsConsumer); AllowPublicUsers: $($externalAccessConfig.AllowPublicUsers); AllowFederatedUsers: $($externalAccessConfig.AllowFederatedUsers); AllowedDomains limited: $allowedDomainsLimited" - FailureReason = if (-not $isCompliant) { "One or more external access configurations are not compliant." } else { "N/A" } + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end { diff --git a/source/tests/Test-TeamsExternalFileSharing.ps1 b/source/tests/Test-TeamsExternalFileSharing.ps1 index fd4e653..1d5a135 100644 --- a/source/tests/Test-TeamsExternalFileSharing.ps1 +++ b/source/tests/Test-TeamsExternalFileSharing.ps1 @@ -11,36 +11,45 @@ function Test-TeamsExternalFileSharing { # Initialization code, if needed $auditResult = [CISAuditResult]::new() + $recnum = "8.1.1" } process { - # 8.1.1 (L2) Ensure external file sharing in Teams is enabled for only approved cloud storage services - # Connect to Teams PowerShell using Connect-MicrosoftTeams + try { + # 8.1.1 (L2) Ensure external file sharing in Teams is enabled for only approved cloud storage services + # Connect to Teams PowerShell using Connect-MicrosoftTeams - # Assuming that 'approvedProviders' is a list of approved cloud storage service names - # This list must be defined according to your organization's approved cloud storage services - $approvedProviders = @("AllowDropBox", "AllowBox", "AllowGoogleDrive", "AllowShareFile", "AllowEgnyte") - $clientConfig = Get-CsTeamsClientConfiguration + # Assuming that 'approvedProviders' is a list of approved cloud storage service names + # This list must be defined according to your organization's approved cloud storage services + $approvedProviders = @("AllowDropBox", "AllowBox", "AllowGoogleDrive", "AllowShareFile", "AllowEgnyte") + $clientConfig = Get-CsTeamsClientConfiguration - $isCompliant = $true - $nonCompliantProviders = @() + $isCompliant = $true + $nonCompliantProviders = @() - foreach ($provider in $approvedProviders) { - if (-not $clientConfig.$provider) { - $isCompliant = $false - $nonCompliantProviders += $provider + foreach ($provider in $approvedProviders) { + if (-not $clientConfig.$provider) { + $isCompliant = $false + $nonCompliantProviders += $provider + } } - } - # Create an instance of CISAuditResult and populate it - $params = @{ - Rec = "8.1.1" - Result = $isCompliant - Status = if ($isCompliant) { "Pass" } else { "Fail" } - Details = if (-not $isCompliant) { "Non-approved providers enabled: $($nonCompliantProviders -join ', ')" } else { "All cloud storage services are approved providers" } - FailureReason = if (-not $isCompliant) { "The following non-approved providers are enabled: $($nonCompliantProviders -join ', ')" } else { "N/A" } + # Create an instance of CISAuditResult and populate it + $params = @{ + Rec = $recnum + Result = $isCompliant + Status = if ($isCompliant) { "Pass" } else { "Fail" } + Details = if (-not $isCompliant) { "Non-approved providers enabled: $($nonCompliantProviders -join ', ')" } else { "All cloud storage services are approved providers" } + FailureReason = if (-not $isCompliant) { "The following non-approved providers are enabled: $($nonCompliantProviders -join ', ')" } else { "N/A" } + } + $auditResult = Initialize-CISAuditResult @params + } + catch { + Write-Error "An error occurred during the test: $_" + + # Call Initialize-CISAuditResult with error parameters + $auditResult = Initialize-CISAuditResult -Rec $recnum -Failure } - $auditResult = Initialize-CISAuditResult @params } end {