diff --git a/CHANGELOG.md b/CHANGELOG.md index cc58231..fff4627 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,24 @@ The format is based on and uses the types of changes according to [Keep a Change ## [Unreleased] +# Fixed + +- SPO tests formatting and output. + +## [0.1.22] - 2024-07-01 + +### Added + +- Added hash and compress steps to `Export-M365SecurityAuditTable` function. + +## [0.1.21] - 2024-07-01 + +### Fixed + +- SPO tests formatting and output. + +## [0.1.22] - 2024-07-01 + ### Added - Added hash and compress steps to `Export-M365SecurityAuditTable` function. diff --git a/source/Private/Get-CISSpoOutput.ps1 b/source/Private/Get-CISSpoOutput.ps1 index 06c56a4..99362cd 100644 --- a/source/Private/Get-CISSpoOutput.ps1 +++ b/source/Private/Get-CISSpoOutput.ps1 @@ -40,12 +40,24 @@ function Get-CISSpoOutput { switch ($Rec) { '7.2.1' { # Test-ModernAuthSharePoint.ps1 + # $SPOTenant Mock Object + <# + $SPOTenant = [PSCustomObject]@{ + LegacyAuthProtocolsEnabled = $true + } + #> $SPOTenant = Get-SPOTenant | Select-Object -Property LegacyAuthProtocolsEnabled return $SPOTenant } '7.2.2' { # Test-SharePointAADB2B.ps1 # 7.2.2 (L1) Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled + # $SPOTenantAzureADB2B Mock Object + <# + $SPOTenantAzureADB2B = [PSCustomObject]@{ + EnableAzureADB2BIntegration = $false + } + #> $SPOTenantAzureADB2B = Get-SPOTenant | Select-Object EnableAzureADB2BIntegration return $SPOTenantAzureADB2B } @@ -53,35 +65,75 @@ function Get-CISSpoOutput { # Test-RestrictExternalSharing.ps1 # 7.2.3 (L1) Ensure external content sharing is restricted # Retrieve the SharingCapability setting for the SharePoint tenant + # $SPOTenantSharingCapability Mock Object + <# + $SPOTenantSharingCapability = [PSCustomObject]@{ + SharingCapability = "ExternalUserAndGuestSharing" + } + #> $SPOTenantSharingCapability = Get-SPOTenant | Select-Object SharingCapability return $SPOTenantSharingCapability } '7.2.4' { # Test-OneDriveContentRestrictions.ps1 + # 7.2.4 (L2) Ensure OneDrive content sharing is restricted + # $SPOTenant Mock Object + <# + $SPOTenant = [PSCustomObject]@{ + OneDriveSharingCapability = "ExternalUserAndGuestSharing" + } + #> $SPOTenant = Get-SPOTenant | Select-Object OneDriveSharingCapability return $SPOTenant } '7.2.5' { # Test-SharePointGuestsItemSharing.ps1 # 7.2.5 (L2) Ensure that SharePoint guest users cannot share items they don't own + # $SPOTenant Mock Object + <# + $SPOTenant = [PSCustomObject]@{ + PreventExternalUsersFromResharing = $false + } + #> $SPOTenant = Get-SPOTenant | Select-Object PreventExternalUsersFromResharing return $SPOTenant } '7.2.6' { # Test-SharePointExternalSharingDomains.ps1 # 7.2.6 (L2) Ensure SharePoint external sharing is managed through domain whitelist/blacklists + # Add Authorized Domains? + # $SPOTenant Mock Object + <# + $SPOTenant = [PSCustomObject]@{ + SharingDomainRestrictionMode = "AllowList" + SharingAllowedDomainList = "domain1.com", "domain2.com" + } + #> $SPOTenant = Get-SPOTenant | Select-Object SharingDomainRestrictionMode, SharingAllowedDomainList return $SPOTenant } '7.2.7' { # Test-LinkSharingRestrictions.ps1 # Retrieve link sharing configuration for SharePoint and OneDrive + # $SPOTenantLinkSharing Mock Object + <# + $$SPOTenantLinkSharing = [PSCustomObject]@{ + DefaultSharingLinkType = "Direct" + } + #> $SPOTenantLinkSharing = Get-SPOTenant | Select-Object DefaultSharingLinkType return $SPOTenantLinkSharing } '7.2.9' { # Test-GuestAccessExpiration.ps1 # Retrieve SharePoint tenant settings related to guest access expiration + # $SPOTenantGuestAccess Mock Object + <# + $SPOTenantGuestAccess = [PSCustomObject]@{ + ExternalUserExpirationRequired = "$false" + ExternalUserExpireInDays = "60" + } + #> $SPOTenantGuestAccess = Get-SPOTenant | Select-Object ExternalUserExpirationRequired, ExternalUserExpireInDays return $SPOTenantGuestAccess } @@ -89,24 +141,53 @@ function Get-CISSpoOutput { # Test-ReauthWithCode.ps1 # 7.2.10 (L1) Ensure reauthentication with verification code is restricted # Retrieve reauthentication settings for SharePoint Online + # $SPOTenantReauthentication Mock Object + <# + $SPOTenantReauthentication = [PSCustomObject]@{ + EmailAttestationRequired = "$false" + EmailAttestationReAuthDays = "30" + } + #> $SPOTenantReauthentication = Get-SPOTenant | Select-Object EmailAttestationRequired, EmailAttestationReAuthDays return $SPOTenantReauthentication } '7.3.1' { # Test-DisallowInfectedFilesDownload.ps1 # Retrieve the SharePoint tenant configuration + # $SPOTenantDisallowInfectedFileDownload Mock Object + <# + $SPOTenantDisallowInfectedFileDownload = [PSCustomObject]@{ + DisallowInfectedFileDownload = $false + } + #> $SPOTenantDisallowInfectedFileDownload = Get-SPOTenant | Select-Object DisallowInfectedFileDownload return $SPOTenantDisallowInfectedFileDownload } '7.3.2' { # Test-OneDriveSyncRestrictions.ps1 # Retrieve OneDrive sync client restriction settings + # Add isHybrid paramter? + # $SPOTenantSyncClientRestriction Mock Object + <# + $SPOTenantSyncClientRestriction = [PSCustomObject]@{ + TenantRestrictionEnabled = $true + AllowedDomainList = "786548DD-877B-4760-A749-6B1EFBC1190A", "877564FF-877B-4760-A749-6B1EFBC1190A" + } + #> $SPOTenantSyncClientRestriction = Get-SPOTenantSyncClientRestriction | Select-Object TenantRestrictionEnabled, AllowedDomainList return $SPOTenantSyncClientRestriction } '7.3.4' { # Test-RestrictCustomScripts.ps1 # Retrieve all site collections and select necessary properties + # $SPOSitesCustomScript Mock Object + <# + $SPOSitesCustomScript = [PSCustomObject]@{ + Title = "Site Collection 1" + Url = "https://contoso.sharepoint.com/sites/site1" + DenyAddAndCustomizePages = "Enabled" + } + #> $SPOSitesCustomScript = Get-SPOSite -Limit All | Select-Object Title, Url, DenyAddAndCustomizePages return $SPOSitesCustomScript } diff --git a/source/Public/Export-M365SecurityAuditTable.ps1 b/source/Public/Export-M365SecurityAuditTable.ps1 index e194998..5003275 100644 --- a/source/Public/Export-M365SecurityAuditTable.ps1 +++ b/source/Public/Export-M365SecurityAuditTable.ps1 @@ -257,4 +257,4 @@ function Export-M365SecurityAuditTable { ########### $createdFiles #} } -} +} \ No newline at end of file diff --git a/source/tests/Test-DisallowInfectedFilesDownload.ps1 b/source/tests/Test-DisallowInfectedFilesDownload.ps1 index 851c90b..8afd659 100644 --- a/source/tests/Test-DisallowInfectedFilesDownload.ps1 +++ b/source/tests/Test-DisallowInfectedFilesDownload.ps1 @@ -5,17 +5,14 @@ function Test-DisallowInfectedFilesDownload { # Aligned # Define your parameters here if needed ) - begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 - # Initialization code, if needed $recnum = "7.3.1" + Write-Verbose "Running Test-DisallowInfectedFilesDownload for $recnum..." } - process { - try { # 7.3.1 (L2) Ensure Office 365 SharePoint infected files are disallowed for download # @@ -32,28 +29,30 @@ function Test-DisallowInfectedFilesDownload { # - 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 Mock Object + <# + $SPOTenantDisallowInfectedFileDownload = [PSCustomObject]@{ + DisallowInfectedFileDownload = $false + } + #> $SPOTenantDisallowInfectedFileDownload = Get-CISSpoOutput -Rec $recnum - # 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." # Condition B: The setting does not prevent users from downloading infected files + "Downloading infected files is not disallowed. To ensure infected files cannot be downloaded, use the following command:`n" + ` # Condition B: The setting does not prevent users from downloading infected files + "Set-SPOTenant -DisallowInfectedFileDownload `$true" } else { "N/A" } - $details = if ($isDisallowInfectedFileDownloadEnabled) { "DisallowInfectedFileDownload: True" # Condition C: Verification confirms the setting is correctly configured } else { "DisallowInfectedFileDownload: False" # Condition C: Verification indicates the setting is incorrectly configured } - # Create and populate the CISAuditResult object $params = @{ Rec = $recnum @@ -69,9 +68,8 @@ function Test-DisallowInfectedFilesDownload { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return the audit result return $auditResult } -} +} \ No newline at end of file diff --git a/source/tests/Test-GuestAccessExpiration.ps1 b/source/tests/Test-GuestAccessExpiration.ps1 index 92d40a0..666ad61 100644 --- a/source/tests/Test-GuestAccessExpiration.ps1 +++ b/source/tests/Test-GuestAccessExpiration.ps1 @@ -5,17 +5,14 @@ function Test-GuestAccessExpiration { # Aligned # Define your parameters here if needed ) - begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 - # Initialization code, if needed $recnum = "7.2.9" + Write-Verbose "Running Test-GuestAccessExpiration for $recnum..." } - process { - try { # 7.2.9 (L1) Ensure guest access to a site or OneDrive will expire automatically # @@ -32,21 +29,25 @@ function Test-GuestAccessExpiration { # - 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 Mock Object + <# + $SPOTenantGuestAccess = [PSCustomObject]@{ + ExternalUserExpirationRequired = "$false" + ExternalUserExpireInDays = "60" + } + #> $SPOTenantGuestAccess = Get-CISSpoOutput -Rec $recnum $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." + "Guest access expiration is not configured to automatically expire within 30 days or less. To remediate this setting, use the Set-SPOTenant command:`n`n" + ` + "Set-SPOTenant -ExternalUserExpirationRequired `$true -ExternalUserExpireInDays 30" } else { "N/A" } - $details = "ExternalUserExpirationRequired: $($SPOTenantGuestAccess.ExternalUserExpirationRequired); ExternalUserExpireInDays: $($SPOTenantGuestAccess.ExternalUserExpireInDays)" - # Create and populate the CISAuditResult object $params = @{ Rec = $recnum @@ -62,7 +63,6 @@ function Test-GuestAccessExpiration { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return the audit result return $auditResult diff --git a/source/tests/Test-LinkSharingRestrictions.ps1 b/source/tests/Test-LinkSharingRestrictions.ps1 index 9816d51..08fdab0 100644 --- a/source/tests/Test-LinkSharingRestrictions.ps1 +++ b/source/tests/Test-LinkSharingRestrictions.ps1 @@ -6,14 +6,13 @@ function Test-LinkSharingRestrictions { # Define your parameters here # Test behavior in prod ) - begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed $recnum = "7.2.7" + Write-Verbose "Running Test-LinkSharingRestrictions for $recnum..." } - process { try { # 7.2.7 (L1) Ensure link sharing is restricted in SharePoint and OneDrive @@ -31,21 +30,24 @@ function Test-LinkSharingRestrictions { # - 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 Mock Object + <# + $$SPOTenantLinkSharing = [PSCustomObject]@{ + DefaultSharingLinkType = "Direct" + } + #> $SPOTenantLinkSharing = Get-CISSpoOutput -Rec $recnum $isLinkSharingRestricted = $SPOTenantLinkSharing.DefaultSharingLinkType -eq 'Direct' # Or 'SpecificPeople' as per the recommendation - # Prepare failure reasons and details based on compliance $failureReasons = if (-not $isLinkSharingRestricted) { - "Link sharing is not restricted to 'Specific people'. Current setting: $($SPOTenantLinkSharing.DefaultSharingLinkType)" + "Link sharing is not restricted to 'Specific people'. Current setting: $($SPOTenantLinkSharing.DefaultSharingLinkType). To remediate this setting, use the Set-SPOTenant command:`n`n" + ` + "Set-SPOTenant -DefaultSharingLinkType Direct" } else { "N/A" } - $details = "DefaultSharingLinkType: $($SPOTenantLinkSharing.DefaultSharingLinkType)" - # Create and populate the CISAuditResult object $params = @{ Rec = $recnum @@ -55,14 +57,12 @@ function Test-LinkSharingRestrictions { FailureReason = $failureReasons } $auditResult = Initialize-CISAuditResult @params - } catch { $LastError = $_ $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return the audit result return $auditResult diff --git a/source/tests/Test-ModernAuthSharePoint.ps1 b/source/tests/Test-ModernAuthSharePoint.ps1 index 64e2598..15fbb81 100644 --- a/source/tests/Test-ModernAuthSharePoint.ps1 +++ b/source/tests/Test-ModernAuthSharePoint.ps1 @@ -12,16 +12,14 @@ function Test-ModernAuthSharePoint { # Initialization code, if needed $recnum = "7.2.1" - + Write-Verbose "Running Test-ModernAuthSharePoint for $recnum..." <# # 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: @@ -29,23 +27,25 @@ function Test-ModernAuthSharePoint { # - Condition B: The PowerShell command `Get-SPOTenant | ft LegacyAuthProtocolsEnabled` returns `True`. #> } - process { try { # 7.2.1 (L1) Ensure modern authentication for SharePoint applications is required + # $SPOTenant Mock Object + <# + $SPOTenant = [PSCustomObject]@{ + LegacyAuthProtocolsEnabled = $true + } + #> $SPOTenant = Get-CISSpoOutput -Rec $recnum $modernAuthForSPRequired = -not $SPOTenant.LegacyAuthProtocolsEnabled - # Prepare failure reasons and details based on compliance $failureReasons = if (-not $modernAuthForSPRequired) { - "Legacy authentication protocols are enabled" # Fail Condition B + "Legacy authentication protocols are enabled. The following command can be used to disable:`nSet-SPOTenant -LegacyAuthProtocolsEnabled `$false" # Fail Condition B } else { "N/A" } - $details = "LegacyAuthProtocolsEnabled: $($SPOTenant.LegacyAuthProtocolsEnabled)" # Details for Condition B - # Create and populate the CISAuditResult object $params = @{ Rec = $recnum @@ -61,7 +61,6 @@ function Test-ModernAuthSharePoint { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return the audit result return $auditResult diff --git a/source/tests/Test-OneDriveContentRestrictions.ps1 b/source/tests/Test-OneDriveContentRestrictions.ps1 index 44b9d7f..d97da01 100644 --- a/source/tests/Test-OneDriveContentRestrictions.ps1 +++ b/source/tests/Test-OneDriveContentRestrictions.ps1 @@ -5,7 +5,6 @@ function Test-OneDriveContentRestrictions { # Aligned # Define your parameters here ) - begin { # 7.2.4 (L2) Ensure OneDrive content sharing is restricted # @@ -22,36 +21,38 @@ function Test-OneDriveContentRestrictions { # - 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 $recnum = "7.2.4" + Write-Verbose "Running Test-OneDriveContentRestrictions for $recnum..." } - process { try { # 7.2.4 (L2) Ensure OneDrive content sharing is restricted - # Retrieve OneDrive sharing capability settings + # $SPOTenant Mock Object + <# + $SPOTenant = [PSCustomObject]@{ + OneDriveSharingCapability = "ExternalUserAndGuestSharing" + } + #> $SPOTenant = Get-CISSpoOutput -Rec $recnum $isOneDriveSharingRestricted = $SPOTenant.OneDriveSharingCapability -eq 'Disabled' - # Prepare failure reasons and details based on compliance $failureReasons = if (-not $isOneDriveSharingRestricted) { - "OneDrive content sharing is not restricted to 'Disabled'. Current setting: $($SPOTenant.OneDriveSharingCapability)" + "OneDrive content sharing is not restricted to 'Disabled'. To remediate this setting, use the Set-SPOTenant command.`n`n" + ` + "Set-SPOTenant -OneDriveSharingCapability Disabled" } else { "N/A" } - $details = if ($isOneDriveSharingRestricted) { "OneDrive content sharing is restricted." } else { "OneDriveSharingCapability: $($SPOTenant.OneDriveSharingCapability)" } - # Create and populate the CISAuditResult object $params = @{ Rec = $recnum @@ -67,7 +68,6 @@ function Test-OneDriveContentRestrictions { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return auditResult return $auditResult diff --git a/source/tests/Test-OneDriveSyncRestrictions.ps1 b/source/tests/Test-OneDriveSyncRestrictions.ps1 index f689d37..b78eeae 100644 --- a/source/tests/Test-OneDriveSyncRestrictions.ps1 +++ b/source/tests/Test-OneDriveSyncRestrictions.ps1 @@ -5,14 +5,13 @@ function Test-OneDriveSyncRestrictions { # Aligned # Define your parameters here ) - begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed $recnum = "7.3.2" + Write-Verbose "Running Test-OneDriveSyncRestrictions for $recnum..." } - process { try { # 7.3.2 (L2) Ensure OneDrive sync is restricted for unmanaged devices @@ -30,20 +29,20 @@ function Test-OneDriveSyncRestrictions { # - 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-CISSpoOutput -Rec $recnum $isSyncRestricted = $SPOTenantSyncClientRestriction.TenantRestrictionEnabled -and $SPOTenantSyncClientRestriction.AllowedDomainList - # 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." + "OneDrive sync is not restricted to managed devices. For hybrid devices, TenantRestrictionEnabled should be True and AllowedDomainList should contain trusted domains GUIDs.`n" + ` + "To remediate this setting, edit and use the Set-SPOTenantSyncClientRestriction command below:`n" + ` + "Set-SPOTenantSyncClientRestriction -TenantRestrictionEnabled `$true -AllowedDomainList `"`",`"`"`n`n" + ` + "Note: Utilize the -BlockMacSync:`$true parameter if you are not using conditional access to ensure Macs cannot sync." } else { "N/A" } - # Condition C: Prepare details based on whether sync is restricted $details = if ($isSyncRestricted) { "OneDrive sync is restricted for unmanaged devices." @@ -51,7 +50,6 @@ function Test-OneDriveSyncRestrictions { else { "TenantRestrictionEnabled: $($SPOTenantSyncClientRestriction.TenantRestrictionEnabled); AllowedDomainList: $($SPOTenantSyncClientRestriction.AllowedDomainList -join ', ')" } - # Create and populate the CISAuditResult object $params = @{ Rec = $recnum @@ -67,7 +65,6 @@ function Test-OneDriveSyncRestrictions { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return auditResult return $auditResult diff --git a/source/tests/Test-ReauthWithCode.ps1 b/source/tests/Test-ReauthWithCode.ps1 index 9e68202..1ec2bb0 100644 --- a/source/tests/Test-ReauthWithCode.ps1 +++ b/source/tests/Test-ReauthWithCode.ps1 @@ -5,7 +5,6 @@ function Test-ReauthWithCode { # Aligned # Define your parameters here ) - begin { <# Conditions for 7.2.10 (L1) Ensure reauthentication with verification code is restricted @@ -22,31 +21,34 @@ function Test-ReauthWithCode { # - 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 $recnum = "7.2.10" + Write-Verbose "Running Test-ReauthWithCode for $recnum..." } - process { try { # 7.2.10 (L1) Ensure reauthentication with verification code is restricted - # Retrieve reauthentication settings for SharePoint Online + # $SPOTenantReauthentication Mock Object + <# + $SPOTenantReauthentication = [PSCustomObject]@{ + EmailAttestationRequired = "$false" + EmailAttestationReAuthDays = "30" + } + #> $SPOTenantReauthentication = Get-CISSpoOutput -Rec $recnum $isReauthenticationRestricted = $SPOTenantReauthentication.EmailAttestationRequired -and $SPOTenantReauthentication.EmailAttestationReAuthDays -le 15 - # Prepare failure reasons and details based on compliance $failureReasons = if (-not $isReauthenticationRestricted) { - "Reauthentication with verification code does not require reauthentication within 15 days or less." + "Reauthentication with verification code does not require reauthentication within 15 days or less. To remediate this setting, use the Set-SPOTenant command:`n" + ` + "Set-SPOTenant -EmailAttestationRequired `$true -EmailAttestationReAuthDays 15" } else { "N/A" } - $details = "EmailAttestationRequired: $($SPOTenantReauthentication.EmailAttestationRequired); EmailAttestationReAuthDays: $($SPOTenantReauthentication.EmailAttestationReAuthDays)" - # Create and populate the CISAuditResult object $params = @{ Rec = $recnum @@ -62,7 +64,6 @@ function Test-ReauthWithCode { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return auditResult return $auditResult diff --git a/source/tests/Test-RestrictCustomScripts.ps1 b/source/tests/Test-RestrictCustomScripts.ps1 index 88f1c75..b9f9cda 100644 --- a/source/tests/Test-RestrictCustomScripts.ps1 +++ b/source/tests/Test-RestrictCustomScripts.ps1 @@ -4,15 +4,13 @@ function Test-RestrictCustomScripts { param ( # Define your parameters here if needed ) - begin { # Dot source the class script if necessary # . .\source\Classes\CISAuditResult.ps1 - # Initialization code, if needed $recnum = "7.3.4" + Write-Verbose "Running Test-RestrictCustomScripts for $recnum..." } - process { try { # 7.3.4 (L1) Ensure custom script execution is restricted on site collections @@ -30,23 +28,27 @@ function Test-RestrictCustomScripts { # - 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 Mock Object + <# + $SPOSitesCustomScript = [PSCustomObject]@{ + Title = "Site Collection 1" + Url = "https://contoso.sharepoint.com/sites/site1" + DenyAddAndCustomizePages = "Enabled" + } + #> $SPOSitesCustomScript = Get-CISSpoOutput -Rec $recnum - # Process URLs to replace 'sharepoint.com' with '' $processedUrls = $SPOSitesCustomScript | ForEach-Object { $_.Url = $_.Url -replace 'sharepoint\.com', '' $_ } - # Find sites where custom scripts are allowed $customScriptAllowedSites = $processedUrls | Where-Object { $_.DenyAddAndCustomizePages -ne 'Enabled' } #$verbosePreference = 'Continue' # Check the total length of URLs $totalUrlLength = ($customScriptAllowedSites.Url -join '').Length Write-Verbose "Total length of URLs: $totalUrlLength" - # Extract hostnames from allowed sites if the total length exceeds the limit $mostUsedHostname = $null if ($totalUrlLength -gt 20000) { @@ -57,7 +59,6 @@ function Test-RestrictCustomScripts { } } Write-Verbose "Extracted hostnames: $($hostnames -join ', ')" - # Find the most used hostname using the Get-MostCommonWord function $mostUsedHostname = Get-MostCommonWord -InputStrings $hostnames Write-Verbose "Most used hostname: $mostUsedHostname" @@ -65,7 +66,6 @@ function Test-RestrictCustomScripts { #$verbosePreference = 'SilentlyContinue' # Compliance is true if no sites allow custom scripts $complianceResult = $customScriptAllowedSites.Count -eq 0 - # Gather details for non-compliant sites (where custom scripts are allowed) $nonCompliantSiteDetails = $customScriptAllowedSites | ForEach-Object { $url = $_.Url @@ -74,32 +74,29 @@ function Test-RestrictCustomScripts { } "$(if ($_.Title) {$_.Title} else {"NoTitle"})|$url" } - # Prepare failure reasons and details based on compliance $failureReasons = if (-not $complianceResult) { - "Some site collections are not restricting custom script execution. Review Details property for sites that are not aligned with the benchmark." + "Some site collections are not restricting custom script execution. Review Details property for sites that are not aligned with the benchmark.`n" + ` + "To remediate this setting, use the following command:`n" + ` + "Set-SPOSite -Identity -DenyAddAndCustomizePages `$true" } else { "N/A" } - $details = if ($complianceResult) { "All site collections have custom script execution restricted" } else { "Title|Url`n" + ($nonCompliantSiteDetails -join "`n") } - # Convert details to PSObject and check length $detailsPSObject = $details | ConvertFrom-Csv -Delimiter '|' $detailsLength = ($detailsPSObject | ForEach-Object { $_.Url }).Length - if ($detailsLength -gt 32767) { # Create a preview of the first 10 results $preview = $detailsPSObject | Select-Object -First 10 | ForEach-Object { "$($_.Title)|$($_.Url)" } $details = "The output is too large. Here is a preview of the first 10 results:`n`n" + ($preview -join "`n") + "`n`nPlease run the test with the following commands to get the full details:`n`nGet-SPOSite -Limit All | Where-Object { `$.DenyAddAndCustomizePages -ne 'Enabled' } | Select-Object Title, Url" } - # Create and populate the CISAuditResult object $params = @{ Rec = $recnum diff --git a/source/tests/Test-RestrictExternalSharing.ps1 b/source/tests/Test-RestrictExternalSharing.ps1 index d508445..a84a53e 100644 --- a/source/tests/Test-RestrictExternalSharing.ps1 +++ b/source/tests/Test-RestrictExternalSharing.ps1 @@ -5,18 +5,15 @@ function Test-RestrictExternalSharing { # Aligned # Define your parameters here ) - 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: @@ -24,34 +21,37 @@ function Test-RestrictExternalSharing { - 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 $recnum = "7.2.3" + Write-Verbose "Running Test-RestrictExternalSharing for $recnum..." } - process { try { # 7.2.3 (L1) Ensure external content sharing is restricted - # Retrieve the SharingCapability setting for the SharePoint tenant + <# + $SPOTenantSharingCapability = [PSCustomObject]@{ + SharingCapability = "ExternalUserAndGuestSharing" + } + #> $SPOTenantSharingCapability = Get-CISSpoOutput -Rec $recnum $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)" + "External content sharing is not adequately restricted. Current setting: $($SPOTenantSharingCapability.SharingCapability)`n" + ` + "The acceptable values for SharingCapability are: 'ExternalUserSharingOnly', 'ExistingExternalUserSharingOnly', or 'Disabled'.`n" + ` + "To remediate this setting, use the Set-SPOTenant cmdlet to set the SharingCapability property to an acceptable value:`n`n" + ` + "Set-SPOTenant -SharingCapability " } else { "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 $params = @{ Rec = $recnum @@ -67,7 +67,6 @@ function Test-RestrictExternalSharing { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return auditResult return $auditResult diff --git a/source/tests/Test-SharePointAADB2B.ps1 b/source/tests/Test-SharePointAADB2B.ps1 index afbc0d9..f39e445 100644 --- a/source/tests/Test-SharePointAADB2B.ps1 +++ b/source/tests/Test-SharePointAADB2B.ps1 @@ -5,7 +5,6 @@ function Test-SharePointAADB2B { # Aligned # Define your parameters here ) - begin { # Conditions for 7.2.2 (L1) Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled # @@ -22,26 +21,29 @@ function Test-SharePointAADB2B { # - 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 - $recnum = "7.2.2" + Write-Verbose "Running Test-SharePointAADB2B for $recnum..." } - process { try { # 7.2.2 (L1) Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled + # $SPOTenantAzureADB2B Mock Object + <# + $SPOTenantAzureADB2B = [PSCustomObject]@{ + EnableAzureADB2BIntegration = $false + } + #> $SPOTenantAzureADB2B = Get-CISSpoOutput -Rec $recnum - # Populate the auditResult object with the required properties $params = @{ Rec = $recnum Result = $SPOTenantAzureADB2B.EnableAzureADB2BIntegration Status = if ($SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Pass" } else { "Fail" } Details = "EnableAzureADB2BIntegration: $($SPOTenantAzureADB2B.EnableAzureADB2BIntegration)" - FailureReason = if (-not $SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Azure AD B2B integration is not enabled" } else { "N/A" } + FailureReason = if (-not $SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Azure AD B2B integration is not enabled. The following command can be used to enable:`nSet-SPOTenant -EnableAzureADB2BIntegration `$true" } else { "N/A" } } $auditResult = Initialize-CISAuditResult @params } @@ -50,7 +52,6 @@ function Test-SharePointAADB2B { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return auditResult return $auditResult diff --git a/source/tests/Test-SharePointExternalSharingDomains.ps1 b/source/tests/Test-SharePointExternalSharingDomains.ps1 index 246c41c..1d26a5b 100644 --- a/source/tests/Test-SharePointExternalSharingDomains.ps1 +++ b/source/tests/Test-SharePointExternalSharingDomains.ps1 @@ -5,14 +5,12 @@ function Test-SharePointExternalSharingDomains { # Aligned # Define your parameters here ) - begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 - # Initialization code, if needed $recnum = "7.2.6" - + Write-Verbose "Running Test-SharePointExternalSharingDomains for $recnum..." # Conditions for 7.2.6 (L2) Ensure SharePoint external sharing is managed through domain whitelist/blacklists # # Validate test for a pass: @@ -29,13 +27,18 @@ function Test-SharePointExternalSharingDomains { # - 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 { try { # 7.2.6 (L2) Ensure SharePoint external sharing is managed through domain whitelist/blacklists $SPOTenant = Get-CISSpoOutput -Rec $recnum + # $SPOTenant Mock Object + <# + $SPOTenant = [PSCustomObject]@{ + SharingDomainRestrictionMode = "AllowList" + SharingAllowedDomainList = "domain1.com", "domain2.com" + } + #> $isDomainRestrictionConfigured = $SPOTenant.SharingDomainRestrictionMode -eq 'AllowList' - # Populate the auditResult object with the required properties $params = @{ Rec = $recnum @@ -51,7 +54,6 @@ function Test-SharePointExternalSharingDomains { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return auditResult return $auditResult diff --git a/source/tests/Test-SharePointGuestsItemSharing.ps1 b/source/tests/Test-SharePointGuestsItemSharing.ps1 index 58c834f..f11fc4a 100644 --- a/source/tests/Test-SharePointGuestsItemSharing.ps1 +++ b/source/tests/Test-SharePointGuestsItemSharing.ps1 @@ -5,14 +5,12 @@ function Test-SharePointGuestsItemSharing { # Aligned # Define your parameters here ) - begin { # Dot source the class script if necessary #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed - $recnum = "7.2.5" - + Write-Verbose "Running Test-SharePointGuestsItemSharing for $recnum..." # Conditions for 7.2.5 (L2) Ensure that SharePoint guest users cannot share items they don't own # # Validate test for a pass: @@ -29,20 +27,24 @@ function Test-SharePointGuestsItemSharing { # - 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 { try { # 7.2.5 (L2) Ensure that SharePoint guest users cannot share items they don't own + # $SPOTenant Mock Object + <# + $SPOTenant = [PSCustomObject]@{ + PreventExternalUsersFromResharing = $false + } + #> $SPOTenant = Get-CISSpoOutput -Rec $recnum $isGuestResharingPrevented = $SPOTenant.PreventExternalUsersFromResharing - # Populate the auditResult object with the required properties $params = @{ Rec = $recnum Result = $isGuestResharingPrevented Status = if ($isGuestResharingPrevented) { "Pass" } else { "Fail" } Details = "PreventExternalUsersFromResharing: $isGuestResharingPrevented" - FailureReason = if (-not $isGuestResharingPrevented) { "Guest users can reshare items they don't own." } else { "N/A" } + FailureReason = if (-not $isGuestResharingPrevented) { "Guest users can reshare items they don't own. To prevent external users from resharing content they don't own,`nuse the following command:`nSet-SPOTenant -PreventExternalUsersFromResharing `$True" } else { "N/A" } } $auditResult = Initialize-CISAuditResult @params } @@ -51,7 +53,6 @@ function Test-SharePointGuestsItemSharing { $auditResult = Get-TestError -LastError $LastError -recnum $recnum } } - end { # Return auditResult return $auditResult