68 Commits

Author SHA1 Message Date
Doug Rios
531cedc0f6 Merge pull request #5 from CriticalSolutionsNetwork/test-arraylist
Refactor and Align Tests with selected template
2024-05-28 20:12:30 -05:00
DrIOS
54f9e086a9 docs: Update README 2024-05-28 20:10:54 -05:00
DrIOS
d1555e1d25 docs: update help 2024-05-28 20:07:46 -05:00
DrIOS
ac8014ae77 docs: update CHANGELOG 2024-05-28 19:53:15 -05:00
DrIOS
fc9923b980 docs: updated online help link 2024-05-28 19:52:47 -05:00
DrIOS
290540b25a fix: Refactor Initialize-CISAuditResult to use global test definitions 2024-05-28 19:25:27 -05:00
DrIOS
b064f9f271 add: refactor of object initialization 2024-05-28 18:50:18 -05:00
DrIOS
cafcaf2671 add: missing properties to csv 2024-05-28 17:13:00 -05:00
DrIOS
129bb33a99 add: New testing function 2024-05-28 17:08:04 -05:00
DrIOS
8505439516 fix: class comment aligned with test-template 2024-05-28 14:54:32 -05:00
DrIOS
686272d4e0 fix: 8.1.1 aligned with test-template 2024-05-28 14:51:24 -05:00
DrIOS
f445893aed fix: 8.2.1 aligned with test-template 2024-05-28 14:49:23 -05:00
DrIOS
050ea83acd fix: 2.1.6 aligned with test-template 2024-05-28 14:47:42 -05:00
DrIOS
deec4c4f5e fix: 7.2.5 aligned with test-template 2024-05-28 14:43:30 -05:00
DrIOS
6930673209 fix: 7.2.6 aligned with test-template 2024-05-28 14:40:56 -05:00
DrIOS
87db439d66 fix: 7.2.2 aligned with test-template 2024-05-28 14:38:28 -05:00
DrIOS
3d84a86793 fix: 2.1.1 aligned with test-template 2024-05-28 14:34:17 -05:00
DrIOS
dbc577bc67 fix: 2.1.5 aligned with test-template 2024-05-28 14:29:09 -05:00
DrIOS
d1a5cb8d73 fix: 2.1.4 aligned with test-template 2024-05-28 14:26:38 -05:00
DrIOS
c1e94ff3bc fix: 5.1.2.3 aligned with test-template 2024-05-28 14:24:09 -05:00
DrIOS
532cb942e8 fix: 6.5.3 aligned with test-template 2024-05-28 14:20:06 -05:00
DrIOS
2d93422027 fix: 6.3.1 aligned with test-template 2024-05-28 14:17:12 -05:00
DrIOS
75faf04ea6 fix: 7.2.3 aligned with test-template 2024-05-28 13:27:15 -05:00
DrIOS
c7cdaa4bf6 fix: 7.3.4 aligned with test-template 2024-05-28 13:24:10 -05:00
DrIOS
d511ea7b27 fix: 8.6.1 aligned with test-template 2024-05-28 13:21:39 -05:00
DrIOS
5b3c68a8f9 fix: 7.2.10 aligned with test-template 2024-05-28 13:19:20 -05:00
DrIOS
3883e33a4a fix: 1.3.1 aligned with test-template 2024-05-28 13:17:11 -05:00
DrIOS
398ce397f5 fix: 5.1.8.1 aligned with test-template 2024-05-28 13:14:34 -05:00
DrIOS
776b0bf2ec fix: 8.5.3 aligned with test-template 2024-05-28 13:12:38 -05:00
DrIOS
8d03d1825b fix: 8.5.6 aligned with test-template 2024-05-28 13:10:32 -05:00
DrIOS
26fa3a8922 fix: 7.3.2 aligned with test-template 2024-05-28 13:08:36 -05:00
DrIOS
c918f0203e fix: 7.2.4 aligned with test-template 2024-05-28 11:31:45 -05:00
DrIOS
c752b7e4fd fix: 6.2.2 aligned with test-template 2024-05-28 11:29:07 -05:00
DrIOS
3cf76bb6b3 fix: 2.1.3 aligned with test-template 2024-05-28 11:25:57 -05:00
DrIOS
36cb3f1944 fix: 8.5.2 aligned with test-template 2024-05-28 11:23:55 -05:00
DrIOS
c122174cb7 fix: 8.5.1 aligned with test-template 2024-05-28 11:22:23 -05:00
DrIOS
d5c64910ab fix: 7.2.1 aligned with test-template 2024-05-28 11:15:22 -05:00
DrIOS
77c74432fe fix: 6.5.1 aligned with test-template 2024-05-28 11:13:37 -05:00
DrIOS
b4c0993240 fix: 8.5.5 aligned with test-template 2024-05-28 11:09:30 -05:00
DrIOS
e96a5a9d48 fix: 1.2.1 aligned with test-template 2024-05-28 11:05:41 -05:00
DrIOS
2148a37b35 fix: 6.5.2 aligned with test-template 2024-05-28 11:02:25 -05:00
DrIOS
0196607f69 fix: 6.1.2/3 aligned with test-template 2024-05-28 10:59:23 -05:00
DrIOS
f5a3f0e460 fix: 6.1.2 aligned with test-template 2024-05-28 10:54:52 -05:00
DrIOS
5ed1e1de35 fix: 7.2.7 aligned with test-template 2024-05-28 10:49:31 -05:00
DrIOS
0d049c6dcb fix: 6.2.3 aligned with test-template 2024-05-28 10:44:16 -05:00
DrIOS
4b28258b3e fix: added test comments 2024-05-28 10:41:57 -05:00
DrIOS
b8690ddb44 fix: 1.1.4 aligned with test-template 2024-05-28 10:39:54 -05:00
DrIOS
dc88df6eef fix: 7.2.9 aligned with test-template 2024-05-28 10:36:29 -05:00
DrIOS
d0c3d907b9 fix: 1.1.3 aligned with test-template 2024-05-28 10:33:54 -05:00
DrIOS
20ee994ebc fix: 1.3.3 aligned with test-template 2024-05-28 10:31:06 -05:00
DrIOS
0d764e6152 fix: 8.5.7 aligned with test-template 2024-05-28 10:27:38 -05:00
DrIOS
0ae69e5b56 fix: 2.1.9 aligned with test-template 2024-05-28 10:25:03 -05:00
DrIOS
ccb02d84d2 fix: 7.3.1 added comment 2024-05-28 10:24:34 -05:00
DrIOS
5f4217d264 fix: 7.3.1 aligned with test-template 2024-05-28 10:15:40 -05:00
DrIOS
5e9fbfd690 fix: 8.5.4 aligned with test-template 2024-05-28 10:09:58 -05:00
DrIOS
fbe22abe9c fix: 1.3.6 aligned with test-template 2024-05-28 10:05:35 -05:00
DrIOS
283b278524 fix: 2.1.2 aligned with test-template 2024-05-28 09:58:49 -05:00
DrIOS
2f8d7b358a fix: 1.2.2 aligned with test-template 2024-05-28 09:55:57 -05:00
DrIOS
b93df00334 fix: "6.2.1" aligned with test-template 2024-05-28 09:52:30 -05:00
DrIOS
d5faf071b9 fix: "8.1.2" aligned with test-template 2024-05-28 09:39:42 -05:00
DrIOS
a1a2ecbd49 fix: Included functions aligned. 2024-05-28 09:29:06 -05:00
DrIOS
f4ae24b99f add: connections to helper table 2024-05-26 17:32:08 -05:00
DrIOS
652e5ead75 add: aligned test-AuditDisabledFalse 2024-05-26 16:28:04 -05:00
DrIOS
71736bfb43 fix: AntiPhishingPolicy aligned with template 2024-05-26 15:53:57 -05:00
DrIOS
4bc75db1dc add: Details to pass. 2024-05-26 15:34:16 -05:00
DrIOS
37fbf2b32a add: Correction to test-template 2024-05-26 15:33:57 -05:00
DrIOS
05dbf4661c add: Arraylist tests and helper Template 2024-05-26 14:36:27 -05:00
DrIOS
5f5b220fd4 add: Array list to store the results of the audit 2024-05-26 13:10:06 -05:00
64 changed files with 1638 additions and 1265 deletions

1
.gitignore vendored
View File

@@ -15,3 +15,4 @@ output/
markdownissues.txt
node_modules
package-lock.json
Aligned.xlsx

View File

@@ -6,6 +6,32 @@ The format is based on and uses the types of changes according to [Keep a Change
### Added
- Array list to store the results of the audit.
- Arraylist tests and helper template.
- New testing function.
- Missing properties to CSV.
### Changed
- Refactored object initialization to source `RecDescription`, `CISControl`, and `CISDescription` properties from the CSV.
- Added `Automated` and `Connection` properties to the output object.
- All test functions aligned with the test-template.
- Initialize-CISAuditResult refactored to use global test definitions.
### Fixed
- Corrected test-template.
- Details added to pass.
### Docs
- Updated comments and documentation for new functions.
## [0.1.2] - 2024-04-29
### Added
- Automated and organized CSV testing and added test 1.1.1.
- Functions to merge tests into an Excel benchmark.
- Public function for merging tests.
@@ -24,6 +50,7 @@ The format is based on and uses the types of changes according to [Keep a Change
- Updated comments for new functions.
- Updated help documentation.
- Updated online link in public function.
## [0.1.1] - 2024-04-02

BIN
README.md

Binary file not shown.

Binary file not shown.

View File

@@ -4,7 +4,7 @@ Import-Module .\output\module\M365FoundationsCISReport\*\*.psd1
<#
$ver = "v0.1.1"
$ver = "v0.1.2"
git checkout main
git pull origin main
git tag -a $ver -m "Release version $ver Bugfix Update"

View File

@@ -0,0 +1,97 @@
function Test-Template {
[CmdletBinding()]
param (
# Parameters can be added if needed
)
begin {
# Initialization code, if needed
# Load necessary scripts, define variables, etc.
}
process {
# Fetch relevant data
# Example: $data = Get-SomeData
# Process the data to evaluate compliance
# Example: $compliantItems = $data | Where-Object { $_.Property -eq 'ExpectedValue' }
# Example: $nonCompliantItems = $data | Where-Object { $_.Property -ne 'ExpectedValue' }
# Prepare failure reasons for non-compliant items
$failureReasons = $nonCompliantItems | ForEach-Object {
# Example: "Item: $($_.Name) - Reason: Missing expected value"
}
$failureReasons = $failureReasons -join "`n"
# Prepare details for non-compliant items
$nonCompliantDetails = $nonCompliantItems | ForEach-Object {
# Example: "$($_.Name) - Value: $($_.Property)"
}
$nonCompliantDetails = $nonCompliantDetails -join "`n"
# Prepare details based on compliance
$details = if ($nonCompliantItems) {
"Non-Compliant Items: $($nonCompliantItems.Count)`nDetails:`n$nonCompliantDetails"
} else {
"Compliant Items: $($compliantItems.Count)"
}
# Create and populate the CISAuditResult object
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($nonCompliantItems) { 'Fail' } else { 'Pass' }
$auditResult.ELevel = 'E3' # Modify as needed
$auditResult.ProfileLevel = 'L1' # Modify as needed
$auditResult.Rec = '1.1.1' # Modify as needed
$auditResult.RecDescription = "Description of the recommendation" # Modify as needed
$auditResult.CISControlVer = 'v8' # Modify as needed
$auditResult.CISControl = "5.4" # Modify as needed
$auditResult.CISDescription = "Description of the CIS control" # Modify as needed
$auditResult.IG1 = $true # Modify as needed
$auditResult.IG2 = $true # Modify as needed
$auditResult.IG3 = $true # Modify as needed
$auditResult.Result = $nonCompliantItems.Count -eq 0
$auditResult.Details = $details
$auditResult.FailureReason = if ($nonCompliantItems) {
"Non-compliant items:`n$failureReasons"
} else {
"N/A"
}
# Example output object for a pass result
# Status : Pass
# ELevel : E3
# ProfileLevel : L2
# Rec : 8.1.1
# RecDescription : Ensure external file sharing in Teams is enabled for only approved cloud storage services
# CISControlVer : v8
# CISControl : 3.3
# CISDescription : Configure Data Access Control Lists
# IG1 : True
# IG2 : True
# IG3 : True
# Result : True
# Details : Compliant Items: 5
# FailureReason : N/A
# Example output object for a fail result
# Status : Fail
# ELevel : E3
# ProfileLevel : L2
# Rec : 8.1.1
# RecDescription : Ensure external file sharing in Teams is enabled for only approved cloud storage services
# CISControlVer : v8
# CISControl : 3.3
# CISDescription : Configure Data Access Control Lists
# IG1 : True
# IG2 : True
# IG3 : True
# Result : False
# Details : Non-Compliant Items: 2
# FailureReason : Non-compliant items:`nUsername | Roles | HybridStatus | Missing Licence
}
end {
# Return the audit result
return $auditResult
}
}

View File

@@ -2,6 +2,8 @@ class CISAuditResult {
[string]$Status
[string]$ELevel
[string]$ProfileLevel
[bool]$Automated
[string]$Connection
[string]$Rec
[string]$RecDescription
[string]$CISControlVer = 'v8'

View File

@@ -0,0 +1,45 @@
function Initialize-CISAuditResult {
param (
[Parameter(Mandatory = $true)]
[string]$Rec,
[Parameter(Mandatory = $true)]
[bool]$Result,
[Parameter(Mandatory = $true)]
[string]$Status,
[Parameter(Mandatory = $true)]
[string]$Details,
[Parameter(Mandatory = $true)]
[string]$FailureReason
)
# Import the test definitions CSV file
$testDefinitions = $script:TestDefinitionsObject
# Find the row that matches the provided recommendation (Rec)
$testDefinition = $testDefinitions | Where-Object { $_.Rec -eq $Rec }
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Rec = $Rec
$auditResult.ELevel = $testDefinition.ELevel
$auditResult.ProfileLevel = $testDefinition.ProfileLevel
$auditResult.IG1 = [bool]::Parse($testDefinition.IG1)
$auditResult.IG2 = [bool]::Parse($testDefinition.IG2)
$auditResult.IG3 = [bool]::Parse($testDefinition.IG3)
$auditResult.RecDescription = $testDefinition.RecDescription
$auditResult.CISControl = $testDefinition.CISControl
$auditResult.CISDescription = $testDefinition.CISDescription
$auditResult.Automated = [bool]::Parse($testDefinition.Automated)
$auditResult.Connection = $testDefinition.Connection
$auditResult.CISControlVer = 'v8'
$auditResult.Result = $Result
$auditResult.Status = $Status
$auditResult.Details = $Details
$auditResult.FailureReason = $FailureReason
return $auditResult
}

View File

@@ -36,8 +36,8 @@ function Get-AdminRoleUserLicense {
Connect-MgGraph -Scopes "Directory.Read.All", "Domain.Read.All", "Policy.Read.All", "Organization.Read.All" -NoWelcome
}
$adminRoleUsers = @()
$userIds = @()
$adminRoleUsers = [System.Collections.ArrayList]::new()
$userIds = [System.Collections.ArrayList]::new()
}
Process {
@@ -50,8 +50,10 @@ function Get-AdminRoleUserLicense {
$userDetails = Get-MgUser -UserId $user.PrincipalId -Property "DisplayName, UserPrincipalName, Id, onPremisesSyncEnabled" -ErrorAction SilentlyContinue
if ($userDetails) {
$userIds += $user.PrincipalId
$adminRoleUsers += [PSCustomObject]@{
[void]($userIds.Add($user.PrincipalId))
[void](
$adminRoleUsers.Add(
[PSCustomObject]@{
RoleName = $role.DisplayName
UserName = $userDetails.DisplayName
UserPrincipalName = $userDetails.UserPrincipalName
@@ -59,15 +61,17 @@ function Get-AdminRoleUserLicense {
HybridUser = $userDetails.onPremisesSyncEnabled
Licenses = $null # Initialize as $null
}
)
)
}
}
}
foreach ($userId in $userIds | Select-Object -Unique) {
foreach ($userId in $userIds.ToArray() | Select-Object -Unique) {
$licenses = Get-MgUserLicenseDetail -UserId $userId -ErrorAction SilentlyContinue
if ($licenses) {
$licenseList = ($licenses.SkuPartNumber -join '|')
$adminRoleUsers | Where-Object { $_.UserId -eq $userId } | ForEach-Object {
$adminRoleUsers.ToArray() | Where-Object { $_.UserId -eq $userId } | ForEach-Object {
$_.Licenses = $licenseList
}
}

View File

@@ -57,7 +57,7 @@
- For full license details, visit: https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en
- Register for CIS Benchmarks at: https://www.cisecurity.org/cis-benchmarks
.LINK
Online Version: https://github.com/CriticalSolutionsNetwork/M365FoundationsCISReport
https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Invoke-M365SecurityAudit
#>
function Invoke-M365SecurityAudit {
@@ -161,7 +161,8 @@ function Invoke-M365SecurityAudit {
# Load test definitions from CSV
$testDefinitionsPath = Join-Path -Path $PSScriptRoot -ChildPath "helper\TestDefinitions.csv"
$testDefinitions = Import-Csv -Path $testDefinitionsPath
# Load the Test Definitions into the script scope for use in other functions
$script:TestDefinitionsObject = $testDefinitions
# Apply filters based on parameter sets
switch ($PSCmdlet.ParameterSetName) {
'ELevelFilter' {
@@ -209,7 +210,7 @@ function Invoke-M365SecurityAudit {
} # End Begin
Process {
$allAuditResults = @() # Initialize a collection to hold all results
$allAuditResults = [System.Collections.ArrayList]::new() #@() # Initialize a collection to hold all results
# Dynamically dot-source the test scripts
$testsFolderPath = Join-Path -Path $PSScriptRoot -ChildPath "tests"
@@ -242,7 +243,7 @@ function Invoke-M365SecurityAudit {
Write-Host "Running $functionName..."
$result = & $functionName @paramList
# Assuming each function returns an array of CISAuditResult or a single CISAuditResult
$allAuditResults += $result
[void]($allAuditResults.add($Result))
}
}
}
@@ -253,7 +254,7 @@ function Invoke-M365SecurityAudit {
Disconnect-M365Suite
}
# Return all collected audit results
return $allAuditResults
return $allAuditResults.ToArray()
# Check if the Disconnect switch is present
}
}

View File

@@ -1,52 +1,52 @@
Index,TestFileName,Rec,ELevel,ProfileLevel,IG1,IG2,IG3,Automated
1,Test-AdministrativeAccountCompliance.ps1,1.1.1,E3,L1,TRUE,TRUE,TRUE,FALSE
2,Test-GlobalAdminsCount.ps1,1.1.3,E3,L1,TRUE,TRUE,TRUE,TRUE
3,Test-ManagedApprovedPublicGroups.ps1,1.2.1,E3,L2,TRUE,TRUE,TRUE,TRUE
4,Test-BlockSharedMailboxSignIn.ps1,1.2.2,E3,L1,FALSE,FALSE,FALSE,TRUE
5,Test-PasswordNeverExpirePolicy.ps1,1.3.1,E3,L1,TRUE,TRUE,TRUE,TRUE
6,Test-ExternalSharingCalendars.ps1,1.3.3,E3,L2,FALSE,TRUE,TRUE,TRUE
7,Test-CustomerLockbox.ps1,1.3.6,E5,L2,FALSE,FALSE,FALSE,TRUE
8,Test-SafeLinksOfficeApps.ps1,2.1.1,E5,L2,TRUE,TRUE,TRUE,TRUE
9,Test-CommonAttachmentFilter.ps1,2.1.2,E3,L1,FALSE,TRUE,TRUE,TRUE
10,Test-NotifyMalwareInternal.ps1,2.1.3,E3,L1,FALSE,TRUE,TRUE,TRUE
11,Test-SafeAttachmentsPolicy.ps1,2.1.4,E5,L2,FALSE,FALSE,TRUE,TRUE
12,Test-SafeAttachmentsTeams.ps1,2.1.5,E5,L2,TRUE,TRUE,TRUE,TRUE
13,Test-SpamPolicyAdminNotify.ps1,2.1.6,E3,L1,FALSE,TRUE,TRUE,TRUE
14,Test-AntiPhishingPolicy.ps1,2.1.7,E5,L1,FALSE,FALSE,TRUE,TRUE
15,Test-EnableDKIM.ps1,2.1.9,E3,L1,FALSE,TRUE,TRUE,TRUE
16,Test-AuditLogSearch.ps1,3.1.1,E3,L1,TRUE,TRUE,TRUE,TRUE
17,Test-RestrictTenantCreation.ps1,5.1.2.3,E3,L1,FALSE,FALSE,FALSE,TRUE
18,Test-PasswordHashSync.ps1,5.1.8.1,E3,L1,FALSE,TRUE,TRUE,TRUE
19,Test-AuditDisabledFalse.ps1,6.1.1,E3,L1,TRUE,TRUE,TRUE,TRUE
20,Test-MailboxAuditingE3.ps1,6.1.2,E3,L1,TRUE,TRUE,TRUE,TRUE
21,Test-MailboxAuditingE5.ps1,6.1.3,E5,L1,TRUE,TRUE,TRUE,TRUE
22,Test-BlockMailForwarding.ps1,6.2.1,E3,L1,FALSE,FALSE,FALSE,TRUE
23,Test-NoWhitelistDomains.ps1,6.2.2,E3,L1,FALSE,FALSE,FALSE,TRUE
24,Test-IdentifyExternalEmail.ps1,6.2.3,E3,L1,FALSE,FALSE,FALSE,TRUE
25,Test-RestrictOutlookAddins.ps1,6.3.1,E3,L2,FALSE,TRUE,TRUE,TRUE
26,Test-ModernAuthExchangeOnline.ps1,6.5.1,E3,L1,FALSE,TRUE,TRUE,TRUE
27,Test-MailTipsEnabled.ps1,6.5.2,E3,L2,FALSE,FALSE,FALSE,TRUE
28,Test-RestrictStorageProvidersOutlook.ps1,6.5.3,E3,L2,TRUE,TRUE,TRUE,TRUE
29,Test-ModernAuthSharePoint.ps1,7.2.1,E3,L1,FALSE,TRUE,TRUE,TRUE
30,Test-SharePointAADB2B.ps1,7.2.2,E3,L1,FALSE,FALSE,FALSE,TRUE
31,Test-RestrictExternalSharing.ps1,7.2.3,E3,L1,TRUE,TRUE,TRUE,TRUE
32,Test-OneDriveContentRestrictions.ps1,7.2.4,E3,L2,TRUE,TRUE,TRUE,TRUE
33,Test-SharePointGuestsItemSharing.ps1,7.2.5,E3,L2,TRUE,TRUE,TRUE,TRUE
34,Test-SharePointExternalSharingDomains.ps1,7.2.6,E3,L2,TRUE,TRUE,TRUE,TRUE
35,Test-LinkSharingRestrictions.ps1,7.2.7,E3,L1,TRUE,TRUE,TRUE,TRUE
36,Test-GuestAccessExpiration.ps1,7.2.9,E3,L1,FALSE,FALSE,FALSE,TRUE
37,Test-ReauthWithCode.ps1,7.2.10,E3,L1,FALSE,FALSE,FALSE,TRUE
38,Test-DisallowInfectedFilesDownload.ps1,7.3.1,E5,L2,TRUE,TRUE,TRUE,TRUE
39,Test-OneDriveSyncRestrictions.ps1,7.3.2,E3,L2,FALSE,FALSE,FALSE,TRUE
40,Test-RestrictCustomScripts.ps1,7.3.4,E3,L1,FALSE,FALSE,TRUE,TRUE
41,Test-TeamsExternalFileSharing.ps1,8.1.1,E3,L2,TRUE,TRUE,TRUE,TRUE
42,Test-BlockChannelEmails.ps1,8.1.2,E3,L1,FALSE,FALSE,FALSE,TRUE
43,Test-TeamsExternalAccess.ps1,8.2.1,E3,L2,FALSE,FALSE,FALSE,TRUE
44,Test-NoAnonymousMeetingJoin.ps1,8.5.1,E3,L2,FALSE,FALSE,FALSE,TRUE
45,Test-NoAnonymousMeetingStart.ps1,8.5.2,E3,L1,FALSE,FALSE,FALSE,TRUE
46,Test-OrgOnlyBypassLobby.ps1,8.5.3,E3,L1,FALSE,FALSE,TRUE,TRUE
47,Test-DialInBypassLobby.ps1,8.5.4,E3,L1,FALSE,FALSE,FALSE,TRUE
48,Test-MeetingChatNoAnonymous.ps1,8.5.5,E3,L1,FALSE,FALSE,FALSE,TRUE
49,Test-OrganizersPresent.ps1,8.5.6,E3,L1,FALSE,FALSE,FALSE,TRUE
50,Test-ExternalNoControl.ps1,8.5.7,E3,L1,FALSE,FALSE,FALSE,TRUE
51,Test-ReportSecurityInTeams.ps1,8.6.1,E3,L1,FALSE,FALSE,FALSE,TRUE
Index,TestFileName,Rec,RecDescription,ELevel,ProfileLevel,CISControl,CISDescription,IG1,IG2,IG3,Automated,Connection
1,Test-AdministrativeAccountCompliance.ps1,1.1.1,Ensure Administrative accounts are separate and cloud-only,E3,L1,5.4,Restrict Administrator Privileges to Dedicated Administrator Accounts,TRUE,TRUE,TRUE,FALSE,AzureAD
2,Test-GlobalAdminsCount.ps1,1.1.3,Ensure that between two and four global admins are designated,E3,L1,5.1,Establish and Maintain an Inventory of Accounts,TRUE,TRUE,TRUE,TRUE,Microsoft Graph
3,Test-ManagedApprovedPublicGroups.ps1,1.2.1,Ensure that only organizationally managed/approved public groups exist,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,Microsoft Graph
4,Test-BlockSharedMailboxSignIn.ps1,1.2.2,Ensure sign-in to shared mailboxes is blocked,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,AzureAD | EXO
5,Test-PasswordNeverExpirePolicy.ps1,1.3.1,Ensure the 'Password expiration policy' is set to 'Set passwords to never expire',E3,L1,5.2,Use Unique Passwords,TRUE,TRUE,TRUE,TRUE,Microsoft Graph
6,Test-ExternalSharingCalendars.ps1,1.3.3,Ensure 'External sharing' of calendars is not available,E3,L2,4.8,Uninstall or Disable Unnecessary Services on Enterprise Assets and Software,FALSE,TRUE,TRUE,TRUE,EXO
7,Test-CustomerLockbox.ps1,1.3.6,Ensure the customer lockbox feature is enabled,E5,L2,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,EXO
8,Test-SafeLinksOfficeApps.ps1,2.1.1,Ensure Safe Links for Office Applications is Enabled,E5,L2,10.1,Deploy and Maintain Anti-Malware Software,TRUE,TRUE,TRUE,TRUE,EXO
9,Test-CommonAttachmentFilter.ps1,2.1.2,Ensure the Common Attachment Types Filter is enabled,E3,L1,9.6,Block Unnecessary File Types,FALSE,TRUE,TRUE,TRUE,EXO
10,Test-NotifyMalwareInternal.ps1,2.1.3,Ensure notifications for internal users sending malware is Enabled,E3,L1,17.5,Assign Key Roles and Responsibilities,FALSE,TRUE,TRUE,TRUE,EXO
11,Test-SafeAttachmentsPolicy.ps1,2.1.4,Ensure Safe Attachments policy is enabled,E5,L2,9.7,Deploy and Maintain Email Server Anti-Malware Protections,FALSE,FALSE,TRUE,TRUE,EXO
12,Test-SafeAttachmentsTeams.ps1,2.1.5,"Ensure Safe Attachments for SharePoint, OneDrive, and Microsoft Teams is Enabled",E5,L2,"9.7, 10.1","Deploy and Maintain Email Server Anti-Malware Protections, Deploy and Maintain Anti-Malware Software",TRUE,TRUE,TRUE,TRUE,EXO
13,Test-SpamPolicyAdminNotify.ps1,2.1.6,Ensure Exchange Online Spam Policies are set to notify administrators,E3,L1,17.5,Assign Key Roles and Responsibilities,FALSE,TRUE,TRUE,TRUE,EXO
14,Test-AntiPhishingPolicy.ps1,2.1.7,Ensure that an anti-phishing policy has been created,E5,L1,9.7,Deploy and Maintain Email Server Anti-Malware Protections,FALSE,FALSE,TRUE,TRUE,EXO
15,Test-EnableDKIM.ps1,2.1.9,Ensure that DKIM is enabled for all Exchange Online Domains,E3,L1,9.5,Implement DMARC,FALSE,TRUE,TRUE,TRUE,EXO
16,Test-AuditLogSearch.ps1,3.1.1,Ensure Microsoft 365 audit log search is Enabled,E3,L1,8.2,Collect Audit Logs,TRUE,TRUE,TRUE,TRUE,EXO
17,Test-RestrictTenantCreation.ps1,5.1.2.3,Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes',E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,Microsoft Graph
18,Test-PasswordHashSync.ps1,5.1.8.1,Ensure password hash sync is enabled for hybrid deployments,E3,L1,6.7,Centralize Access Control,FALSE,TRUE,TRUE,TRUE,Microsoft Graph
19,Test-AuditDisabledFalse.ps1,6.1.1,Ensure 'AuditDisabled' organizationally is set to 'False',E3,L1,8.2,Collect Audit Logs,TRUE,TRUE,TRUE,TRUE,Microsoft Graph
20,Test-MailboxAuditingE3.ps1,6.1.2,Ensure mailbox auditing for Office E3 users is Enabled,E3,L1,8.2,Collect audit logs.,TRUE,TRUE,TRUE,TRUE,EXO
21,Test-MailboxAuditingE5.ps1,6.1.3,Ensure mailbox auditing for Office E5 users is Enabled,E5,L1,8.2,Collect audit logs.,TRUE,TRUE,TRUE,TRUE,EXO
22,Test-BlockMailForwarding.ps1,6.2.1,Ensure all forms of mail forwarding are blocked and/or disabled,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,EXO
23,Test-NoWhitelistDomains.ps1,6.2.2,Ensure mail transport rules do not whitelist specific domains,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,EXO
24,Test-IdentifyExternalEmail.ps1,6.2.3,Ensure email from external senders is identified,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,EXO
25,Test-RestrictOutlookAddins.ps1,6.3.1,Ensure users installing Outlook add-ins is not allowed,E3,L2,9.4,Restrict Unnecessary or Unauthorized Browser and Email Client Extensions,FALSE,TRUE,TRUE,TRUE,EXO
26,Test-ModernAuthExchangeOnline.ps1,6.5.1,Ensure modern authentication for Exchange Online is enabled (Automated),E3,L1,3.1,Encrypt Sensitive Data in Transit,FALSE,TRUE,TRUE,TRUE,EXO
27,Test-MailTipsEnabled.ps1,6.5.2,Ensure MailTips are enabled for end users,E3,L2,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,EXO
28,Test-RestrictStorageProvidersOutlook.ps1,6.5.3,Ensure additional storage providers are restricted in Outlook on the web,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,EXO
29,Test-ModernAuthSharePoint.ps1,7.2.1,Modern Authentication for SharePoint Applications,E3,L1,3.1,Encrypt Sensitive Data in Transit,FALSE,TRUE,TRUE,TRUE,SPO
30,Test-SharePointAADB2B.ps1,7.2.2,Ensure reauthentication with verification code is restricted,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,SPO
31,Test-RestrictExternalSharing.ps1,7.2.3,Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled,E3,L1,0,Explicitly Not Mapped,TRUE,TRUE,TRUE,TRUE,SPO
32,Test-OneDriveContentRestrictions.ps1,7.2.4,Ensure external content sharing is restricted,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,SPO
33,Test-SharePointGuestsItemSharing.ps1,7.2.5,Ensure OneDrive content sharing is restricted,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,SPO
34,Test-SharePointExternalSharingDomains.ps1,7.2.6,Ensure that SharePoint guest users cannot share items they don't own,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,SPO
35,Test-LinkSharingRestrictions.ps1,7.2.7,Ensure SharePoint external sharing is managed through domain whitelist/blacklists,E3,L1,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,SPO
36,Test-GuestAccessExpiration.ps1,7.2.9,Ensure link sharing is restricted in SharePoint and OneDrive,E3,L1,3.3,Configure Data Access Control Lists,FALSE,FALSE,FALSE,TRUE,SPO
37,Test-ReauthWithCode.ps1,7.2.10,Ensure guest access to a site or OneDrive will expire automatically,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,SPO
38,Test-DisallowInfectedFilesDownload.ps1,7.3.1,Ensure Office 365 SharePoint infected files are disallowed for download,E5,L2,10.1,Deploy and Maintain Anti-Malware Software,TRUE,TRUE,TRUE,TRUE,SPO
39,Test-OneDriveSyncRestrictions.ps1,7.3.2,Ensure OneDrive sync is restricted for unmanaged devices,E3,L2,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,SPO
40,Test-RestrictCustomScripts.ps1,7.3.4,Ensure custom script execution is restricted on site collections,E3,L1,2.7,Allowlist Authorized Scripts,FALSE,FALSE,TRUE,TRUE,SPO
41,Test-TeamsExternalFileSharing.ps1,8.1.1,Ensure external file sharing in Teams is enabled for only approved cloud storage services,E3,L2,3.3,Configure Data Access Control Lists,TRUE,TRUE,TRUE,TRUE,Microsoft Teams
42,Test-BlockChannelEmails.ps1,8.1.2,Ensure users can't send emails to a channel email address,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,Microsoft Teams
43,Test-TeamsExternalAccess.ps1,8.2.1,Ensure 'external access' is restricted in the Teams admin center,E3,L2,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,Microsoft Teams
44,Test-NoAnonymousMeetingJoin.ps1,8.5.1,Ensure anonymous users can't join a meeting,E3,L2,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,Microsoft Teams
45,Test-NoAnonymousMeetingStart.ps1,8.5.2,Ensure anonymous users and dial-in callers can't start a meeting,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,Microsoft Teams
46,Test-OrgOnlyBypassLobby.ps1,8.5.3,Ensure only people in my org can bypass the lobby,E3,L1,6.8,Define and Maintain Role-Based Access Control,FALSE,FALSE,TRUE,TRUE,Microsoft Teams
47,Test-DialInBypassLobby.ps1,8.5.4,Ensure users dialing in can't bypass the lobby,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,Microsoft Teams
48,Test-MeetingChatNoAnonymous.ps1,8.5.5,Ensure meeting chat does not allow anonymous users,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,Microsoft Teams
49,Test-OrganizersPresent.ps1,8.5.6,Ensure only organizers and co-organizers can present,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,Microsoft Teams
50,Test-ExternalNoControl.ps1,8.5.7,Ensure external participants can't give or request control,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,Microsoft Teams
51,Test-ReportSecurityInTeams.ps1,8.6.1,Ensure users can report security concerns in Teams,E3,L1,0,Explicitly Not Mapped,FALSE,FALSE,FALSE,TRUE,Microsoft Teams | EXO
1 Index TestFileName Rec RecDescription ELevel ProfileLevel CISControl CISDescription IG1 IG2 IG3 Automated Connection
2 1 Test-AdministrativeAccountCompliance.ps1 1.1.1 Ensure Administrative accounts are separate and cloud-only E3 L1 5.4 Restrict Administrator Privileges to Dedicated Administrator Accounts TRUE TRUE TRUE FALSE AzureAD
3 2 Test-GlobalAdminsCount.ps1 1.1.3 Ensure that between two and four global admins are designated E3 L1 5.1 Establish and Maintain an Inventory of Accounts TRUE TRUE TRUE TRUE Microsoft Graph
4 3 Test-ManagedApprovedPublicGroups.ps1 1.2.1 Ensure that only organizationally managed/approved public groups exist E3 L2 3.3 Configure Data Access Control Lists TRUE TRUE TRUE TRUE Microsoft Graph
5 4 Test-BlockSharedMailboxSignIn.ps1 1.2.2 Ensure sign-in to shared mailboxes is blocked E3 L1 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE AzureAD | EXO
6 5 Test-PasswordNeverExpirePolicy.ps1 1.3.1 Ensure the 'Password expiration policy' is set to 'Set passwords to never expire' E3 L1 5.2 Use Unique Passwords TRUE TRUE TRUE TRUE Microsoft Graph
7 6 Test-ExternalSharingCalendars.ps1 1.3.3 Ensure 'External sharing' of calendars is not available E3 L2 4.8 Uninstall or Disable Unnecessary Services on Enterprise Assets and Software FALSE TRUE TRUE TRUE EXO
8 7 Test-CustomerLockbox.ps1 1.3.6 Ensure the customer lockbox feature is enabled E5 L2 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE EXO
9 8 Test-SafeLinksOfficeApps.ps1 2.1.1 Ensure Safe Links for Office Applications is Enabled E5 L2 10.1 Deploy and Maintain Anti-Malware Software TRUE TRUE TRUE TRUE EXO
10 9 Test-CommonAttachmentFilter.ps1 2.1.2 Ensure the Common Attachment Types Filter is enabled E3 L1 9.6 Block Unnecessary File Types FALSE TRUE TRUE TRUE EXO
11 10 Test-NotifyMalwareInternal.ps1 2.1.3 Ensure notifications for internal users sending malware is Enabled E3 L1 17.5 Assign Key Roles and Responsibilities FALSE TRUE TRUE TRUE EXO
12 11 Test-SafeAttachmentsPolicy.ps1 2.1.4 Ensure Safe Attachments policy is enabled E5 L2 9.7 Deploy and Maintain Email Server Anti-Malware Protections FALSE FALSE TRUE TRUE EXO
13 12 Test-SafeAttachmentsTeams.ps1 2.1.5 Ensure Safe Attachments for SharePoint, OneDrive, and Microsoft Teams is Enabled E5 L2 9.7, 10.1 Deploy and Maintain Email Server Anti-Malware Protections, Deploy and Maintain Anti-Malware Software TRUE TRUE TRUE TRUE EXO
14 13 Test-SpamPolicyAdminNotify.ps1 2.1.6 Ensure Exchange Online Spam Policies are set to notify administrators E3 L1 17.5 Assign Key Roles and Responsibilities FALSE TRUE TRUE TRUE EXO
15 14 Test-AntiPhishingPolicy.ps1 2.1.7 Ensure that an anti-phishing policy has been created E5 L1 9.7 Deploy and Maintain Email Server Anti-Malware Protections FALSE FALSE TRUE TRUE EXO
16 15 Test-EnableDKIM.ps1 2.1.9 Ensure that DKIM is enabled for all Exchange Online Domains E3 L1 9.5 Implement DMARC FALSE TRUE TRUE TRUE EXO
17 16 Test-AuditLogSearch.ps1 3.1.1 Ensure Microsoft 365 audit log search is Enabled E3 L1 8.2 Collect Audit Logs TRUE TRUE TRUE TRUE EXO
18 17 Test-RestrictTenantCreation.ps1 5.1.2.3 Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes' E3 L1 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE Microsoft Graph
19 18 Test-PasswordHashSync.ps1 5.1.8.1 Ensure password hash sync is enabled for hybrid deployments E3 L1 6.7 Centralize Access Control FALSE TRUE TRUE TRUE Microsoft Graph
20 19 Test-AuditDisabledFalse.ps1 6.1.1 Ensure 'AuditDisabled' organizationally is set to 'False' E3 L1 8.2 Collect Audit Logs TRUE TRUE TRUE TRUE Microsoft Graph
21 20 Test-MailboxAuditingE3.ps1 6.1.2 Ensure mailbox auditing for Office E3 users is Enabled E3 L1 8.2 Collect audit logs. TRUE TRUE TRUE TRUE EXO
22 21 Test-MailboxAuditingE5.ps1 6.1.3 Ensure mailbox auditing for Office E5 users is Enabled E5 L1 8.2 Collect audit logs. TRUE TRUE TRUE TRUE EXO
23 22 Test-BlockMailForwarding.ps1 6.2.1 Ensure all forms of mail forwarding are blocked and/or disabled E3 L1 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE EXO
24 23 Test-NoWhitelistDomains.ps1 6.2.2 Ensure mail transport rules do not whitelist specific domains E3 L1 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE EXO
25 24 Test-IdentifyExternalEmail.ps1 6.2.3 Ensure email from external senders is identified E3 L1 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE EXO
26 25 Test-RestrictOutlookAddins.ps1 6.3.1 Ensure users installing Outlook add-ins is not allowed E3 L2 9.4 Restrict Unnecessary or Unauthorized Browser and Email Client Extensions FALSE TRUE TRUE TRUE EXO
27 26 Test-ModernAuthExchangeOnline.ps1 6.5.1 Ensure modern authentication for Exchange Online is enabled (Automated) E3 L1 3.1 Encrypt Sensitive Data in Transit FALSE TRUE TRUE TRUE EXO
28 27 Test-MailTipsEnabled.ps1 6.5.2 Ensure MailTips are enabled for end users E3 L2 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE EXO
29 28 Test-RestrictStorageProvidersOutlook.ps1 6.5.3 Ensure additional storage providers are restricted in Outlook on the web E3 L2 3.3 Configure Data Access Control Lists TRUE TRUE TRUE TRUE EXO
30 29 Test-ModernAuthSharePoint.ps1 7.2.1 Modern Authentication for SharePoint Applications E3 L1 3.1 Encrypt Sensitive Data in Transit FALSE TRUE TRUE TRUE SPO
31 30 Test-SharePointAADB2B.ps1 7.2.2 Ensure reauthentication with verification code is restricted E3 L1 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE SPO
32 31 Test-RestrictExternalSharing.ps1 7.2.3 Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled E3 L1 0 Explicitly Not Mapped TRUE TRUE TRUE TRUE SPO
33 32 Test-OneDriveContentRestrictions.ps1 7.2.4 Ensure external content sharing is restricted E3 L2 3.3 Configure Data Access Control Lists TRUE TRUE TRUE TRUE SPO
34 33 Test-SharePointGuestsItemSharing.ps1 7.2.5 Ensure OneDrive content sharing is restricted E3 L2 3.3 Configure Data Access Control Lists TRUE TRUE TRUE TRUE SPO
35 34 Test-SharePointExternalSharingDomains.ps1 7.2.6 Ensure that SharePoint guest users cannot share items they don't own E3 L2 3.3 Configure Data Access Control Lists TRUE TRUE TRUE TRUE SPO
36 35 Test-LinkSharingRestrictions.ps1 7.2.7 Ensure SharePoint external sharing is managed through domain whitelist/blacklists E3 L1 3.3 Configure Data Access Control Lists TRUE TRUE TRUE TRUE SPO
37 36 Test-GuestAccessExpiration.ps1 7.2.9 Ensure link sharing is restricted in SharePoint and OneDrive E3 L1 3.3 Configure Data Access Control Lists FALSE FALSE FALSE TRUE SPO
38 37 Test-ReauthWithCode.ps1 7.2.10 Ensure guest access to a site or OneDrive will expire automatically E3 L1 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE SPO
39 38 Test-DisallowInfectedFilesDownload.ps1 7.3.1 Ensure Office 365 SharePoint infected files are disallowed for download E5 L2 10.1 Deploy and Maintain Anti-Malware Software TRUE TRUE TRUE TRUE SPO
40 39 Test-OneDriveSyncRestrictions.ps1 7.3.2 Ensure OneDrive sync is restricted for unmanaged devices E3 L2 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE SPO
41 40 Test-RestrictCustomScripts.ps1 7.3.4 Ensure custom script execution is restricted on site collections E3 L1 2.7 Allowlist Authorized Scripts FALSE FALSE TRUE TRUE SPO
42 41 Test-TeamsExternalFileSharing.ps1 8.1.1 Ensure external file sharing in Teams is enabled for only approved cloud storage services E3 L2 3.3 Configure Data Access Control Lists TRUE TRUE TRUE TRUE Microsoft Teams
43 42 Test-BlockChannelEmails.ps1 8.1.2 Ensure users can't send emails to a channel email address E3 L1 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE Microsoft Teams
44 43 Test-TeamsExternalAccess.ps1 8.2.1 Ensure 'external access' is restricted in the Teams admin center E3 L2 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE Microsoft Teams
45 44 Test-NoAnonymousMeetingJoin.ps1 8.5.1 Ensure anonymous users can't join a meeting E3 L2 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE Microsoft Teams
46 45 Test-NoAnonymousMeetingStart.ps1 8.5.2 Ensure anonymous users and dial-in callers can't start a meeting E3 L1 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE Microsoft Teams
47 46 Test-OrgOnlyBypassLobby.ps1 8.5.3 Ensure only people in my org can bypass the lobby E3 L1 6.8 Define and Maintain Role-Based Access Control FALSE FALSE TRUE TRUE Microsoft Teams
48 47 Test-DialInBypassLobby.ps1 8.5.4 Ensure users dialing in can't bypass the lobby E3 L1 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE Microsoft Teams
49 48 Test-MeetingChatNoAnonymous.ps1 8.5.5 Ensure meeting chat does not allow anonymous users E3 L1 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE Microsoft Teams
50 49 Test-OrganizersPresent.ps1 8.5.6 Ensure only organizers and co-organizers can present E3 L1 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE Microsoft Teams
51 50 Test-ExternalNoControl.ps1 8.5.7 Ensure external participants can't give or request control E3 L1 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE Microsoft Teams
52 51 Test-ReportSecurityInTeams.ps1 8.6.1 Ensure users can report security concerns in Teams E3 L1 0 Explicitly Not Mapped FALSE FALSE FALSE TRUE Microsoft Teams | EXO

View File

@@ -1,12 +1,15 @@
function Test-AdministrativeAccountCompliance {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added if needed
)
begin {
#. C:\Temp\CISAuditResult.ps1
#. .\source\Classes\CISAuditResult.ps1
$validLicenses = @('AAD_PREMIUM', 'AAD_PREMIUM_P2')
}
process {
$adminRoles = Get-MgRoleManagementDirectoryRoleDefinition | Where-Object { $_.DisplayName -like "*Admin*" }
$adminRoleUsers = @()
@@ -50,22 +53,27 @@ function Test-AdministrativeAccountCompliance {
"$($_.UserName)|$($_.Roles)|$accountType|Missing: $($missingLicenses -join ',')"
}
$failureReasons = $failureReasons -join "`n"
$details = if ($nonCompliantUsers) {
"Non-Compliant Accounts: $($nonCompliantUsers.Count)`nDetails:`n" + ($nonCompliantUsers | ForEach-Object { $_.UserName }) -join "`n"
}
else {
"Compliant Accounts: $($uniqueAdminRoleUsers.Count)"
}
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($nonCompliantUsers) { 'Fail' } else { 'Pass' }
$auditResult.ELevel = 'E3'
$auditResult.ProfileLevel = 'L1'
$auditResult.Rec = '1.1.1'
$auditResult.RecDescription = "Ensure Administrative accounts are separate and cloud-only"
$auditResult.CISControlVer = 'v8'
$auditResult.CISControl = "5.4"
$auditResult.CISDescription = "Restrict Administrator Privileges to Dedicated Administrator Accounts"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.Result = $nonCompliantUsers.Count -eq 0
$auditResult.Details = "Compliant Accounts: $($uniqueAdminRoleUsers.Count - $nonCompliantUsers.Count); Non-Compliant Accounts: $($nonCompliantUsers.Count)"
$auditResult.FailureReason = if ($nonCompliantUsers) { "Non-compliant accounts: `nUsername | Roles | HybridStatus | Missing Licence`n$failureReasons" } else { "N/A" }
$result = $nonCompliantUsers.Count -eq 0
$status = if ($result) { 'Pass' } else { 'Fail' }
$failureReason = if ($nonCompliantUsers) { "Non-compliant accounts: `nUsername | Roles | HybridStatus | Missing Licence`n$failureReasons" } else { "N/A" }
# Create the parameter splat
$params = @{
Rec = "1.1.1"
Result = $result
Status = $status
Details = $details
FailureReason = $failureReason
}
$auditResult = Initialize-CISAuditResult @params
}
end {

View File

@@ -1,13 +1,15 @@
function Test-AntiPhishingPolicy {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
#$auditResults = @()
}
process {
@@ -24,37 +26,54 @@ function Test-AntiPhishingPolicy {
}
# Check if there is at least one policy that meets the requirements
$isCompliant = $validatedPolicies.Count -gt 0
$nonCompliantItems = $antiPhishPolicies | Where-Object {
$_.Enabled -ne $true -or
$_.PhishThresholdLevel -lt 2 -or
$_.EnableMailboxIntelligenceProtection -ne $true -or
$_.EnableMailboxIntelligence -ne $true -or
$_.EnableSpoofIntelligence -ne $true
}
$compliantItems = $validatedPolicies
$isCompliant = $compliantItems.Count -gt 0
# Prepare 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 ', ')
# Prepare failure reasons for non-compliant items
$nonCompliantNames = $nonCompliantItems | ForEach-Object { $_.Name }
$failureReasons = if ($nonCompliantNames.Count -gt 0) {
"Reason: Does not meet one or more compliance criteria.`nNon-compliant Policies:`n" + ($nonCompliantNames -join "`n")
}
else {
"N/A"
}
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($isCompliant) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E5"
$auditResult.ProfileLevel = "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" }
# Prepare details for non-compliant items
$nonCompliantDetails = $nonCompliantItems | ForEach-Object {
"Policy: $($_.Name)"
}
$nonCompliantDetails = $nonCompliantDetails -join "`n"
$auditResults += $auditResult
# Prepare details based on compliance
$details = if ($nonCompliantItems) {
"Non-Compliant Items: $($nonCompliantItems.Count)`nDetails:`n$nonCompliantDetails"
}
else {
"Compliant Items: $($compliantItems.Count)"
}
# Parameter splat for Initialize-CISAuditResult function
$params = @{
Rec = "2.1.7"
Result = $nonCompliantItems.Count -eq 0
Status = if ($isCompliant) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
# Create and populate the CISAuditResult object
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return auditResult
return $auditResult
}
}

View File

@@ -1,43 +1,51 @@
function Test-AuditDisabledFalse {
[CmdletBinding()]
# Aligned
param (
# Parameters can be added if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# 6.1.1 (L1) Ensure 'AuditDisabled' organizationally is set to 'False'
# Pass if AuditDisabled is False. Fail otherwise.
# Retrieve the AuditDisabled configuration
$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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $auditNotDisabled) {
"AuditDisabled is set to True"
}
else {
"N/A"
}
$auditResults += $auditResult
$details = if ($auditNotDisabled) {
"Audit is not disabled organizationally"
}
else {
"Audit is disabled organizationally"
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "6.1.1"
Result = $auditNotDisabled
Status = if ($auditNotDisabled) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,43 +1,52 @@
function Test-AuditLogSearch {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# 3.1.1 (L1) Ensure Microsoft 365 audit log search is Enabled
# Pass if UnifiedAuditLogIngestionEnabled is True. Fail otherwise.
# Retrieve the audit log configuration
$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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $auditLogResult) {
"Audit log search is not enabled"
}
else {
"N/A"
}
$details = if ($auditLogResult) {
"UnifiedAuditLogIngestionEnabled: True"
}
else {
"UnifiedAuditLogIngestionEnabled: False"
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "3.1.1"
Result = $auditLogResult
Status = if ($auditLogResult) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
$auditResults += $auditResult
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,44 +1,51 @@
function Test-BlockChannelEmails {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added here if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# 8.1.2 (L1) Ensure users can't send emails to a channel email address
# Connect to Teams PowerShell using Connect-MicrosoftTeams
# Retrieve Teams client configuration
$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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if ($allowEmailIntoChannel) {
"Emails can be sent to a channel email address"
}
else {
"N/A"
}
$auditResults += $auditResult
$details = if ($allowEmailIntoChannel) {
"AllowEmailIntoChannel is set to True"
}
else {
"AllowEmailIntoChannel is set to False"
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "8.1.2"
Result = -not $allowEmailIntoChannel
Status = if (-not $allowEmailIntoChannel) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,51 +1,52 @@
function Test-BlockMailForwarding {
[CmdletBinding()]
param (
# Aligned Compare
# Parameters can be added if needed
)
begin {
$auditResult = [CISAuditResult]::new()
$auditResult.Rec = "6.2.1"
$auditResult.ELevel = "E3"
$auditResult.ProfileLevel = "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"
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# Verify that no rules are forwarding the email to external domains
$transportRules = Get-TransportRule | Where-Object { $_.RedirectMessageTo -ne $null }
# 6.2.1 (L1) Ensure all forms of mail forwarding are blocked and/or disabled
# Retrieve the transport rules that redirect messages
$transportRules = Get-TransportRule | Where-Object { $null -ne $_.RedirectMessageTo }
$forwardingBlocked = $transportRules.Count -eq 0
$auditResult.Result = $forwardingBlocked
$auditResult.Details = if ($transportRules.Count -gt 0) {
# Prepare failure reasons and details based on compliance
$failureReasons = if ($transportRules.Count -gt 0) {
"Mail forwarding rules found: $($transportRules.Name -join ', ')"
}
else {
"N/A"
}
$details = if ($transportRules.Count -gt 0) {
$transportRules | ForEach-Object {
"$($_.Name) redirects to $($_.RedirectMessageTo)"
} -join " | "
} else {
}
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"
$params = @{
Rec = "6.2.1"
Result = $forwardingBlocked
Status = if ($forwardingBlocked) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult.Status = if ($forwardingBlocked) { "Pass" } else { "Fail" }
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return the result object
# Return the audit result
return $auditResult
}
}

View File

@@ -1,48 +1,53 @@
function Test-BlockSharedMailboxSignIn {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
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.
# Review: Details property - Add verbosity.
# Retrieve shared mailbox details
$MBX = Get-EXOMailbox -RecipientTypeDetails SharedMailbox
$sharedMailboxDetails = $MBX | ForEach-Object { Get-AzureADUser -ObjectId $_.ExternalDirectoryObjectId }
$enabledMailboxes = $sharedMailboxDetails | Where-Object { $_.AccountEnabled } | ForEach-Object { $_.DisplayName }
$allBlocked = $enabledMailboxes.Count -eq 0
# 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 = "Explicitly Not Mapped"
$auditResult.Rec = "1.2.2"
$auditResult.ELevel = "E3"
$auditResult.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $allBlocked) {
"Some mailboxes have sign-in enabled: $($enabledMailboxes -join ', ')"
}
else {
"N/A"
}
$auditResults += $auditResult
$details = if ($allBlocked) {
"All shared mailboxes have sign-in blocked."
}
else {
"Enabled Mailboxes: $($enabledMailboxes -join ', ')"
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "1.2.2"
Result = $allBlocked
Status = if ($allBlocked) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,46 +1,51 @@
function Test-CommonAttachmentFilter {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added if needed
)
begin {
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# 2.1.2 (L1) Ensure the Common Attachment Types Filter is enabled
# Pass if EnableFileFilter is set to True. Fail otherwise.
# Retrieve the attachment filter policy
$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.ProfileLevel = "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
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $result) {
"Common Attachment Types Filter is disabled"
}
else {
"N/A"
}
$auditResults += $auditResult
$details = if ($result) {
"File Filter Enabled: True"
}
else {
"File Filter Enabled: False"
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "2.1.2"
Result = $result
Status = if ($result) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,40 +1,51 @@
function Test-CustomerLockbox {
[CmdletBinding()]
param (
# Define your parameters here
# Aligned
# Define your parameters here if needed
)
begin {
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# 1.3.6 (L2) Ensure the customer lockbox feature is enabled
# Retrieve the organization configuration
$orgConfig = Get-OrganizationConfig | Select-Object CustomerLockBoxEnabled
$customerLockboxEnabled = $orgConfig.CustomerLockBoxEnabled
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($customerLockboxEnabled) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E5"
$auditResult.ProfileLevel = "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 = "Explicitly Not Mapped"
$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." }
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $customerLockboxEnabled) {
"Customer lockbox feature is not enabled."
}
else {
"N/A"
}
$auditResults += $auditResult
$details = if ($customerLockboxEnabled) {
"Customer Lockbox Enabled: True"
}
else {
"Customer Lockbox Enabled: False"
}
# Create and populate the CISAuditResult object #
$params = @{
Rec = "1.3.6"
Result = $customerLockboxEnabled
Status = if ($customerLockboxEnabled) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,45 +1,51 @@
function Test-DialInBypassLobby {
[CmdletBinding()]
param (
# Aligned
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# 8.5.4 (L1) Ensure users dialing in can't bypass the lobby
# Connect to Teams PowerShell using Connect-MicrosoftTeams
# Retrieve Teams meeting policy for PSTN users
$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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $PSTNBypassDisabled) {
"Users dialing in can bypass the lobby"
}
else {
"N/A"
}
$auditResults += $auditResult
$details = if ($PSTNBypassDisabled) {
"AllowPSTNUsersToBypassLobby is set to False"
}
else {
"AllowPSTNUsersToBypassLobby is set to True"
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "8.5.4"
Result = $PSTNBypassDisabled
Status = if ($PSTNBypassDisabled) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,41 +1,53 @@
function Test-DisallowInfectedFilesDownload {
[CmdletBinding()]
param (
# Define your parameters here
# Aligned
# Define your parameters here if needed
)
begin {
# Initialization code
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
$auditResult = [CISAuditResult]::new()
# Initialization code, if needed
}
process {
# 7.3.1 (L2) Ensure Office 365 SharePoint infected files are disallowed for download
# Retrieve the SharePoint tenant configuration
$SPOTenantDisallowInfectedFileDownload = Get-SPOTenant | Select-Object DisallowInfectedFileDownload
$isDisallowInfectedFileDownloadEnabled = $SPOTenantDisallowInfectedFileDownload.DisallowInfectedFileDownload
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "10.1"
$auditResult.CISDescription = "Deploy and Maintain Anti-Malware Software"
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $isDisallowInfectedFileDownloadEnabled) {
"Downloading infected files is not disallowed."
}
else {
"N/A"
}
$auditResult.Rec = "7.3.1"
$auditResult.ELevel = "E5"
$auditResult.ProfileLevel = "L2"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.RecDescription = "Ensure Office 365 SharePoint infected files are disallowed for download"
$details = if ($isDisallowInfectedFileDownloadEnabled) {
"DisallowInfectedFileDownload: True"
}
else {
"DisallowInfectedFileDownload: False"
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "7.3.1"
Result = $isDisallowInfectedFileDownloadEnabled
Status = if ($isDisallowInfectedFileDownloadEnabled) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
$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 the audit result
return $auditResult
}
}

View File

@@ -1,44 +1,52 @@
function Test-EnableDKIM {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
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.
# Retrieve DKIM configuration for all domains
$dkimConfig = Get-DkimSigningConfig | Select-Object Domain, Enabled
$dkimResult = ($dkimConfig | ForEach-Object { $_.Enabled }) -notcontains $false
$dkimFailedDomains = $dkimConfig | Where-Object { -not $_.Enabled } | ForEach-Object { $_.Domain }
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($dkimResult) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E3"
$auditResult.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $dkimResult) {
"DKIM is not enabled for some domains"
}
else {
"N/A"
}
$auditResults += $auditResult
$details = if ($dkimResult) {
"All domains have DKIM enabled"
}
else {
"DKIM not enabled for: $($dkimFailedDomains -join ', ')"
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "2.1.9"
Result = $dkimResult
Status = if ($dkimResult) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,45 +1,52 @@
function Test-ExternalNoControl {
[CmdletBinding()]
param (
# Aligned
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
$auditResults = @()
# Initialization code, if needed
}
process {
# 8.5.7 (L1) Ensure external participants can't give or request control
# Connect to Teams PowerShell using Connect-MicrosoftTeams
# Retrieve Teams meeting policy for external participant control
$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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $externalControlRestricted) {
"External participants can give or request control"
}
else {
"N/A"
}
$auditResults += $auditResult
$details = if ($externalControlRestricted) {
"AllowExternalParticipantGiveRequestControl is set to False"
}
else {
"AllowExternalParticipantGiveRequestControl is set to True"
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "8.5.7"
Result = $externalControlRestricted
Status = if ($externalControlRestricted) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,17 +1,21 @@
function Test-ExternalSharingCalendars {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added if needed
)
begin {
# Dot source the class script
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
$auditResults = @()
# Initialization code, if needed
}
process {
# 1.3.3 (L2) Ensure 'External sharing' of calendars is not available (Automated)
# Retrieve sharing policies related to calendar sharing
$sharingPolicies = Get-SharingPolicy | Where-Object { $_.Domains -like '*CalendarSharing*' }
# Check if calendar sharing is disabled in all applicable policies
@@ -24,30 +28,34 @@ function Test-ExternalSharingCalendars {
}
}
# 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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $isExternalSharingDisabled) {
"Calendar sharing with external users is enabled in one or more policies."
}
else {
"N/A"
}
$auditResults += $auditResult
$details = if ($isExternalSharingDisabled) {
"Calendar sharing with external users is disabled."
}
else {
"Enabled Sharing Policies: $($sharingPolicyDetails -join ', ')"
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "1.3.3"
Result = $isExternalSharingDisabled
Status = if ($isExternalSharingDisabled) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,46 +1,52 @@
function Test-GlobalAdminsCount {
[CmdletBinding()]
param (
# Define your parameters here
# Aligned
# Define your parameters here if needed
)
begin {
# Dot source the class script
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
$auditResults = @()
# Initialization code, if needed
}
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.
# Retrieve global admin role and members
$globalAdminRole = Get-MgDirectoryRole -Filter "RoleTemplateId eq '62e90394-69f5-4237-9190-012177145e10'"
$globalAdmins = Get-MgDirectoryRoleMember -DirectoryRoleId $globalAdminRole.Id
$globalAdminCount = $globalAdmins.AdditionalProperties.Count
$globalAdminUsernames = ($globalAdmins | ForEach-Object { $_.AdditionalProperties["displayName"] }) -join ', '
# 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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if ($globalAdminCount -lt 2) {
"Less than 2 global admins: $globalAdminUsernames"
}
elseif ($globalAdminCount -gt 4) {
"More than 4 global admins: $globalAdminUsernames"
}
else {
"N/A"
}
$auditResults += $auditResult
$details = "Count: $globalAdminCount; Users: $globalAdminUsernames"
# Create and populate the CISAuditResult object
$params = @{
Rec = "1.1.3"
Result = $globalAdminCount -ge 2 -and $globalAdminCount -le 4
Status = if ($globalAdminCount -ge 2 -and $globalAdminCount -le 4) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,41 +1,47 @@
function Test-GuestAccessExpiration {
[CmdletBinding()]
param (
# Define your parameters here
# Aligned
# Define your parameters here if needed
)
begin {
# Initialization code
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
$auditResult = [CISAuditResult]::new()
# Initialization code, if needed
}
process {
# 7.2.9 (L1) Ensure guest access to a site or OneDrive will expire automatically
# Retrieve SharePoint tenant settings related to guest access expiration
$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"
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $isGuestAccessExpirationConfiguredCorrectly) {
"Guest access expiration is not configured to automatically expire within 30 days or less."
}
else {
"N/A"
}
$auditResult.Rec = "7.2.9"
$auditResult.ELevel = "E3"
$auditResult.ProfileLevel = "L1"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $false
$auditResult.RecDescription = "Ensure guest access to a site or OneDrive will expire automatically"
$details = "ExternalUserExpirationRequired: $($SPOTenantGuestAccess.ExternalUserExpirationRequired); ExternalUserExpireInDays: $($SPOTenantGuestAccess.ExternalUserExpireInDays)"
$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" }
# Create and populate the CISAuditResult object
$params = @{
Rec = "7.2.9"
Result = $isGuestAccessExpirationConfiguredCorrectly
Status = if ($isGuestAccessExpirationConfiguredCorrectly) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResult
# Return the audit result
return $auditResult
}
}

View File

@@ -1,61 +1,54 @@
function Test-GuestUsersBiweeklyReview {
[CmdletBinding()]
param ()
param (
# Aligned
# Define your parameters here if needed
)
begin {
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
$auditResults = @()
# Initialization code, if needed
}
process {
# 1.1.4 (L1) Ensure Guest Users are reviewed at least biweekly
# The function will fail if guest users are found since they should be reviewed manually biweekly.
try {
# Connect to Microsoft Graph - placeholder for connection command
# Retrieve guest users from Microsoft Graph
# Connect-MgGraph -Scopes "User.Read.All"
$guestUsers = Get-MgUser -All -Filter "UserType eq 'Guest'"
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.CISControl = "5.1, 5.3"
$auditResult.CISDescription = "Establish and Maintain an Inventory of Accounts, Disable Dormant Accounts"
$auditResult.Rec = "1.1.4"
$auditResult.RecDescription = "Ensure Guest Users are reviewed at least biweekly"
$auditResult.ELevel = "E3"
$auditResult.ProfileLevel = "L1"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.CISControlVer = 'v8'
# Prepare failure reasons and details based on compliance
$failureReasons = if ($guestUsers) {
"Guest users present: $($guestUsers.Count)"
}
else {
"N/A"
}
if ($guestUsers) {
$details = if ($guestUsers) {
$auditCommand = "Get-MgUser -All -Property UserType,UserPrincipalName | Where {`$_.UserType -ne 'Member'} | Format-Table UserPrincipalName, UserType"
$auditResult.Status = "Fail"
$auditResult.Result = $false
$auditResult.Details = "Manual review required. To list guest users, run: `"$auditCommand`"."
$auditResult.FailureReason = "Guest users present: $($guestUsers.Count)"
} else {
$auditResult.Status = "Pass"
$auditResult.Result = $true
$auditResult.Details = "No guest users found."
$auditResult.FailureReason = "N/A"
"Manual review required. To list guest users, run: `"$auditCommand`"."
}
}
catch {
$auditResult.Status = "Error"
$auditResult.Result = $false
$auditResult.Details = "Error while attempting to check guest users. Error message: $($_.Exception.Message)"
$auditResult.FailureReason = "An error occurred during the audit check."
else {
"No guest users found."
}
$auditResults += $auditResult
# Create and populate the CISAuditResult object
$params = @{
Rec = "1.1.4"
Result = -not $guestUsers
Status = if ($guestUsers) { "Fail" } else { "Pass" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,45 +1,47 @@
function Test-IdentifyExternalEmail {
[CmdletBinding()]
param (
# Aligned
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
$auditResults = @()
# Initialization code, if needed
}
process {
# 6.2.3 (L1) Ensure email from external senders is identified
# Requirement is to have external sender tagging enabled
# Review
# Retrieve external sender tagging configuration
$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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $externalTaggingEnabled) {
"External sender tagging is disabled"
}
else {
"N/A"
}
$auditResults += $auditResult
$details = "Enabled: $($externalTaggingEnabled); AllowList: $($externalInOutlook.AllowList)"
# Create and populate the CISAuditResult object
$params = @{
Rec = "6.2.3"
Result = $externalTaggingEnabled
Status = if ($externalTaggingEnabled) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,42 +1,47 @@
function Test-LinkSharingRestrictions {
[CmdletBinding()]
param (
# Aligned
# Define your parameters here
# Test behavior in prod
)
begin {
# Initialization code
$auditResult = [CISAuditResult]::new()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# 7.2.7 (L1) Ensure link sharing is restricted in SharePoint and OneDrive
# Retrieve link sharing configuration for SharePoint and OneDrive
$SPOTenantLinkSharing = Get-SPOTenant | Select-Object DefaultSharingLinkType
$isLinkSharingRestricted = $SPOTenantLinkSharing.DefaultSharingLinkType -eq 'Direct' # Or 'SpecificPeople' as per the recommendation
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "3.3"
$auditResult.CISDescription = "Configure Data Access Control Lists"
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $isLinkSharingRestricted) {
"Link sharing is not restricted to 'Specific people'. Current setting: $($SPOTenantLinkSharing.DefaultSharingLinkType)"
}
else {
"N/A"
}
$auditResult.Rec = "7.2.7"
$auditResult.ELevel = "E3"
$auditResult.ProfileLevel = "L1"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.RecDescription = "Ensure link sharing is restricted in SharePoint and OneDrive"
$details = "DefaultSharingLinkType: $($SPOTenantLinkSharing.DefaultSharingLinkType)"
$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" }
# Create and populate the CISAuditResult object
$params = @{
Rec = "7.2.7"
Result = $isLinkSharingRestricted
Status = if ($isLinkSharingRestricted) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResult
# Return the audit result
return $auditResult
}
}

View File

@@ -1,43 +1,54 @@
function Test-MailTipsEnabled {
[CmdletBinding()]
param (
# Define your parameters here
# Aligned
# Parameters can be added if needed
)
begin {
# Initialization code
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
$auditResult = [CISAuditResult]::new()
}
process {
# 6.5.2 (L2) Ensure MailTips are enabled for end users
# Retrieve organization configuration for MailTips settings
$orgConfig = Get-OrganizationConfig | Select-Object MailTipsAllTipsEnabled, MailTipsExternalRecipientsTipsEnabled, MailTipsGroupMetricsEnabled, MailTipsLargeAudienceThreshold
$allTipsEnabled = $orgConfig.MailTipsAllTipsEnabled -and $orgConfig.MailTipsGroupMetricsEnabled -and $orgConfig.MailTipsLargeAudienceThreshold -eq 25
$externalRecipientsTipsEnabled = $orgConfig.MailTipsExternalRecipientsTipsEnabled
# Since there is no direct CIS Control mapping, the control will be set as not applicable.
$auditResult.CISControl = "0"
$auditResult.CISControlVer = "v8"
$auditResult.CISDescription = "Explicitly Not Mapped"
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not ($allTipsEnabled -and $externalRecipientsTipsEnabled)) {
"One or more MailTips settings are not configured as required."
}
else {
"N/A"
}
$auditResult.Rec = "6.5.2"
$auditResult.ELevel = "E3"
$auditResult.ProfileLevel = "L2"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $false
$auditResult.RecDescription = "Ensure MailTips are enabled for end users"
$details = if ($allTipsEnabled -and $externalRecipientsTipsEnabled) {
"MailTipsAllTipsEnabled: $($orgConfig.MailTipsAllTipsEnabled); MailTipsExternalRecipientsTipsEnabled: $($orgConfig.MailTipsExternalRecipientsTipsEnabled); MailTipsGroupMetricsEnabled: $($orgConfig.MailTipsGroupMetricsEnabled); MailTipsLargeAudienceThreshold: $($orgConfig.MailTipsLargeAudienceThreshold)"
}
else {
"One or more MailTips settings are not configured as required."
}
$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" }
# Create and populate the CISAuditResult object
$params = @{
Rec = "6.5.2"
Result = $allTipsEnabled -and $externalRecipientsTipsEnabled
Status = if ($allTipsEnabled -and $externalRecipientsTipsEnabled) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResult
# Return the audit result
return $auditResult
}
}

View File

@@ -1,26 +1,20 @@
function Test-MailboxAuditingE3 {
[CmdletBinding()]
param (
# Aligned
# Create Table for Details
# Parameters can be added if needed
)
begin {
# Dot source the class script if necessary
#. .\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.ProfileLevel = "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
@@ -72,10 +66,19 @@ function Test-MailboxAuditingE3 {
}
}
$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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if ($allFailures.Count -eq 0) { "N/A" } else { "Audit issues detected." }
$details = if ($allFailures.Count -eq 0) { "All Office E3 users have correct mailbox audit settings." } else { $allFailures -join " | " }
# Populate the audit result
$params = @{
Rec = "6.1.2"
Result = $allFailures.Count -eq 0
Status = if ($allFailures.Count -eq 0) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {

View File

@@ -1,23 +1,21 @@
function Test-MailboxAuditingE5 {
[CmdletBinding()]
param ()
param (
# Aligned
# Create Table for Details
# Parameters can be added if needed
)
begin {
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
$e5SkuPartNumbers = @("SPE_E5", "ENTERPRISEPREMIUM", "OFFICEE5")
$AdminActions = @("ApplyRecord", "Copy", "Create", "FolderBind", "HardDelete", "MailItemsAccessed", "Move", "MoveToDeletedItems", "SendAs", "SendOnBehalf", "Send", "SoftDelete", "Update", "UpdateCalendarDelegation", "UpdateFolderPermissions", "UpdateInboxRules")
$DelegateActions = @("ApplyRecord", "Create", "FolderBind", "HardDelete", "MailItemsAccessed", "Move", "MoveToDeletedItems", "SendAs", "SendOnBehalf", "SoftDelete", "Update", "UpdateFolderPermissions", "UpdateInboxRules")
$OwnerActions = @("ApplyRecord", "Create", "HardDelete", "MailboxLogin", "Move", "MailItemsAccessed", "MoveToDeletedItems", "Send", "SoftDelete", "Update", "UpdateCalendarDelegation", "UpdateFolderPermissions", "UpdateInboxRules")
$auditResult = [CISAuditResult]::new()
$auditResult.ELevel = "E5"
$auditResult.ProfileLevel = "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
@@ -31,15 +29,11 @@ function Test-MailboxAuditingE5 {
}
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 = @()
@@ -78,13 +72,19 @@ function Test-MailboxAuditingE5 {
}
}
if ($allFailures.Count -eq 0) {
Write-Verbose "All evaluated E5 users have correct mailbox audit settings."
# Prepare failure reasons and details based on compliance
$failureReasons = if ($allFailures.Count -eq 0) { "N/A" } else { "Audit issues detected." }
$details = if ($allFailures.Count -eq 0) { "All Office E5 users have correct mailbox audit settings." } else { $allFailures -join " | " }
# Populate the audit result
$params = @{
Rec = "6.1.3"
Result = $allFailures.Count -eq 0
Status = if ($allFailures.Count -eq 0) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$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" }
$auditResult = Initialize-CISAuditResult @params
}
end {

View File

@@ -1,54 +1,52 @@
function Test-ManagedApprovedPublicGroups {
[CmdletBinding()]
param (
# Define your parameters here
# Aligned
# Parameters can be added if needed
)
begin {
# Dot source the class script
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
$auditResults = @()
}
process {
# 1.2.1 (L2) Ensure that only organizationally managed/approved public groups exist (Automated)
# Retrieve all public groups
$allGroups = Get-MgGroup -All | Where-Object { $_.Visibility -eq "Public" } | Select-Object DisplayName, Visibility
# 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.ProfileLevel = "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"
# Prepare failure reasons and details based on compliance
$failureReasons = if ($null -ne $allGroups -and $allGroups.Count -gt 0) {
"There are public groups present that are not organizationally managed/approved."
}
else {
"N/A"
}
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"
$details = if ($null -eq $allGroups -or $allGroups.Count -eq 0) {
"No public groups found."
}
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"
"Public groups found: $($groupDetails -join ', ')"
}
$auditResults += $auditResult
# Create and populate the CISAuditResult object
$params = @{
Rec = "1.2.1"
Result = $null -eq $allGroups -or $allGroups.Count -eq 0
Status = if ($null -eq $allGroups -or $allGroups.Count -eq 0) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
return $auditResult
}
}

View File

@@ -1,46 +1,48 @@
function Test-MeetingChatNoAnonymous {
[CmdletBinding()]
param (
# Aligned
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
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
# Retrieve the Teams meeting policy for meeting chat
$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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if ($chatAnonDisabled) {
"N/A"
}
else {
"Meeting chat allows anonymous users"
}
$auditResults += $auditResult
$details = "MeetingChatEnabledType is set to $($CsTeamsMeetingPolicyChat.MeetingChatEnabledType)"
# Create and populate the CISAuditResult object
$params = @{
Rec = "8.5.5"
Result = $chatAnonDisabled
Status = if ($chatAnonDisabled) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,40 +1,42 @@
function Test-ModernAuthExchangeOnline {
[CmdletBinding()]
param (
# Aligned
# Define your parameters here
)
begin {
$auditResults = [CISAuditResult]::new()
# Initialization code
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
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
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $orgConfig.OAuth2ClientProfileEnabled) {
"Modern authentication is disabled"
}
else {
"N/A"
}
$auditResults.CISControlVer = "v8"
$auditResults.CISControl = "3.10"
$auditResults.CISDescription = "Encrypt Sensitive Data in Transit"
$auditResults.IG1 = $false # As per CIS Control v8 mapping for IG1
$auditResults.IG2 = $true # As per CIS Control v8 mapping for IG2
$auditResults.IG3 = $true # As per CIS Control v8 mapping for IG3
$auditResults.ELevel = "E3" # Based on your environment (E3, E5, etc.)
$auditResults.ProfileLevel = "L1"
$auditResults.Rec = "6.5.1"
$auditResults.RecDescription = "Ensure modern authentication for Exchange Online is enabled (Automated)"
$auditResults.Result = $orgConfig.OAuth2ClientProfileEnabled
$auditResults.Details = $auditResults.Details = $orgConfig.Name + " OAuth2ClientProfileEnabled: " + $orgConfig.OAuth2ClientProfileEnabled
$auditResults.FailureReason = if (-not $orgConfig.OAuth2ClientProfileEnabled) { "Modern authentication is disabled" } else { "N/A" }
$auditResults.Status = if ($orgConfig.OAuth2ClientProfileEnabled) { "Pass" } else { "Fail" }
$details = "OAuth2ClientProfileEnabled: $($orgConfig.OAuth2ClientProfileEnabled) for Organization: $($orgConfig.Name)"
# Create and populate the CISAuditResult object
$params = @{
Rec = "6.5.1"
Result = $orgConfig.OAuth2ClientProfileEnabled
Status = if ($orgConfig.OAuth2ClientProfileEnabled) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
catch {
@@ -43,12 +45,7 @@ function Test-ModernAuthExchangeOnline {
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,13 +1,14 @@
function Test-ModernAuthSharePoint {
[CmdletBinding()]
param (
# Aligned
# Define your parameters here
)
begin {
# Initialization code
$auditResult = [CISAuditResult]::new()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
@@ -15,25 +16,29 @@ function Test-ModernAuthSharePoint {
$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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $modernAuthForSPRequired) {
"Legacy authentication protocols are enabled"
}
else {
"N/A"
}
$details = "LegacyAuthProtocolsEnabled: $($SPOTenant.LegacyAuthProtocolsEnabled)"
# Create and populate the CISAuditResult object
$params = @{
Rec = "7.2.1"
Result = $modernAuthForSPRequired
Status = if ($modernAuthForSPRequired) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResult
# Return the audit result
return $auditResult
}
}

View File

@@ -1,13 +1,14 @@
function Test-NoAnonymousMeetingJoin {
[CmdletBinding()]
param (
# Aligned
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
@@ -18,28 +19,29 @@ function Test-NoAnonymousMeetingJoin {
$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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if ($allowAnonymousUsersToJoinMeeting) {
"Anonymous users are allowed to join meetings"
}
else {
"N/A"
}
$auditResults += $auditResult
$details = "AllowAnonymousUsersToJoinMeeting is set to $allowAnonymousUsersToJoinMeeting"
# Create and populate the CISAuditResult object
$params = @{
Rec = "8.5.1"
Result = -not $allowAnonymousUsersToJoinMeeting
Status = if (-not $allowAnonymousUsersToJoinMeeting) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,13 +1,14 @@
function Test-NoAnonymousMeetingStart {
[CmdletBinding()]
param (
# Aligned
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
@@ -18,28 +19,29 @@ function Test-NoAnonymousMeetingStart {
$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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if ($anonymousStartDisabled) {
"N/A"
}
else {
"Anonymous users and dial-in callers can start a meeting"
}
$auditResults += $auditResult
$details = "AllowAnonymousUsersToStartMeeting is set to $($CsTeamsMeetingPolicyAnonymous.AllowAnonymousUsersToStartMeeting)"
# Create and populate the CISAuditResult object
$params = @{
Rec = "8.5.2"
Result = $anonymousStartDisabled
Status = if ($anonymousStartDisabled) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,43 +1,47 @@
function Test-NoWhitelistDomains {
[CmdletBinding()]
param (
# Aligned
# Define your parameters here
)
begin {
# Initialization code
$auditResult = [CISAuditResult]::new()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
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"
# Retrieve transport rules that whitelist specific domains
$whitelistedRules = Get-TransportRule | Where-Object { $_.SetSCL -eq -1 -and $null -ne $_.SenderDomainIs }
$auditResult.Rec = "6.2.2"
$auditResult.ELevel = "E3"
$auditResult.ProfileLevel = "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"
# Prepare failure reasons and details based on compliance
$failureReasons = if ($whitelistedRules) {
"There are transport rules whitelisting specific domains."
}
else {
"N/A"
}
$details = if ($whitelistedRules) {
$ruleDetails = $whitelistedRules | ForEach-Object { "{0}: {1}" -f $_.Name, ($_.SenderDomainIs -join ', ') }
"Whitelisted Rules: $($ruleDetails -join '; ')"
}
else {
"No transport rules whitelisting specific domains found."
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "6.2.2"
Result = -not $whitelistedRules
Status = if ($whitelistedRules) { "Fail" } else { "Pass" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {

View File

@@ -1,12 +1,14 @@
function Test-NotifyMalwareInternal {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added if needed
)
begin {
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
@@ -24,31 +26,35 @@ function Test-NotifyMalwareInternal {
# 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.ProfileLevel = "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
# Prepare failure reasons and details based on compliance
$failureReasons = if ($result) {
"N/A"
}
else {
"Some custom policies do not have notifications for internal users sending malware enabled."
}
$auditResults += $auditResult
$details = if ($result) {
"All custom malware policies have notifications enabled."
}
else {
"Misconfigured Policies: $($policiesToReport -join ', ')"
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "2.1.3"
Result = $result
Status = if ($result) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,37 +1,47 @@
function Test-OneDriveContentRestrictions {
[CmdletBinding()]
param (
# Aligned
# Define your parameters here
)
begin {
# Initialization code
$auditResult = [CISAuditResult]::new()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# 7.2.4 (L2) Ensure OneDrive content sharing is restricted
# Retrieve OneDrive sharing capability settings
$SPOTenant = Get-SPOTenant | Select-Object OneDriveSharingCapability
$isOneDriveSharingRestricted = $SPOTenant.OneDriveSharingCapability -eq 'Disabled'
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "3.3"
$auditResult.CISDescription = "Configure Data Access Control Lists"
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $isOneDriveSharingRestricted) {
"OneDrive content sharing is not restricted to 'Disabled'. Current setting: $($SPOTenant.OneDriveSharingCapability)"
}
else {
"N/A"
}
$auditResult.Rec = "7.2.4"
$auditResult.ELevel = "E3"
$auditResult.ProfileLevel = "L2"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.RecDescription = "Ensure OneDrive content sharing is restricted"
$details = if ($isOneDriveSharingRestricted) {
"OneDrive content sharing is restricted."
}
else {
"OneDriveSharingCapability: $($SPOTenant.OneDriveSharingCapability)"
}
$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" }
# Create and populate the CISAuditResult object
$params = @{
Rec = "7.2.4"
Result = $isOneDriveSharingRestricted
Status = if ($isOneDriveSharingRestricted) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {

View File

@@ -1,37 +1,47 @@
function Test-OneDriveSyncRestrictions {
[CmdletBinding()]
param (
# Aligned
# Define your parameters here
)
begin {
# Initialization code
$auditResult = [CISAuditResult]::new()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# 7.3.2 (L2) Ensure OneDrive sync is restricted for unmanaged devices
# Retrieve OneDrive sync client restriction settings
$SPOTenantSyncClientRestriction = Get-SPOTenantSyncClientRestriction | Select-Object TenantRestrictionEnabled, AllowedDomainList
$isSyncRestricted = $SPOTenantSyncClientRestriction.TenantRestrictionEnabled -and $SPOTenantSyncClientRestriction.AllowedDomainList
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0"
$auditResult.CISDescription = "Explicitly Not Mapped"
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $isSyncRestricted) {
"OneDrive sync is not restricted to managed devices. TenantRestrictionEnabled should be True and AllowedDomainList should contain trusted domains GUIDs."
}
else {
"N/A"
}
$auditResult.Rec = "7.3.2"
$auditResult.ELevel = "E3"
$auditResult.ProfileLevel = "L2"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $false
$auditResult.RecDescription = "Ensure OneDrive sync is restricted for unmanaged devices"
$details = if ($isSyncRestricted) {
"OneDrive sync is restricted for unmanaged devices."
}
else {
"TenantRestrictionEnabled: $($SPOTenantSyncClientRestriction.TenantRestrictionEnabled); AllowedDomainList: $($SPOTenantSyncClientRestriction.AllowedDomainList -join ', ')"
}
$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" }
# Create and populate the CISAuditResult object
$params = @{
Rec = "7.3.2"
Result = $isSyncRestricted
Status = if ($isSyncRestricted) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {

View File

@@ -1,13 +1,14 @@
function Test-OrgOnlyBypassLobby {
[CmdletBinding()]
param (
# Aligned
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
@@ -15,31 +16,38 @@ function Test-OrgOnlyBypassLobby {
# Connect to Teams PowerShell using Connect-MicrosoftTeams
# Retrieve the Teams meeting policy for lobby bypass settings
$CsTeamsMeetingPolicyLobby = Get-CsTeamsMeetingPolicy -Identity Global | Select-Object -Property AutoAdmittedUsers
$lobbyBypassRestricted = $CsTeamsMeetingPolicyLobby.AutoAdmittedUsers -eq 'EveryoneInCompanyExcludingGuests'
# 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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $lobbyBypassRestricted) {
"External participants can bypass the lobby"
}
else {
"N/A"
}
$auditResults += $auditResult
$details = if ($lobbyBypassRestricted) {
"Only people in the organization can bypass the lobby."
}
else {
"AutoAdmittedUsers is set to $($CsTeamsMeetingPolicyLobby.AutoAdmittedUsers)"
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "8.5.3"
Result = $lobbyBypassRestricted
Status = if ($lobbyBypassRestricted) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,13 +1,14 @@
function Test-OrganizersPresent {
[CmdletBinding()]
param (
# Aligned
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
@@ -15,31 +16,38 @@ function Test-OrganizersPresent {
# Connect to Teams PowerShell using Connect-MicrosoftTeams
# Retrieve the Teams meeting policy for presenters
$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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $presenterRoleRestricted) {
"Others besides organizers and co-organizers can present"
}
else {
"N/A"
}
$auditResults += $auditResult
$details = if ($presenterRoleRestricted) {
"Only organizers and co-organizers can present."
}
else {
"DesignatedPresenterRoleMode is set to $($CsTeamsMeetingPolicyPresenters.DesignatedPresenterRoleMode)"
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "8.5.6"
Result = $presenterRoleRestricted
Status = if ($presenterRoleRestricted) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,43 +1,47 @@
function Test-PasswordHashSync {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
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.ProfileLevel = "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" }
# Retrieve password hash sync status
$passwordHashSync = Get-MgOrganization | Select-Object -ExpandProperty OnPremisesSyncEnabled
$hashSyncResult = $passwordHashSync
$auditResults += $auditResult
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $hashSyncResult) {
"Password hash sync for hybrid deployments is not enabled"
}
else {
"N/A"
}
$details = "OnPremisesSyncEnabled: $($passwordHashSync)"
# Create and populate the CISAuditResult object
$params = @{
Rec = "5.1.8.1"
Result = $hashSyncResult
Status = if ($hashSyncResult) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,45 +1,47 @@
function Test-PasswordNeverExpirePolicy {
[CmdletBinding()]
param (
# Aligned
[Parameter(Mandatory)]
[string]$DomainName # DomainName parameter is now mandatory
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
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.
# Pass if PasswordValidityPeriodInDays is 0. Fail otherwise.
$passwordPolicy = Get-MgDomain -DomainId $DomainName | Select-Object PasswordValidityPeriodInDays
# Retrieve password expiration policy
$passwordPolicy = Get-MgDomain -DomainId $DomainName | Select-Object -ExpandProperty 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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if ($passwordPolicy -ne 0) {
"Password expiration is not set to never expire"
}
else {
"N/A"
}
$auditResults += $auditResult
$details = "Validity Period: $passwordPolicy days"
# Create and populate the CISAuditResult object
$params = @{
Rec = "1.3.1"
Result = $passwordPolicy -eq 0
Status = if ($passwordPolicy -eq 0) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,37 +1,42 @@
function Test-ReauthWithCode {
[CmdletBinding()]
param (
# Aligned
# Define your parameters here
)
begin {
# Initialization code
$auditResult = [CISAuditResult]::new()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# 7.2.10 (L1) Ensure reauthentication with verification code is restricted
# Retrieve reauthentication settings for SharePoint Online
$SPOTenantReauthentication = Get-SPOTenant | Select-Object EmailAttestationRequired, EmailAttestationReAuthDays
$isReauthenticationRestricted = $SPOTenantReauthentication.EmailAttestationRequired -and $SPOTenantReauthentication.EmailAttestationReAuthDays -le 15
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "0.0"
$auditResult.CISDescription = "Explicitly Not Mapped"
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $isReauthenticationRestricted) {
"Reauthentication with verification code does not require reauthentication within 15 days or less."
}
else {
"N/A"
}
$auditResult.Rec = "7.2.10"
$auditResult.ELevel = "E3"
$auditResult.ProfileLevel = "L1"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $false
$auditResult.RecDescription = "Ensure reauthentication with verification code is restricted"
$details = "EmailAttestationRequired: $($SPOTenantReauthentication.EmailAttestationRequired); EmailAttestationReAuthDays: $($SPOTenantReauthentication.EmailAttestationReAuthDays)"
$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" }
# Create and populate the CISAuditResult object
$params = @{
Rec = "7.2.10"
Result = $isReauthenticationRestricted
Status = if ($isReauthenticationRestricted) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {

View File

@@ -1,21 +1,20 @@
function Test-ReportSecurityInTeams {
[CmdletBinding()]
param (
# Aligned
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
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
# Retrieve the necessary settings for Teams and Exchange Online
$CsTeamsMessagingPolicy = Get-CsTeamsMessagingPolicy -Identity Global | Select-Object -Property AllowSecurityEndUserReporting
$ReportSubmissionPolicy = Get-ReportSubmissionPolicy | Select-Object -Property ReportJunkToCustomizedAddress, ReportNotJunkToCustomizedAddress, ReportPhishToCustomizedAddress, ReportChatMessageToCustomizedAddressEnabled
@@ -25,32 +24,33 @@ function Test-ReportSecurityInTeams {
$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.ProfileLevel = "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); " +
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $securityReportEnabled) {
"Users cannot report security concerns in Teams due to one or more incorrect settings"
}
else {
"N/A"
}
$details = "AllowSecurityEndUserReporting: $($CsTeamsMessagingPolicy.AllowSecurityEndUserReporting); " +
"ReportJunkToCustomizedAddress: $($ReportSubmissionPolicy.ReportJunkToCustomizedAddress); " +
"ReportNotJunkToCustomizedAddress: $($ReportSubmissionPolicy.ReportNotJunkToCustomizedAddress); " +
"ReportPhishToCustomizedAddress: $($ReportSubmissionPolicy.ReportPhishToCustomizedAddress); " +
"ReportChatMessageToCustomizedAddressEnabled: $($ReportSubmissionPolicy.ReportChatMessageToCustomizedAddressEnabled)"
$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
# Create and populate the CISAuditResult object
$params = @{
Rec = "8.6.1"
Result = $securityReportEnabled
Status = if ($securityReportEnabled) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return auditResult
return $auditResult
}
}

View File

@@ -1,21 +1,20 @@
function Test-RestrictCustomScripts {
[CmdletBinding()]
param (
# Aligned
# Define your parameters here if needed
)
#Limit All
begin {
# .TODO Test behavior in Prod
# Dot source the class script
$auditResults = @()
begin {
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# CIS 2.7 Ensure custom script execution is restricted on site collections
# Pass if DenyAddAndCustomizePages is set to true (Enabled). Fail otherwise.
# 7.3.4 (L1) Ensure custom script execution is restricted on site collections
# Get all site collections and select necessary properties
# Retrieve all site collections and select necessary properties
$SPOSitesCustomScript = Get-SPOSite -Limit All | Select-Object Title, Url, DenyAddAndCustomizePages
# Find sites where custom scripts are allowed (DenyAddAndCustomizePages is not 'Enabled')
@@ -29,42 +28,34 @@ function Test-RestrictCustomScripts {
"$($_.Title) ($($_.Url)): Custom Script Allowed"
}
# 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.ProfileLevel = "L1"
$auditResult.IG1 = $false
$auditResult.IG2 = $false
$auditResult.IG3 = $true
$auditResult.RecDescription = "Ensure custom script execution is restricted on site collections"
$auditResult.Result = $complianceResult
$auditResult.Details = if (-not $complianceResult) {
$nonCompliantSiteDetails -join "; "
} else {
"All site collections have custom script execution restricted"
}
$auditResult.FailureReason = if (-not $complianceResult) {
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $complianceResult) {
"The following site collections allow custom script execution: " + ($nonCompliantSiteDetails -join "; ")
} else {
}
else {
"N/A"
}
$auditResult.Status = if ($complianceResult) {
"Pass"
} else {
"Fail"
$details = if ($complianceResult) {
"All site collections have custom script execution restricted"
}
else {
$nonCompliantSiteDetails -join "; "
}
$auditResults += $auditResult
# Create and populate the CISAuditResult object
$params = @{
Rec = "7.3.4"
Result = $complianceResult
Status = if ($complianceResult) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return auditResult
return $auditResult
}
}

View File

@@ -1,37 +1,42 @@
function Test-RestrictExternalSharing {
[CmdletBinding()]
param (
# Aligned
# Define your parameters here
)
begin {
# Initialization code
$auditResult = [CISAuditResult]::new()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# 7.2.3 (L1) Ensure external content sharing is restricted
# Retrieve the SharingCapability setting for the SharePoint tenant
$SPOTenantSharingCapability = Get-SPOTenant | Select-Object SharingCapability
$isRestricted = $SPOTenantSharingCapability.SharingCapability -in @('ExternalUserSharingOnly', 'ExistingExternalUserSharingOnly', 'Disabled')
# Populate the auditResult object with the required properties
$auditResult.CISControlVer = "v8"
$auditResult.CISControl = "3.3"
$auditResult.CISDescription = "Configure Data Access Control Lists"
# Prepare failure reasons and details based on compliance
$failureReasons = if (-not $isRestricted) {
"External content sharing is not adequately restricted. Current setting: $($SPOTenantSharingCapability.SharingCapability)"
}
else {
"N/A"
}
$auditResult.Rec = "7.2.3"
$auditResult.ELevel = "E3"
$auditResult.ProfileLevel = "L1"
$auditResult.IG1 = $true
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.RecDescription = "Ensure external content sharing is restricted"
$details = "SharingCapability: $($SPOTenantSharingCapability.SharingCapability)"
$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" }
# Create and populate the CISAuditResult object
$params = @{
Rec = "7.2.3"
Result = $isRestricted
Status = if ($isRestricted) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {

View File

@@ -1,20 +1,20 @@
function Test-RestrictOutlookAddins {
[CmdletBinding()]
param (
# Aligned
# Parameters could include credentials or other necessary data
)
begin {
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code
$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
@@ -38,24 +38,11 @@ function Test-RestrictOutlookAddins {
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.ProfileLevel = "L2"
$auditResult.IG1 = $false
$auditResult.IG2 = $true
$auditResult.IG3 = $true
$auditResult.RecDescription = "Ensure users installing Outlook add-ins is not allowed"
# Prepare result details string
$detailsString = ""
if ($customPolicyFailures) {
$detailsString += "Custom Policy Failures: | "
# Use pipes or tabs here instead of newlines
$detailsString += ($customPolicyFailures -join " | ")
}
else {
@@ -70,20 +57,22 @@ function Test-RestrictOutlookAddins {
$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."
# Determine result based on findings
$isCompliant = -not ($customPolicyFailures -or $defaultPolicyFailureDetails)
# Create and populate the CISAuditResult object
$params = @{
Rec = "6.3.1"
Result = $isCompliant
Status = if ($isCompliant) { "Pass" } else { "Fail" }
Details = $detailsString
FailureReason = if ($isCompliant) { "N/A" } else { "Unauthorized Outlook add-ins found in custom or default policies." }
}
else {
$auditResult.Result = $true
$auditResult.Status = "Pass"
$auditResult.Details = "No unauthorized Outlook add-ins found in custom or default policies."
$auditResult.FailureReason = "N/A"
$auditResult = Initialize-CISAuditResult @params
}
# Return auditResult
end {
# Return the audit result
return $auditResult
}
}

View File

@@ -1,48 +1,56 @@
function Test-RestrictStorageProvidersOutlook {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added here if needed
)
begin {
# Dot source the class script
$auditResult = [CISAuditResult]::new()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
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.ProfileLevel = "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 ', ')"
# Retrieve all OwaMailbox policies
$owaPolicies = Get-OwaMailboxPolicy
$nonCompliantPolicies = $owaPolicies | Where-Object { $_.AdditionalStorageProvidersAvailable }
# Determine compliance
$allPoliciesRestricted = $nonCompliantPolicies.Count -eq 0
# Prepare failure reasons and details based on compliance
$failureReasons = if ($allPoliciesRestricted) {
"N/A"
}
$auditResult.FailureReason = if(-not $allPoliciesRestricted) { "One or more OwaMailbox policies allow AdditionalStorageProvidersAvailable." } else { "N/A" }
$auditResult.Status = if($allPoliciesRestricted) { "Pass" } else { "Fail" }
else {
"One or more OwaMailbox policies allow AdditionalStorageProvidersAvailable."
}
$details = if ($allPoliciesRestricted) {
"All OwaMailbox policies restrict AdditionalStorageProvidersAvailable"
}
else {
"Non-compliant OwaMailbox policies: $($nonCompliantPolicies.Name -join ', ')"
}
# Create and populate the CISAuditResult object
$params = @{
Rec = "6.5.3"
Result = $allPoliciesRestricted
Status = if ($allPoliciesRestricted) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResult
# Return the audit result
return $auditResult
}
}
# Additional helper functions (if any)

View File

@@ -1,43 +1,48 @@
function Test-RestrictTenantCreation {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added if needed
)
begin {
# Dot source the class script
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
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.
# Retrieve the tenant creation policy
$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.ProfileLevel = "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" }
# Prepare failure reasons and details based on compliance
$failureReasons = if ($tenantCreationResult) {
"N/A"
}
else {
"Non-admin users can create tenants"
}
$auditResults += $auditResult
$details = "AllowedToCreateTenants: $($tenantCreationPolicy.AllowedToCreateTenants)"
# Create and populate the CISAuditResult object
$params = @{
Rec = "5.1.2.3"
Result = $tenantCreationResult
Status = if ($tenantCreationResult) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}
# Additional helper functions (if any)

View File

@@ -1,49 +1,53 @@
function Test-SafeAttachmentsPolicy {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added if needed
)
begin {
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# 2.1.4 (L2) Ensure Safe Attachments policy is enabled
# Retrieve all Safe Attachment policies where Enable is set to True
$safeAttachmentPolicies = Get-SafeAttachmentPolicy | Where-Object { $_.Enable -eq $true }
# If there are any enabled policies, the result is Pass. If not, it's Fail.
$result = $safeAttachmentPolicies -ne $null -and $safeAttachmentPolicies.Count -gt 0
# Determine result and details based on the presence of enabled policies
$result = $null -ne $safeAttachmentPolicies -and $safeAttachmentPolicies.Count -gt 0
$details = if ($result) {
"Enabled Safe Attachments Policies: $($safeAttachmentPolicies.Name -join ', ')"
} else {
}
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.ProfileLevel = "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
$failureReasons = if ($result) {
"N/A"
}
else {
"Safe Attachments policy is not enabled."
}
$auditResults += $auditResult
# Create and populate the CISAuditResult object
$params = @{
Rec = "2.1.4"
Result = $result
Status = if ($result) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}
# Additional helper functions (if any)

View File

@@ -1,16 +1,19 @@
function Test-SafeAttachmentsTeams {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added if needed
)
begin {
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# Requires E5 license
# 2.1.5 (L2) Ensure Safe Attachments for SharePoint, OneDrive, and Microsoft Teams is Enabled
# Retrieve the ATP policies for Office 365 and check Safe Attachments settings
$atpPolicies = Get-AtpPolicyForO365
@@ -25,33 +28,33 @@ function Test-SafeAttachmentsTeams {
$result = $null -ne $atpPolicyResult
$details = if ($result) {
"ATP for SharePoint, OneDrive, and Teams is enabled with correct settings."
} else {
}
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.ProfileLevel = "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
$failureReasons = if ($result) {
"N/A"
}
else {
"ATP policy for SharePoint, OneDrive, and Microsoft Teams is not correctly configured."
}
$auditResults += $auditResult
# Create and populate the CISAuditResult object
$params = @{
Rec = "2.1.5"
Result = $result
Status = if ($result) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}
# Additional helper functions (if any)

View File

@@ -1,16 +1,19 @@
function Test-SafeLinksOfficeApps {
[CmdletBinding()]
param (
# Aligned
# Define your parameters here if needed
)
begin {
# Initialization code
$auditResults = @()
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
}
process {
# 2.1.1 (L2) Ensure Safe Links for Office Applications is Enabled
# Retrieve all Safe Links policies
$policies = Get-SafeLinksPolicy
@@ -42,29 +45,21 @@ function Test-SafeLinksOfficeApps {
# Prepare the final result
$result = $misconfiguredDetails.Count -eq 0
$details = if ($result) { "All Safe Links policies are correctly configured." } else { $misconfiguredDetails -join ' | ' }
$failureReasons = if ($result) { "N/A" } else { "The following Safe Links policies settings do not meet the recommended configuration: $($misconfiguredDetails -join ' | ')" }
# Create the audit result object
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($result) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E5"
$auditResult.ProfileLevel = "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
# Create and populate the CISAuditResult object
$params = @{
Rec = "2.1.1"
Result = $result
Status = if ($result) { "Pass" } else { "Fail" }
Details = $details
FailureReason = $failureReasons
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return the audit result
return $auditResult
}
}

View File

@@ -1,11 +1,14 @@
function Test-SharePointAADB2B {
[CmdletBinding()]
param (
# Aligned
# Define your parameters here
)
begin {
# Initialization code
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
$auditResult = [CISAuditResult]::new()
}
@@ -15,22 +18,14 @@ function Test-SharePointAADB2B {
$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.ProfileLevel = "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" }
$params = @{
Rec = "7.2.2"
Result = $SPOTenantAzureADB2B.EnableAzureADB2BIntegration
Status = if ($SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Pass" } else { "Fail" }
Details = "EnableAzureADB2BIntegration: $($SPOTenantAzureADB2B.EnableAzureADB2BIntegration)"
FailureReason = if (-not $SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Azure AD B2B integration is not enabled" } else { "N/A" }
}
$auditResult = Initialize-CISAuditResult @params
}
end {

View File

@@ -1,11 +1,14 @@
function Test-SharePointExternalSharingDomains {
[CmdletBinding()]
param (
# Aligned
# Define your parameters here
)
begin {
# Initialization code
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
$auditResult = [CISAuditResult]::new()
}
@@ -16,22 +19,14 @@ function Test-SharePointExternalSharingDomains {
$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.ProfileLevel = "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" }
$params = @{
Rec = "7.2.6"
Result = $isDomainRestrictionConfigured
Status = if ($isDomainRestrictionConfigured) { "Pass" } else { "Fail" }
Details = "SharingDomainRestrictionMode: $($SPOTenant.SharingDomainRestrictionMode); SharingAllowedDomainList: $($SPOTenant.SharingAllowedDomainList)"
FailureReason = if (-not $isDomainRestrictionConfigured) { "Domain restrictions for SharePoint external sharing are not configured to 'AllowList'. Current setting: $($SPOTenant.SharingDomainRestrictionMode)" } else { "N/A" }
}
$auditResult = Initialize-CISAuditResult @params
}
end {

View File

@@ -1,11 +1,14 @@
function Test-SharePointGuestsItemSharing {
[CmdletBinding()]
param (
# Aligned
# Define your parameters here
)
begin {
# Initialization code
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
$auditResult = [CISAuditResult]::new()
}
@@ -16,22 +19,14 @@ function Test-SharePointGuestsItemSharing {
$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.ProfileLevel = "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" }
$params = @{
Rec = "7.2.5"
Result = $isGuestResharingPrevented
Status = if ($isGuestResharingPrevented) { "Pass" } else { "Fail" }
Details = "PreventExternalUsersFromResharing: $isGuestResharingPrevented"
FailureReason = if (-not $isGuestResharingPrevented) { "Guest users can reshare items they don't own." } else { "N/A" }
}
$auditResult = Initialize-CISAuditResult @params
}
end {

View File

@@ -1,12 +1,16 @@
function Test-SpamPolicyAdminNotify {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added if needed
)
begin {
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
$auditResults = @()
$auditResult = [CISAuditResult]::new()
}
process {
@@ -30,29 +34,18 @@ function Test-SpamPolicyAdminNotify {
}
# Create an instance of CISAuditResult and populate it
$auditResult = [CISAuditResult]::new()
$auditResult.Status = if ($areSettingsEnabled) { "Pass" } else { "Fail" }
$auditResult.ELevel = "E3"
$auditResult.ProfileLevel = "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
$params = @{
Rec = "2.1.6"
Result = $areSettingsEnabled
Status = if ($areSettingsEnabled) { "Pass" } else { "Fail" }
Details = if ($areSettingsEnabled) { "Both BccSuspiciousOutboundMail and NotifyOutboundSpam are enabled." } else { $failureDetails -join ' ' }
FailureReason = if (-not $areSettingsEnabled) { "One or both spam policies are not set to notify administrators." } else { "N/A" }
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return auditResult
return $auditResult
}
}

View File

@@ -1,13 +1,16 @@
function Test-TeamsExternalAccess {
[CmdletBinding()]
param (
# Aligned
# Parameters can be defined here if needed
)
begin {
# Dot source the class script
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
$auditResults = @()
$auditResult = [CISAuditResult]::new()
}
process {
@@ -26,27 +29,18 @@ function Test-TeamsExternalAccess {
$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.ProfileLevel = "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
$params = @{
Rec = "8.2.1"
Result = $isCompliant
Status = if ($isCompliant) { "Pass" } else { "Fail" }
Details = "AllowTeamsConsumer: $($externalAccessConfig.AllowTeamsConsumer); AllowPublicUsers: $($externalAccessConfig.AllowPublicUsers); AllowFederatedUsers: $($externalAccessConfig.AllowFederatedUsers); AllowedDomains limited: $allowedDomainsLimited"
FailureReason = if (-not $isCompliant) { "One or more external access configurations are not compliant." } else { "N/A" }
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return auditResult
return $auditResult
}
}

View File

@@ -1,13 +1,16 @@
function Test-TeamsExternalFileSharing {
[CmdletBinding()]
param (
# Aligned
# Parameters can be added here if needed
)
begin {
# Dot source the class script
# Dot source the class script if necessary
#. .\source\Classes\CISAuditResult.ps1
# Initialization code, if needed
$auditResults = @()
$auditResult = [CISAuditResult]::new()
}
process {
@@ -30,27 +33,18 @@ function Test-TeamsExternalFileSharing {
}
# 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.ProfileLevel = "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
$params = @{
Rec = "8.1.1"
Result = $isCompliant
Status = if ($isCompliant) { "Pass" } else { "Fail" }
Details = if (-not $isCompliant) { "Non-approved providers enabled: $($nonCompliantProviders -join ', ')" } else { "All cloud storage services are approved providers" }
FailureReason = if (-not $isCompliant) { "The following non-approved providers are enabled: $($nonCompliantProviders -join ', ')" } else { "N/A" }
}
$auditResult = Initialize-CISAuditResult @params
}
end {
# Return auditResults
return $auditResults
# Return auditResult
return $auditResult
}
}

View File

@@ -0,0 +1,27 @@
$ProjectPath = "$PSScriptRoot\..\..\.." | Convert-Path
$ProjectName = ((Get-ChildItem -Path $ProjectPath\*\*.psd1).Where{
($_.Directory.Name -match 'source|src' -or $_.Directory.Name -eq $_.BaseName) -and
$(try { Test-ModuleManifest $_.FullName -ErrorAction Stop } catch { $false } )
}).BaseName
Import-Module $ProjectName
InModuleScope $ProjectName {
Describe Get-PrivateFunction {
Context 'Default' {
BeforeEach {
$return = Get-PrivateFunction -PrivateData 'string'
}
It 'Returns a single object' {
($return | Measure-Object).Count | Should -Be 1
}
It 'Returns a string based on the parameter PrivateData' {
$return | Should -Be 'string'
}
}
}
}