diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d80707..58fd6be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ The format is based on and uses the types of changes according to [Keep a Change ## [Unreleased] +### Added + +- Added condition comments to each test. + +### Fixed + +- Fixed csv CIS controls that were not matched correctly. + +## [0.1.9] - 2024-06-10 + ### Fixed - Fixed bug in 1.1.1 that caused the test to fail/pass incorrectly. Added verbose output. @@ -12,6 +22,7 @@ The format is based on and uses the types of changes according to [Keep a Change - Updated helper csv formatting for one cis control. + ## [0.1.8] - 2024-06-09 ### Added diff --git a/helpers/Build-Help.ps1 b/helpers/Build-Help.ps1 index a5da881..bebbbf8 100644 --- a/helpers/Build-Help.ps1 +++ b/helpers/Build-Help.ps1 @@ -4,7 +4,7 @@ Import-Module .\output\module\M365FoundationsCISReport\*\*.psd1 <# - $ver = "v0.1.8" + $ver = "v0.1.9" git checkout main git pull origin main git tag -a $ver -m "Release version $ver refactor Update" diff --git a/source/helper/TestDefinitions.csv b/source/helper/TestDefinitions.csv index d94e425..63434ec 100644 --- a/source/helper/TestDefinitions.csv +++ b/source/helper/TestDefinitions.csv @@ -28,14 +28,14 @@ 27,Test-MailTipsEnabled.ps1,6.5.2,Ensure MailTips are enabled for end users,E3,L2,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,EXO 28,Test-RestrictStorageProvidersOutlook.ps1,6.5.3,Ensure additional storage providers are restricted in Outlook on the web,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,EXO 29,Test-ModernAuthSharePoint.ps1,7.2.1,Modern Authentication for SharePoint Applications,E3,L1,3.1,Encrypt Sensitive Data in Transit,FALSE,TRUE,TRUE,TRUE,SPO -30,Test-SharePointAADB2B.ps1,7.2.2,Ensure reauthentication with verification code is restricted,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,SPO -31,Test-RestrictExternalSharing.ps1,7.2.3,Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled,E3,L1,0,Explicitly Not Mapped,TRUE,TRUE,TRUE,TRUE,SPO -32,Test-OneDriveContentRestrictions.ps1,7.2.4,Ensure external content sharing is restricted,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,SPO -33,Test-SharePointGuestsItemSharing.ps1,7.2.5,Ensure OneDrive content sharing is restricted,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,SPO -34,Test-SharePointExternalSharingDomains.ps1,7.2.6,Ensure that SharePoint guest users cannot share items they don't own,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,SPO -35,Test-LinkSharingRestrictions.ps1,7.2.7,Ensure SharePoint external sharing is managed through domain whitelist/blacklists,E3,L1,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,SPO -36,Test-GuestAccessExpiration.ps1,7.2.9,Ensure link sharing is restricted in SharePoint and OneDrive,E3,L1,3.3,Configure Data Access Control Lists,FALSE,FALSE,FALSE,TRUE,SPO -37,Test-ReauthWithCode.ps1,7.2.10,Ensure guest access to a site or OneDrive will expire automatically,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,SPO +30,Test-SharePointAADB2B.ps1,7.2.2,Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,SPO +31,Test-RestrictExternalSharing.ps1,7.2.3,Ensure external content sharing is restricted,E3,L1,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,SPO +32,Test-OneDriveContentRestrictions.ps1,7.2.4,Ensure OneDrive content sharing is restricted,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,SPO +33,Test-SharePointGuestsItemSharing.ps1,7.2.5,Ensure that SharePoint guest users cannot share items they don't own,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,SPO +34,Test-SharePointExternalSharingDomains.ps1,7.2.6,Ensure SharePoint external sharing is managed through domain whitelist/blacklists,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,SPO +35,Test-LinkSharingRestrictions.ps1,7.2.7,Ensure link sharing is restricted in SharePoint and OneDrive,E3,L1,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,SPO +36,Test-GuestAccessExpiration.ps1,7.2.9,Ensure guest access to a site or OneDrive will expire automatically,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,SPO +37,Test-ReauthWithCode.ps1,7.2.10,Ensure reauthentication with verification code is restricted,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,SPO 38,Test-DisallowInfectedFilesDownload.ps1,7.3.1,Ensure Office 365 SharePoint infected files are disallowed for download,E5,L2,10.1,Deploy and Maintain Anti-Malware Software,TRUE,TRUE,TRUE,TRUE,SPO 39,Test-OneDriveSyncRestrictions.ps1,7.3.2,Ensure OneDrive sync is restricted for unmanaged devices,E3,L2,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,SPO 40,Test-RestrictCustomScripts.ps1,7.3.4,Ensure custom script execution is restricted on site collections,E3,L1,2.7,Allowlist Authorized Scripts,FALSE,FALSE,TRUE,TRUE,SPO diff --git a/source/tests/Test-AntiPhishingPolicy.ps1 b/source/tests/Test-AntiPhishingPolicy.ps1 index 4e4de8c..24cb320 100644 --- a/source/tests/Test-AntiPhishingPolicy.ps1 +++ b/source/tests/Test-AntiPhishingPolicy.ps1 @@ -12,15 +12,31 @@ function Test-AntiPhishingPolicy { # Initialization code, if needed #$auditResults = @() $recnum = "2.1.7" + + <# + Conditions for 2.1.7 (L1) Ensure that an anti-phishing policy has been created + + Validate test for a pass: + - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + - Specific conditions to check: + - Condition A: Verify that an anti-phishing policy exists in the Microsoft 365 Security Center. + - Condition B: Using PowerShell, ensure the anti-phishing policy is configured with appropriate settings such as enabling impersonation protection and spoof intelligence. + + Validate test for a fail: + - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + - Specific conditions to check: + - Condition A: No anti-phishing policy exists in the Microsoft 365 Security Center. + - Condition B: Using PowerShell, the anti-phishing policy is not configured with the required settings. + #> } process { try { - # 2.1.7 Ensure that an anti-phishing policy has been created - - # Retrieve and validate the anti-phishing policies + # Condition A: Ensure that an anti-phishing policy has been created $antiPhishPolicies = Get-AntiPhishPolicy + + # Condition B: Verify the anti-phishing policy settings using PowerShell $validatedPolicies = $antiPhishPolicies | Where-Object { $_.Enabled -eq $true -and $_.PhishThresholdLevel -ge 2 -and diff --git a/source/tests/Test-AuditDisabledFalse.ps1 b/source/tests/Test-AuditDisabledFalse.ps1 index 8a26323..263e929 100644 --- a/source/tests/Test-AuditDisabledFalse.ps1 +++ b/source/tests/Test-AuditDisabledFalse.ps1 @@ -9,32 +9,48 @@ function Test-AuditDisabledFalse { begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 + + # Conditions for 6.1.1 (L1) Ensure 'AuditDisabled' organizationally is set to 'False' + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The `AuditDisabled` organizational setting is set to `False` in the Microsoft 365 admin center. + # - Condition B: Using PowerShell, the `AuditDisabled` property in the organization's configuration is set to `False`. + # - Condition C: Ensure mailbox auditing is enabled by default at the organizational level. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The `AuditDisabled` organizational setting is set to `True` in the Microsoft 365 admin center. + # - Condition B: Using PowerShell, the `AuditDisabled` property in the organization's configuration is set to `True`. + # - Condition C: Mailbox auditing is not enabled by default at the organizational level. + # Initialization code, if needed $recnum = "6.1.1" } process { - try { # 6.1.1 (L1) Ensure 'AuditDisabled' organizationally is set to 'False' - # Retrieve the AuditDisabled configuration + # Retrieve the AuditDisabled configuration (Condition B) $auditDisabledConfig = Get-OrganizationConfig | Select-Object AuditDisabled $auditNotDisabled = -not $auditDisabledConfig.AuditDisabled # Prepare failure reasons and details based on compliance $failureReasons = if (-not $auditNotDisabled) { - "AuditDisabled is set to True" + "AuditDisabled is set to True" # Condition A Fail } else { "N/A" } $details = if ($auditNotDisabled) { - "Audit is not disabled organizationally" + "Audit is not disabled organizationally" # Condition C Pass } else { - "Audit is disabled organizationally" + "Audit is disabled organizationally" # Condition C Fail } # Create and populate the CISAuditResult object diff --git a/source/tests/Test-AuditLogSearch.ps1 b/source/tests/Test-AuditLogSearch.ps1 index bbedbca..90e828e 100644 --- a/source/tests/Test-AuditLogSearch.ps1 +++ b/source/tests/Test-AuditLogSearch.ps1 @@ -11,6 +11,24 @@ function Test-AuditLogSearch { #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed $recnum = "3.1.1" + + <# + Conditions for 3.1.1 (L1) Ensure Microsoft 365 audit log search is Enabled + + Validate test for a pass: + - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + - Specific conditions to check: + - Condition A: Audit log search is enabled in the Microsoft Purview compliance portal. + - Condition B: The audit log retains user and admin activity for 90 days. + - Condition C: Audit log search capabilities are functional (search results are displayed for activities within the past 30 days). + + Validate test for a fail: + - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + - Specific conditions to check: + - Condition A: Audit log search is not enabled in the Microsoft Purview compliance portal. + - Condition B: The audit log does not retain user and admin activity for 90 days. + - Condition C: Audit log search capabilities are non-functional (no search results are displayed for activities within the past 30 days). + #> } process { @@ -24,6 +42,7 @@ function Test-AuditLogSearch { # Prepare failure reasons and details based on compliance $failureReasons = if (-not $auditLogResult) { + # Condition A (Fail): Audit log search is not enabled in the Microsoft Purview compliance portal "Audit log search is not enabled" } else { @@ -31,6 +50,7 @@ function Test-AuditLogSearch { } $details = if ($auditLogResult) { + # Condition A (Pass): Audit log search is enabled in the Microsoft Purview compliance portal "UnifiedAuditLogIngestionEnabled: True" } else { diff --git a/source/tests/Test-BlockChannelEmails.ps1 b/source/tests/Test-BlockChannelEmails.ps1 index 5165b61..a6f2827 100644 --- a/source/tests/Test-BlockChannelEmails.ps1 +++ b/source/tests/Test-BlockChannelEmails.ps1 @@ -16,36 +16,50 @@ function Test-BlockChannelEmails { process { try { - # 8.1.2 (L1) Ensure users can't send emails to a channel email address + # 8.1.2 (L1) Ensure users can't send emails to a channel email address + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The `AllowEmailIntoChannel` setting in Teams is set to `False`. + # - Condition B: The setting `Users can send emails to a channel email address` is set to `Off` in the Teams admin center. + # - Condition C: Verification using PowerShell confirms that the `AllowEmailIntoChannel` setting is disabled. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The `AllowEmailIntoChannel` setting in Teams is not set to `False`. + # - Condition B: The setting `Users can send emails to a channel email address` is not set to `Off` in the Teams admin center. + # - Condition C: Verification using PowerShell indicates that the `AllowEmailIntoChannel` setting is enabled. - # Retrieve Teams client configuration - $teamsClientConfig = Get-CsTeamsClientConfiguration -Identity Global - $allowEmailIntoChannel = $teamsClientConfig.AllowEmailIntoChannel + # Retrieve Teams client configuration + $teamsClientConfig = Get-CsTeamsClientConfiguration -Identity Global + $allowEmailIntoChannel = $teamsClientConfig.AllowEmailIntoChannel - # Prepare failure reasons and details based on compliance - $failureReasons = if ($allowEmailIntoChannel) { - "Emails can be sent to a channel email address" - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if ($allowEmailIntoChannel) { + "Emails can be sent to a channel email address" # Condition A Fail: AllowEmailIntoChannel is True + } + else { + "N/A" # Condition A Pass: AllowEmailIntoChannel is False + } - $details = if ($allowEmailIntoChannel) { - "AllowEmailIntoChannel is set to True" - } - else { - "AllowEmailIntoChannel is set to False" - } + $details = if ($allowEmailIntoChannel) { + "AllowEmailIntoChannel is set to True" # Condition B Fail: Emails are allowed + } + else { + "AllowEmailIntoChannel is set to False" # Condition B Pass: Emails are blocked + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = $recnum - Result = -not $allowEmailIntoChannel - Status = if (-not $allowEmailIntoChannel) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons - } - $auditResult = Initialize-CISAuditResult @params + # Create and populate the CISAuditResult object + $params = @{ + 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: $_" diff --git a/source/tests/Test-BlockMailForwarding.ps1 b/source/tests/Test-BlockMailForwarding.ps1 index 0ea1c1b..f0633ad 100644 --- a/source/tests/Test-BlockMailForwarding.ps1 +++ b/source/tests/Test-BlockMailForwarding.ps1 @@ -10,6 +10,24 @@ function Test-BlockMailForwarding { #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed $recnum = "6.2.1" + + <# + Conditions for 6.2.1 (L1) Ensure all forms of mail forwarding are blocked and/or disabled + + Validate test for a pass: + - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + - Specific conditions to check: + - Condition A: Transport rules do not forward email to external domains. + - Condition B: Anti-spam outbound policy is configured to disable automatic email forwarding to external domains. + - Condition C: No exceptions to the forwarding rules unless explicitly defined by organizational policy. + + Validate test for a fail: + - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + - Specific conditions to check: + - Condition A: One or more transport rules forward email to external domains. + - Condition B: Anti-spam outbound policy does not disable automatic email forwarding to external domains. + - Condition C: Unapproved exceptions to the forwarding rules are present. + #> } process { @@ -34,6 +52,7 @@ function Test-BlockMailForwarding { $details = @() if ($transportRules.Count -gt 0) { + # Fail Condition A $failureReasons += "Mail forwarding rules found: $($transportRules.Name -join ', ')" $details += "Transport Rules Details:`nRule Name|Redirects To" $details += $transportRules | ForEach-Object { @@ -43,6 +62,7 @@ function Test-BlockMailForwarding { } if ($nonCompliantSpamPoliciesArray.Count -gt 0) { + # Fail Condition B $failureReasons += "Outbound spam policies allowing automatic forwarding found." $details += "Outbound Spam Policies Details:`nPolicy|AutoForwardingMode" $details += $nonCompliantSpamPoliciesArray | ForEach-Object { diff --git a/source/tests/Test-BlockSharedMailboxSignIn.ps1 b/source/tests/Test-BlockSharedMailboxSignIn.ps1 index d1af582..db217e1 100644 --- a/source/tests/Test-BlockSharedMailboxSignIn.ps1 +++ b/source/tests/Test-BlockSharedMailboxSignIn.ps1 @@ -2,29 +2,44 @@ function Test-BlockSharedMailboxSignIn { [CmdletBinding()] [OutputType([CISAuditResult])] param ( - # Aligned # Parameters can be added if needed ) begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 + # Initialization code, if needed $recnum = "1.2.2" + + # Conditions for 1.2.2 (L1) Ensure sign-in to shared mailboxes is blocked + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: No shared mailboxes have the "Sign-in blocked" option disabled in the properties pane on the Microsoft 365 admin center. + # - Condition B: Using PowerShell, the `AccountEnabled` property for all shared mailboxes is set to `False`. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: One or more shared mailboxes have the "Sign-in blocked" option enabled in the properties pane on the Microsoft 365 admin center. + # - Condition B: Using PowerShell, the `AccountEnabled` property for one or more shared mailboxes is set to `True`. } process { - try { - # 1.2.2 (L1) Ensure sign-in to shared mailboxes is blocked - - # Retrieve shared mailbox details + # Step: Retrieve shared mailbox details $MBX = Get-EXOMailbox -RecipientTypeDetails SharedMailbox + + # Step: Retrieve details of shared mailboxes from Azure AD (Condition B: Pass/Fail) $sharedMailboxDetails = $MBX | ForEach-Object { Get-AzureADUser -ObjectId $_.ExternalDirectoryObjectId } + + # Step: Identify enabled mailboxes (Condition B: Pass/Fail) $enabledMailboxes = $sharedMailboxDetails | Where-Object { $_.AccountEnabled } | ForEach-Object { $_.DisplayName } $allBlocked = $enabledMailboxes.Count -eq 0 - # Prepare failure reasons and details based on compliance + # Step: Determine failure reasons based on enabled mailboxes (Condition A & B: Fail) $failureReasons = if (-not $allBlocked) { "Some mailboxes have sign-in enabled: $($enabledMailboxes -join ', ')" } @@ -32,6 +47,7 @@ function Test-BlockSharedMailboxSignIn { "N/A" } + # Step: Prepare details for the audit result (Condition A & B: Pass/Fail) $details = if ($allBlocked) { "All shared mailboxes have sign-in blocked." } @@ -39,10 +55,10 @@ function Test-BlockSharedMailboxSignIn { "Enabled Mailboxes: $($enabledMailboxes -join ', ')" } - # Create and populate the CISAuditResult object + # Step: Create and populate the CISAuditResult object $params = @{ Rec = $recnum - Result = $allBlocked + Result = $allBlocked # Pass: Condition A, Condition B Status = if ($allBlocked) { "Pass" } else { "Fail" } Details = $details FailureReason = $failureReasons diff --git a/source/tests/Test-CommonAttachmentFilter.ps1 b/source/tests/Test-CommonAttachmentFilter.ps1 index 3341ca5..0384880 100644 --- a/source/tests/Test-CommonAttachmentFilter.ps1 +++ b/source/tests/Test-CommonAttachmentFilter.ps1 @@ -7,6 +7,24 @@ function Test-CommonAttachmentFilter { ) begin { + <# + Conditions for 2.1.2 (L1) Ensure the Common Attachment Types Filter is enabled + + Validate test for a pass: + - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + - Specific conditions to check: + - Condition A: The Common Attachment Types Filter is enabled in the Microsoft 365 Security & Compliance Center. + - Condition B: Using Exchange Online PowerShell, verify that the `EnableFileFilter` property of the default malware filter policy is set to `True`. + - Condition C: Ensure that the setting is enabled in the highest priority policy listed if custom policies exist. + + Validate test for a fail: + - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + - Specific conditions to check: + - Condition A: The Common Attachment Types Filter is not enabled in the Microsoft 365 Security & Compliance Center. + - Condition B: Using Exchange Online PowerShell, verify that the `EnableFileFilter` property of the default malware filter policy is set to `False`. + - Condition C: Ensure that the setting is not enabled in the highest priority policy listed if custom policies exist. + #> + # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed @@ -16,6 +34,8 @@ function Test-CommonAttachmentFilter { process { try { # 2.1.2 (L1) Ensure the Common Attachment Types Filter is enabled + # Condition A: The Common Attachment Types Filter is enabled in the Microsoft 365 Security & Compliance Center. + # Condition B: Using Exchange Online PowerShell, verify that the `EnableFileFilter` property of the default malware filter policy is set to `True`. # Retrieve the attachment filter policy $attachmentFilter = Get-MalwareFilterPolicy -Identity Default | Select-Object EnableFileFilter @@ -23,6 +43,8 @@ function Test-CommonAttachmentFilter { # Prepare failure reasons and details based on compliance $failureReasons = if (-not $result) { + # Condition A: The Common Attachment Types Filter is not enabled in the Microsoft 365 Security & Compliance Center. + # Condition B: Using Exchange Online PowerShell, verify that the `EnableFileFilter` property of the default malware filter policy is set to `False`. "Common Attachment Types Filter is disabled" } else { diff --git a/source/tests/Test-CustomerLockbox.ps1 b/source/tests/Test-CustomerLockbox.ps1 index 8396ffc..cc67246 100644 --- a/source/tests/Test-CustomerLockbox.ps1 +++ b/source/tests/Test-CustomerLockbox.ps1 @@ -9,43 +9,58 @@ function Test-CustomerLockbox { begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 + # Initialization code, if needed $recnum = "1.3.6" + + # Conditions for 1.3.6 (L2) Ensure the customer lockbox feature is enabled (Automated) + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: In the Microsoft 365 admin center, the box labeled "Customer Lockbox Requests" is checked. + # - Condition B: Using the SecureScore portal, the Customer Lockbox feature is enabled. + # - Condition C: Using PowerShell, the Customer Lockbox feature is set to `True`. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: In the Microsoft 365 admin center, the box labeled "Customer Lockbox Requests" is not checked. + # - Condition B: Using the SecureScore portal, the Customer Lockbox feature is not enabled. + # - Condition C: Using PowerShell, the Customer Lockbox feature is not set to `True`. } process { - try { - # 1.3.6 (L2) Ensure the customer lockbox feature is enabled + # Step: Retrieve the organization configuration (Condition C: Pass/Fail) + $orgConfig = Get-OrganizationConfig | Select-Object CustomerLockBoxEnabled + $customerLockboxEnabled = $orgConfig.CustomerLockBoxEnabled - # Retrieve the organization configuration - $orgConfig = Get-OrganizationConfig | Select-Object CustomerLockBoxEnabled - $customerLockboxEnabled = $orgConfig.CustomerLockBoxEnabled + # Step: Prepare failure reasons and details based on compliance (Condition A, B, & C: Fail) + $failureReasons = if (-not $customerLockboxEnabled) { + "Customer lockbox feature is not enabled." + } + else { + "N/A" + } - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $customerLockboxEnabled) { - "Customer lockbox feature is not enabled." - } - else { - "N/A" - } + # Step: Prepare details for the audit result (Condition A, B, & C: Pass/Fail) + $details = if ($customerLockboxEnabled) { + "Customer Lockbox Enabled: True" + } + else { + "Customer Lockbox Enabled: False" + } - $details = if ($customerLockboxEnabled) { - "Customer Lockbox Enabled: True" - } - else { - "Customer Lockbox Enabled: False" - } - - # Create and populate the CISAuditResult object # - $params = @{ - Rec = $recnum - Result = $customerLockboxEnabled - Status = if ($customerLockboxEnabled) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons - } - $auditResult = Initialize-CISAuditResult @params + # Step: Create and populate the CISAuditResult object + $params = @{ + 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: $_" diff --git a/source/tests/Test-DialInBypassLobby.ps1 b/source/tests/Test-DialInBypassLobby.ps1 index b7088ee..52f7afd 100644 --- a/source/tests/Test-DialInBypassLobby.ps1 +++ b/source/tests/Test-DialInBypassLobby.ps1 @@ -17,6 +17,20 @@ function Test-DialInBypassLobby { try { # 8.5.4 (L1) Ensure users dialing in can't bypass the lobby + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The `AllowPSTNUsersToBypassLobby` setting in the Global Teams meeting policy is set to `False`. + # - Condition B: Verification using the UI in the Microsoft Teams admin center confirms that "People dialing in can't bypass the lobby" is set to `Off`. + # - Condition C: Ensure that individuals who dial in by phone must wait in the lobby until admitted by a meeting organizer, co-organizer, or presenter. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The `AllowPSTNUsersToBypassLobby` setting in the Global Teams meeting policy is not set to `False`. + # - Condition B: Verification using the UI in the Microsoft Teams admin center shows that "People dialing in can't bypass the lobby" is not set to `Off`. + # - Condition C: Individuals who dial in by phone are able to join the meeting directly without waiting in the lobby. # Retrieve Teams meeting policy for PSTN users $CsTeamsMeetingPolicyPSTN = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AllowPSTNUsersToBypassLobby diff --git a/source/tests/Test-DisallowInfectedFilesDownload.ps1 b/source/tests/Test-DisallowInfectedFilesDownload.ps1 index 514dda7..b9e72af 100644 --- a/source/tests/Test-DisallowInfectedFilesDownload.ps1 +++ b/source/tests/Test-DisallowInfectedFilesDownload.ps1 @@ -18,24 +18,40 @@ function Test-DisallowInfectedFilesDownload { try { # 7.3.1 (L2) Ensure Office 365 SharePoint infected files are disallowed for download + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The `DisallowInfectedFileDownload` setting is set to `True`. + # - Condition B: The setting prevents users from downloading infected files as detected by Defender for Office 365. + # - Condition C: Verification using the PowerShell command confirms that the setting is correctly configured. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The `DisallowInfectedFileDownload` setting is not set to `True`. + # - Condition B: The setting does not prevent users from downloading infected files. + # - Condition C: Verification using the PowerShell command indicates that the setting is incorrectly configured. # Retrieve the SharePoint tenant configuration $SPOTenantDisallowInfectedFileDownload = Get-SPOTenant | Select-Object DisallowInfectedFileDownload + + # Condition A: The `DisallowInfectedFileDownload` setting is set to `True` $isDisallowInfectedFileDownloadEnabled = $SPOTenantDisallowInfectedFileDownload.DisallowInfectedFileDownload # Prepare failure reasons and details based on compliance $failureReasons = if (-not $isDisallowInfectedFileDownloadEnabled) { - "Downloading infected files is not disallowed." + "Downloading infected files is not disallowed." # Condition B: The setting does not prevent users from downloading infected files } else { "N/A" } $details = if ($isDisallowInfectedFileDownloadEnabled) { - "DisallowInfectedFileDownload: True" + "DisallowInfectedFileDownload: True" # Condition C: Verification confirms the setting is correctly configured } else { - "DisallowInfectedFileDownload: False" + "DisallowInfectedFileDownload: False" # Condition C: Verification indicates the setting is incorrectly configured } # Create and populate the CISAuditResult object diff --git a/source/tests/Test-EnableDKIM.ps1 b/source/tests/Test-EnableDKIM.ps1 index a6662e1..e686dd7 100644 --- a/source/tests/Test-EnableDKIM.ps1 +++ b/source/tests/Test-EnableDKIM.ps1 @@ -9,44 +9,61 @@ function Test-EnableDKIM { begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 + # Initialization code, if needed $recnum = "2.1.9" + + <# + Conditions for 2.1.9 (L1) Ensure DKIM is enabled for all Exchange Online Domains (Automated) + + Validate test for a pass: + - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + - Specific conditions to check: + - Condition A: DKIM is enabled for all Exchange Online domains in the Microsoft 365 security center. + - Condition B: Using the Exchange Online PowerShell Module, the `CnameConfiguration.Enabled` property for each domain is set to `True`. + + Validate test for a fail: + - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + - Specific conditions to check: + - Condition A: DKIM is not enabled for one or more Exchange Online domains in the Microsoft 365 security center. + - Condition B: Using the Exchange Online PowerShell Module, the `CnameConfiguration.Enabled` property for one or more domains is set to `False`. + #> } process { try { - # 2.1.9 (L1) Ensure DKIM is enabled for all Exchange Online Domains + # 2.1.9 (L1) Ensure DKIM is enabled for all Exchange Online Domains - # Retrieve DKIM configuration for all domains - $dkimConfig = Get-DkimSigningConfig | Select-Object Domain, Enabled - $dkimResult = ($dkimConfig | ForEach-Object { $_.Enabled }) -notcontains $false - $dkimFailedDomains = $dkimConfig | Where-Object { -not $_.Enabled } | ForEach-Object { $_.Domain } + # Retrieve DKIM configuration for all domains + $dkimConfig = Get-DkimSigningConfig | Select-Object Domain, Enabled + $dkimResult = ($dkimConfig | ForEach-Object { $_.Enabled }) -notcontains $false + $dkimFailedDomains = $dkimConfig | Where-Object { -not $_.Enabled } | ForEach-Object { $_.Domain } - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $dkimResult) { - "DKIM is not enabled for some domains" - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $dkimResult) { + "DKIM is not enabled for some domains" # Condition A fail + } + else { + "N/A" + } - $details = if ($dkimResult) { - "All domains have DKIM enabled" - } - else { - "DKIM not enabled for: $($dkimFailedDomains -join ', ')" - } + $details = if ($dkimResult) { + "All domains have DKIM enabled" # Condition A pass + } + else { + "DKIM not enabled for: $($dkimFailedDomains -join ', ')" # Condition B fail + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = $recnum - Result = $dkimResult - Status = if ($dkimResult) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons - } - $auditResult = Initialize-CISAuditResult @params + # Create and populate the CISAuditResult object + $params = @{ + 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: $_" diff --git a/source/tests/Test-ExternalNoControl.ps1 b/source/tests/Test-ExternalNoControl.ps1 index 1a8c82d..462bb43 100644 --- a/source/tests/Test-ExternalNoControl.ps1 +++ b/source/tests/Test-ExternalNoControl.ps1 @@ -8,7 +8,7 @@ function Test-ExternalNoControl { begin { # Dot source the class script if necessary - #. .\source\Classes\CISAuditResult.ps1 + # . .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed $recnum = "8.5.7" @@ -17,36 +17,50 @@ function Test-ExternalNoControl { process { try { - # 8.5.7 (L1) Ensure external participants can't give or request control + # 8.5.7 (L1) Ensure external participants can't give or request control + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: Ensure the `AllowExternalParticipantGiveRequestControl` setting in Teams is set to `False`. + # - Condition B: The setting is verified through the Microsoft Teams admin center or via PowerShell command. + # - Condition C: Verification using the UI confirms that external participants are unable to give or request control. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The `AllowExternalParticipantGiveRequestControl` setting in Teams is not set to `False`. + # - Condition B: The setting is verified through the Microsoft Teams admin center or via PowerShell command. + # - Condition C: Verification using the UI indicates that external participants can give or request control. - # Retrieve Teams meeting policy for external participant control - $CsTeamsMeetingPolicyControl = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AllowExternalParticipantGiveRequestControl - $externalControlRestricted = -not $CsTeamsMeetingPolicyControl.AllowExternalParticipantGiveRequestControl + # Retrieve Teams meeting policy for external participant control + $CsTeamsMeetingPolicyControl = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AllowExternalParticipantGiveRequestControl + $externalControlRestricted = -not $CsTeamsMeetingPolicyControl.AllowExternalParticipantGiveRequestControl - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $externalControlRestricted) { - "External participants can give or request control" - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $externalControlRestricted) { + "External participants can give or request control" + } + else { + "N/A" + } - $details = if ($externalControlRestricted) { - "AllowExternalParticipantGiveRequestControl is set to False" - } - else { - "AllowExternalParticipantGiveRequestControl is set to True" - } + $details = if ($externalControlRestricted) { + "AllowExternalParticipantGiveRequestControl is set to False" + } + else { + "AllowExternalParticipantGiveRequestControl is set to True" + } - # Create and populate the CISAuditResult object - $params = @{ - Rec = $recnum - Result = $externalControlRestricted - Status = if ($externalControlRestricted) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons - } - $auditResult = Initialize-CISAuditResult @params + # Create and populate the CISAuditResult object + $params = @{ + 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: $_" diff --git a/source/tests/Test-ExternalSharingCalendars.ps1 b/source/tests/Test-ExternalSharingCalendars.ps1 index ed5e941..2b1946e 100644 --- a/source/tests/Test-ExternalSharingCalendars.ps1 +++ b/source/tests/Test-ExternalSharingCalendars.ps1 @@ -12,17 +12,28 @@ function Test-ExternalSharingCalendars { # Initialization code, if needed $recnum = "1.3.3" + + # Conditions for 1.3.3 (L2) Ensure 'External sharing' of calendars is not available (Automated) + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: In the Microsoft 365 admin center, external calendar sharing is disabled. + # - Condition B: Using the Exchange Online PowerShell Module, the `OrganizationConfig` property `ExternalSharingEnabled` is set to `False`. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: In the Microsoft 365 admin center, external calendar sharing is enabled. + # - Condition B: Using the Exchange Online PowerShell Module, the `OrganizationConfig` property `ExternalSharingEnabled` is set to `True`. } process { - try { - # 1.3.3 (L2) Ensure 'External sharing' of calendars is not available (Automated) - - # Retrieve sharing policies related to calendar sharing + # Step: 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 + # Step (Condition A & B: Pass/Fail): Check if calendar sharing is disabled in all applicable policies $isExternalSharingDisabled = $true $sharingPolicyDetails = @() foreach ($policy in $sharingPolicies) { @@ -32,7 +43,7 @@ function Test-ExternalSharingCalendars { } } - # Prepare failure reasons and details based on compliance + # Step: Prepare failure reasons and details based on compliance (Condition A & B: Fail) $failureReasons = if (-not $isExternalSharingDisabled) { "Calendar sharing with external users is enabled in one or more policies." } @@ -40,6 +51,7 @@ function Test-ExternalSharingCalendars { "N/A" } + # Step: Prepare details for the audit result (Condition A & B: Pass/Fail) $details = if ($isExternalSharingDisabled) { "Calendar sharing with external users is disabled." } @@ -47,7 +59,7 @@ function Test-ExternalSharingCalendars { "Enabled Sharing Policies: $($sharingPolicyDetails -join ', ')" } - # Create and populate the CISAuditResult object + # Step: Create and populate the CISAuditResult object $params = @{ Rec = $recnum Result = $isExternalSharingDisabled diff --git a/source/tests/Test-GlobalAdminsCount.ps1 b/source/tests/Test-GlobalAdminsCount.ps1 index 0c71f28..865d02e 100644 --- a/source/tests/Test-GlobalAdminsCount.ps1 +++ b/source/tests/Test-GlobalAdminsCount.ps1 @@ -2,13 +2,27 @@ function Test-GlobalAdminsCount { [CmdletBinding()] [OutputType([CISAuditResult])] param ( - # Aligned # Define your parameters here if needed ) begin { - # Dot source the class script if necessary + # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 + # Conditions for 1.1.3 (L1) Ensure that between two and four global admins are designated + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The number of global admins is at least 2. + # - Condition B: The number of global admins is at most 4. + # - Condition C: The list of global admin usernames is accurately retrieved and displayed. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The number of global admins is less than 2. + # - Condition B: The number of global admins is more than 4. + # - Condition C: Any discrepancies or errors in retrieving the list of global admin usernames. # Initialization code, if needed $recnum = "1.1.3" @@ -16,17 +30,21 @@ function Test-GlobalAdminsCount { process { try { - # 1.1.3 (L1) Ensure that between two and four global admins are designated - - # Retrieve global admin role and members + # Step: Retrieve global admin role $globalAdminRole = Get-MgDirectoryRole -Filter "RoleTemplateId eq '62e90394-69f5-4237-9190-012177145e10'" + + # Step: Retrieve global admin members $globalAdmins = Get-MgDirectoryRoleMember -DirectoryRoleId $globalAdminRole.Id + + # Step: Count the number of global admins $globalAdminCount = $globalAdmins.Count + + # Step: Retrieve and format the usernames of global admins $globalAdminUsernames = ($globalAdmins | ForEach-Object { "$($_.AdditionalProperties["displayName"]) ($($_.AdditionalProperties["userPrincipalName"]))" }) -join ', ' - # Prepare failure reasons and details based on compliance + # Step: Determine failure reasons based on global admin count $failureReasons = if ($globalAdminCount -lt 2) { "Less than 2 global admins: $globalAdminUsernames" } @@ -37,9 +55,10 @@ function Test-GlobalAdminsCount { "N/A" } + # Step: Prepare details for the audit result $details = "Count: $globalAdminCount; Users: $globalAdminUsernames" - # Create and populate the CISAuditResult object + # Step: Create and populate the CISAuditResult object $params = @{ Rec = $recnum Result = $globalAdminCount -ge 2 -and $globalAdminCount -le 4 diff --git a/source/tests/Test-GuestAccessExpiration.ps1 b/source/tests/Test-GuestAccessExpiration.ps1 index 986c8d7..782b9d7 100644 --- a/source/tests/Test-GuestAccessExpiration.ps1 +++ b/source/tests/Test-GuestAccessExpiration.ps1 @@ -17,31 +17,45 @@ function Test-GuestAccessExpiration { process { try { - # 7.2.9 (L1) Ensure guest access to a site or OneDrive will expire automatically + # 7.2.9 (L1) Ensure guest access to a site or OneDrive will expire automatically + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The ExternalUserExpirationRequired setting in SharePoint is set to True. + # - Condition B: The ExternalUserExpireInDays setting in SharePoint is configured to 30 or less. + # - Condition C: Verification using the SharePoint Admin Center confirms that guest access will expire automatically after the specified number of days. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The ExternalUserExpirationRequired setting in SharePoint is not set to True. + # - Condition B: The ExternalUserExpireInDays setting in SharePoint is configured to more than 30 days. + # - Condition C: Verification using the SharePoint Admin Center indicates that guest access is not set to expire automatically after the specified number of days. - # Retrieve SharePoint tenant settings related to guest access expiration - $SPOTenantGuestAccess = Get-SPOTenant | Select-Object ExternalUserExpirationRequired, ExternalUserExpireInDays - $isGuestAccessExpirationConfiguredCorrectly = $SPOTenantGuestAccess.ExternalUserExpirationRequired -and $SPOTenantGuestAccess.ExternalUserExpireInDays -le 30 + # Retrieve SharePoint tenant settings related to guest access expiration + $SPOTenantGuestAccess = Get-SPOTenant | Select-Object ExternalUserExpirationRequired, ExternalUserExpireInDays + $isGuestAccessExpirationConfiguredCorrectly = $SPOTenantGuestAccess.ExternalUserExpirationRequired -and $SPOTenantGuestAccess.ExternalUserExpireInDays -le 30 - # Prepare failure reasons and details based on compliance - $failureReasons = if (-not $isGuestAccessExpirationConfiguredCorrectly) { - "Guest access expiration is not configured to automatically expire within 30 days or less." - } - else { - "N/A" - } + # Prepare failure reasons and details based on compliance + $failureReasons = if (-not $isGuestAccessExpirationConfiguredCorrectly) { + "Guest access expiration is not configured to automatically expire within 30 days or less." + } + else { + "N/A" + } - $details = "ExternalUserExpirationRequired: $($SPOTenantGuestAccess.ExternalUserExpirationRequired); ExternalUserExpireInDays: $($SPOTenantGuestAccess.ExternalUserExpireInDays)" + $details = "ExternalUserExpirationRequired: $($SPOTenantGuestAccess.ExternalUserExpirationRequired); ExternalUserExpireInDays: $($SPOTenantGuestAccess.ExternalUserExpireInDays)" - # Create and populate the CISAuditResult object - $params = @{ - Rec = $recnum - Result = $isGuestAccessExpirationConfiguredCorrectly - Status = if ($isGuestAccessExpirationConfiguredCorrectly) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons - } - $auditResult = Initialize-CISAuditResult @params + # Create and populate the CISAuditResult object + $params = @{ + 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: $_" diff --git a/source/tests/Test-IdentifyExternalEmail.ps1 b/source/tests/Test-IdentifyExternalEmail.ps1 index 63bce34..21f96ca 100644 --- a/source/tests/Test-IdentifyExternalEmail.ps1 +++ b/source/tests/Test-IdentifyExternalEmail.ps1 @@ -12,6 +12,22 @@ function Test-IdentifyExternalEmail { # Initialization code, if needed $recnum = "6.2.3" + + # Conditions for 6.2.3 (L1) Ensure email from external senders is identified + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: External tagging is enabled using PowerShell for all identities. + # - Condition B: The BypassAllowList only contains email addresses the organization has permitted to bypass external tagging. + # - Condition C: External sender tag appears in email messages received from external sources. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: External tagging is not enabled using PowerShell for all identities. + # - Condition B: The BypassAllowList contains unauthorized email addresses. + # - Condition C: External sender tag does not appear in email messages received from external sources. } process { @@ -25,12 +41,14 @@ function Test-IdentifyExternalEmail { # Prepare failure reasons and details based on compliance $failureReasons = if (-not $externalTaggingEnabled) { + # Condition A: External tagging is not enabled using PowerShell for all identities. "External sender tagging is disabled" } else { "N/A" } + # Details for external tagging configuration $details = "Enabled: $($externalTaggingEnabled); AllowList: $($externalInOutlook.AllowList)" # Create and populate the CISAuditResult object diff --git a/source/tests/Test-LinkSharingRestrictions.ps1 b/source/tests/Test-LinkSharingRestrictions.ps1 index 24cd22b..5f41fe8 100644 --- a/source/tests/Test-LinkSharingRestrictions.ps1 +++ b/source/tests/Test-LinkSharingRestrictions.ps1 @@ -17,6 +17,20 @@ function Test-LinkSharingRestrictions { process { try { # 7.2.7 (L1) Ensure link sharing is restricted in SharePoint and OneDrive + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The `DefaultSharingLinkType` setting in SharePoint and OneDrive is set to `Direct`. + # - Condition B: The setting `Choose the type of link that's selected by default when users share files and folders in SharePoint and OneDrive` is set to `Specific people (only the people the user specifies)`. + # - Condition C: Verification using the UI confirms that the link sharing settings are configured as recommended. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The `DefaultSharingLinkType` setting in SharePoint and OneDrive is not set to `Direct`. + # - Condition B: The setting `Choose the type of link that's selected by default when users share files and folders in SharePoint and OneDrive` is not set to `Specific people (only the people the user specifies)`. + # - Condition C: Verification using the UI indicates that the link sharing settings are not configured as recommended. # Retrieve link sharing configuration for SharePoint and OneDrive $SPOTenantLinkSharing = Get-SPOTenant | Select-Object DefaultSharingLinkType diff --git a/source/tests/Test-MailTipsEnabled.ps1 b/source/tests/Test-MailTipsEnabled.ps1 index 2ccf106..4869fe8 100644 --- a/source/tests/Test-MailTipsEnabled.ps1 +++ b/source/tests/Test-MailTipsEnabled.ps1 @@ -13,6 +13,24 @@ function Test-MailTipsEnabled { $auditResult = [CISAuditResult]::new() $recnum = "6.5.2" + + # Conditions for 6.5.2 (L2) Ensure MailTips are enabled for end users + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: MailTipsAllTipsEnabled is set to True. + # - Condition B: MailTipsExternalRecipientsTipsEnabled is set to True. + # - Condition C: MailTipsGroupMetricsEnabled is set to True. + # - Condition D: MailTipsLargeAudienceThreshold is set to an acceptable value (default is 25). + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: MailTipsAllTipsEnabled is not set to True. + # - Condition B: MailTipsExternalRecipientsTipsEnabled is not set to True. + # - Condition C: MailTipsGroupMetricsEnabled is not set to True. + # - Condition D: MailTipsLargeAudienceThreshold is not set to an acceptable value (default is 25). } process { @@ -21,6 +39,8 @@ function Test-MailTipsEnabled { # Retrieve organization configuration for MailTips settings $orgConfig = Get-OrganizationConfig | Select-Object MailTipsAllTipsEnabled, MailTipsExternalRecipientsTipsEnabled, MailTipsGroupMetricsEnabled, MailTipsLargeAudienceThreshold + + # Check the MailTips settings (Conditions A, B, C, D) $allTipsEnabled = $orgConfig.MailTipsAllTipsEnabled -and $orgConfig.MailTipsGroupMetricsEnabled -and $orgConfig.MailTipsLargeAudienceThreshold -eq 25 $externalRecipientsTipsEnabled = $orgConfig.MailTipsExternalRecipientsTipsEnabled diff --git a/source/tests/Test-MailboxAuditingE3.ps1 b/source/tests/Test-MailboxAuditingE3.ps1 index ca9efcd..010b049 100644 --- a/source/tests/Test-MailboxAuditingE3.ps1 +++ b/source/tests/Test-MailboxAuditingE3.ps1 @@ -6,6 +6,26 @@ function Test-MailboxAuditingE3 { ) begin { + <# + Conditions for 6.1.2 (L1) Ensure mailbox auditing for E3 users is Enabled + + Validate test for a pass: + - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + - Specific conditions to check: + - Condition A: Mailbox audit logging is enabled for all user mailboxes. + - Condition B: The `AuditAdmin` actions include `ApplyRecord`, `Create`, `HardDelete`, `MoveToDeletedItems`, `SendAs`, `SendOnBehalf`, `SoftDelete`, `Update`, `UpdateCalendarDelegation`, `UpdateFolderPermissions`, and `UpdateInboxRules`. + - Condition C: The `AuditDelegate` actions include `ApplyRecord`, `Create`, `HardDelete`, `MoveToDeletedItems`, `SendAs`, `SendOnBehalf`, `SoftDelete`, `Update`, `UpdateFolderPermissions`, and `UpdateInboxRules`. + - Condition D: The `AuditOwner` actions include `ApplyRecord`, `HardDelete`, `MoveToDeletedItems`, `SoftDelete`, `Update`, `UpdateCalendarDelegation`, `UpdateFolderPermissions`, and `UpdateInboxRules`. + + Validate test for a fail: + - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + - Specific conditions to check: + - Condition A: Mailbox audit logging is not enabled for all user mailboxes. + - Condition B: The `AuditAdmin` actions do not include `ApplyRecord`, `Create`, `HardDelete`, `MoveToDeletedItems`, `SendAs`, `SendOnBehalf`, `SoftDelete`, `Update`, `UpdateCalendarDelegation`, `UpdateFolderPermissions`, and `UpdateInboxRules`. + - Condition C: The `AuditDelegate` actions do not include `ApplyRecord`, `Create`, `HardDelete`, `MoveToDeletedItems`, `SendAs`, `SendOnBehalf`, `SoftDelete`, `Update`, `UpdateFolderPermissions`, and `UpdateInboxRules`. + - Condition D: The `AuditOwner` actions do not include `ApplyRecord`, `HardDelete`, `MoveToDeletedItems`, `SoftDelete`, `Update`, `UpdateCalendarDelegation`, `UpdateFolderPermissions`, and `UpdateInboxRules`. + #> + # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 @@ -39,12 +59,15 @@ function Test-MailboxAuditingE3 { $missingActions = @() if ($mailbox.AuditEnabled) { foreach ($action in $AdminActions) { + # Condition B: Checking if the `AuditAdmin` actions include required actions if ($mailbox.AuditAdmin -notcontains $action) { $missingActions += "Admin action '$action' missing" } } foreach ($action in $DelegateActions) { + # Condition C: Checking if the `AuditDelegate` actions include required actions if ($mailbox.AuditDelegate -notcontains $action) { $missingActions += "Delegate action '$action' missing" } } foreach ($action in $OwnerActions) { + # Condition D: Checking if the `AuditOwner` actions include required actions if ($mailbox.AuditOwner -notcontains $action) { $missingActions += "Owner action '$action' missing" } } @@ -54,6 +77,7 @@ function Test-MailboxAuditingE3 { } } else { + # Condition A: Checking if mailbox audit logging is enabled $allFailures += "$userUPN|False|||" } diff --git a/source/tests/Test-MailboxAuditingE5.ps1 b/source/tests/Test-MailboxAuditingE5.ps1 index b21f6a2..f5c3891 100644 --- a/source/tests/Test-MailboxAuditingE5.ps1 +++ b/source/tests/Test-MailboxAuditingE5.ps1 @@ -9,6 +9,24 @@ function Test-MailboxAuditingE5 { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 + # Conditions for 6.1.3 (L1) Ensure mailbox auditing for E5 users is Enabled + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: Mailbox auditing is enabled for E5 users. + # - Condition B: AuditAdmin actions include ApplyRecord, Create, HardDelete, MailItemsAccessed, MoveToDeletedItems, Send, SendAs, SendOnBehalf, SoftDelete, Update, UpdateCalendarDelegation, UpdateFolderPermissions, UpdateInboxRules. + # - Condition C: AuditDelegate actions include ApplyRecord, Create, HardDelete, MailItemsAccessed, MoveToDeletedItems, SendAs, SendOnBehalf, SoftDelete, Update, UpdateFolderPermissions, UpdateInboxRules. + # - Condition D: AuditOwner actions include ApplyRecord, HardDelete, MailItemsAccessed, MoveToDeletedItems, Send, SoftDelete, Update, UpdateCalendarDelegation, UpdateFolderPermissions, UpdateInboxRules. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: Mailbox auditing is not enabled for E5 users. + # - Condition B: AuditAdmin actions do not include all of the following: ApplyRecord, Create, HardDelete, MailItemsAccessed, MoveToDeletedItems, Send, SendAs, SendOnBehalf, SoftDelete, Update, UpdateCalendarDelegation, UpdateFolderPermissions, UpdateInboxRules. + # - Condition C: AuditDelegate actions do not include all of the following: ApplyRecord, Create, HardDelete, MailItemsAccessed, MoveToDeletedItems, SendAs, SendOnBehalf, SoftDelete, Update, UpdateFolderPermissions, UpdateInboxRules. + # - Condition D: AuditOwner actions do not include all of the following: ApplyRecord, HardDelete, MailItemsAccessed, MoveToDeletedItems, Send, SoftDelete, Update, UpdateCalendarDelegation, UpdateFolderPermissions, UpdateInboxRules. + $e5SkuPartNumbers = @("SPE_E5", "ENTERPRISEPREMIUM", "OFFICEE5") $AdminActions = @("ApplyRecord", "Copy", "Create", "FolderBind", "HardDelete", "MailItemsAccessed", "Move", "MoveToDeletedItems", "SendAs", "SendOnBehalf", "Send", "SoftDelete", "Update", "UpdateCalendarDelegation", "UpdateFolderPermissions", "UpdateInboxRules") $DelegateActions = @("ApplyRecord", "Create", "FolderBind", "HardDelete", "MailItemsAccessed", "Move", "MoveToDeletedItems", "SendAs", "SendOnBehalf", "SoftDelete", "Update", "UpdateFolderPermissions", "UpdateInboxRules") @@ -38,14 +56,17 @@ function Test-MailboxAuditingE5 { $missingActions = @() if ($mailbox.AuditEnabled) { + # Validate Admin actions foreach ($action in $AdminActions) { - if ($mailbox.AuditAdmin -notcontains $action) { $missingActions += "Admin action '$action' missing" } + if ($mailbox.AuditAdmin -notcontains $action) { $missingActions += "Admin action '$action' missing" } # Condition B } + # Validate Delegate actions foreach ($action in $DelegateActions) { - if ($mailbox.AuditDelegate -notcontains $action) { $missingActions += "Delegate action '$action' missing" } + if ($mailbox.AuditDelegate -notcontains $action) { $missingActions += "Delegate action '$action' missing" } # Condition C } + # Validate Owner actions foreach ($action in $OwnerActions) { - if ($mailbox.AuditOwner -notcontains $action) { $missingActions += "Owner action '$action' missing" } + if ($mailbox.AuditOwner -notcontains $action) { $missingActions += "Owner action '$action' missing" } # Condition D } if ($missingActions.Count -gt 0) { @@ -65,10 +86,10 @@ function Test-MailboxAuditingE5 { # 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 E5 users have correct mailbox audit settings." + "All Office E5 users have correct mailbox audit settings." # Condition A for pass } else { - "UserPrincipalName|AuditEnabled|AdminActionsMissing|DelegateActionsMissing|OwnerActionsMissing`n" + ($allFailures -join "`n") + "UserPrincipalName|AuditEnabled|AdminActionsMissing|DelegateActionsMissing|OwnerActionsMissing`n" + ($allFailures -join "`n") # Condition A for fail } # Populate the audit result diff --git a/source/tests/Test-ManagedApprovedPublicGroups.ps1 b/source/tests/Test-ManagedApprovedPublicGroups.ps1 index 073d540..829f202 100644 --- a/source/tests/Test-ManagedApprovedPublicGroups.ps1 +++ b/source/tests/Test-ManagedApprovedPublicGroups.ps1 @@ -2,25 +2,37 @@ function Test-ManagedApprovedPublicGroups { [CmdletBinding()] [OutputType([CISAuditResult])] param ( - # Aligned # Parameters can be added if needed ) begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 + # Initialization code, if needed $recnum = "1.2.1" + + # Conditions for 1.2.1 (L2) Ensure that only organizationally managed/approved public groups exist (Automated) + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: No groups have the status 'Public' in the privacy column on the Active teams and groups page. + # - Condition B: Using Microsoft Graph PowerShell, all groups return a status other than 'Public' when checked. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: One or more groups have the status 'Public' in the privacy column on the Active teams and groups page. + # - Condition B: Using Microsoft Graph PowerShell, one or more groups return a status of 'Public' when checked. } process { try { - # 1.2.1 (L2) Ensure that only organizationally managed/approved public groups exist (Automated) - - # Retrieve all public groups + # Step: Retrieve all groups with visibility set to 'Public' $allGroups = Get-MgGroup -All | Where-Object { $_.Visibility -eq "Public" } | Select-Object DisplayName, Visibility - # Prepare failure reasons and details based on compliance + # Step: Determine failure reasons based on the presence of public groups $failureReasons = if ($null -ne $allGroups -and $allGroups.Count -gt 0) { "There are public groups present that are not organizationally managed/approved." } @@ -28,6 +40,7 @@ function Test-ManagedApprovedPublicGroups { "N/A" } + # Step: Prepare details for the audit result $details = if ($null -eq $allGroups -or $allGroups.Count -eq 0) { "No public groups found." } @@ -36,7 +49,7 @@ function Test-ManagedApprovedPublicGroups { "Public groups found: $($groupDetails -join ', ')" } - # Create and populate the CISAuditResult object + # Step: Create and populate the CISAuditResult object $params = @{ Rec = $recnum Result = $null -eq $allGroups -or $allGroups.Count -eq 0 @@ -61,7 +74,7 @@ function Test-ManagedApprovedPublicGroups { } end { - # Return auditResults + # Return the audit result return $auditResult } } diff --git a/source/tests/Test-MeetingChatNoAnonymous.ps1 b/source/tests/Test-MeetingChatNoAnonymous.ps1 index 3524c6b..25b9367 100644 --- a/source/tests/Test-MeetingChatNoAnonymous.ps1 +++ b/source/tests/Test-MeetingChatNoAnonymous.ps1 @@ -16,11 +16,24 @@ function Test-MeetingChatNoAnonymous { process { try { # 8.5.5 (L2) Ensure meeting chat does not allow anonymous users - - # Connect to Teams PowerShell using Connect-MicrosoftTeams + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The `MeetingChatEnabledType` setting in Teams is set to `EnabledExceptAnonymous`. + # - Condition B: The setting for meeting chat is configured to allow chat for everyone except anonymous users. + # - Condition C: Verification using the Teams Admin Center confirms that the meeting chat settings are configured as recommended. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The `MeetingChatEnabledType` setting in Teams is not set to `EnabledExceptAnonymous`. + # - Condition B: The setting for meeting chat allows chat for anonymous users. + # - Condition C: Verification using the Teams Admin Center indicates that the meeting chat settings are not configured as recommended. # Retrieve the Teams meeting policy for meeting chat $CsTeamsMeetingPolicyChat = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property MeetingChatEnabledType + # Condition A: Check if the MeetingChatEnabledType is set to 'EnabledExceptAnonymous' $chatAnonDisabled = $CsTeamsMeetingPolicyChat.MeetingChatEnabledType -eq 'EnabledExceptAnonymous' # Prepare failure reasons and details based on compliance diff --git a/source/tests/Test-ModernAuthExchangeOnline.ps1 b/source/tests/Test-ModernAuthExchangeOnline.ps1 index 8735fa4..e856abf 100644 --- a/source/tests/Test-ModernAuthExchangeOnline.ps1 +++ b/source/tests/Test-ModernAuthExchangeOnline.ps1 @@ -9,7 +9,23 @@ function Test-ModernAuthExchangeOnline { begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 - # Initialization code, if needed + + # Conditions for 6.5.1 (L1) Ensure modern authentication for Exchange Online is enabled + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: Modern authentication for Exchange Online is enabled. + # - Condition B: Exchange Online clients use modern authentication to log in to Microsoft 365 mailboxes. + # - Condition C: Users of older email clients, such as Outlook 2013 and Outlook 2016, are no longer able to authenticate to Exchange using Basic Authentication. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: Modern authentication for Exchange Online is not enabled. + # - Condition B: Exchange Online clients do not use modern authentication to log in to Microsoft 365 mailboxes. + # - Condition C: Users of older email clients, such as Outlook 2013 and Outlook 2016, are still able to authenticate to Exchange using Basic Authentication. + $recnum = "6.5.1" } @@ -18,6 +34,8 @@ function Test-ModernAuthExchangeOnline { # Ensuring the ExchangeOnlineManagement module is available # 6.5.1 (L1) Ensure modern authentication for Exchange Online is enabled + + # Check modern authentication setting in Exchange Online configuration (Condition A and B) $orgConfig = Get-OrganizationConfig | Select-Object -Property Name, OAuth2ClientProfileEnabled # Prepare failure reasons and details based on compliance @@ -28,6 +46,7 @@ function Test-ModernAuthExchangeOnline { "N/A" } + # Details include the current setting (Condition A and B) $details = "OAuth2ClientProfileEnabled: $($orgConfig.OAuth2ClientProfileEnabled) for Organization: $($orgConfig.Name)" # Create and populate the CISAuditResult object diff --git a/source/tests/Test-ModernAuthSharePoint.ps1 b/source/tests/Test-ModernAuthSharePoint.ps1 index c56ef59..66d6614 100644 --- a/source/tests/Test-ModernAuthSharePoint.ps1 +++ b/source/tests/Test-ModernAuthSharePoint.ps1 @@ -9,8 +9,25 @@ function Test-ModernAuthSharePoint { begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 + # Initialization code, if needed $recnum = "7.2.1" + + <# + # Conditions for 7.2.1 (L1) Ensure modern authentication for SharePoint applications is required + + ## Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The setting "Apps that don't use modern authentication" is set to "Block access" in the SharePoint admin center. + # - Condition B: The PowerShell command `Get-SPOTenant | ft LegacyAuthProtocolsEnabled` returns `False`. + + ## Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The setting "Apps that don't use modern authentication" is not set to "Block access" in the SharePoint admin center. + # - Condition B: The PowerShell command `Get-SPOTenant | ft LegacyAuthProtocolsEnabled` returns `True`. + #> } process { @@ -21,13 +38,13 @@ function Test-ModernAuthSharePoint { # Prepare failure reasons and details based on compliance $failureReasons = if (-not $modernAuthForSPRequired) { - "Legacy authentication protocols are enabled" + "Legacy authentication protocols are enabled" # Fail Condition B } else { "N/A" } - $details = "LegacyAuthProtocolsEnabled: $($SPOTenant.LegacyAuthProtocolsEnabled)" + $details = "LegacyAuthProtocolsEnabled: $($SPOTenant.LegacyAuthProtocolsEnabled)" # Details for Condition B # Create and populate the CISAuditResult object $params = @{ diff --git a/source/tests/Test-NoAnonymousMeetingJoin.ps1 b/source/tests/Test-NoAnonymousMeetingJoin.ps1 index e28ebdb..e859a53 100644 --- a/source/tests/Test-NoAnonymousMeetingJoin.ps1 +++ b/source/tests/Test-NoAnonymousMeetingJoin.ps1 @@ -16,6 +16,20 @@ function Test-NoAnonymousMeetingJoin { process { try { # 8.5.1 (L2) Ensure anonymous users can't join a meeting + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: `AllowAnonymousUsersToJoinMeeting` is set to `False`. + # - Condition B: Verification using the UI confirms that `Anonymous users can join a meeting` is set to `Off` in the Global meeting policy. + # - Condition C: PowerShell command output indicates that anonymous users are not allowed to join meetings. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: `AllowAnonymousUsersToJoinMeeting` is not set to `False`. + # - Condition B: Verification using the UI shows that `Anonymous users can join a meeting` is not set to `Off` in the Global meeting policy. + # - Condition C: PowerShell command output indicates that anonymous users are allowed to join meetings. # Connect to Teams PowerShell using Connect-MicrosoftTeams diff --git a/source/tests/Test-NoAnonymousMeetingStart.ps1 b/source/tests/Test-NoAnonymousMeetingStart.ps1 index 5ffa6e2..0a9b2dc 100644 --- a/source/tests/Test-NoAnonymousMeetingStart.ps1 +++ b/source/tests/Test-NoAnonymousMeetingStart.ps1 @@ -16,9 +16,24 @@ function Test-NoAnonymousMeetingStart { process { try { # 8.5.2 (L1) Ensure anonymous users and dial-in callers can't start a meeting + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The `AllowAnonymousUsersToStartMeeting` setting in the Teams admin center is set to `False`. + # - Condition B: The setting for anonymous users and dial-in callers starting a meeting is configured to ensure they must wait in the lobby. + # - Condition C: Verification using the UI confirms that the setting `Anonymous users and dial-in callers can start a meeting` is set to `Off`. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The `AllowAnonymousUsersToStartMeeting` setting in the Teams admin center is not set to `False`. + # - Condition B: The setting for anonymous users and dial-in callers starting a meeting allows them to bypass the lobby. + # - Condition C: Verification using the UI indicates that the setting `Anonymous users and dial-in callers can start a meeting` is not set to `Off`. # Connect to Teams PowerShell using Connect-MicrosoftTeams + # Retrieve the Teams meeting policy for the global scope and check if anonymous users can start meetings $CsTeamsMeetingPolicyAnonymous = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AllowAnonymousUsersToStartMeeting $anonymousStartDisabled = -not $CsTeamsMeetingPolicyAnonymous.AllowAnonymousUsersToStartMeeting @@ -27,10 +42,10 @@ function Test-NoAnonymousMeetingStart { "N/A" } else { - "Anonymous users and dial-in callers can start a meeting" + "Anonymous users and dial-in callers can start a meeting" # Condition A and B } - $details = "AllowAnonymousUsersToStartMeeting is set to $($CsTeamsMeetingPolicyAnonymous.AllowAnonymousUsersToStartMeeting)" + $details = "AllowAnonymousUsersToStartMeeting is set to $($CsTeamsMeetingPolicyAnonymous.AllowAnonymousUsersToStartMeeting)" # Condition C # Create and populate the CISAuditResult object $params = @{ diff --git a/source/tests/Test-NoWhitelistDomains.ps1 b/source/tests/Test-NoWhitelistDomains.ps1 index d51fdc1..b9c6d0b 100644 --- a/source/tests/Test-NoWhitelistDomains.ps1 +++ b/source/tests/Test-NoWhitelistDomains.ps1 @@ -9,8 +9,27 @@ function Test-NoWhitelistDomains { begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 + # Initialization code, if needed $recnum = "6.2.2" + + <# + Conditions for 6.2.2 (L1) Ensure mail transport rules do not whitelist specific domains (Automated) + + Validate test for a pass: + - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + - Specific conditions to check: + - Condition A: No mail transport rules whitelist any specific domains. + - Condition B: Verification of mail transport rules using PowerShell shows no domains are whitelisted. + - Condition C: Manual review in Exchange Online admin center confirms no whitelisted domains in transport rules. + + Validate test for a fail: + - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + - Specific conditions to check: + - Condition A: One or more mail transport rules whitelist specific domains. + - Condition B: Verification of mail transport rules using PowerShell shows one or more domains are whitelisted. + - Condition C: Manual review in Exchange Online admin center shows whitelisted domains in transport rules. + #> } process { @@ -18,9 +37,11 @@ function Test-NoWhitelistDomains { # 6.2.2 (L1) Ensure mail transport rules do not whitelist specific domains # Retrieve transport rules that whitelist specific domains + # Condition A: Checking for 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 + # Condition B: Prepare failure reasons based on the presence of whitelisted rules $failureReasons = if ($whitelistedRules) { "There are transport rules whitelisting specific domains." } @@ -28,6 +49,7 @@ function Test-NoWhitelistDomains { "N/A" } + # Condition C: Prepare details about the whitelisted rules if found $details = if ($whitelistedRules) { $ruleDetails = $whitelistedRules | ForEach-Object { "{0}: {1}" -f $_.Name, ($_.SenderDomainIs -join ', ') } "Whitelisted Rules: $($ruleDetails -join '; ')" diff --git a/source/tests/Test-NotifyMalwareInternal.ps1 b/source/tests/Test-NotifyMalwareInternal.ps1 index 1e466fb..6c15c9a 100644 --- a/source/tests/Test-NotifyMalwareInternal.ps1 +++ b/source/tests/Test-NotifyMalwareInternal.ps1 @@ -7,6 +7,22 @@ function Test-NotifyMalwareInternal { ) begin { + <# + # Conditions for 2.1.3 (L1) Ensure notifications for internal users sending malware is Enabled + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: Notifications for internal users sending malware are enabled in the Microsoft 365 Security & Compliance Center. + # - Condition B: Using PowerShell, the `NotifyInternal` property in the anti-malware policy is set to `True` and includes at least one valid email address for notifications. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: Notifications for internal users sending malware are not enabled in the Microsoft 365 Security & Compliance Center. + # - Condition B: Using PowerShell, the `NotifyInternal` property in the anti-malware policy is set to `False` or does not include any valid email addresses for notifications. + #> + # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed @@ -19,8 +35,9 @@ function Test-NotifyMalwareInternal { # Retrieve all 'Custom' malware filter policies and check notification settings $malwareNotifications = Get-MalwareFilterPolicy | Where-Object { $_.RecommendedPolicyType -eq 'Custom' } - $policiesToReport = @() + # Condition B: Using PowerShell, the `NotifyInternal` property in the anti-malware policy is set to `True` and includes at least one valid email address for notifications. + $policiesToReport = @() foreach ($policy in $malwareNotifications) { if ($policy.EnableInternalSenderAdminNotifications -ne $true) { $policiesToReport += "$($policy.Identity): Notifications Disabled" @@ -35,6 +52,7 @@ function Test-NotifyMalwareInternal { "N/A" } else { + # Condition A: Notifications for internal users sending malware are not enabled in the Microsoft 365 Security & Compliance Center. "Some custom policies do not have notifications for internal users sending malware enabled." } diff --git a/source/tests/Test-OneDriveContentRestrictions.ps1 b/source/tests/Test-OneDriveContentRestrictions.ps1 index 0043aa9..a87ffd1 100644 --- a/source/tests/Test-OneDriveContentRestrictions.ps1 +++ b/source/tests/Test-OneDriveContentRestrictions.ps1 @@ -7,6 +7,22 @@ function Test-OneDriveContentRestrictions { ) begin { + # 7.2.4 (L2) Ensure OneDrive content sharing is restricted + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The OneDriveSharingCapability setting is configured to "Disabled" using the PowerShell cmdlet `Get-SPOTenant | fl OneDriveSharingCapability`. + # - Condition B: The OneDriveSharingCapability is set to "Only people in your organization" in the SharePoint admin center under Policies > Sharing > OneDrive. + # - Condition C: OneDrive content sharing is not more permissive than SharePoint content sharing. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The OneDriveSharingCapability setting is not configured to "Disabled" using the PowerShell cmdlet `Get-SPOTenant | fl OneDriveSharingCapability`. + # - Condition B: The OneDriveSharingCapability is not set to "Only people in your organization" in the SharePoint admin center under Policies > Sharing > OneDrive. + # - Condition C: OneDrive content sharing is more permissive than SharePoint content sharing. + # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed diff --git a/source/tests/Test-OneDriveSyncRestrictions.ps1 b/source/tests/Test-OneDriveSyncRestrictions.ps1 index 436899a..4a6d0fb 100644 --- a/source/tests/Test-OneDriveSyncRestrictions.ps1 +++ b/source/tests/Test-OneDriveSyncRestrictions.ps1 @@ -16,12 +16,27 @@ function Test-OneDriveSyncRestrictions { process { try { # 7.3.2 (L2) Ensure OneDrive sync is restricted for unmanaged devices + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: Verify that "Allow syncing only on computers joined to specific domains" is enabled. + # - Condition B: Check that "TenantRestrictionEnabled" is set to True. + # - Condition C: Ensure that "AllowedDomainList" contains the trusted domain GUIDs from the on-premises environment. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: "Allow syncing only on computers joined to specific domains" is not enabled. + # - Condition B: "TenantRestrictionEnabled" is set to False. + # - Condition C: "AllowedDomainList" does not contain the trusted domain GUIDs from the on-premises environment. # 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 + # Condition A: Check if TenantRestrictionEnabled is True + # Condition B: Ensure AllowedDomainList contains trusted domains GUIDs $failureReasons = if (-not $isSyncRestricted) { "OneDrive sync is not restricted to managed devices. TenantRestrictionEnabled should be True and AllowedDomainList should contain trusted domains GUIDs." } @@ -29,6 +44,7 @@ function Test-OneDriveSyncRestrictions { "N/A" } + # Condition C: Prepare details based on whether sync is restricted $details = if ($isSyncRestricted) { "OneDrive sync is restricted for unmanaged devices." } diff --git a/source/tests/Test-OrgOnlyBypassLobby.ps1 b/source/tests/Test-OrgOnlyBypassLobby.ps1 index 735c86d..b039c4d 100644 --- a/source/tests/Test-OrgOnlyBypassLobby.ps1 +++ b/source/tests/Test-OrgOnlyBypassLobby.ps1 @@ -16,6 +16,20 @@ function Test-OrgOnlyBypassLobby { process { try { # 8.5.3 (L1) Ensure only people in my org can bypass the lobby + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The `AutoAdmittedUsers` setting in the Teams meeting policy is set to `EveryoneInCompanyExcludingGuests`. + # - Condition B: The setting for "Who can bypass the lobby" is configured to "People in my org" using the UI. + # - Condition C: Verification using the Microsoft Teams admin center confirms that the meeting join & lobby settings are configured as recommended. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The `AutoAdmittedUsers` setting in the Teams meeting policy is not set to `EveryoneInCompanyExcludingGuests`. + # - Condition B: The setting for "Who can bypass the lobby" is not configured to "People in my org" using the UI. + # - Condition C: Verification using the Microsoft Teams admin center indicates that the meeting join & lobby settings are not configured as recommended. # Connect to Teams PowerShell using Connect-MicrosoftTeams @@ -25,6 +39,7 @@ function Test-OrgOnlyBypassLobby { # Prepare failure reasons and details based on compliance $failureReasons = if (-not $lobbyBypassRestricted) { + # Condition A: The `AutoAdmittedUsers` setting in the Teams meeting policy is not set to `EveryoneInCompanyExcludingGuests`. "External participants can bypass the lobby" } else { @@ -32,9 +47,11 @@ function Test-OrgOnlyBypassLobby { } $details = if ($lobbyBypassRestricted) { + # Condition B: The setting for "Who can bypass the lobby" is configured to "People in my org" using the UI. "Only people in the organization can bypass the lobby." } else { + # Condition C: Verification using the Microsoft Teams admin center indicates that the meeting join & lobby settings are not configured as recommended. "AutoAdmittedUsers is set to $($CsTeamsMeetingPolicyLobby.AutoAdmittedUsers)" } diff --git a/source/tests/Test-OrganizersPresent.ps1 b/source/tests/Test-OrganizersPresent.ps1 index 014d13d..c57ad39 100644 --- a/source/tests/Test-OrganizersPresent.ps1 +++ b/source/tests/Test-OrganizersPresent.ps1 @@ -16,8 +16,20 @@ function Test-OrganizersPresent { process { try { # 8.5.6 (L2) Ensure only organizers and co-organizers can present - - # Connect to Teams PowerShell using Connect-MicrosoftTeams + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The `DesignatedPresenterRoleMode` setting in the Teams meeting policy is set to `OrganizerOnlyUserOverride`. + # - Condition B: Verification using the Teams admin center confirms that the setting "Who can present" is configured to "Only organizers and co-organizers". + # - Condition C: Verification using PowerShell confirms that the `DesignatedPresenterRoleMode` is set to `OrganizerOnlyUserOverride`. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The `DesignatedPresenterRoleMode` setting in the Teams meeting policy is not set to `OrganizerOnlyUserOverride`. + # - Condition B: Verification using the Teams admin center indicates that the setting "Who can present" is not configured to "Only organizers and co-organizers". + # - Condition C: Verification using PowerShell indicates that the `DesignatedPresenterRoleMode` is not set to `OrganizerOnlyUserOverride`. # Retrieve the Teams meeting policy for presenters $CsTeamsMeetingPolicyPresenters = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property DesignatedPresenterRoleMode diff --git a/source/tests/Test-PasswordHashSync.ps1 b/source/tests/Test-PasswordHashSync.ps1 index 83e6d9d..1d8362e 100644 --- a/source/tests/Test-PasswordHashSync.ps1 +++ b/source/tests/Test-PasswordHashSync.ps1 @@ -7,6 +7,22 @@ function Test-PasswordHashSync { ) begin { + # Conditions for 5.1.8.1 (L1) Ensure password hash sync is enabled for hybrid deployments + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: Password hash sync is enabled in the Azure AD Connect tool on the on-premises server. + # - Condition B: Password hash sync is verified as enabled in the Azure AD Connect Sync section in the Microsoft Entra admin center. + # - Condition C: Using Microsoft Graph PowerShell, the verification command returns the expected result indicating that password sync is enabled for the on-premises AD. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: Password hash sync is not enabled in the Azure AD Connect tool on the on-premises server. + # - Condition B: Password hash sync is not verified as enabled in the Azure AD Connect Sync section in the Microsoft Entra admin center. + # - Condition C: Using Microsoft Graph PowerShell, the verification command returns no result indicating that password sync is not enabled for the on-premises AD. + # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed @@ -16,9 +32,8 @@ function Test-PasswordHashSync { process { try { # 5.1.8.1 (L1) Ensure password hash sync is enabled for hybrid deployments - # Pass if OnPremisesSyncEnabled is True. Fail otherwise. - # Retrieve password hash sync status + # Retrieve password hash sync status (Condition A and C) $passwordHashSync = Get-MgOrganization | Select-Object -ExpandProperty OnPremisesSyncEnabled $hashSyncResult = $passwordHashSync diff --git a/source/tests/Test-PasswordNeverExpirePolicy.ps1 b/source/tests/Test-PasswordNeverExpirePolicy.ps1 index b94a22e..5d0723e 100644 --- a/source/tests/Test-PasswordNeverExpirePolicy.ps1 +++ b/source/tests/Test-PasswordNeverExpirePolicy.ps1 @@ -7,6 +7,7 @@ function Test-PasswordNeverExpirePolicy { ) begin { + # .TODO add supported services to output details. ({Email, OfficeCommunicationsOnline, Intune}) # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed @@ -17,11 +18,25 @@ function Test-PasswordNeverExpirePolicy { # Add headers for the details $detailsList += "Domain|Validity Period|IsDefault" + + # Conditions for 1.3.1 (L1) Ensure the 'Password expiration policy' is set to 'Set passwords to never expire (recommended)' + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: Password expiration policy is set to "Set passwords to never expire" in the Microsoft 365 admin center. + # - Condition B: Using Microsoft Graph PowerShell, the `PasswordPolicies` property for all users is set to `DisablePasswordExpiration`. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: Password expiration policy is not set to "Set passwords to never expire" in the Microsoft 365 admin center. + # - Condition B: Using Microsoft Graph PowerShell, the `PasswordPolicies` property for one or more users is not set to `DisablePasswordExpiration`. } process { try { - # Retrieve all domains or a specific domain + # Step: Retrieve all domains or a specific domain $domains = if ($DomainName) { Get-MgDomain -DomainId $DomainName } else { @@ -31,14 +46,14 @@ function Test-PasswordNeverExpirePolicy { foreach ($domain in $domains) { $domainName = $domain.Id $isDefault = $domain.IsDefault - # Retrieve password expiration policy + # Step (Condition A): Retrieve password expiration policy $passwordPolicy = $domain.PasswordValidityPeriodInDays - # Determine if the policy is compliant + # Step (Condition A & B): Determine if the policy is compliant $isCompliant = $passwordPolicy -eq 0 $overallResult = $overallResult -and $isCompliant - # Prepare failure reasons and details based on compliance + # Step (Condition A & B): Prepare failure reasons and details based on compliance $failureReasons = if ($isCompliant) { "N/A" } else { @@ -56,7 +71,7 @@ function Test-PasswordNeverExpirePolicy { $finalFailureReason = $failureReasonsList -join "`n" $finalDetails = $detailsList -join "`n" - # Create and populate the CISAuditResult object + # Step: Create and populate the CISAuditResult object $params = @{ Rec = $recnum Result = $overallResult diff --git a/source/tests/Test-ReauthWithCode.ps1 b/source/tests/Test-ReauthWithCode.ps1 index 6adfd31..feccb93 100644 --- a/source/tests/Test-ReauthWithCode.ps1 +++ b/source/tests/Test-ReauthWithCode.ps1 @@ -7,6 +7,22 @@ function Test-ReauthWithCode { ) begin { + <# + Conditions for 7.2.10 (L1) Ensure reauthentication with verification code is restricted + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The `EmailAttestationRequired` property is set to `True`. + # - Condition B: The `EmailAttestationReAuthDays` property is set to `15` or less. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The `EmailAttestationRequired` property is set to `False`. + # - Condition B: The `EmailAttestationReAuthDays` property is set to more than `15`. + #> + # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed diff --git a/source/tests/Test-ReportSecurityInTeams.ps1 b/source/tests/Test-ReportSecurityInTeams.ps1 index 9c889dd..23b1c47 100644 --- a/source/tests/Test-ReportSecurityInTeams.ps1 +++ b/source/tests/Test-ReportSecurityInTeams.ps1 @@ -9,6 +9,7 @@ function Test-ReportSecurityInTeams { begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 + # Initialization code, if needed $recnum = "8.6.1" } @@ -18,9 +19,14 @@ function Test-ReportSecurityInTeams { # 8.6.1 (L1) Ensure users can report security concerns in Teams # Retrieve the necessary settings for Teams and Exchange Online + # Condition A: Ensure the 'Report a security concern' setting in the Teams admin center is set to 'On'. $CsTeamsMessagingPolicy = Get-CsTeamsMessagingPolicy -Identity Global | Select-Object -Property AllowSecurityEndUserReporting + + # Condition B: Verify that 'Monitor reported messages in Microsoft Teams' is checked in the Microsoft 365 Defender portal. + # Condition C: Ensure the 'Send reported messages to' setting in the Microsoft 365 Defender portal is set to 'My reporting mailbox only' with the correct report email addresses. $ReportSubmissionPolicy = Get-ReportSubmissionPolicy | Select-Object -Property ReportJunkToCustomizedAddress, ReportNotJunkToCustomizedAddress, ReportPhishToCustomizedAddress, ReportChatMessageToCustomizedAddressEnabled + # Check if all the required settings are enabled $securityReportEnabled = $CsTeamsMessagingPolicy.AllowSecurityEndUserReporting -and $ReportSubmissionPolicy.ReportJunkToCustomizedAddress -and $ReportSubmissionPolicy.ReportNotJunkToCustomizedAddress -and @@ -66,7 +72,7 @@ function Test-ReportSecurityInTeams { } end { - # Return auditResult + # Return the audit result return $auditResult } } diff --git a/source/tests/Test-RestrictCustomScripts.ps1 b/source/tests/Test-RestrictCustomScripts.ps1 index fea4a0f..f492085 100644 --- a/source/tests/Test-RestrictCustomScripts.ps1 +++ b/source/tests/Test-RestrictCustomScripts.ps1 @@ -14,14 +14,27 @@ function Test-RestrictCustomScripts { } process { - try { # 7.3.4 (L1) Ensure custom script execution is restricted on site collections + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The `DenyAddAndCustomizePages` setting is set to `Enabled` for each site collection. + # - Condition B: The setting is validated through PowerShell commands ensuring the correct state. + # - Condition C: Verification using the SharePoint Admin Center confirms the `DenyAddAndCustomizePages` setting is enforced. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The `DenyAddAndCustomizePages` setting is not set to `Enabled` for any site collection. + # - Condition B: The setting is not validated through PowerShell commands, indicating misconfiguration. + # - Condition C: Verification using the SharePoint Admin Center indicates that the `DenyAddAndCustomizePages` setting is not enforced. # Retrieve all site collections and select necessary properties $SPOSitesCustomScript = Get-SPOSite -Limit All | Select-Object Title, Url, DenyAddAndCustomizePages - # Replace 'sharepoint.com' with '' + # Process URLs to replace 'sharepoint.com' with '' $processedUrls = $SPOSitesCustomScript | ForEach-Object { $_.Url = $_.Url -replace 'sharepoint\.com', '' $_ diff --git a/source/tests/Test-RestrictExternalSharing.ps1 b/source/tests/Test-RestrictExternalSharing.ps1 index 04b00eb..dc9c016 100644 --- a/source/tests/Test-RestrictExternalSharing.ps1 +++ b/source/tests/Test-RestrictExternalSharing.ps1 @@ -7,6 +7,24 @@ function Test-RestrictExternalSharing { ) begin { + <# + Conditions for 7.2.3 (L1) Ensure external content sharing is restricted + + Validate test for a pass: + - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + - Specific conditions to check: + - Condition A: The SharingCapability is set to "ExternalUserSharingOnly" or more restrictive in the SharePoint admin center. + - Condition B: Using PowerShell, the SharingCapability property for the SharePoint tenant is set to "ExternalUserSharingOnly", "ExistingExternalUserSharingOnly", or "Disabled". + - Condition C: The external sharing settings in SharePoint Online and OneDrive are set to the same or a more restrictive level than the organization’s sharing settings. + + Validate test for a fail: + - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + - Specific conditions to check: + - Condition A: The SharingCapability is set to "Anyone" or "ExternalUserAndGuestSharing" in the SharePoint admin center. + - Condition B: Using PowerShell, the SharingCapability property for the SharePoint tenant is set to "Anyone" or "ExternalUserAndGuestSharing". + - Condition C: The external sharing settings in SharePoint Online and OneDrive are set to a more permissive level than the organization’s sharing settings. + #> + # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed @@ -22,6 +40,7 @@ function Test-RestrictExternalSharing { $isRestricted = $SPOTenantSharingCapability.SharingCapability -in @('ExternalUserSharingOnly', 'ExistingExternalUserSharingOnly', 'Disabled') # Prepare failure reasons and details based on compliance + # Condition B: Using PowerShell, the SharingCapability property for the SharePoint tenant is set to "ExternalUserSharingOnly", "ExistingExternalUserSharingOnly", or "Disabled". $failureReasons = if (-not $isRestricted) { "External content sharing is not adequately restricted. Current setting: $($SPOTenantSharingCapability.SharingCapability)" } @@ -29,6 +48,8 @@ function Test-RestrictExternalSharing { "N/A" } + # Condition A: The SharingCapability is set to "ExternalUserSharingOnly" or more restrictive in the SharePoint admin center. + # Condition C: The external sharing settings in SharePoint Online and OneDrive are set to the same or a more restrictive level than the organization’s sharing settings. $details = "SharingCapability: $($SPOTenantSharingCapability.SharingCapability)" # Create and populate the CISAuditResult object diff --git a/source/tests/Test-RestrictOutlookAddins.ps1 b/source/tests/Test-RestrictOutlookAddins.ps1 index 39f1ae6..6b6eb20 100644 --- a/source/tests/Test-RestrictOutlookAddins.ps1 +++ b/source/tests/Test-RestrictOutlookAddins.ps1 @@ -9,11 +9,26 @@ function Test-RestrictOutlookAddins { begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 + # Initialization code $customPolicyFailures = @() $defaultPolicyFailureDetails = @() $relevantRoles = @('My Custom Apps', 'My Marketplace Apps', 'My ReadWriteMailbox Apps') $recnum = "6.3.1" + + # Conditions for 6.3.1 (L2) Ensure users installing Outlook add-ins is not allowed + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: Verify that the roles MyCustomApps, MyMarketplaceApps, and MyReadWriteMailboxApps are unchecked under Other roles. + # - Condition B: Using PowerShell, verify that MyCustomApps, MyMarketplaceApps, and MyReadWriteMailboxApps are not assigned to users. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: One or more of the roles MyCustomApps, MyMarketplaceApps, and MyReadWriteMailboxApps are checked under Other roles. + # - Condition B: Using PowerShell, verify that MyCustomApps, MyMarketplaceApps, and MyReadWriteMailboxApps are assigned to users. } process { @@ -28,6 +43,8 @@ function Test-RestrictOutlookAddins { if ($policy.RoleAssignmentPolicy) { $rolePolicyDetails = Get-RoleAssignmentPolicy -Identity $policy.RoleAssignmentPolicy $foundRoles = $rolePolicyDetails.AssignedRoles | Where-Object { $_ -in $relevantRoles } + + # Condition B: Using PowerShell, verify that MyCustomApps, MyMarketplaceApps, and MyReadWriteMailboxApps are not assigned to users. if ($foundRoles) { $customPolicyFailures += "Policy: $($policy.RoleAssignmentPolicy): Roles: $($foundRoles -join ', ')" } @@ -38,6 +55,8 @@ function Test-RestrictOutlookAddins { # Check Default Role Assignment Policy $defaultPolicy = Get-RoleAssignmentPolicy "Default Role Assignment Policy" $defaultPolicyRoles = $defaultPolicy.AssignedRoles | Where-Object { $_ -in $relevantRoles } + + # Condition A: Verify that the roles MyCustomApps, MyMarketplaceApps, and MyReadWriteMailboxApps are unchecked under Other roles. if ($defaultPolicyRoles) { $defaultPolicyFailureDetails = $defaultPolicyRoles } diff --git a/source/tests/Test-RestrictStorageProvidersOutlook.ps1 b/source/tests/Test-RestrictStorageProvidersOutlook.ps1 index fa7b256..820796d 100644 --- a/source/tests/Test-RestrictStorageProvidersOutlook.ps1 +++ b/source/tests/Test-RestrictStorageProvidersOutlook.ps1 @@ -7,6 +7,22 @@ function Test-RestrictStorageProvidersOutlook { ) begin { + <# + # 6.5.3 (L2) Ensure additional storage providers are restricted in Outlook on the web + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: Using PowerShell, verify that `AdditionalStorageProvidersAvailable` is set to `False` in the OwaMailboxPolicy. + # - Condition B: Ensure that the command `Get-OwaMailboxPolicy | Format-Table Name, AdditionalStorageProvidersAvailable` returns `False`. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: Using PowerShell, verify that `AdditionalStorageProvidersAvailable` is not set to `False` in the OwaMailboxPolicy. + # - Condition B: Ensure that the command `Get-OwaMailboxPolicy | Format-Table Name, AdditionalStorageProvidersAvailable` does not return `False`. + #> + # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed @@ -19,6 +35,7 @@ function Test-RestrictStorageProvidersOutlook { # Retrieve all OwaMailbox policies $owaPolicies = Get-OwaMailboxPolicy + # Condition A: Check if AdditionalStorageProvidersAvailable is set to False $nonCompliantPolicies = $owaPolicies | Where-Object { $_.AdditionalStorageProvidersAvailable } # Determine compliance @@ -68,5 +85,3 @@ function Test-RestrictStorageProvidersOutlook { return $auditResult } } - -# Additional helper functions (if any) diff --git a/source/tests/Test-RestrictTenantCreation.ps1 b/source/tests/Test-RestrictTenantCreation.ps1 index ede53c4..6d3c314 100644 --- a/source/tests/Test-RestrictTenantCreation.ps1 +++ b/source/tests/Test-RestrictTenantCreation.ps1 @@ -9,8 +9,25 @@ function Test-RestrictTenantCreation { begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 + # Initialization code, if needed $recnum = "5.1.2.3" + + <# + Conditions for 5.1.2.3 (L1) Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes' + + Validate test for a pass: + - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + - Specific conditions to check: + - Condition A: Restrict non-admin users from creating tenants is set to 'Yes' in the Azure AD and Entra administration portal. + - Condition B: Using PowerShell, the setting for restricting non-admin users from creating tenants is set to 'Yes'. + + Validate test for a fail: + - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + - Specific conditions to check: + - Condition A: Restrict non-admin users from creating tenants is not set to 'Yes' in the Azure AD and Entra administration portal. + - Condition B: Using PowerShell, the setting for restricting non-admin users from creating tenants is not set to 'Yes'. + #> } process { @@ -60,5 +77,3 @@ function Test-RestrictTenantCreation { return $auditResult } } - -# Additional helper functions (if any) diff --git a/source/tests/Test-SafeAttachmentsPolicy.ps1 b/source/tests/Test-SafeAttachmentsPolicy.ps1 index 18a90a2..8b5fe06 100644 --- a/source/tests/Test-SafeAttachmentsPolicy.ps1 +++ b/source/tests/Test-SafeAttachmentsPolicy.ps1 @@ -9,8 +9,29 @@ function Test-SafeAttachmentsPolicy { begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 + # Initialization code, if needed $recnum = "2.1.4" + + <# + Conditions for 2.1.4 (L2) Ensure Safe Attachments policy is enabled + + Validate test for a pass: + - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + - Specific conditions to check: + - Condition A: The Safe Attachments policy is enabled in the Microsoft 365 Defender portal. + - Condition B: The policy covers all recipients within the organization. + - Condition C: The policy action is set to "Dynamic Delivery" or "Quarantine". + - Condition D: The policy is not disabled. + + Validate test for a fail: + - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + - Specific conditions to check: + - Condition A: The Safe Attachments policy is not enabled in the Microsoft 365 Defender portal. + - Condition B: The policy does not cover all recipients within the organization. + - Condition C: The policy action is not set to "Dynamic Delivery" or "Quarantine". + - Condition D: The policy is disabled. + #> } process { @@ -20,8 +41,12 @@ function Test-SafeAttachmentsPolicy { # 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 + # Condition A: Check if any Safe Attachments policy is enabled $result = $null -ne $safeAttachmentPolicies -and $safeAttachmentPolicies.Count -gt 0 + + # Condition B, C, D: Additional checks can be added here if more detailed policy attributes are required + + # Determine details and failure reasons based on the presence of enabled policies $details = if ($result) { "Enabled Safe Attachments Policies: $($safeAttachmentPolicies.Name -join ', ')" } @@ -66,4 +91,3 @@ function Test-SafeAttachmentsPolicy { } } -# Additional helper functions (if any) diff --git a/source/tests/Test-SafeAttachmentsTeams.ps1 b/source/tests/Test-SafeAttachmentsTeams.ps1 index 1fae789..8c0b5f3 100644 --- a/source/tests/Test-SafeAttachmentsTeams.ps1 +++ b/source/tests/Test-SafeAttachmentsTeams.ps1 @@ -9,6 +9,23 @@ function Test-SafeAttachmentsTeams { begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 + + # Conditions for 2.1.5 (L2) Ensure Safe Attachments for SharePoint, OneDrive, and Microsoft Teams is Enabled + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: Safe Attachments for SharePoint is enabled. + # - Condition B: Safe Attachments for OneDrive is enabled. + # - Condition C: Safe Attachments for Microsoft Teams is enabled. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: Safe Attachments for SharePoint is not enabled. + # - Condition B: Safe Attachments for OneDrive is not enabled. + # - Condition C: Safe Attachments for Microsoft Teams is not enabled. + # Initialization code, if needed $recnum = "2.1.5" } @@ -27,6 +44,10 @@ function Test-SafeAttachmentsTeams { $_.AllowSafeDocsOpen -eq $false } + # Condition A: Check Safe Attachments for SharePoint + # Condition B: Check Safe Attachments for OneDrive + # Condition C: Check Safe Attachments for Microsoft Teams + # Determine the result based on the ATP policy settings $result = $null -ne $atpPolicyResult $details = if ($result) { @@ -71,6 +92,4 @@ function Test-SafeAttachmentsTeams { # Return the audit result return $auditResult } -} - -# Additional helper functions (if any) +} \ No newline at end of file diff --git a/source/tests/Test-SafeLinksOfficeApps.ps1 b/source/tests/Test-SafeLinksOfficeApps.ps1 index aa30dbc..37a864b 100644 --- a/source/tests/Test-SafeLinksOfficeApps.ps1 +++ b/source/tests/Test-SafeLinksOfficeApps.ps1 @@ -11,6 +11,32 @@ function Test-SafeLinksOfficeApps { #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed $recnum = "2.1.1" + + <# + Conditions for 2.1.1 (L2) Ensure Safe Links for Office Applications is Enabled + + Validate test for a pass: + - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + - Specific conditions to check: + - Condition A: In the Microsoft 365 security center, Safe Links policy for Office applications is enabled and the following protection settings are set: + - Office 365 Apps: On + - Teams: On + - Email: On + - Click protection settings: On + - Do not track when users click safe links: Off + - Condition B: Using the Exchange Online PowerShell Module, Safe Links policies are retrieved, and the relevant policy shows Safe Links for Office applications is enabled. + + Validate test for a fail: + - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + - Specific conditions to check: + - Condition A: In the Microsoft 365 security center, Safe Links policy for Office applications is not enabled or one or more of the required protection settings are not set correctly. + - Office 365 Apps: Off + - Teams: Off + - Email: Off + - Click protection settings: Off + - Do not track when users click safe links: On + - Condition B: Using the Exchange Online PowerShell Module, Safe Links policies are retrieved, and the relevant policy shows Safe Links for Office applications is not enabled. + #> } process { @@ -28,16 +54,13 @@ function Test-SafeLinksOfficeApps { $policyDetails = Get-SafeLinksPolicy -Identity $policy.Name # Check each required property and record failures + # Condition A: Checking policy settings $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" } + if ($policyDetails.EnableSafeLinksForEmail -ne $true) { $failures += "EnableSafeLinksForEmail: False" } # Email: On + if ($policyDetails.EnableSafeLinksForTeams -ne $true) { $failures += "EnableSafeLinksForTeams: False" } # Teams: On + if ($policyDetails.EnableSafeLinksForOffice -ne $true) { $failures += "EnableSafeLinksForOffice: False" } # Office 365 Apps: On + if ($policyDetails.TrackClicks -ne $true) { $failures += "TrackClicks: False" } # Click protection settings: On + if ($policyDetails.AllowClickThrough -ne $false) { $failures += "AllowClickThrough: True" } # Do not track when users click safe links: Off # Only add details for policies that have misconfigurations if ($failures.Count -gt 0) { @@ -46,6 +69,7 @@ function Test-SafeLinksOfficeApps { } # Prepare the final result + # Condition B: Ensuring no misconfigurations $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 ' | ')" } diff --git a/source/tests/Test-SharePointAADB2B.ps1 b/source/tests/Test-SharePointAADB2B.ps1 index c95e415..fa1f733 100644 --- a/source/tests/Test-SharePointAADB2B.ps1 +++ b/source/tests/Test-SharePointAADB2B.ps1 @@ -7,11 +7,26 @@ function Test-SharePointAADB2B { ) begin { + # Conditions for 7.2.2 (L1) Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: Ensure the `EnableAzureADB2BIntegration` property is set to `True` for the SharePoint tenant. + # - Condition B: Verify that the SharePoint and OneDrive integration with Azure AD B2B is active. + # - Condition C: Ensure that guest accounts are managed in Azure AD and subject to access policies. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The `EnableAzureADB2BIntegration` property is set to `False` for the SharePoint tenant. + # - Condition B: The integration between SharePoint, OneDrive, and Azure AD B2B is not active. + # - Condition C: Guest accounts are not managed in Azure AD and are not subject to access policies. + # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed - $auditResult = [CISAuditResult]::new() $recnum = "7.2.2" } diff --git a/source/tests/Test-SharePointExternalSharingDomains.ps1 b/source/tests/Test-SharePointExternalSharingDomains.ps1 index ee309d7..035dc29 100644 --- a/source/tests/Test-SharePointExternalSharingDomains.ps1 +++ b/source/tests/Test-SharePointExternalSharingDomains.ps1 @@ -9,10 +9,25 @@ function Test-SharePointExternalSharingDomains { begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 - # Initialization code, if needed - $auditResult = [CISAuditResult]::new() + # Initialization code, if needed $recnum = "7.2.6" + + # Conditions for 7.2.6 (L2) Ensure SharePoint external sharing is managed through domain whitelist/blacklists + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The "Limit external sharing by domain" option is enabled in the SharePoint admin center. + # - Condition B: The "SharingDomainRestrictionMode" is set to "AllowList" using PowerShell. + # - Condition C: The "SharingAllowedDomainList" contains the domains trusted by the organization for external sharing. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The "Limit external sharing by domain" option is not enabled in the SharePoint admin center. + # - Condition B: The "SharingDomainRestrictionMode" is not set to "AllowList" using PowerShell. + # - Condition C: The "SharingAllowedDomainList" does not contain the domains trusted by the organization for external sharing. } process { diff --git a/source/tests/Test-SharePointGuestsItemSharing.ps1 b/source/tests/Test-SharePointGuestsItemSharing.ps1 index 75159b4..0ac33e2 100644 --- a/source/tests/Test-SharePointGuestsItemSharing.ps1 +++ b/source/tests/Test-SharePointGuestsItemSharing.ps1 @@ -11,8 +11,23 @@ function Test-SharePointGuestsItemSharing { #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed - $auditResult = [CISAuditResult]::new() $recnum = "7.2.5" + + # Conditions for 7.2.5 (L2) Ensure that SharePoint guest users cannot share items they don't own + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The SharePoint setting "PreventExternalUsersFromResharing" is set to `True` using PowerShell. + # - Condition B: The SharePoint admin center setting "Allow guests to share items they don't own" is unchecked. + # - Condition C: Ensure that external users cannot re-share items they don't own. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The SharePoint setting "PreventExternalUsersFromResharing" is set to `False` using PowerShell. + # - Condition B: The SharePoint admin center setting "Allow guests to share items they don't own" is checked. + # - Condition C: Ensure that external users can re-share items they don't own. } process { diff --git a/source/tests/Test-SpamPolicyAdminNotify.ps1 b/source/tests/Test-SpamPolicyAdminNotify.ps1 index 8f100c7..314d6fd 100644 --- a/source/tests/Test-SpamPolicyAdminNotify.ps1 +++ b/source/tests/Test-SpamPolicyAdminNotify.ps1 @@ -11,23 +11,41 @@ function Test-SpamPolicyAdminNotify { #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed - $auditResult = [CISAuditResult]::new() $recnum = "2.1.6" + + <# + Conditions for 2.1.6 (L1) Ensure Exchange Online Spam Policies are set to notify administrators + + Validate recommendation details: + - Confirm that the recommendation details are accurate and complete as per the CIS benchmark. + + Validate test for a pass: + - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + - Specific conditions to check: + - Condition A: In the Microsoft 365 Security & Compliance Center, the Exchange Online Spam Policies are set to notify administrators when a sender in the organization has been blocked for sending spam emails. + - Condition B: Using PowerShell, the `NotifyOutboundSpam` and `NotifyOutboundSpamContact` properties are correctly set in all relevant spam filter policies. + + Validate test for a fail: + - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + - Specific conditions to check: + - Condition A: In the Microsoft 365 Security & Compliance Center, the Exchange Online Spam Policies are not set to notify administrators when a sender in the organization has been blocked for sending spam emails. + - Condition B: Using PowerShell, the `NotifyOutboundSpam` and `NotifyOutboundSpamContact` properties are not correctly set in all relevant spam filter policies. + #> } process { try { # 2.1.6 Ensure Exchange Online Spam Policies are set to notify administrators - # Get the default hosted outbound spam filter policy + # Retrieve the default hosted outbound spam filter policy $hostedOutboundSpamFilterPolicy = Get-HostedOutboundSpamFilterPolicy | Where-Object { $_.IsDefault -eq $true } - # Check if both settings are enabled + # Check if both settings are enabled (Condition A and Condition B for pass) $bccSuspiciousOutboundMailEnabled = $hostedOutboundSpamFilterPolicy.BccSuspiciousOutboundMail $notifyOutboundSpamEnabled = $hostedOutboundSpamFilterPolicy.NotifyOutboundSpam $areSettingsEnabled = $bccSuspiciousOutboundMailEnabled -and $notifyOutboundSpamEnabled - # Prepare failure details if any setting is not enabled + # Prepare failure details if any setting is not enabled (Condition A and Condition B for fail) $failureDetails = @() if (-not $bccSuspiciousOutboundMailEnabled) { $failureDetails += "BccSuspiciousOutboundMail is not enabled." @@ -65,3 +83,4 @@ function Test-SpamPolicyAdminNotify { return $auditResult } } + diff --git a/source/tests/Test-TeamsExternalAccess.ps1 b/source/tests/Test-TeamsExternalAccess.ps1 index aec7caa..a6d4bbb 100644 --- a/source/tests/Test-TeamsExternalAccess.ps1 +++ b/source/tests/Test-TeamsExternalAccess.ps1 @@ -8,7 +8,7 @@ function Test-TeamsExternalAccess { begin { # Dot source the class script if necessary - #. .\source\Classes\CISAuditResult.ps1 + # . .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed $auditResult = [CISAuditResult]::new() @@ -18,6 +18,20 @@ function Test-TeamsExternalAccess { process { try { # 8.2.1 (L1) Ensure 'external access' is restricted in the Teams admin center + # + # Validate test for a pass: + # - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark. + # - Specific conditions to check: + # - Condition A: The `AllowTeamsConsumer` setting is `False`. + # - Condition B: The `AllowPublicUsers` setting is `False`. + # - Condition C: The `AllowFederatedUsers` setting is `False` or, if `True`, the `AllowedDomains` contains only authorized domain names. + # + # Validate test for a fail: + # - Confirm that the failure conditions in the automated test are consistent with the manual audit results. + # - Specific conditions to check: + # - Condition A: The `AllowTeamsConsumer` setting is not `False`. + # - Condition B: The `AllowPublicUsers` setting is not `False`. + # - Condition C: The `AllowFederatedUsers` setting is `True` and the `AllowedDomains` contains unauthorized domain names or is not configured correctly. # Connect to Teams PowerShell using Connect-MicrosoftTeams diff --git a/source/tests/Test-TeamsExternalFileSharing.ps1 b/source/tests/Test-TeamsExternalFileSharing.ps1 index 92ef78c..6502fa0 100644 --- a/source/tests/Test-TeamsExternalFileSharing.ps1 +++ b/source/tests/Test-TeamsExternalFileSharing.ps1 @@ -8,10 +8,8 @@ function Test-TeamsExternalFileSharing { begin { # Dot source the class script if necessary - #. .\source\Classes\CISAuditResult.ps1 + # . .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed - - $auditResult = [CISAuditResult]::new() $recnum = "8.1.1" } @@ -20,6 +18,12 @@ function Test-TeamsExternalFileSharing { # 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 + # Condition A: The `AllowDropbox` setting is set to `False`. + # Condition B: The `AllowBox` setting is set to `False`. + # Condition C: The `AllowGoogleDrive` setting is set to `False`. + # Condition D: The `AllowShareFile` setting is set to `False`. + # Condition E: The `AllowEgnyte` setting is set to `False`. + # 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")