Initial Commit

This commit is contained in:
DrIOS
2024-03-25 08:34:43 -05:00
commit 0226b293b5
137 changed files with 9448 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
function Test-AntiPhishingPolicy_2.1.7_E5L1_IG3 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# Retrieve and validate the anti-phishing policies
$antiPhishPolicies = Get-AntiPhishPolicy
$validatedPolicies = $antiPhishPolicies | Where-Object {
$_.Enabled -eq $true -and
$_.PhishThresholdLevel -ge 2 -and
$_.EnableMailboxIntelligenceProtection -eq $true -and
$_.EnableMailboxIntelligence -eq $true -and
$_.EnableSpoofIntelligence -eq $true
}
# Check if there is at least one policy that meets the requirements
$isCompliant = $validatedPolicies.Count -gt 0
# Prepare failure details if policies are not compliant
$failureDetails = if (-not $isCompliant) {
"No anti-phishing policy is fully compliant with CIS benchmark requirements."
} else {
"Compliant Anti-Phish Policy Names: " + ($validatedPolicies.Name -join ', ')
}
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($isCompliant) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E5"
$auditResult.Profile = "L1"
$auditResult.Rec = "2.1.7"
$auditResult.RecDescription = "Ensure that an anti-phishing policy has been created"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "9.7"
$auditResult.CISDescription = "Deploy and Maintain Email Server Anti-Malware Protections"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $true
$auditResult.Result = $isCompliant
$auditResult.Details = $failureDetails
$auditResult.FailureReason = if (-not $isCompliant) { "Anti-phishing policies do not meet CIS benchmark requirements." } else { "N/A" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,43 @@
function Test-AuditDisabledFalse_6.1.1_E3L1_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 6.1.1 (L1) Ensure 'AuditDisabled' organizationally is set to 'False'
# Pass if AuditDisabled is False. Fail otherwise.
$auditDisabledConfig = Get-OrganizationConfig | Select-Object AuditDisabled
$auditNotDisabled = -not $auditDisabledConfig.AuditDisabled
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($auditNotDisabled) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.Rec = "6.1.1"
$auditResult.RecDescription = "Ensure 'AuditDisabled' organizationally is set to 'False'"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "8.2"
$auditResult.CISDescription = "Collect Audit Logs"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.Result = $auditNotDisabled
$auditResult.Details = if ($auditNotDisabled) { "Audit is not disabled organizationally" } else { "Audit is disabled organizationally" }
$auditResult.FailureReason = if (-not $auditNotDisabled) { "AuditDisabled is set to True" } else { "N/A" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,43 @@
function Test-AuditLogSearch_3.1.1_E3L1_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 3.1.1 (L1) Ensure Microsoft 365 audit log search is Enabled
# Pass if UnifiedAuditLogIngestionEnabled is True. Fail otherwise.
$auditLogConfig = Get-AdminAuditLogConfig | Select-Object UnifiedAuditLogIngestionEnabled
$auditLogResult = $auditLogConfig.UnifiedAuditLogIngestionEnabled
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($auditLogResult) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.Rec = "3.1.1"
$auditResult.RecDescription = "Ensure Microsoft 365 audit log search is Enabled"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "8.2"
$auditResult.CISDescription = "Collect Audit Logs"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.Result = $auditLogResult
$auditResult.Details = "UnifiedAuditLogIngestionEnabled: $($auditLogConfig.UnifiedAuditLogIngestionEnabled)"
$auditResult.FailureReason = if (-not $auditLogResult) { "Audit log search is not enabled" } else { "N/A" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,44 @@
function Test-BlockChannelEmails_8.1.2_E3L1 {
[CmdletBinding()]
param (
# Parameters can be added here if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 8.1.2 (L1) Ensure users can't send emails to a channel email address
# Connect to Teams PowerShell using Connect-MicrosoftTeams
$teamsClientConfig = Get-CsTeamsClientConfiguration -Identity Global
$allowEmailIntoChannel = $teamsClientConfig.AllowEmailIntoChannel
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0" # This control is Explicitly Not Mapped as per the image provided
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "8.1.2"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false # Set based on the benchmark
$auditResult.IG2 = $false # Set based on the benchmark
$auditResult.IG3 = $false # Set based on the benchmark
$auditResult.RecDescription = "Ensure users can't send emails to a channel email address"
$auditResult.Result = -not $allowEmailIntoChannel
$auditResult.Details = "AllowEmailIntoChannel is set to $allowEmailIntoChannel"
$auditResult.FailureReason = if ($allowEmailIntoChannel) { "Emails can be sent to a channel email address" } else { "N/A" }
$auditResult.Status = if (-not $allowEmailIntoChannel) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,51 @@
function Test-BlockMailForwarding_6.2.1_E3L1 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
$auditResult.Rec = "6.2.1"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0"
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $false
$auditResult.RecDescription = "Ensure all forms of mail forwarding are blocked and/or disabled"
}
process {
# Verify that no rules are forwarding the email to external domains
$transportRules = Get-TransportRule | Where-Object { $_.RedirectMessageTo -ne $null }
$forwardingBlocked = $transportRules.Count -eq 0
$auditResult.Result = $forwardingBlocked
$auditResult.Details = if ($transportRules.Count -gt 0) {
$transportRules | ForEach-Object {
"$($_.Name) redirects to $($_.RedirectMessageTo)"
} -join " | "
} else {
"Step 1: No forwarding rules found. Please proceed with Step 2 described in CIS Benchmark."
}
$auditResult.FailureReason = if (-not $forwardingBlocked) {
"Mail forwarding rules found: $($transportRules.Name -join ', ')"
} else {
"N/A"
}
$auditResult.Status = if ($forwardingBlocked) { "Pass" } else { "Fail" }
}
end {
# Return the result object
return $auditResult
}
}

View File

@@ -0,0 +1,47 @@
function Test-BlockSharedMailboxSignIn_1.2.2_E3L1 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 1.2.2 (L1) Ensure sign-in to shared mailboxes is blocked
# Pass if all shared mailboxes have AccountEnabled set to False.
# Fail if any shared mailbox has AccountEnabled set to True.
$MBX = Get-EXOMailbox -RecipientTypeDetails SharedMailbox
$sharedMailboxDetails = $MBX | ForEach-Object { Get-AzureADUser -ObjectId $_.ExternalDirectoryObjectId }
$enabledMailboxes = $sharedMailboxDetails | Where-Object { $_.AccountEnabled } | ForEach-Object { $_.DisplayName }
$allBlocked = $enabledMailboxes.Count -eq 0
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0" # Control is explicitly not mapped
$auditResult.CISDescription = "Control not mapped to CIS Controls v7 or v8"
$auditResult.Rec = "1.2.2"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false # Control is not mapped, hence IG1 is false
$auditResult.IG2 = $false # Control is not mapped, hence IG2 is false
$auditResult.IG3 = $false # Control is not mapped, hence IG3 is false
$auditResult.RecDescription = "Ensure sign-in to shared mailboxes is blocked"
$auditResult.Result = $allBlocked
$auditResult.Details = "Enabled Mailboxes: $($enabledMailboxes -join ', ')"
$auditResult.FailureReason = if ($allBlocked) { "N/A" } else { "Some mailboxes have sign-in enabled: $($enabledMailboxes -join ', ')" }
$auditResult.Status = if ($allBlocked) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,46 @@
function Test-CommonAttachmentFilter_2.1.2_E3L1_IG2_IG3 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 2.1.2 (L1) Ensure the Common Attachment Types Filter is enabled
# Pass if EnableFileFilter is set to True. Fail otherwise.
$attachmentFilter = Get-MalwareFilterPolicy -Identity Default | Select-Object EnableFileFilter
$result = $attachmentFilter.EnableFileFilter
$details = "File Filter Enabled: $($attachmentFilter.EnableFileFilter)"
$failureReason = if ($result) { "N/A" } else { "Common Attachment Types Filter is disabled" }
$status = if ($result) { "Pass" } else { "Fail" }
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = $status
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.Rec = "2.1.2"
$auditResult.RecDescription = "Ensure the Common Attachment Types Filter is enabled"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "9.6"
$auditResult.CISDescription = "Block Unnecessary File Types"
$auditResult.IG1 = $false
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.Result = $result
$auditResult.Details = $details
$auditResult.FailureReason = $failureReason
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,40 @@
function Test-CustomerLockbox_1.3.6_E5L2 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 1.3.6 (L2) Ensure the customer lockbox feature is enabled
$orgConfig = Get-OrganizationConfig | Select-Object CustomerLockBoxEnabled
$customerLockboxEnabled = $orgConfig.CustomerLockBoxEnabled
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($customerLockboxEnabled) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E5"
$auditResult.Profile = "L2"
$auditResult.Rec = "1.3.6"
$auditResult.RecDescription = "Ensure the customer lockbox feature is enabled"
$auditResult.CISControlVer = 'v8'
$auditResult.CISControl = "0.0" # As per the snapshot provided, this is explicitly not mapped
$auditResult.CISDescription = "Control not mapped to CIS Controls v7 or v8"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $false
$auditResult.Result = $customerLockboxEnabled
$auditResult.Details = "Customer Lockbox Enabled: $customerLockboxEnabled"
$auditResult.FailureReason = if ($customerLockboxEnabled) { "N/A" } else { "Customer lockbox feature is not enabled." }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,45 @@
function Test-DialInBypassLobby_8.5.4_E3L1 {
[CmdletBinding()]
param (
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 8.5.4 (L1) Ensure users dialing in can't bypass the lobby
# Connect to Teams PowerShell using Connect-MicrosoftTeams
$CsTeamsMeetingPolicyPSTN = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AllowPSTNUsersToBypassLobby
$PSTNBypassDisabled = -not $CsTeamsMeetingPolicyPSTN.AllowPSTNUsersToBypassLobby
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0" # Explicitly Not Mapped as per the image provided
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "8.5.4"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false # Set based on the CIS Controls image
$auditResult.IG2 = $false # Set based on the CIS Controls image
$auditResult.IG3 = $false # Set based on the CIS Controls image
$auditResult.RecDescription = "Ensure users dialing in can't bypass the lobby"
$auditResult.Result = $PSTNBypassDisabled
$auditResult.Details = "AllowPSTNUsersToBypassLobby is set to $($CsTeamsMeetingPolicyPSTN.AllowPSTNUsersToBypassLobby)"
$auditResult.FailureReason = if ($PSTNBypassDisabled) { "N/A" } else { "Users dialing in can bypass the lobby" }
$auditResult.Status = if ($PSTNBypassDisabled) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,41 @@
function Test-DisallowInfectedFilesDownload_7.3.1_E5L2_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
}
process {
# 7.3.1 (L2) Ensure Office 365 SharePoint infected files are disallowed for download
$SPOTenantDisallowInfectedFileDownload = Get-SPOTenant | Select-Object DisallowInfectedFileDownload
$isDisallowInfectedFileDownloadEnabled = $SPOTenantDisallowInfectedFileDownload.DisallowInfectedFileDownload
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "10.1"
$auditResult.CISDescription = "Deploy and Maintain Anti-Malware Software"
$auditResult.Rec = "7.3.1"
$auditResult.ELevel = "E5"
$auditResult.Profile = "L2"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.RecDescription = "Ensure Office 365 SharePoint infected files are disallowed for download"
$auditResult.Result = $isDisallowInfectedFileDownloadEnabled
$auditResult.Details = "DisallowInfectedFileDownload: $($SPOTenantDisallowInfectedFileDownload.DisallowInfectedFileDownload)"
$auditResult.FailureReason = if (-not $isDisallowInfectedFileDownloadEnabled) { "Downloading infected files is not disallowed." } else { "N/A" }
$auditResult.Status = if ($isDisallowInfectedFileDownloadEnabled) { "Pass" } else { "Fail" }
}
end {
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,44 @@
function Test-EnableDKIM_2.1.9_E3L1_IG2_IG3 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 2.1.9 (L1) Ensure DKIM is enabled for all Exchange Online Domains
# Pass if Enabled is True for all domains. Fail if any domain has Enabled set to False.
$dkimConfig = Get-DkimSigningConfig | Select-Object Domain, Enabled
$dkimResult = ($dkimConfig | ForEach-Object { $_.Enabled }) -notcontains $false
$dkimFailedDomains = $dkimConfig | Where-Object { -not $_.Enabled } | ForEach-Object { $_.Domain }
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($dkimResult) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.Rec = "2.1.9"
$auditResult.RecDescription = "Ensure that DKIM is enabled for all Exchange Online Domains"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "9.5"
$auditResult.CISDescription = "Implement DMARC"
$auditResult.IG1 = $false
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.Result = $dkimResult
$auditResult.Details = if (-not $dkimResult) { "DKIM not enabled for: $($dkimFailedDomains -join ', ')" } else { "All domains have DKIM enabled" }
$auditResult.FailureReason = if (-not $dkimResult) { "DKIM is not enabled for some domains" } else { "N/A" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,45 @@
function Test-ExternalNoControl_8.5.7_E3L1 {
[CmdletBinding()]
param (
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 8.5.7 (L1) Ensure external participants can't give or request control
# Connect to Teams PowerShell using Connect-MicrosoftTeams
$CsTeamsMeetingPolicyControl = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AllowExternalParticipantGiveRequestControl
$externalControlRestricted = -not $CsTeamsMeetingPolicyControl.AllowExternalParticipantGiveRequestControl
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0" # Explicitly Not Mapped as per the image provided
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "8.5.7"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false # Set based on the CIS Controls image
$auditResult.IG2 = $false # Set based on the CIS Controls image
$auditResult.IG3 = $false # Set based on the CIS Controls image
$auditResult.RecDescription = "Ensure external participants can't give or request control"
$auditResult.Result = $externalControlRestricted
$auditResult.Details = "AllowExternalParticipantGiveRequestControl is set to $($CsTeamsMeetingPolicyControl.AllowExternalParticipantGiveRequestControl)"
$auditResult.FailureReason = if ($externalControlRestricted) { "N/A" } else { "External participants can give or request control" }
$auditResult.Status = if ($externalControlRestricted) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,53 @@
function Test-ExternalSharingCalendars_1.3.3_E3L2_IG2_IG3 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 1.3.3 (L2) Ensure 'External sharing' of calendars is not available (Automated)
$sharingPolicies = Get-SharingPolicy | Where-Object { $_.Domains -like '*CalendarSharing*' }
# Check if calendar sharing is disabled in all applicable policies
$isExternalSharingDisabled = $true
$sharingPolicyDetails = @()
foreach ($policy in $sharingPolicies) {
if ($policy.Enabled -eq $true) {
$isExternalSharingDisabled = $false
$sharingPolicyDetails += "$($policy.Name): Enabled"
}
}
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Rec = "1.3.3"
$auditResult.RecDescription = "Ensure 'External sharing' of calendars is not available"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L2"
# The following IG values are placeholders. Replace with actual values when known.
$auditResult.IG1 = $false
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.CISControlVer = "v8"
# Placeholder for CIS Control, to be replaced with the actual value when available
$auditResult.CISControl = "4.8"
$auditResult.CISDescription = "Uninstall or Disable Unnecessary Services on Enterprise Assets and Software"
$auditResult.Result = $isExternalSharingDisabled
$auditResult.Details = if ($isExternalSharingDisabled) { "Calendar sharing with external users is disabled." } else { "Enabled Sharing Policies: $($sharingPolicyDetails -join ', ')" }
$auditResult.FailureReason = if ($isExternalSharingDisabled) { "N/A" } else { "Calendar sharing with external users is enabled in one or more policies." }
$auditResult.Status = if ($isExternalSharingDisabled) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,46 @@
function Test-GlobalAdminsCount_1.1.3_E3L1_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 1.1.3 (L1) Ensure that between two and four global admins are designated
# Pass if the count of global admins is between 2 and 4. Fail otherwise.
$globalAdminRole = Get-MgDirectoryRole -Filter "RoleTemplateId eq '62e90394-69f5-4237-9190-012177145e10'"
$globalAdmins = Get-MgDirectoryRoleMember -DirectoryRoleId $globalAdminRole.Id
$globalAdminCount = $globalAdmins.AdditionalProperties.Count
$globalAdminUsernames = ($globalAdmins | ForEach-Object { $_.AdditionalProperties["displayName"] }) -join ', '
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "5.1"
$auditResult.CISDescription = "Establish and Maintain an Inventory of Accounts"
$auditResult.Rec = "1.1.3"
$auditResult.ELevel = "E3" # Based on your environment (E3, E5, etc.)
$auditResult.Profile = "L1"
$auditResult.IG1 = $true # Set based on the benchmark
$auditResult.IG2 = $true # Set based on the benchmark
$auditResult.IG3 = $true # Set based on the benchmark
$auditResult.RecDescription = "Ensure that between two and four global admins are designated"
$auditResult.Result = $globalAdminCount -ge 2 -and $globalAdminCount -le 4
$auditResult.Details = "Count: $globalAdminCount; Users: $globalAdminUsernames"
$auditResult.FailureReason = if ($globalAdminCount -lt 2) { "Less than 2 global admins: $globalAdminUsernames" } elseif ($globalAdminCount -gt 4) { "More than 4 global admins: $globalAdminUsernames" } else { "N/A" }
$auditResult.Status = if ($globalAdminCount -ge 2 -and $globalAdminCount -le 4) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,41 @@
function Test-GuestAccessExpiration_7.2.9_E3L1 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
}
process {
# 7.2.9 (L1) Ensure guest access to a site or OneDrive will expire automatically
$SPOTenantGuestAccess = Get-SPOTenant | Select-Object ExternalUserExpirationRequired, ExternalUserExpireInDays
$isGuestAccessExpirationConfiguredCorrectly = $SPOTenantGuestAccess.ExternalUserExpirationRequired -and $SPOTenantGuestAccess.ExternalUserExpireInDays -le 30
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0"
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "7.2.9"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $false
$auditResult.RecDescription = "Ensure guest access to a site or OneDrive will expire automatically"
$auditResult.Result = $isGuestAccessExpirationConfiguredCorrectly
$auditResult.Details = "ExternalUserExpirationRequired: $($SPOTenantGuestAccess.ExternalUserExpirationRequired); ExternalUserExpireInDays: $($SPOTenantGuestAccess.ExternalUserExpireInDays)"
$auditResult.FailureReason = if (-not $isGuestAccessExpirationConfiguredCorrectly) { "Guest access expiration is not configured to automatically expire within 30 days or less." } else { "N/A" }
$auditResult.Status = if ($isGuestAccessExpirationConfiguredCorrectly) { "Pass" } else { "Fail" }
}
end {
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,44 @@
function Test-IdentifyExternalEmail_6.2.3_E3L1 {
[CmdletBinding()]
param (
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 6.2.3 (L1) Ensure email from external senders is identified
# Requirement is to have external sender tagging enabled
$externalInOutlook = Get-ExternalInOutlook
$externalTaggingEnabled = ($externalInOutlook | ForEach-Object { $_.Enabled }) -contains $true
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($externalTaggingEnabled) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.Rec = "6.2.3"
$auditResult.RecDescription = "Ensure email from external senders is identified"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0"
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $false
$auditResult.Result = $externalTaggingEnabled
$auditResult.Details = "Enabled: $($externalTaggingEnabled); AllowList: $($externalInOutlook.AllowList)"
$auditResult.FailureReason = if (-not $externalTaggingEnabled) { "External sender tagging is disabled" } else { "N/A" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,42 @@
function Test-LinkSharingRestrictions_7.2.7_E3L1_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Define your parameters here
# Test behavior in prod
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
}
process {
# 7.2.7 (L1) Ensure link sharing is restricted in SharePoint and OneDrive
$SPOTenantLinkSharing = Get-SPOTenant | Select-Object DefaultSharingLinkType
$isLinkSharingRestricted = $SPOTenantLinkSharing.DefaultSharingLinkType -eq 'Direct' # Or 'SpecificPeople' as per the recommendation
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "3.3"
$auditResult.CISDescription = "Configure Data Access Control Lists"
$auditResult.Rec = "7.2.7"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.RecDescription = "Ensure link sharing is restricted in SharePoint and OneDrive"
$auditResult.Result = $isLinkSharingRestricted
$auditResult.Details = "DefaultSharingLinkType: $($SPOTenantLinkSharing.DefaultSharingLinkType)"
$auditResult.FailureReason = if (-not $isLinkSharingRestricted) { "Link sharing is not restricted to 'Specific people'. Current setting: $($SPOTenantLinkSharing.DefaultSharingLinkType)" } else { "N/A" }
$auditResult.Status = if ($isLinkSharingRestricted) { "Pass" } else { "Fail" }
}
end {
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,43 @@
function Test-MailTipsEnabled_6.5.2_E3L2 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
}
process {
# 6.5.2 (L2) Ensure MailTips are enabled for end users
$orgConfig = Get-OrganizationConfig | Select-Object MailTipsAllTipsEnabled, MailTipsExternalRecipientsTipsEnabled, MailTipsGroupMetricsEnabled, MailTipsLargeAudienceThreshold
$allTipsEnabled = $orgConfig.MailTipsAllTipsEnabled -and $orgConfig.MailTipsGroupMetricsEnabled -and $orgConfig.MailTipsLargeAudienceThreshold -eq 25
$externalRecipientsTipsEnabled = $orgConfig.MailTipsExternalRecipientsTipsEnabled
# Since there is no direct CIS Control mapping, the control will be set as not applicable.
$auditResult.CISControl = "N/A"
$auditResult.CISControlVer = "v8"
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "6.5.2"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L2"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $false
$auditResult.RecDescription = "Ensure MailTips are enabled for end users"
$auditResult.Result = $allTipsEnabled -and $externalRecipientsTipsEnabled
$auditResult.Details = "MailTipsAllTipsEnabled: $($orgConfig.MailTipsAllTipsEnabled); MailTipsExternalRecipientsTipsEnabled: $($orgConfig.MailTipsExternalRecipientsTipsEnabled); MailTipsGroupMetricsEnabled: $($orgConfig.MailTipsGroupMetricsEnabled); MailTipsLargeAudienceThreshold: $($orgConfig.MailTipsLargeAudienceThreshold)"
$auditResult.FailureReason = if (-not $auditResult.Result) { "One or more MailTips settings are not configured as required." } else { "N/A" }
$auditResult.Status = if ($auditResult.Result) { "Pass" } else { "Fail" }
}
end {
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,111 @@
function Test-MailboxAuditingE3_6.1.2_E3L1_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
. ".\source\Classes\CISAuditResult.ps1"
$e3SkuPartNumbers = @("ENTERPRISEPACK", "OFFICESUBSCRIPTION")
$AdminActions = @("ApplyRecord", "Copy", "Create", "FolderBind", "HardDelete", "Move", "MoveToDeletedItems", "SendAs", "SendOnBehalf", "SoftDelete", "Update", "UpdateCalendarDelegation", "UpdateFolderPermissions", "UpdateInboxRules")
$DelegateActions = @("ApplyRecord", "Create", "FolderBind", "HardDelete", "Move", "MoveToDeletedItems", "SendAs", "SendOnBehalf", "SoftDelete", "Update", "UpdateFolderPermissions", "UpdateInboxRules")
$OwnerActions = @("ApplyRecord", "Create", "HardDelete", "MailboxLogin", "Move", "MoveToDeletedItems", "SoftDelete", "Update", "UpdateCalendarDelegation", "UpdateFolderPermissions", "UpdateInboxRules")
$auditResult = [CISAuditResult]::new()
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.Rec = "6.1.2"
$auditResult.RecDescription = "Ensure mailbox auditing for Office E3 users is Enabled"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "8.2"
$auditResult.CISDescription = "Collect audit logs."
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$allFailures = @()
$allUsers = Get-AzureADUser -All $true
$processedUsers = @{} # Dictionary to track processed users
}
process {
foreach ($user in $allUsers) {
if ($processedUsers.ContainsKey($user.UserPrincipalName)) {
Write-Verbose "Skipping already processed user: $($user.UserPrincipalName)"
continue
}
try {
$licenseDetails = Get-MgUserLicenseDetail -UserId $user.UserPrincipalName
$hasOfficeE3 = ($licenseDetails | Where-Object { $_.SkuPartNumber -in $e3SkuPartNumbers }).Count -gt 0
Write-Verbose "Evaluating user $($user.UserPrincipalName) for Office E3 license."
if ($hasOfficeE3) {
$userUPN = $user.UserPrincipalName
$mailbox = Get-EXOMailbox -Identity $userUPN -PropertySets Audit
$missingActions = @()
if ($mailbox.AuditEnabled) {
foreach ($action in $AdminActions) {
if ($mailbox.AuditAdmin -notcontains $action) { $missingActions += "Admin action '$action' missing" }
}
foreach ($action in $DelegateActions) {
if ($mailbox.AuditDelegate -notcontains $action) { $missingActions += "Delegate action '$action' missing" }
}
foreach ($action in $OwnerActions) {
if ($mailbox.AuditOwner -notcontains $action) { $missingActions += "Owner action '$action' missing" }
}
}
else {
$allFailures += "$userUPN`: AuditEnabled - False"
continue
}
if ($missingActions) {
$formattedActions = Format-MissingActions $missingActions
$allFailures += "$userUPN`: AuditEnabled - True; $formattedActions"
}
# Mark the user as processed
$processedUsers[$user.UserPrincipalName] = $true
}
}
catch {
Write-Warning "Could not retrieve license details for user $($user.UserPrincipalName): $_"
}
}
$auditResult.Result = $allFailures.Count -eq 0
$auditResult.Status = if ($auditResult.Result) { "Pass" } else { "Fail" }
$auditResult.Details = if ($auditResult.Result) { "All Office E3 users have correct mailbox audit settings." } else { $allFailures -join " | " }
$auditResult.FailureReason = if (-not $auditResult.Result) { "Audit issues detected." } else { "N/A" }
}
end {
return $auditResult
}
}
function Format-MissingActions {
param ([array]$missingActions)
$actionGroups = @{
"Admin" = @()
"Delegate" = @()
"Owner" = @()
}
foreach ($action in $missingActions) {
if ($action -match "(Admin|Delegate|Owner) action '([^']+)' missing") {
$type = $matches[1]
$actionName = $matches[2]
$actionGroups[$type] += $actionName
}
}
$formattedResults = @()
foreach ($type in $actionGroups.Keys) {
if ($actionGroups[$type].Count -gt 0) {
$formattedResults += "$($type) actions missing: $($actionGroups[$type] -join ', ')"
}
}
return $formattedResults -join '; '
}

View File

@@ -0,0 +1,120 @@
function Test-MailboxAuditingE5_6.1.3_E5L1_IG1_IG2_IG3 {
[CmdletBinding()]
param ()
begin {
. ".\source\Classes\CISAuditResult.ps1"
$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")
$OwnerActions = @("ApplyRecord", "Create", "HardDelete", "MailboxLogin", "Move", "MailItemsAccessed", "MoveToDeletedItems", "Send", "SoftDelete", "Update", "UpdateCalendarDelegation", "UpdateFolderPermissions", "UpdateInboxRules")
$auditResult = [CISAuditResult]::new()
$auditResult.ELevel = "E5"
$auditResult.Profile = "L1"
$auditResult.Rec = "6.1.3"
$auditResult.RecDescription = "Ensure mailbox auditing for Office E5 users is Enabled"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "8.2"
$auditResult.CISDescription = "Collect audit logs."
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$allFailures = @()
$allUsers = Get-AzureADUser -All $true
$processedUsers = @{} # Dictionary to track processed users
}
process {
foreach ($user in $allUsers) {
if ($processedUsers.ContainsKey($user.UserPrincipalName)) {
continue
}
try {
# Define SKU Part Numbers for Office E5 licenses
# Define SKU Part Numbers for Office E5 licenses
$e5SkuPartNumbers = @("SPE_E5", "ENTERPRISEPREMIUM", "OFFICEE5")
$licenseDetails = Get-MgUserLicenseDetail -UserId $user.UserPrincipalName
$hasOfficeE5 = ($licenseDetails | Where-Object { $_.SkuPartNumber -in $e5SkuPartNumbers }).Count -gt 0
Write-Verbose "Evaluating user $($user.UserPrincipalName) for Office E5 license."
if ($hasOfficeE5) {
$userUPN = $user.UserPrincipalName
$mailbox = Get-EXOMailbox -Identity $userUPN -PropertySets Audit
$missingActions = @()
if ($mailbox.AuditEnabled) {
foreach ($action in $AdminActions) {
if ($mailbox.AuditAdmin -notcontains $action) { $missingActions += "Admin action '$action' missing" }
}
foreach ($action in $DelegateActions) {
if ($mailbox.AuditDelegate -notcontains $action) { $missingActions += "Delegate action '$action' missing" }
}
foreach ($action in $OwnerActions) {
if ($mailbox.AuditOwner -notcontains $action) { $missingActions += "Owner action '$action' missing" }
}
}
else {
$allFailures += "$userUPN`: AuditEnabled - False"
continue
}
if ($missingActions) {
$formattedActions = Format-MissingActions $missingActions
$allFailures += "$userUPN`: AuditEnabled - True; $formattedActions"
}
else {
Write-Verbose "User $($user.UserPrincipalName) passed the mailbox audit checks."
}
$processedUsers[$user.UserPrincipalName] = $true
}
else {
# Adding verbose output to indicate the user does not have an E5 license
Write-Verbose "User $($user.UserPrincipalName) does not have an Office E5 license."
}
}
catch {
Write-Warning "Could not retrieve license details for user $($user.UserPrincipalName): $_"
}
}
if ($allFailures.Count -eq 0) {
Write-Verbose "All evaluated E5 users have correct mailbox audit settings."
}
$auditResult.Result = $allFailures.Count -eq 0
$auditResult.Status = if ($auditResult.Result) { "Pass" } else { "Fail" }
$auditResult.Details = if ($auditResult.Result) { "All Office E5 users have correct mailbox audit settings." } else { $allFailures -join " | " }
$auditResult.FailureReason = if (-not $auditResult.Result) { "Audit issues detected." } else { "N/A" }
}
end {
return $auditResult
}
}
function Format-MissingActions {
param ([array]$missingActions)
$actionGroups = @{
"Admin" = @()
"Delegate" = @()
"Owner" = @()
}
foreach ($action in $missingActions) {
if ($action -match "(Admin|Delegate|Owner) action '([^']+)' missing") {
$type = $matches[1]
$actionName = $matches[2]
$actionGroups[$type] += $actionName
}
}
$formattedResults = @()
foreach ($type in $actionGroups.Keys) {
if ($actionGroups[$type].Count -gt 0) {
$formattedResults += "$($type) actions missing: $($actionGroups[$type] -join ', ')"
}
}
return $formattedResults -join '; '
}

View File

@@ -0,0 +1,54 @@
function Test-ManagedApprovedPublicGroups_1.2.1_E3L2_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 1.2.1 (L2) Ensure that only organizationally managed/approved public groups exist (Automated)
$allGroups = Get-MgGroup -All | Where-Object { $_.Visibility -eq "Public" } | Select-Object DisplayName, Visibility
# Check if there are public groups and if they are organizationally managed/approved
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "3.3"
$auditResult.CISDescription = "Configure Data Access Control Lists"
$auditResult.Rec = "1.2.1"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L2"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true # Based on the provided CIS Control image, IG3 is not applicable
$auditResult.RecDescription = "Ensure that only organizationally managed/approved public groups exist"
if ($null -eq $allGroups -or $allGroups.Count -eq 0) {
$auditResult.Result = $true
$auditResult.Details = "No public groups found."
$auditResult.FailureReason = "N/A"
$auditResult.Status = "Pass"
}
else {
$groupDetails = $allGroups | ForEach-Object { $_.DisplayName + " (" + $_.Visibility + ")" }
$detailsString = $groupDetails -join ', '
$auditResult.Result = $false
$auditResult.Details = "Public groups found: $detailsString"
$auditResult.FailureReason = "There are public groups present that are not organizationally managed/approved."
$auditResult.Status = "Fail"
}
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,46 @@
function Test-MeetingChatNoAnonymous_8.5.5_E3L1 {
[CmdletBinding()]
param (
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 8.5.5 (L2) Ensure meeting chat does not allow anonymous users
# Name doesn't match profile level in benchmarks either.
# Connect to Teams PowerShell using Connect-MicrosoftTeams
$CsTeamsMeetingPolicyChat = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property MeetingChatEnabledType
$chatAnonDisabled = $CsTeamsMeetingPolicyChat.MeetingChatEnabledType -eq 'EnabledExceptAnonymous'
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0" # Explicitly Not Mapped as per the image provided
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "8.5.5"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false # Set based on the CIS Controls image
$auditResult.IG2 = $false # Set based on the CIS Controls image
$auditResult.IG3 = $false # Set based on the CIS Controls image
$auditResult.RecDescription = "Ensure meeting chat does not allow anonymous users"
$auditResult.Result = $chatAnonDisabled
$auditResult.Details = "MeetingChatEnabledType is set to $($CsTeamsMeetingPolicyChat.MeetingChatEnabledType)"
$auditResult.FailureReason = if ($chatAnonDisabled) { "N/A" } else { "Meeting chat allows anonymous users" }
$auditResult.Status = if ($chatAnonDisabled) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,54 @@
function Test-ModernAuthExchangeOnline_6.5.1_E3L1_IG2_IG3 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
. ".\source\Classes\CISAuditResult.ps1"
$CISAuditResult = [CISAuditResult]::new()
# Initialization code
}
process {
try {
# Ensuring the ExchangeOnlineManagement module is available
# 6.5.1 (L1) Ensure modern authentication for Exchange Online is enabled
$orgConfig = Get-OrganizationConfig | Select-Object -Property Name, OAuth2ClientProfileEnabled
# Create an instance of CISAuditResult and populate it
$CISAuditResult.CISControlVer = "v8"
$CISAuditResult.CISControl = "3.10"
$CISAuditResult.CISDescription = "Encrypt Sensitive Data in Transit"
$CISAuditResult.IG1 = $false # As per CIS Control v8 mapping for IG1
$CISAuditResult.IG2 = $true # As per CIS Control v8 mapping for IG2
$CISAuditResult.IG3 = $true # As per CIS Control v8 mapping for IG3
$CISAuditResult.ELevel = "E3" # Based on your environment (E3, E5, etc.)
$CISAuditResult.Profile = "L1"
$CISAuditResult.Rec = "6.5.1"
$CISAuditResult.RecDescription = "Ensure modern authentication for Exchange Online is enabled (Automated)"
$CISAuditResult.Result = $orgConfig.OAuth2ClientProfileEnabled
$CISAuditResult.Details = $orgConfig | Out-String
$CISAuditResult.FailureReason = if (-not $orgConfig.OAuth2ClientProfileEnabled) { "Modern authentication is disabled" } else { "N/A" }
$CISAuditResult.Status = if ($orgConfig.OAuth2ClientProfileEnabled) { "Pass" } else { "Fail" }
}
catch {
Write-Error "An error occurred while testing modern authentication for Exchange Online: $_"
}
}
end {
# Return auditResults
return $CISAuditResult
}
}

View File

@@ -0,0 +1,39 @@
function Test-ModernAuthSharePoint_7.2.1_E3L1_IG2_IG3 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
}
process {
# 7.2.1 (L1) Ensure modern authentication for SharePoint applications is required
$SPOTenant = Get-SPOTenant | Select-Object -Property LegacyAuthProtocolsEnabled
$modernAuthForSPRequired = -not $SPOTenant.LegacyAuthProtocolsEnabled
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "3.10"
$auditResult.CISDescription = "Encrypt Sensitive Data in Transit"
$auditResult.Rec = "7.2.1"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.RecDescription = "Modern Authentication for SharePoint Applications"
$auditResult.Result = $modernAuthForSPRequired
$auditResult.Details = "LegacyAuthProtocolsEnabled: $($SPOTenant.LegacyAuthProtocolsEnabled)"
$auditResult.FailureReason = if (-not $modernAuthForSPRequired) { "Legacy authentication protocols are enabled" } else { "N/A" }
$auditResult.Status = if ($modernAuthForSPRequired) { "Pass" } else { "Fail" }
}
end {
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,45 @@
function Test-NoAnonymousMeetingJoin_8.5.1_E3L2 {
[CmdletBinding()]
param (
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 8.5.1 (L2) Ensure anonymous users can't join a meeting
# Connect to Teams PowerShell using Connect-MicrosoftTeams
$teamsMeetingPolicy = Get-CsTeamsMeetingPolicy -Identity Global
$allowAnonymousUsersToJoinMeeting = $teamsMeetingPolicy.AllowAnonymousUsersToJoinMeeting
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0" # The control is Explicitly Not Mapped as per the image provided
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "8.5.1"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L2"
$auditResult.IG1 = $false # Set based on the CIS Controls image
$auditResult.IG2 = $false # Set based on the CIS Controls image
$auditResult.IG3 = $false # Set based on the CIS Controls image
$auditResult.RecDescription = "Ensure anonymous users can't join a meeting"
$auditResult.Result = -not $allowAnonymousUsersToJoinMeeting
$auditResult.Details = "AllowAnonymousUsersToJoinMeeting is set to $allowAnonymousUsersToJoinMeeting"
$auditResult.FailureReason = if ($allowAnonymousUsersToJoinMeeting) { "Anonymous users are allowed to join meetings" } else { "N/A" }
$auditResult.Status = if (-not $allowAnonymousUsersToJoinMeeting) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,45 @@
function Test-NoAnonymousMeetingStart_8.5.2_E3L1 {
[CmdletBinding()]
param (
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 8.5.2 (L1) Ensure anonymous users and dial-in callers can't start a meeting
# Connect to Teams PowerShell using Connect-MicrosoftTeams
$CsTeamsMeetingPolicyAnonymous = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AllowAnonymousUsersToStartMeeting
$anonymousStartDisabled = -not $CsTeamsMeetingPolicyAnonymous.AllowAnonymousUsersToStartMeeting
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0" # Explicitly Not Mapped as per the image provided
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "8.5.2"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false # Set based on the CIS Controls image
$auditResult.IG2 = $false # Set based on the CIS Controls image
$auditResult.IG3 = $false # Set based on the CIS Controls image
$auditResult.RecDescription = "Ensure anonymous users and dial-in callers can't start a meeting"
$auditResult.Result = $anonymousStartDisabled
$auditResult.Details = "AllowAnonymousUsersToStartMeeting is set to $($CsTeamsMeetingPolicyAnonymous.AllowAnonymousUsersToStartMeeting)"
$auditResult.FailureReason = if ($anonymousStartDisabled) { "N/A" } else { "Anonymous users and dial-in callers can start a meeting" }
$auditResult.Status = if ($anonymousStartDisabled) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,47 @@
function Test-NoWhitelistDomains_6.2.2_E3L1 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
}
process {
# 6.2.2 (L1) Ensure mail transport rules do not whitelist specific domains
$whitelistedRules = Get-TransportRule | Where-Object { $_.SetSCL -eq -1 -and $_.SenderDomainIs -ne $null }
$auditResult.CISControl = "0.0"
$auditResult.CISControlVer = "v8"
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "6.2.2"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $false
$auditResult.RecDescription = "Ensure mail transport rules do not whitelist specific domains"
if ($whitelistedRules) {
$ruleDetails = $whitelistedRules | ForEach-Object { "{0}: {1}" -f $_.Name, ($_.SenderDomainIs -join ', ') }
$auditResult.Result = $false
$auditResult.Details = "Whitelisted Rules: $($ruleDetails -join '; ')"
$auditResult.FailureReason = "There are transport rules whitelisting specific domains."
$auditResult.Status = "Fail"
} else {
$auditResult.Result = $true
$auditResult.Details = "No transport rules whitelisting specific domains found."
$auditResult.FailureReason = "N/A"
$auditResult.Status = "Pass"
}
}
end {
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,52 @@
function Test-NotifyMalwareInternal_2.1.3_E3L1_IG2_IG3 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# Retrieve all 'Custom' malware filter policies and check notification settings
$malwareNotifications = Get-MalwareFilterPolicy | Where-Object { $_.RecommendedPolicyType -eq 'Custom' }
$policiesToReport = @()
foreach ($policy in $malwareNotifications) {
if ($policy.EnableInternalSenderAdminNotifications -ne $true) {
$policiesToReport += "$($policy.Identity): Notifications Disabled"
}
}
# Determine the result based on the presence of custom policies without notifications
$result = $policiesToReport.Count -eq 0
$details = if ($result) { "All custom malware policies have notifications enabled." } else { "Misconfigured Policies: $($policiesToReport -join ', ')" }
$failureReason = if ($result) { "N/A" } else { "Some custom policies do not have notifications for internal users sending malware enabled." }
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($result) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.Rec = "2.1.3"
$auditResult.RecDescription = "Ensure notifications for internal users sending malware is Enabled"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "17.5"
$auditResult.CISDescription = "Assign Key Roles and Responsibilities"
$auditResult.IG1 = $false
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.Result = $result
$auditResult.Details = $details
$auditResult.FailureReason = $failureReason
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,41 @@
function Test-OneDriveContentRestrictions_7.2.4_E3L2_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
}
process {
# 7.2.4 (L2) Ensure OneDrive content sharing is restricted
$SPOTenant = Get-SPOTenant | Select-Object OneDriveSharingCapability
$isOneDriveSharingRestricted = $SPOTenant.OneDriveSharingCapability -eq 'Disabled'
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "3.3"
$auditResult.CISDescription = "Configure Data Access Control Lists"
$auditResult.Rec = "7.2.4"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L2"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.RecDescription = "Ensure OneDrive content sharing is restricted"
$auditResult.Result = $isOneDriveSharingRestricted
$auditResult.Details = "OneDriveSharingCapability: $($SPOTenant.OneDriveSharingCapability)"
$auditResult.FailureReason = if (-not $isOneDriveSharingRestricted) { "OneDrive content sharing is not restricted to 'Disabled'. Current setting: $($SPOTenant.OneDriveSharingCapability)" } else { "N/A" }
$auditResult.Status = if ($isOneDriveSharingRestricted) { "Pass" } else { "Fail" }
}
end {
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,41 @@
function Test-OneDriveSyncRestrictions_7.3.2_E3L2 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
}
process {
# 7.3.2 (L2) Ensure OneDrive sync is restricted for unmanaged devices
$SPOTenantSyncClientRestriction = Get-SPOTenantSyncClientRestriction | Select-Object TenantRestrictionEnabled, AllowedDomainList
$isSyncRestricted = $SPOTenantSyncClientRestriction.TenantRestrictionEnabled -and $SPOTenantSyncClientRestriction.AllowedDomainList
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0"
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "7.3.2"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L2"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $false
$auditResult.RecDescription = "Ensure OneDrive sync is restricted for unmanaged devices"
$auditResult.Result = $isSyncRestricted
$auditResult.Details = "TenantRestrictionEnabled: $($SPOTenantSyncClientRestriction.TenantRestrictionEnabled); AllowedDomainList: $($SPOTenantSyncClientRestriction.AllowedDomainList -join ', ')"
$auditResult.FailureReason = if (-not $isSyncRestricted) { "OneDrive sync is not restricted to managed devices. TenantRestrictionEnabled should be True and AllowedDomainList should contain trusted domains GUIDs." } else { "N/A" }
$auditResult.Status = if ($isSyncRestricted) { "Pass" } else { "Fail" }
}
end {
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,45 @@
function Test-OrgOnlyBypassLobby_8.5.3_E3L1_IG3 {
[CmdletBinding()]
param (
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 8.5.3 (L1) Ensure only people in my org can bypass the lobby
# Connect to Teams PowerShell using Connect-MicrosoftTeams
$CsTeamsMeetingPolicyLobby = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AutoAdmittedUsers
$lobbyBypassRestricted = $CsTeamsMeetingPolicyLobby.AutoAdmittedUsers -eq 'EveryoneInCompanyExcludingGuests'
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "6.8"
$auditResult.CISDescription = "Define and Maintain Role-Based Access Control"
$auditResult.Rec = "8.5.3"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false # Set based on the CIS Controls image
$auditResult.IG2 = $false # Set based on the CIS Controls image
$auditResult.IG3 = $true # Set based on the CIS Controls image
$auditResult.RecDescription = "Ensure only people in my org can bypass the lobby"
$auditResult.Result = $lobbyBypassRestricted
$auditResult.Details = "AutoAdmittedUsers is set to $($CsTeamsMeetingPolicyLobby.AutoAdmittedUsers)"
$auditResult.FailureReason = if ($lobbyBypassRestricted) { "N/A" } else { "External participants can bypass the lobby" }
$auditResult.Status = if ($lobbyBypassRestricted) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,45 @@
function Test-OrganizersPresent_8.5.6_E3L1 {
[CmdletBinding()]
param (
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 8.5.6 (L2) Ensure only organizers and co-organizers can present
# Connect to Teams PowerShell using Connect-MicrosoftTeams
$CsTeamsMeetingPolicyPresenters = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property DesignatedPresenterRoleMode
$presenterRoleRestricted = $CsTeamsMeetingPolicyPresenters.DesignatedPresenterRoleMode -eq 'OrganizerOnlyUserOverride'
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0" # Explicitly Not Mapped as per the image provided
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "8.5.6"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false # Set based on the CIS Controls image
$auditResult.IG2 = $false # Set based on the CIS Controls image
$auditResult.IG3 = $false # Set based on the CIS Controls image
$auditResult.RecDescription = "Ensure only organizers and co-organizers can present"
$auditResult.Result = $presenterRoleRestricted
$auditResult.Details = "DesignatedPresenterRoleMode is set to $($CsTeamsMeetingPolicyPresenters.DesignatedPresenterRoleMode)"
$auditResult.FailureReason = if ($presenterRoleRestricted) { "N/A" } else { "Others besides organizers and co-organizers can present" }
$auditResult.Status = if ($presenterRoleRestricted) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,43 @@
function Test-PasswordHashSync_5.1.8.1_E3L1_IG2_IG3 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 5.1.8.1 (L1) Ensure password hash sync is enabled for hybrid deployments
# Pass if OnPremisesSyncEnabled is True. Fail otherwise.
$passwordHashSync = Get-MgOrganization | Select-Object OnPremisesSyncEnabled
$hashSyncResult = $passwordHashSync.OnPremisesSyncEnabled
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($hashSyncResult) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.Rec = "5.1.8.1"
$auditResult.RecDescription = "Ensure password hash sync is enabled for hybrid deployments"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "6.7"
$auditResult.CISDescription = "Centralize Access Control"
$auditResult.IG1 = $false
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.Result = $hashSyncResult
$auditResult.Details = "OnPremisesSyncEnabled: $($passwordHashSync.OnPremisesSyncEnabled)"
$auditResult.FailureReason = if (-not $hashSyncResult) { "Password hash sync for hybrid deployments is not enabled" } else { "N/A" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,45 @@
function Test-PasswordNeverExpirePolicy_1.3.1_E3L1_IG1_IG2_IG3 {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string]$DomainName # DomainName parameter is now mandatory
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 1.3.1 (L1) Ensure the 'Password expiration policy' is set to 'Set passwords to never expire'
# Pass if PasswordValidityPeriodInDays is 0.
# Fail otherwise.
$passwordPolicy = Get-MgDomain -DomainId $DomainName | Select-Object PasswordValidityPeriodInDays
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Rec = "1.3.1"
$auditResult.RecDescription = "Ensure the 'Password expiration policy' is set to 'Set passwords to never expire'"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "5.2"
$auditResult.CISDescription = "Use Unique Passwords"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true # All are true
$auditResult.Result = $passwordPolicy.PasswordValidityPeriodInDays -eq 0
$auditResult.Details = "Validity Period: $($passwordPolicy.PasswordValidityPeriodInDays) days"
$auditResult.FailureReason = if ($passwordPolicy.PasswordValidityPeriodInDays -eq 0) { "N/A" } else { "Password expiration is not set to never expire" }
$auditResult.Status = if ($passwordPolicy.PasswordValidityPeriodInDays -eq 0) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,41 @@
function Test-ReauthWithCode_7.2.10_E3L1 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
}
process {
# 7.2.10 (L1) Ensure reauthentication with verification code is restricted
$SPOTenantReauthentication = Get-SPOTenant | Select-Object EmailAttestationRequired, EmailAttestationReAuthDays
$isReauthenticationRestricted = $SPOTenantReauthentication.EmailAttestationRequired -and $SPOTenantReauthentication.EmailAttestationReAuthDays -le 15
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0"
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "7.2.10"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $false
$auditResult.RecDescription = "Ensure reauthentication with verification code is restricted"
$auditResult.Result = $isReauthenticationRestricted
$auditResult.Details = "EmailAttestationRequired: $($SPOTenantReauthentication.EmailAttestationRequired); EmailAttestationReAuthDays: $($SPOTenantReauthentication.EmailAttestationReAuthDays)"
$auditResult.FailureReason = if (-not $isReauthenticationRestricted) { "Reauthentication with verification code does not require reauthentication within 15 days or less." } else { "N/A" }
$auditResult.Status = if ($isReauthenticationRestricted) { "Pass" } else { "Fail" }
}
end {
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,56 @@
function Test-ReportSecurityInTeams_8.6.1_E3L1 {
[CmdletBinding()]
param (
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 8.6.1 (L1) Ensure users can report security concerns in Teams
# Connect to Teams PowerShell using Connect-MicrosoftTeams
# Connect to Exchange Online PowerShell using Connect-ExchangeOnline
$CsTeamsMessagingPolicy = Get-CsTeamsMessagingPolicy -Identity Global | Select-Object -Property AllowSecurityEndUserReporting
$ReportSubmissionPolicy = Get-ReportSubmissionPolicy | Select-Object -Property ReportJunkToCustomizedAddress, ReportNotJunkToCustomizedAddress, ReportPhishToCustomizedAddress, ReportChatMessageToCustomizedAddressEnabled
$securityReportEnabled = $CsTeamsMessagingPolicy.AllowSecurityEndUserReporting -and
$ReportSubmissionPolicy.ReportJunkToCustomizedAddress -and
$ReportSubmissionPolicy.ReportNotJunkToCustomizedAddress -and
$ReportSubmissionPolicy.ReportPhishToCustomizedAddress -and
$ReportSubmissionPolicy.ReportChatMessageToCustomizedAddressEnabled
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0" # Explicitly Not Mapped as per the image provided
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "8.6.1"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false # Set based on the CIS Controls image
$auditResult.IG2 = $false # Set based on the CIS Controls image
$auditResult.IG3 = $false # Set based on the CIS Controls image
$auditResult.RecDescription = "Ensure users can report security concerns in Teams"
$auditResult.Result = $securityReportEnabled
$auditResult.Details = "AllowSecurityEndUserReporting: $($CsTeamsMessagingPolicy.AllowSecurityEndUserReporting); " +
"ReportJunkToCustomizedAddress: $($ReportSubmissionPolicy.ReportJunkToCustomizedAddress); " +
"ReportNotJunkToCustomizedAddress: $($ReportSubmissionPolicy.ReportNotJunkToCustomizedAddress); " +
"ReportPhishToCustomizedAddress: $($ReportSubmissionPolicy.ReportPhishToCustomizedAddress); " +
"ReportChatMessageToCustomizedAddressEnabled: $($ReportSubmissionPolicy.ReportChatMessageToCustomizedAddressEnabled)"
$auditResult.FailureReason = if (-not $securityReportEnabled) { "Users cannot report security concerns in Teams due to one or more incorrect settings" } else { "N/A" }
$auditResult.Status = if ($securityReportEnabled) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,52 @@
function Test-RestrictCustomScripts_7.3.4_E3L1_IG3 {
[CmdletBinding()]
param (
# Define your parameters here if needed
)
begin {
# .TODO Test behavior in Prod
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# CIS 2.7 Ensure custom script execution is restricted on site collections
# Pass if DenyAddAndCustomizePages is set to true. Fail otherwise.
# Connect to SharePoint Online using Connect-SPOService
$SPOSitesCustomScript = Get-SPOSite | Select-Object Title, Url, DenyAddAndCustomizePages
$customScriptDisabledSites = $SPOSitesCustomScript | Where-Object { $_.DenyAddAndCustomizePages -eq 'Enabled' }
$customScriptEnabledSites = $SPOSitesCustomScript | Where-Object { $_.DenyAddAndCustomizePages -ne 'Enabled' }
$customScriptDisabledResult = $customScriptEnabledSites.Count -eq 0
# Correctly gathering details for sites with custom scripts enabled
$customScriptEnabledDetails = $customScriptEnabledSites | ForEach-Object { "$($_.Title) ($($_.Url)): Custom Script - $($_.DenyAddAndCustomizePages)" }
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "2.7"
$auditResult.CISDescription = "Allowlist Authorized Scripts"
$auditResult.Rec = "7.3.4"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false # Set based on the benchmark
$auditResult.IG2 = $false # Set based on the benchmark
$auditResult.IG3 = $true # Set based on the benchmark
$auditResult.RecDescription = "Ensure custom script execution is restricted on site collections"
$auditResult.Result = $customScriptDisabledResult
$auditResult.Details = if (-not $customScriptDisabledResult) { $customScriptEnabledDetails -join "; " } else { "All site collections have custom script execution restricted" }
$auditResult.FailureReason = if (-not $customScriptDisabledResult) { "The following site collections have custom script execution enabled: " + ($customScriptEnabledDetails -join "; ") } else { "N/A" }
$auditResult.Status = if ($customScriptDisabledResult) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,41 @@
function Test-RestrictExternalSharing_7.2.3_E3L1_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
}
process {
# 7.2.3 (L1) Ensure external content sharing is restricted
$SPOTenantSharingCapability = Get-SPOTenant | Select-Object SharingCapability
$isRestricted = $SPOTenantSharingCapability.SharingCapability -in @('ExternalUserSharingOnly', 'ExistingExternalUserSharingOnly', 'Disabled')
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "3.3"
$auditResult.CISDescription = "Configure Data Access Control Lists"
$auditResult.Rec = "7.2.3"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.RecDescription = "Ensure external content sharing is restricted"
$auditResult.Result = $isRestricted
$auditResult.Details = "SharingCapability: $($SPOTenantSharingCapability.SharingCapability)"
$auditResult.FailureReason = if (-not $isRestricted) { "External content sharing is not adequately restricted. Current setting: $($SPOTenantSharingCapability.SharingCapability)" } else { "N/A" }
$auditResult.Status = if ($isRestricted) { "Pass" } else { "Fail" }
}
end {
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,90 @@
function Test-RestrictOutlookAddins_6.3.1_E3L2_IG2_IG3 {
[CmdletBinding()]
param (
# Parameters could include credentials or other necessary data
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
$customPolicyFailures = @()
$defaultPolicyFailureDetails = @()
$relevantRoles = @('My Custom Apps', 'My Marketplace Apps', 'My ReadWriteMailbox Apps')
}
process {
# Main functionality
# 6.3.1 (L2) Ensure users installing Outlook add-ins is not allowed
# Check all mailboxes for custom policies with unallowed add-ins
$roleAssignmentPolicies = Get-EXOMailbox | Select-Object -Unique RoleAssignmentPolicy
if ($roleAssignmentPolicies.RoleAssignmentPolicy) {
foreach ($policy in $roleAssignmentPolicies) {
if ($policy.RoleAssignmentPolicy) {
$rolePolicyDetails = Get-RoleAssignmentPolicy -Identity $policy.RoleAssignmentPolicy
$foundRoles = $rolePolicyDetails.AssignedRoles | Where-Object { $_ -in $relevantRoles }
if ($foundRoles) {
$customPolicyFailures += "Policy: $($policy.RoleAssignmentPolicy): Roles: $($foundRoles -join ', ')"
}
}
}
}
# Check Default Role Assignment Policy
$defaultPolicy = Get-RoleAssignmentPolicy "Default Role Assignment Policy"
$defaultPolicyRoles = $defaultPolicy.AssignedRoles | Where-Object { $_ -in $relevantRoles }
if ($defaultPolicyRoles) {
$defaultPolicyFailureDetails = $defaultPolicyRoles
}
}
end {
# Prepare result object
$auditResult.Rec = "6.3.1"
$auditResult.CISControl = "9.4"
$auditResult.CISDescription = "Restrict Unnecessary or Unauthorized Browser and Email Client Extensions"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L2"
$auditResult.IG1 = $false
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.RecDescription = "Ensure users installing Outlook add-ins is not allowed"
$detailsString = ""
if ($customPolicyFailures) {
$detailsString += "Custom Policy Failures: `n"
foreach ($failure in $customPolicyFailures) {
$detailsString += "`t$failure`n"
}
}
else {
$detailsString += "Custom Policy Failures: None`n"
}
$detailsString += "Default Role Assignment Policy: "
if ($defaultPolicyFailureDetails) {
$detailsString += "$($defaultPolicyFailureDetails -join ', ')"
}
else {
$detailsString += "Compliant"
}
if ($customPolicyFailures -or $defaultPolicyFailureDetails) {
$auditResult.Result = $false
$auditResult.Status = "Fail"
$auditResult.Details = $detailsString
$auditResult.FailureReason = "Unauthorized Outlook add-ins found in custom or default policies."
}
else {
$auditResult.Result = $true
$auditResult.Status = "Pass"
$auditResult.Details = "No unauthorized Outlook add-ins found in custom or default policies."
$auditResult.FailureReason = "N/A"
}
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,48 @@
function Test-RestrictStorageProvidersOutlook_6.5.3_E3L2_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Parameters can be added here if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
}
process {
# 6.5.3 (L2) Ensure additional storage providers are restricted in Outlook on the web
$owaPolicies = Get-OwaMailboxPolicy
$allPoliciesRestricted = $owaPolicies | ForEach-Object { $_.AdditionalStorageProvidersAvailable } | ForEach-Object { -not $_ }
# Create an instance of CISAuditResult and populate it
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "3.3"
$auditResult.CISDescription = "Configure Data Access Control Lists"
$auditResult.Rec = "6.5.3"
$auditResult.ELevel = "E3" # Based on your environment
$auditResult.Profile = "L2"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.RecDescription = "Ensure additional storage providers are restricted in Outlook on the web"
$auditResult.Result = $allPoliciesRestricted
$auditResult.Details = if($allPoliciesRestricted) {
"All OwaMailbox policies restrict AdditionalStorageProvidersAvailable"
} else {
$nonCompliantPolicies = $owaPolicies | Where-Object { $_.AdditionalStorageProvidersAvailable } | Select-Object -ExpandProperty Name
"Non-compliant OwaMailbox policies: $($nonCompliantPolicies -join ', ')"
}
$auditResult.FailureReason = if(-not $allPoliciesRestricted) { "One or more OwaMailbox policies allow AdditionalStorageProvidersAvailable." } else { "N/A" }
$auditResult.Status = if($allPoliciesRestricted) { "Pass" } else { "Fail" }
}
end {
# Return auditResult
return $auditResult
}
}
# Additional helper functions (if any)

View File

@@ -0,0 +1,43 @@
function Test-RestrictTenantCreation_5.1.2.3_E3L1 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 5.1.2.3 (L1) Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes'
# Pass if AllowedToCreateTenants is False. Fail otherwise.
$tenantCreationPolicy = (Get-MgPolicyAuthorizationPolicy).DefaultUserRolePermissions | Select-Object AllowedToCreateTenants
$tenantCreationResult = -not $tenantCreationPolicy.AllowedToCreateTenants
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($tenantCreationResult) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.Rec = "5.1.2.3"
$auditResult.RecDescription = "Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes'"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0"
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $false
$auditResult.Result = $tenantCreationResult
$auditResult.Details = "AllowedToCreateTenants: $($tenantCreationPolicy.AllowedToCreateTenants)"
$auditResult.FailureReason = if (-not $tenantCreationResult) { "Non-admin users can create tenants" } else { "N/A" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,49 @@
function Test-SafeAttachmentsPolicy_2.1.4_E5L2_IG3 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# Retrieve all Safe Attachment policies where Enable is set to True
$safeAttachmentPolicies = Get-SafeAttachmentPolicy | Where-Object { $_.Enable -eq $true }
# If there are any enabled policies, the result is Pass. If not, it's Fail.
$result = $safeAttachmentPolicies -ne $null -and $safeAttachmentPolicies.Count -gt 0
$details = if ($result) {
"Enabled Safe Attachments Policies: $($safeAttachmentPolicies.Name -join ', ')"
} else {
"No Safe Attachments Policies are enabled."
}
$failureReason = if ($result) { "N/A" } else { "Safe Attachments policy is not enabled." }
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($result) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E5"
$auditResult.Profile = "L2"
$auditResult.Rec = "2.1.4"
$auditResult.RecDescription = "Ensure Safe Attachments policy is enabled"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "9.7"
$auditResult.CISDescription = "Deploy and Maintain Email Server Anti-Malware Protections"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $true
$auditResult.Result = $result
$auditResult.Details = $details
$auditResult.FailureReason = $failureReason
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,56 @@
function Test-SafeAttachmentsTeams_2.1.5_E5L2_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# Retrieve the ATP policies for Office 365 and check Safe Attachments settings
$atpPolicies = Get-AtpPolicyForO365
# Check if the required ATP policies are enabled
$atpPolicyResult = $atpPolicies | Where-Object {
$_.EnableATPForSPOTeamsODB -eq $true -and
$_.EnableSafeDocs -eq $true -and
$_.AllowSafeDocsOpen -eq $false
}
# Determine the result based on the ATP policy settings
$result = $null -ne $atpPolicyResult
$details = if ($result) {
"ATP for SharePoint, OneDrive, and Teams is enabled with correct settings."
} else {
"ATP for SharePoint, OneDrive, and Teams is not enabled with correct settings."
}
$failureReason = if ($result) { "N/A" } else { "ATP policy for SharePoint, OneDrive, and Microsoft Teams is not correctly configured." }
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($result) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E5"
$auditResult.Profile = "L2"
$auditResult.Rec = "2.1.5"
$auditResult.RecDescription = "Ensure Safe Attachments for SharePoint, OneDrive, and Microsoft Teams is Enabled"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "9.7, 10.1"
$auditResult.CISDescription = "Deploy and Maintain Email Server Anti-Malware Protections, Deploy and Maintain Anti-Malware Software"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.Result = $result
$auditResult.Details = $details
$auditResult.FailureReason = $failureReason
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,70 @@
function Test-SafeLinksOfficeApps_2.1.1_E5L2_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Define your parameters here if needed
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# Retrieve all Safe Links policies
$policies = Get-SafeLinksPolicy
# Initialize the details collection
$misconfiguredDetails = @()
foreach ($policy in $policies) {
# Get the detailed configuration of each policy
$policyDetails = Get-SafeLinksPolicy -Identity $policy.Name
# Check each required property and record failures
$failures = @()
if ($policyDetails.EnableSafeLinksForEmail -ne $true) { $failures += "EnableSafeLinksForEmail: False" }
if ($policyDetails.EnableSafeLinksForTeams -ne $true) { $failures += "EnableSafeLinksForTeams: False" }
if ($policyDetails.EnableSafeLinksForOffice -ne $true) { $failures += "EnableSafeLinksForOffice: False" }
if ($policyDetails.TrackClicks -ne $true) { $failures += "TrackClicks: False" }
if ($policyDetails.AllowClickThrough -ne $false) { $failures += "AllowClickThrough: True" }
if ($policyDetails.ScanUrls -ne $true) { $failures += "ScanUrls: False" }
if ($policyDetails.EnableForInternalSenders -ne $true) { $failures += "EnableForInternalSenders: False" }
if ($policyDetails.DeliverMessageAfterScan -ne $true) { $failures += "DeliverMessageAfterScan: False" }
if ($policyDetails.DisableUrlRewrite -ne $false) { $failures += "DisableUrlRewrite: True" }
# Only add details for policies that have misconfigurations
if ($failures.Count -gt 0) {
$misconfiguredDetails += "Policy: $($policy.Name); Failures: $($failures -join ', ')"
}
}
# Prepare the final result
$result = $misconfiguredDetails.Count -eq 0
$details = if ($result) { "All Safe Links policies are correctly configured." } else { $misconfiguredDetails -join ' | ' }
# Create the audit result object
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($result) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E5"
$auditResult.Profile = "L2"
$auditResult.Rec = "2.1.1"
$auditResult.RecDescription = "Ensure Safe Links for Office Applications is Enabled"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "10.1"
$auditResult.CISDescription = "Deploy and Maintain Anti-Malware Software"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.Result = $result
$auditResult.Details = $details
$auditResult.FailureReason = if ($result) { "N/A" } else { "The following Safe Links policies settings do not meet the recommended configuration: $($misconfiguredDetails -join ' | ')" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,40 @@
function Test-SharePointAADB2B_7.2.2_E3L1 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
}
process {
# 7.2.2 (L1) Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled
$SPOTenantAzureADB2B = Get-SPOTenant | Select-Object EnableAzureADB2BIntegration
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0"
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "7.2.2"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $false
$auditResult.RecDescription = "Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled"
$auditResult.Result = $SPOTenantAzureADB2B.EnableAzureADB2BIntegration
$auditResult.Details = "EnableAzureADB2BIntegration: $($SPOTenantAzureADB2B.EnableAzureADB2BIntegration)"
$auditResult.FailureReason = if (-not $SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Azure AD B2B integration is not enabled" } else { "N/A" }
$auditResult.Status = if ($SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Pass" } else { "Fail" }
}
end {
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,41 @@
function Test-SharePointExternalSharingDomains_7.2.6_E3L2_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
}
process {
# 7.2.6 (L2) Ensure SharePoint external sharing is managed through domain whitelist/blacklists
$SPOTenant = Get-SPOTenant | Select-Object SharingDomainRestrictionMode, SharingAllowedDomainList
$isDomainRestrictionConfigured = $SPOTenant.SharingDomainRestrictionMode -eq 'AllowList'
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "3.3"
$auditResult.CISDescription = "Configure Data Access Control Lists"
$auditResult.Rec = "7.2.6"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L2"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.RecDescription = "Ensure SharePoint external sharing is managed through domain whitelist/blacklists"
$auditResult.Result = $isDomainRestrictionConfigured
$auditResult.Details = "SharingDomainRestrictionMode: $($SPOTenant.SharingDomainRestrictionMode); SharingAllowedDomainList: $($SPOTenant.SharingAllowedDomainList)"
$auditResult.FailureReason = if (-not $isDomainRestrictionConfigured) { "Domain restrictions for SharePoint external sharing are not configured to 'AllowList'. Current setting: $($SPOTenant.SharingDomainRestrictionMode)" } else { "N/A" }
$auditResult.Status = if ($isDomainRestrictionConfigured) { "Pass" } else { "Fail" }
}
end {
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,41 @@
function Test-SharePointGuestsItemSharing_7.2.5_E3L2_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Define your parameters here
)
begin {
# Initialization code
. ".\source\Classes\CISAuditResult.ps1"
$auditResult = [CISAuditResult]::new()
}
process {
# 7.2.5 (L2) Ensure that SharePoint guest users cannot share items they don't own
$SPOTenant = Get-SPOTenant | Select-Object PreventExternalUsersFromResharing
$isGuestResharingPrevented = $SPOTenant.PreventExternalUsersFromResharing
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "3.3"
$auditResult.CISDescription = "Configure Data Access Control Lists"
$auditResult.Rec = "7.2.5"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L2"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.RecDescription = "Ensure that SharePoint guest users cannot share items they don't own"
$auditResult.Result = $isGuestResharingPrevented
$auditResult.Details = "PreventExternalUsersFromResharing: $isGuestResharingPrevented"
$auditResult.FailureReason = if (-not $isGuestResharingPrevented) { "Guest users can reshare items they don't own." } else { "N/A" }
$auditResult.Status = if ($isGuestResharingPrevented) { "Pass" } else { "Fail" }
}
end {
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,56 @@
function Test-SpamPolicyAdminNotify_2.1.6_E3L1_IG2_IG3 {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# Get the default hosted outbound spam filter policy
$hostedOutboundSpamFilterPolicy = Get-HostedOutboundSpamFilterPolicy | Where-Object { $_.IsDefault -eq $true }
# Check if both settings are enabled
$bccSuspiciousOutboundMailEnabled = $hostedOutboundSpamFilterPolicy.BccSuspiciousOutboundMail
$notifyOutboundSpamEnabled = $hostedOutboundSpamFilterPolicy.NotifyOutboundSpam
$areSettingsEnabled = $bccSuspiciousOutboundMailEnabled -and $notifyOutboundSpamEnabled
# Prepare failure details if any setting is not enabled
$failureDetails = @()
if (-not $bccSuspiciousOutboundMailEnabled) {
$failureDetails += "BccSuspiciousOutboundMail is not enabled."
}
if (-not $notifyOutboundSpamEnabled) {
$failureDetails += "NotifyOutboundSpam is not enabled."
}
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($areSettingsEnabled) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E3"
$auditResult.Profile = "L1"
$auditResult.Rec = "2.1.6"
$auditResult.RecDescription = "Ensure Exchange Online Spam Policies are set to notify administrators"
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "17.5"
$auditResult.CISDescription = "Assign Key Roles and Responsibilities"
$auditResult.IG1 = $false
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.Result = $areSettingsEnabled
$auditResult.Details = if ($areSettingsEnabled) { "Both BccSuspiciousOutboundMail and NotifyOutboundSpam are enabled." } else { $failureDetails -join ' ' }
$auditResult.FailureReason = if (-not $areSettingsEnabled) { "One or both spam policies are not set to notify administrators." } else { "N/A" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,52 @@
function Test-TeamsExternalAccess_8.2.1_E3L2 {
[CmdletBinding()]
param (
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 8.2.1 (L1) Ensure 'external access' is restricted in the Teams admin center
# Connect to Teams PowerShell using Connect-MicrosoftTeams
$externalAccessConfig = Get-CsTenantFederationConfiguration
$allowedDomainsLimited = $false
if ($externalAccessConfig.AllowFederatedUsers -and $externalAccessConfig.AllowedDomains -and $externalAccessConfig.AllowedDomains.AllowedDomain.Count -gt 0) {
$allowedDomainsLimited = $true
}
# Check if the configurations are as recommended
$isCompliant = -not $externalAccessConfig.AllowTeamsConsumer -and -not $externalAccessConfig.AllowPublicUsers -and (-not $externalAccessConfig.AllowFederatedUsers -or $allowedDomainsLimited)
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0" # The control is Explicitly Not Mapped as per the image provided
$auditResult.CISDescription = "Explicitly Not Mapped"
$auditResult.Rec = "8.2.1"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L2"
$auditResult.IG1 = $false # Set based on the CIS Controls image
$auditResult.IG2 = $false # Set based on the CIS Controls image
$auditResult.IG3 = $false # Set based on the CIS Controls image
$auditResult.RecDescription = "Ensure 'external access' is restricted in the Teams admin center"
$auditResult.Result = $isCompliant
$auditResult.Details = "AllowTeamsConsumer: $($externalAccessConfig.AllowTeamsConsumer); AllowPublicUsers: $($externalAccessConfig.AllowPublicUsers); AllowFederatedUsers: $($externalAccessConfig.AllowFederatedUsers); AllowedDomains limited: $allowedDomainsLimited"
$auditResult.FailureReason = if (-not $isCompliant) { "One or more external access configurations are not compliant." } else { "N/A" }
$auditResult.Status = if ($isCompliant) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}

View File

@@ -0,0 +1,56 @@
function Test-TeamsExternalFileSharing_8.1.1_E3L2_IG1_IG2_IG3 {
[CmdletBinding()]
param (
# Parameters can be added here if needed
)
begin {
# Dot source the class script
. ".\source\Classes\CISAuditResult.ps1"
$auditResults = @()
}
process {
# 8.1.1 (L2) Ensure external file sharing in Teams is enabled for only approved cloud storage services
# Connect to Teams PowerShell using Connect-MicrosoftTeams
# Assuming that 'approvedProviders' is a list of approved cloud storage service names
# This list must be defined according to your organization's approved cloud storage services
$approvedProviders = @("AllowDropBox", "AllowBox", "AllowGoogleDrive", "AllowShareFile", "AllowEgnyte")
$clientConfig = Get-CsTeamsClientConfiguration
$isCompliant = $true
$nonCompliantProviders = @()
foreach ($provider in $approvedProviders) {
if (-not $clientConfig.$provider) {
$isCompliant = $false
$nonCompliantProviders += $provider
}
}
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "3.3"
$auditResult.CISDescription = "Configure Data Access Control Lists"
$auditResult.Rec = "8.1.1"
$auditResult.ELevel = "E3"
$auditResult.Profile = "L2"
$auditResult.IG1 = $true # Set based on the benchmark
$auditResult.IG2 = $true # Set based on the benchmark
$auditResult.IG3 = $true # Set based on the benchmark
$auditResult.RecDescription = "Ensure external file sharing in Teams is enabled for only approved cloud storage services"
$auditResult.Result = $isCompliant
$auditResult.Details = if (-not $isCompliant) { "Non-approved providers enabled: $($nonCompliantProviders -join ', ')" } else { "All cloud storage services are approved providers" }
$auditResult.FailureReason = if (-not $isCompliant) { "The following non-approved providers are enabled: $($nonCompliantProviders -join ', ')" } else { "N/A" }
$auditResult.Status = if ($isCompliant) { "Pass" } else { "Fail" }
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
}
}