Merge pull request #12 from CriticalSolutionsNetwork/Better-Error-Handling
Better error handling
This commit is contained in:
5
.github/workflows/powershell.yml
vendored
5
.github/workflows/powershell.yml
vendored
@@ -36,10 +36,11 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
# Check https://github.com/microsoft/action-psscriptanalyzer for more info about the options.
|
# Check https://github.com/microsoft/action-psscriptanalyzer for more info about the options.
|
||||||
# The below set up runs PSScriptAnalyzer to your entire repository and runs some basic security rules.
|
# The below set up runs PSScriptAnalyzer to your entire repository and runs some basic security rules.
|
||||||
path: .\
|
path: .\source
|
||||||
recurse: true
|
recurse: true
|
||||||
# Include your own basic security rules. Removing this option will run all the rules
|
# Include your own basic security rules. Removing this option will run all the rules
|
||||||
includeRule: '"PSAvoidGlobalAliases", "PSAvoidUsingConvertToSecureStringWithPlainText"'
|
includeRule: '"PSAvoidGlobalAliases", "PSAvoidUsingConvertToSecureStringWithPlainText", "PSAvoidUsingPlainTextForPassword", "PSAvoidUsingInvokeExpression", "PSUseApprovedVerbs", "PSAvoidUsingPositionalParameters", "PSAvoidUsingEmptyCatchBlock", "PSAvoidUsingDeprecatedManifestFields", "PSAvoidUsingUserNameAndPasswordParams", "PSAvoidUsingCmdletAliases"'
|
||||||
|
|
||||||
output: results.sarif
|
output: results.sarif
|
||||||
|
|
||||||
# Upload the SARIF file generated in the previous step
|
# Upload the SARIF file generated in the previous step
|
||||||
|
32
CHANGELOG.md
32
CHANGELOG.md
@@ -6,6 +6,38 @@ The format is based on and uses the types of changes according to [Keep a Change
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- Updated test definitions for CIS Microsoft 365 Foundations Benchmark for better error handling and object output when errors occur.
|
||||||
|
- Added a parameter to the `Initialize-CISAuditResult` function to allow for a static failed object to be created when an error occurs.
|
||||||
|
- Refactored `Invoke-M365SecurityAudit` to include a new private function `Invoke-TestFunction` for executing test functions and handling errors.
|
||||||
|
- Added a new private function `Measure-AuditResult` to calculate and display audit results.
|
||||||
|
- Enhanced error logging to capture failed test details and display them at the end of the audit.
|
||||||
|
- Added a private function `Get-RequiredModule` to initialize the `$requiredModules` variable for better code organization in the main script.
|
||||||
|
- Updated `Test-MailboxAuditingE3` and `Test-MailboxAuditingE5` functions to use `Format-MissingAction` for structuring missing actions into a pipe-separated table format.
|
||||||
|
- Added more verbose logging to `Test-BlockMailForwarding` and improved error handling for better troubleshooting.
|
||||||
|
- Improved `Test-RestrictCustomScripts` to handle long URL lengths better by extracting and replacing common hostnames, and provided detailed output.
|
||||||
|
- Added sorting to output.
|
||||||
|
- Created new functions for improved modularity.
|
||||||
|
- Parameter validation for excel and csv path in sync function
|
||||||
|
- Added Output type to tests.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Ensured the `Invoke-TestFunction` returns a `CISAuditResult` object, which is then managed in the `Invoke-M365SecurityAudit` function.
|
||||||
|
- Corrected the usage of the join operation within `$details` in `Test-BlockMailForwarding` to handle arrays properly.
|
||||||
|
- Fixed the logic in `Test-RestrictCustomScripts` to accurately replace and manage URLs, ensuring compliance checks are correctly performed.
|
||||||
|
- Updated the `Test-MailboxAuditingE3` and `Test-MailboxAuditingE5` functions to handle the `$allFailures` variable correctly, ensuring accurate pass/fail results.
|
||||||
|
- Fixed the connections in helper CSV and connect function.
|
||||||
|
- Removed verbose preference from `Test-RestrictCustomScripts`.
|
||||||
|
- Ensured that the output in `Test-BlockMailForwarding` does not include extra spaces between table headers and data.
|
||||||
|
- Fixed output in `Test-MailboxAuditingE3` and `Test-MailboxAuditingE5` to correctly align with the new table format.
|
||||||
|
- Added step 1 and step 2 in `Test-BlockMailForwarding` details to ensure comprehensive compliance checks.
|
||||||
|
- Fixed the issue with the output in `Test-RestrictCustomScripts` to ensure no extra spaces between table headers and data.
|
||||||
|
|
||||||
|
|
||||||
|
## [0.1.4] - 2024-05-30
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
- Test definitions filter function.
|
- Test definitions filter function.
|
||||||
- Logging function for future use.
|
- Logging function for future use.
|
||||||
- Test grade written to console.
|
- Test grade written to console.
|
||||||
|
BIN
docs/index.html
BIN
docs/index.html
Binary file not shown.
@@ -60,7 +60,7 @@ function Test-MailboxAuditingE3_6.1.2_E3L1_IG1_IG2_IG3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($missingActions) {
|
if ($missingActions) {
|
||||||
$formattedActions = Format-MissingActions $missingActions
|
$formattedActions = Format-MissingAction $missingActions
|
||||||
$allFailures += "$userUPN`: AuditEnabled - True; $formattedActions"
|
$allFailures += "$userUPN`: AuditEnabled - True; $formattedActions"
|
||||||
}
|
}
|
||||||
# Mark the user as processed
|
# Mark the user as processed
|
||||||
@@ -83,7 +83,7 @@ function Test-MailboxAuditingE3_6.1.2_E3L1_IG1_IG2_IG3 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Format-MissingActions {
|
function Format-MissingAction {
|
||||||
param ([array]$missingActions)
|
param ([array]$missingActions)
|
||||||
|
|
||||||
$actionGroups = @{
|
$actionGroups = @{
|
||||||
|
@@ -60,7 +60,7 @@ function Test-MailboxAuditingE5_6.1.3_E5L1_IG1_IG2_IG3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($missingActions) {
|
if ($missingActions) {
|
||||||
$formattedActions = Format-MissingActions $missingActions
|
$formattedActions = Format-MissingAction $missingActions
|
||||||
$allFailures += "$userUPN`: AuditEnabled - True; $formattedActions"
|
$allFailures += "$userUPN`: AuditEnabled - True; $formattedActions"
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -92,7 +92,7 @@ function Test-MailboxAuditingE5_6.1.3_E5L1_IG1_IG2_IG3 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Format-MissingActions {
|
function Format-MissingAction {
|
||||||
param ([array]$missingActions)
|
param ([array]$missingActions)
|
||||||
|
|
||||||
$actionGroups = @{
|
$actionGroups = @{
|
||||||
|
@@ -11,13 +11,13 @@ function Connect-M365Suite {
|
|||||||
$VerbosePreference = "SilentlyContinue"
|
$VerbosePreference = "SilentlyContinue"
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ($RequiredConnections -contains "AzureAD" -or $RequiredConnections -contains "AzureAD | EXO") {
|
if ($RequiredConnections -contains "AzureAD" -or $RequiredConnections -contains "AzureAD | EXO" -or $RequiredConnections -contains "AzureAD | EXO | Microsoft Graph") {
|
||||||
Write-Host "Connecting to Azure Active Directory..." -ForegroundColor Cyan
|
Write-Host "Connecting to Azure Active Directory..." -ForegroundColor Cyan
|
||||||
Connect-AzureAD | Out-Null
|
Connect-AzureAD | Out-Null
|
||||||
Write-Host "Successfully connected to Azure Active Directory." -ForegroundColor Green
|
Write-Host "Successfully connected to Azure Active Directory." -ForegroundColor Green
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($RequiredConnections -contains "Microsoft Graph") {
|
if ($RequiredConnections -contains "Microsoft Graph" -or $RequiredConnections -contains "AzureAD | EXO | Microsoft Graph") {
|
||||||
Write-Host "Connecting to Microsoft Graph with scopes: Directory.Read.All, Domain.Read.All, Policy.Read.All, Organization.Read.All" -ForegroundColor Cyan
|
Write-Host "Connecting to Microsoft Graph with scopes: Directory.Read.All, Domain.Read.All, Policy.Read.All, Organization.Read.All" -ForegroundColor Cyan
|
||||||
try {
|
try {
|
||||||
Connect-MgGraph -Scopes "Directory.Read.All", "Domain.Read.All", "Policy.Read.All", "Organization.Read.All" -NoWelcome | Out-Null
|
Connect-MgGraph -Scopes "Directory.Read.All", "Domain.Read.All", "Policy.Read.All", "Organization.Read.All" -NoWelcome | Out-Null
|
||||||
@@ -30,7 +30,7 @@ function Connect-M365Suite {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($RequiredConnections -contains "EXO" -or $RequiredConnections -contains "AzureAD | EXO" -or $RequiredConnections -contains "Microsoft Teams | EXO") {
|
if ($RequiredConnections -contains "EXO" -or $RequiredConnections -contains "AzureAD | EXO" -or $RequiredConnections -contains "Microsoft Teams | EXO" -or $RequiredConnections -contains "AzureAD | EXO | Microsoft Graph") {
|
||||||
Write-Host "Connecting to Exchange Online..." -ForegroundColor Cyan
|
Write-Host "Connecting to Exchange Online..." -ForegroundColor Cyan
|
||||||
Connect-ExchangeOnline | Out-Null
|
Connect-ExchangeOnline | Out-Null
|
||||||
Write-Host "Successfully connected to Exchange Online." -ForegroundColor Green
|
Write-Host "Successfully connected to Exchange Online." -ForegroundColor Green
|
||||||
|
25
source/Private/Format-MissingAction.ps1
Normal file
25
source/Private/Format-MissingAction.ps1
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
function Format-MissingAction {
|
||||||
|
param ([array]$missingActions)
|
||||||
|
|
||||||
|
$actionGroups = @{
|
||||||
|
"Admin" = @()
|
||||||
|
"Delegate" = @()
|
||||||
|
"Owner" = @()
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($action in $missingActions) {
|
||||||
|
if ($action -match "(Admin|Delegate|Owner) action '([^']+)' missing") {
|
||||||
|
$type = $matches[1]
|
||||||
|
$actionName = $matches[2]
|
||||||
|
$actionGroups[$type] += $actionName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$formattedResults = @{
|
||||||
|
Admin = $actionGroups["Admin"] -join ', '
|
||||||
|
Delegate = $actionGroups["Delegate"] -join ', '
|
||||||
|
Owner = $actionGroups["Owner"] -join ', '
|
||||||
|
}
|
||||||
|
|
||||||
|
return $formattedResults
|
||||||
|
}
|
22
source/Private/Get-MostCommonWord.ps1
Normal file
22
source/Private/Get-MostCommonWord.ps1
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
function Get-MostCommonWord {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string[]]$InputStrings
|
||||||
|
)
|
||||||
|
|
||||||
|
# Combine all strings into one large string
|
||||||
|
$allText = $InputStrings -join ' '
|
||||||
|
|
||||||
|
# Split the large string into words
|
||||||
|
$words = $allText -split '\s+'
|
||||||
|
|
||||||
|
# Group words and count occurrences
|
||||||
|
$wordGroups = $words | Group-Object | Sort-Object Count -Descending
|
||||||
|
|
||||||
|
# Return the most common word if it occurs at least 3 times
|
||||||
|
if ($wordGroups.Count -gt 0 -and $wordGroups[0].Count -ge 3) {
|
||||||
|
return $wordGroups[0].Name
|
||||||
|
} else {
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
}
|
37
source/Private/Get-RequiredModule.ps1
Normal file
37
source/Private/Get-RequiredModule.ps1
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
function Get-RequiredModule {
|
||||||
|
[CmdletBinding(DefaultParameterSetName = 'AuditFunction')]
|
||||||
|
[OutputType([System.Object[]])]
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true, ParameterSetName = 'AuditFunction')]
|
||||||
|
[switch]$AuditFunction,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true, ParameterSetName = 'SyncFunction')]
|
||||||
|
[switch]$SyncFunction
|
||||||
|
)
|
||||||
|
|
||||||
|
switch ($PSCmdlet.ParameterSetName) {
|
||||||
|
'AuditFunction' {
|
||||||
|
return @(
|
||||||
|
@{ ModuleName = "ExchangeOnlineManagement"; RequiredVersion = "3.3.0" },
|
||||||
|
@{ ModuleName = "AzureAD"; RequiredVersion = "2.0.2.182" },
|
||||||
|
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModuleName = "Authentication" },
|
||||||
|
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModuleName = "Users" },
|
||||||
|
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModuleName = "Groups" },
|
||||||
|
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModuleName = "DirectoryObjects" },
|
||||||
|
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModuleName = "Domains" },
|
||||||
|
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModuleName = "Reports" },
|
||||||
|
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModuleName = "Mail" },
|
||||||
|
@{ ModuleName = "Microsoft.Online.SharePoint.PowerShell"; RequiredVersion = "16.0.24009.12000" },
|
||||||
|
@{ ModuleName = "MicrosoftTeams"; RequiredVersion = "5.5.0" }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
'SyncFunction' {
|
||||||
|
return @(
|
||||||
|
@{ ModuleName = "ImportExcel"; RequiredVersion = "7.8.9" }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
throw "Please specify either -AuditFunction or -SyncFunction switch."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,19 +1,23 @@
|
|||||||
function Initialize-CISAuditResult {
|
function Initialize-CISAuditResult {
|
||||||
|
[CmdletBinding()]
|
||||||
param (
|
param (
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true)]
|
||||||
[string]$Rec,
|
[string]$Rec,
|
||||||
|
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true, ParameterSetName = 'Full')]
|
||||||
[bool]$Result,
|
[bool]$Result,
|
||||||
|
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true, ParameterSetName = 'Full')]
|
||||||
[string]$Status,
|
[string]$Status,
|
||||||
|
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true, ParameterSetName = 'Full')]
|
||||||
[string]$Details,
|
[string]$Details,
|
||||||
|
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true, ParameterSetName = 'Full')]
|
||||||
[string]$FailureReason
|
[string]$FailureReason,
|
||||||
|
|
||||||
|
[Parameter(ParameterSetName = 'Error')]
|
||||||
|
[switch]$Failure
|
||||||
)
|
)
|
||||||
|
|
||||||
# Import the test definitions CSV file
|
# Import the test definitions CSV file
|
||||||
@@ -22,6 +26,10 @@ function Initialize-CISAuditResult {
|
|||||||
# Find the row that matches the provided recommendation (Rec)
|
# Find the row that matches the provided recommendation (Rec)
|
||||||
$testDefinition = $testDefinitions | Where-Object { $_.Rec -eq $Rec }
|
$testDefinition = $testDefinitions | Where-Object { $_.Rec -eq $Rec }
|
||||||
|
|
||||||
|
if (-not $testDefinition) {
|
||||||
|
throw "Test definition for recommendation '$Rec' not found."
|
||||||
|
}
|
||||||
|
|
||||||
# Create an instance of CISAuditResult and populate it
|
# Create an instance of CISAuditResult and populate it
|
||||||
$auditResult = [CISAuditResult]::new()
|
$auditResult = [CISAuditResult]::new()
|
||||||
$auditResult.Rec = $Rec
|
$auditResult.Rec = $Rec
|
||||||
@@ -36,10 +44,18 @@ function Initialize-CISAuditResult {
|
|||||||
$auditResult.Automated = [bool]::Parse($testDefinition.Automated)
|
$auditResult.Automated = [bool]::Parse($testDefinition.Automated)
|
||||||
$auditResult.Connection = $testDefinition.Connection
|
$auditResult.Connection = $testDefinition.Connection
|
||||||
$auditResult.CISControlVer = 'v8'
|
$auditResult.CISControlVer = 'v8'
|
||||||
|
|
||||||
|
if ($PSCmdlet.ParameterSetName -eq 'Full') {
|
||||||
$auditResult.Result = $Result
|
$auditResult.Result = $Result
|
||||||
$auditResult.Status = $Status
|
$auditResult.Status = $Status
|
||||||
$auditResult.Details = $Details
|
$auditResult.Details = $Details
|
||||||
$auditResult.FailureReason = $FailureReason
|
$auditResult.FailureReason = $FailureReason
|
||||||
|
} elseif ($PSCmdlet.ParameterSetName -eq 'Error') {
|
||||||
|
$auditResult.Result = $false
|
||||||
|
$auditResult.Status = 'Fail'
|
||||||
|
$auditResult.Details = "An error occurred while processing the test."
|
||||||
|
$auditResult.FailureReason = "Initialization error: Failed to process the test."
|
||||||
|
}
|
||||||
|
|
||||||
return $auditResult
|
return $auditResult
|
||||||
}
|
}
|
||||||
|
34
source/Private/Invoke-TestFunction.ps1
Normal file
34
source/Private/Invoke-TestFunction.ps1
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
function Invoke-TestFunction {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[PSObject]$FunctionFile,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[string]$DomainName
|
||||||
|
)
|
||||||
|
|
||||||
|
$functionName = $FunctionFile.BaseName
|
||||||
|
$functionCmd = Get-Command -Name $functionName
|
||||||
|
|
||||||
|
# Check if the test function needs DomainName parameter
|
||||||
|
$paramList = @{}
|
||||||
|
if ('DomainName' -in $functionCmd.Parameters.Keys) {
|
||||||
|
$paramList.DomainName = $DomainName
|
||||||
|
}
|
||||||
|
|
||||||
|
# Use splatting to pass parameters
|
||||||
|
Write-Verbose "Running $functionName..."
|
||||||
|
try {
|
||||||
|
$result = & $functionName @paramList
|
||||||
|
# Assuming each function returns an array of CISAuditResult or a single CISAuditResult
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Test = $functionName; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $functionName -Failure
|
||||||
|
return $auditResult
|
||||||
|
}
|
||||||
|
}
|
31
source/Private/Measure-AuditResult.ps1
Normal file
31
source/Private/Measure-AuditResult.ps1
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
function Measure-AuditResult {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[System.Collections.ArrayList]$AllAuditResults,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $false)]
|
||||||
|
[System.Collections.ArrayList]$FailedTests
|
||||||
|
)
|
||||||
|
|
||||||
|
# Calculate the total number of tests
|
||||||
|
$totalTests = $AllAuditResults.Count
|
||||||
|
|
||||||
|
# Calculate the number of passed tests
|
||||||
|
$passedTests = $AllAuditResults.ToArray() | Where-Object { $_.Result -eq $true } | Measure-Object | Select-Object -ExpandProperty Count
|
||||||
|
|
||||||
|
# Calculate the pass percentage
|
||||||
|
$passPercentage = if ($totalTests -eq 0) { 0 } else { [math]::Round(($passedTests / $totalTests) * 100, 2) }
|
||||||
|
|
||||||
|
# Display the pass percentage to the user
|
||||||
|
Write-Host "Audit completed. $passedTests out of $totalTests tests passed." -ForegroundColor Cyan
|
||||||
|
Write-Host "Your passing percentage is $passPercentage%."
|
||||||
|
|
||||||
|
# Display details of failed tests
|
||||||
|
if ($FailedTests.Count -gt 0) {
|
||||||
|
Write-Host "The following tests failed to complete:" -ForegroundColor Red
|
||||||
|
foreach ($failedTest in $FailedTests) {
|
||||||
|
Write-Host "Test: $($failedTest.Test)" -ForegroundColor Yellow
|
||||||
|
Write-Host "Error: $($failedTest.Error)" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
function Merge-CISExcelAndCsvData {
|
function Merge-CISExcelAndCsvData {
|
||||||
[CmdletBinding()]
|
[CmdletBinding(DefaultParameterSetName = 'CsvInput')]
|
||||||
param (
|
param (
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true)]
|
||||||
[string]$ExcelPath,
|
[string]$ExcelPath,
|
||||||
@@ -7,36 +7,31 @@ function Merge-CISExcelAndCsvData {
|
|||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true)]
|
||||||
[string]$WorksheetName,
|
[string]$WorksheetName,
|
||||||
|
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true, ParameterSetName = 'CsvInput')]
|
||||||
[string]$CsvPath
|
[string]$CsvPath,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true, ParameterSetName = 'ObjectInput')]
|
||||||
|
[CISAuditResult[]]$AuditResults
|
||||||
)
|
)
|
||||||
|
|
||||||
process {
|
process {
|
||||||
# Import data from Excel and CSV
|
# Import data from Excel
|
||||||
$import = Import-Excel -Path $ExcelPath -WorksheetName $WorksheetName
|
$import = Import-Excel -Path $ExcelPath -WorksheetName $WorksheetName
|
||||||
$csvData = Import-Csv -Path $CsvPath
|
|
||||||
|
|
||||||
# Define a function to create a merged object
|
# Import data from CSV or use provided object
|
||||||
function CreateMergedObject($excelItem, $csvRow) {
|
$csvData = if ($PSCmdlet.ParameterSetName -eq 'CsvInput') {
|
||||||
$newObject = New-Object PSObject
|
Import-Csv -Path $CsvPath
|
||||||
|
} else {
|
||||||
foreach ($property in $excelItem.PSObject.Properties) {
|
$AuditResults
|
||||||
$newObject | Add-Member -MemberType NoteProperty -Name $property.Name -Value $property.Value
|
|
||||||
}
|
|
||||||
$newObject | Add-Member -MemberType NoteProperty -Name 'CSV_Connection' -Value $csvRow.Connection
|
|
||||||
$newObject | Add-Member -MemberType NoteProperty -Name 'CSV_Status' -Value $csvRow.Status
|
|
||||||
$newObject | Add-Member -MemberType NoteProperty -Name 'CSV_Details' -Value $csvRow.Details
|
|
||||||
$newObject | Add-Member -MemberType NoteProperty -Name 'CSV_FailureReason' -Value $csvRow.FailureReason
|
|
||||||
return $newObject
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Iterate over each item in the imported Excel object and merge with CSV data
|
# Iterate over each item in the imported Excel object and merge with CSV data or audit results
|
||||||
$mergedData = foreach ($item in $import) {
|
$mergedData = foreach ($item in $import) {
|
||||||
$csvRow = $csvData | Where-Object { $_.Rec -eq $item.'recommendation #' }
|
$csvRow = $csvData | Where-Object { $_.Rec -eq $item.'recommendation #' }
|
||||||
if ($csvRow) {
|
if ($csvRow) {
|
||||||
CreateMergedObject -excelItem $item -csvRow $csvRow
|
New-MergedObject -ExcelItem $item -CsvRow $csvRow
|
||||||
} else {
|
} else {
|
||||||
CreateMergedObject -excelItem $item -csvRow ([PSCustomObject]@{Connection=$null;Status=$null; Details=$null; FailureReason=$null })
|
New-MergedObject -ExcelItem $item -CsvRow ([PSCustomObject]@{Connection=$null;Status=$null; Details=$null; FailureReason=$null })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
source/Private/New-MergedObject.ps1
Normal file
20
source/Private/New-MergedObject.ps1
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
function New-MergedObject {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[psobject]$ExcelItem,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true)]
|
||||||
|
[psobject]$CsvRow
|
||||||
|
)
|
||||||
|
|
||||||
|
$newObject = New-Object PSObject
|
||||||
|
|
||||||
|
foreach ($property in $ExcelItem.PSObject.Properties) {
|
||||||
|
$newObject | Add-Member -MemberType NoteProperty -Name $property.Name -Value $property.Value
|
||||||
|
}
|
||||||
|
$newObject | Add-Member -MemberType NoteProperty -Name 'CSV_Connection' -Value $CsvRow.Connection
|
||||||
|
$newObject | Add-Member -MemberType NoteProperty -Name 'CSV_Status' -Value $CsvRow.Status
|
||||||
|
$newObject | Add-Member -MemberType NoteProperty -Name 'CSV_Details' -Value $CsvRow.Details
|
||||||
|
$newObject | Add-Member -MemberType NoteProperty -Name 'CSV_FailureReason' -Value $CsvRow.FailureReason
|
||||||
|
return $newObject
|
||||||
|
}
|
@@ -25,7 +25,7 @@ function Update-CISExcelWorksheet {
|
|||||||
|
|
||||||
|
|
||||||
# Update the worksheet with the provided data
|
# Update the worksheet with the provided data
|
||||||
Update-WorksheetCells -Worksheet $worksheet -Data $Data -StartingRowIndex $StartingRowIndex
|
Update-WorksheetCell -Worksheet $worksheet -Data $Data -StartingRowIndex $StartingRowIndex
|
||||||
|
|
||||||
# Save and close the Excel package
|
# Save and close the Excel package
|
||||||
Close-ExcelPackage $excelPackage
|
Close-ExcelPackage $excelPackage
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
function Update-WorksheetCells {
|
function Update-WorksheetCell {
|
||||||
param (
|
param (
|
||||||
$Worksheet,
|
$Worksheet,
|
||||||
$Data,
|
$Data,
|
@@ -25,6 +25,8 @@
|
|||||||
https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Get-AdminRoleUserLicense
|
https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Get-AdminRoleUserLicense
|
||||||
#>
|
#>
|
||||||
function Get-AdminRoleUserLicense {
|
function Get-AdminRoleUserLicense {
|
||||||
|
# Set output type to System.Collections.ArrayList
|
||||||
|
[OutputType([System.Collections.ArrayList])]
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param (
|
param (
|
||||||
[Parameter(Mandatory = $false)]
|
[Parameter(Mandatory = $false)]
|
||||||
|
@@ -63,10 +63,12 @@ function Invoke-M365SecurityAudit {
|
|||||||
[CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = 'Default')]
|
[CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = 'Default')]
|
||||||
[OutputType([CISAuditResult[]])]
|
[OutputType([CISAuditResult[]])]
|
||||||
param (
|
param (
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true, HelpMessage = "The SharePoint tenant admin URL, which should end with '-admin.sharepoint.com'.")]
|
||||||
|
[ValidatePattern('^https://[a-zA-Z0-9-]+-admin\.sharepoint\.com$')]
|
||||||
[string]$TenantAdminUrl,
|
[string]$TenantAdminUrl,
|
||||||
|
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true, HelpMessage = "The domain name of your organization, e.g., 'example.com'.")]
|
||||||
|
[ValidatePattern('^[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$')]
|
||||||
[string]$DomainName,
|
[string]$DomainName,
|
||||||
|
|
||||||
# E-Level with optional ProfileLevel selection
|
# E-Level with optional ProfileLevel selection
|
||||||
@@ -120,43 +122,23 @@ function Invoke-M365SecurityAudit {
|
|||||||
[switch]$NoModuleCheck
|
[switch]$NoModuleCheck
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Begin {
|
Begin {
|
||||||
if ($script:MaximumFunctionCount -lt 8192) {
|
if ($script:MaximumFunctionCount -lt 8192) {
|
||||||
$script:MaximumFunctionCount = 8192
|
$script:MaximumFunctionCount = 8192
|
||||||
}
|
}
|
||||||
# Ensure required modules are installed
|
# Ensure required modules are installed
|
||||||
# Define the required modules and versions in a hashtable
|
|
||||||
if (!($NoModuleCheck)) {
|
if (!($NoModuleCheck)) {
|
||||||
$requiredModules = @(
|
$requiredModules = Get-RequiredModule -AuditFunction
|
||||||
@{ ModuleName = "ExchangeOnlineManagement"; RequiredVersion = "3.3.0" },
|
|
||||||
@{ ModuleName = "AzureAD"; RequiredVersion = "2.0.2.182" },
|
|
||||||
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModuleName = "Authentication" },
|
|
||||||
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModuleName = "Users" },
|
|
||||||
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModuleName = "Groups" },
|
|
||||||
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModuleName = "DirectoryObjects" },
|
|
||||||
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModuleName = "Domains" },
|
|
||||||
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModuleName = "Reports" },
|
|
||||||
@{ ModuleName = "Microsoft.Graph"; RequiredVersion = "2.4.0"; SubModuleName = "Mail" },
|
|
||||||
@{ ModuleName = "Microsoft.Online.SharePoint.PowerShell"; RequiredVersion = "16.0.24009.12000" },
|
|
||||||
@{ ModuleName = "MicrosoftTeams"; RequiredVersion = "5.5.0" }
|
|
||||||
)
|
|
||||||
foreach ($module in $requiredModules) {
|
foreach ($module in $requiredModules) {
|
||||||
Assert-ModuleAvailability -ModuleName $module.ModuleName -RequiredVersion $module.RequiredVersion -SubModuleName $module.SubModuleName
|
Assert-ModuleAvailability -ModuleName $module.ModuleName -RequiredVersion $module.RequiredVersion -SubModuleName $module.SubModuleName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Loop through each required module and assert its availability
|
|
||||||
|
|
||||||
# Establishing connections
|
|
||||||
|
|
||||||
# Load test definitions from CSV
|
# Load test definitions from CSV
|
||||||
$testDefinitionsPath = Join-Path -Path $PSScriptRoot -ChildPath "helper\TestDefinitions.csv"
|
$testDefinitionsPath = Join-Path -Path $PSScriptRoot -ChildPath "helper\TestDefinitions.csv"
|
||||||
$testDefinitions = Import-Csv -Path $testDefinitionsPath
|
$testDefinitions = Import-Csv -Path $testDefinitionsPath
|
||||||
# Load the Test Definitions into the script scope for use in other functions
|
# Load the Test Definitions into the script scope for use in other functions
|
||||||
$script:TestDefinitionsObject = $testDefinitions
|
$script:TestDefinitionsObject = $testDefinitions
|
||||||
|
|
||||||
# Apply filters based on parameter sets
|
# Apply filters based on parameter sets
|
||||||
$params = @{
|
$params = @{
|
||||||
TestDefinitions = $testDefinitions
|
TestDefinitions = $testDefinitions
|
||||||
@@ -167,58 +149,54 @@ function Invoke-M365SecurityAudit {
|
|||||||
SkipRecommendation = $SkipRecommendation
|
SkipRecommendation = $SkipRecommendation
|
||||||
}
|
}
|
||||||
$testDefinitions = Get-TestDefinitionsObject @params
|
$testDefinitions = Get-TestDefinitionsObject @params
|
||||||
# End switch ($PSCmdlet.ParameterSetName)
|
|
||||||
# Extract unique connections needed
|
# Extract unique connections needed
|
||||||
$requiredConnections = $testDefinitions.Connection | Sort-Object -Unique
|
$requiredConnections = $testDefinitions.Connection | Sort-Object -Unique
|
||||||
|
|
||||||
# Establishing connections if required
|
# Establishing connections if required
|
||||||
if (!($DoNotConnect)) {
|
if (!($DoNotConnect)) {
|
||||||
Connect-M365Suite -TenantAdminUrl $TenantAdminUrl -RequiredConnections $requiredConnections
|
Connect-M365Suite -TenantAdminUrl $TenantAdminUrl -RequiredConnections $requiredConnections
|
||||||
}
|
}
|
||||||
# Determine which test files to load based on filtering
|
# Determine which test files to load based on filtering
|
||||||
$testsToLoad = $testDefinitions.TestFileName | ForEach-Object { $_ -replace '.ps1$', '' }
|
$testsToLoad = $testDefinitions.TestFileName | ForEach-Object { $_ -replace '.ps1$', '' }
|
||||||
|
|
||||||
# Display the tests that would be loaded if the function is called with -WhatIf
|
|
||||||
|
|
||||||
Write-Verbose "The $(($testsToLoad).count) test/s that would be loaded based on filter criteria:"
|
Write-Verbose "The $(($testsToLoad).count) test/s that would be loaded based on filter criteria:"
|
||||||
$testsToLoad | ForEach-Object { Write-Verbose " $_" }
|
$testsToLoad | ForEach-Object { Write-Verbose " $_" }
|
||||||
|
# Initialize a collection to hold failed test details
|
||||||
|
$script:FailedTests = [System.Collections.ArrayList]::new()
|
||||||
} # End Begin
|
} # End Begin
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
$allAuditResults = [System.Collections.ArrayList]::new() #@() # 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
|
# Dynamically dot-source the test scripts
|
||||||
$testsFolderPath = Join-Path -Path $PSScriptRoot -ChildPath "tests"
|
$testsFolderPath = Join-Path -Path $PSScriptRoot -ChildPath "tests"
|
||||||
$testFiles = Get-ChildItem -Path $testsFolderPath -Filter "Test-*.ps1" |
|
$testFiles = Get-ChildItem -Path $testsFolderPath -Filter "Test-*.ps1" |
|
||||||
Where-Object { $testsToLoad -contains $_.BaseName }
|
Where-Object { $testsToLoad -contains $_.BaseName }
|
||||||
|
|
||||||
|
$totalTests = $testFiles.Count
|
||||||
|
$currentTestIndex = 0
|
||||||
|
|
||||||
# Import the test functions
|
# Import the test functions
|
||||||
$testFiles | ForEach-Object {
|
$testFiles | ForEach-Object {
|
||||||
|
$currentTestIndex++
|
||||||
|
Write-Progress -Activity "Loading Test Scripts" -Status "Loading $($currentTestIndex) of $($totalTests): $($_.Name)" -PercentComplete (($currentTestIndex / $totalTests) * 100)
|
||||||
Try {
|
Try {
|
||||||
|
# Dot source the test function
|
||||||
. $_.FullName
|
. $_.FullName
|
||||||
}
|
}
|
||||||
Catch {
|
Catch {
|
||||||
|
# Log the error and add the test to the failed tests collection
|
||||||
Write-Error "Failed to load test function $($_.Name): $_"
|
Write-Error "Failed to load test function $($_.Name): $_"
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Test = $_.Name; Error = $_ })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$currentTestIndex = 0
|
||||||
# Execute each test function from the prepared list
|
# Execute each test function from the prepared list
|
||||||
foreach ($testFunction in $testFiles) {
|
foreach ($testFunction in $testFiles) {
|
||||||
|
$currentTestIndex++
|
||||||
|
Write-Progress -Activity "Executing Tests" -Status "Executing $($currentTestIndex) of $($totalTests): $($testFunction.Name)" -PercentComplete (($currentTestIndex / $totalTests) * 100)
|
||||||
$functionName = $testFunction.BaseName
|
$functionName = $testFunction.BaseName
|
||||||
$functionCmd = Get-Command -Name $functionName
|
|
||||||
|
|
||||||
# Check if the test function needs DomainName parameter
|
|
||||||
$paramList = @{}
|
|
||||||
if ('DomainName' -in $functionCmd.Parameters.Keys) {
|
|
||||||
$paramList.DomainName = $DomainName
|
|
||||||
}
|
|
||||||
|
|
||||||
# Use splatting to pass parameters
|
|
||||||
if ($PSCmdlet.ShouldProcess($functionName, "Execute test")) {
|
if ($PSCmdlet.ShouldProcess($functionName, "Execute test")) {
|
||||||
Write-Host "Running $functionName..."
|
$auditResult = Invoke-TestFunction -FunctionFile $testFunction -DomainName $DomainName
|
||||||
$result = & $functionName @paramList
|
# Add the result to the collection
|
||||||
# Assuming each function returns an array of CISAuditResult or a single CISAuditResult
|
[void]$allAuditResults.Add($auditResult)
|
||||||
[void]($allAuditResults.add($Result))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,20 +206,10 @@ function Invoke-M365SecurityAudit {
|
|||||||
# Clean up sessions
|
# Clean up sessions
|
||||||
Disconnect-M365Suite -RequiredConnections $requiredConnections
|
Disconnect-M365Suite -RequiredConnections $requiredConnections
|
||||||
}
|
}
|
||||||
# Calculate the total number of tests
|
# Call the private function to calculate and display results
|
||||||
$totalTests = $allAuditResults.Count
|
Measure-AuditResult -AllAuditResults $allAuditResults -FailedTests $script:FailedTests
|
||||||
|
|
||||||
# Calculate the number of passed tests
|
|
||||||
$passedTests = $allAuditResults.ToArray() | Where-Object { $_.Result -eq $true } | Measure-Object | Select-Object -ExpandProperty Count
|
|
||||||
|
|
||||||
# Calculate the pass percentage
|
|
||||||
$passPercentage = if ($totalTests -eq 0) { 0 } else { [math]::Round(($passedTests / $totalTests) * 100, 2) }
|
|
||||||
|
|
||||||
# Display the pass percentage to the user
|
|
||||||
Write-Host "Audit completed. $passedTests out of $totalTests tests passed." -ForegroundColor Cyan
|
|
||||||
Write-Host "Your passing percentage is $passPercentage%."
|
|
||||||
# Return all collected audit results
|
# Return all collected audit results
|
||||||
return $allAuditResults.ToArray()
|
return $allAuditResults.ToArray() | Sort-Object -Property Rec
|
||||||
# Check if the Disconnect switch is present
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,14 +1,16 @@
|
|||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Synchronizes data between an Excel file and a CSV file and optionally updates the Excel worksheet.
|
Synchronizes data between an Excel file and either a CSV file or an output object from Invoke-M365SecurityAudit, and optionally updates the Excel worksheet.
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
The Sync-CISExcelAndCsvData function merges data from a specified Excel file and a CSV file based on a common key. It can also update the Excel worksheet with the merged data. This function is particularly useful for updating Excel records with additional data from a CSV file while preserving the original formatting and structure of the Excel worksheet.
|
The Sync-CISExcelAndCsvData function merges data from a specified Excel file with data from either a CSV file or an output object from Invoke-M365SecurityAudit based on a common key. It can also update the Excel worksheet with the merged data. This function is particularly useful for updating Excel records with additional data from a CSV file or audit results while preserving the original formatting and structure of the Excel worksheet.
|
||||||
.PARAMETER ExcelPath
|
.PARAMETER ExcelPath
|
||||||
The path to the Excel file that contains the original data. This parameter is mandatory.
|
The path to the Excel file that contains the original data. This parameter is mandatory.
|
||||||
.PARAMETER WorksheetName
|
.PARAMETER WorksheetName
|
||||||
The name of the worksheet within the Excel file that contains the data to be synchronized. This parameter is mandatory.
|
The name of the worksheet within the Excel file that contains the data to be synchronized. This parameter is mandatory.
|
||||||
.PARAMETER CsvPath
|
.PARAMETER CsvPath
|
||||||
The path to the CSV file containing data to be merged with the Excel data. This parameter is mandatory.
|
The path to the CSV file containing data to be merged with the Excel data. This parameter is mandatory when using the CsvInput parameter set.
|
||||||
|
.PARAMETER AuditResults
|
||||||
|
An array of CISAuditResult objects from Invoke-M365SecurityAudit to be merged with the Excel data. This parameter is mandatory when using the ObjectInput parameter set.
|
||||||
.PARAMETER SkipUpdate
|
.PARAMETER SkipUpdate
|
||||||
If specified, the function will return the merged data object without updating the Excel worksheet. This is useful for previewing the merged data.
|
If specified, the function will return the merged data object without updating the Excel worksheet. This is useful for previewing the merged data.
|
||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
@@ -17,6 +19,14 @@
|
|||||||
.EXAMPLE
|
.EXAMPLE
|
||||||
PS> $mergedData = Sync-CISExcelAndCsvData -ExcelPath "path\to\excel.xlsx" -WorksheetName "DataSheet" -CsvPath "path\to\data.csv" -SkipUpdate
|
PS> $mergedData = Sync-CISExcelAndCsvData -ExcelPath "path\to\excel.xlsx" -WorksheetName "DataSheet" -CsvPath "path\to\data.csv" -SkipUpdate
|
||||||
Retrieves the merged data object for preview without updating the Excel worksheet.
|
Retrieves the merged data object for preview without updating the Excel worksheet.
|
||||||
|
.EXAMPLE
|
||||||
|
PS> $auditResults = Invoke-M365SecurityAudit -TenantAdminUrl "https://tenant-admin.url" -DomainName "example.com"
|
||||||
|
PS> Sync-CISExcelAndCsvData -ExcelPath "path\to\excel.xlsx" -WorksheetName "DataSheet" -AuditResults $auditResults
|
||||||
|
Merges data from the audit results into 'excel.xlsx' on the 'DataSheet' worksheet and updates the worksheet with the merged data.
|
||||||
|
.EXAMPLE
|
||||||
|
PS> $auditResults = Invoke-M365SecurityAudit -TenantAdminUrl "https://tenant-admin.url" -DomainName "example.com"
|
||||||
|
PS> $mergedData = Sync-CISExcelAndCsvData -ExcelPath "path\to\excel.xlsx" -WorksheetName "DataSheet" -AuditResults $auditResults -SkipUpdate
|
||||||
|
Retrieves the merged data object for preview without updating the Excel worksheet.
|
||||||
.INPUTS
|
.INPUTS
|
||||||
None. You cannot pipe objects to Sync-CISExcelAndCsvData.
|
None. You cannot pipe objects to Sync-CISExcelAndCsvData.
|
||||||
.OUTPUTS
|
.OUTPUTS
|
||||||
@@ -30,25 +40,41 @@
|
|||||||
https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Sync-CISExcelAndCsvData
|
https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Sync-CISExcelAndCsvData
|
||||||
#>
|
#>
|
||||||
|
|
||||||
|
|
||||||
function Sync-CISExcelAndCsvData {
|
function Sync-CISExcelAndCsvData {
|
||||||
[CmdletBinding()]
|
[CmdletBinding(DefaultParameterSetName = 'CsvInput')]
|
||||||
param (
|
param (
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true)]
|
||||||
|
[ValidateScript({ Test-Path $_ })]
|
||||||
[string]$ExcelPath,
|
[string]$ExcelPath,
|
||||||
|
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true)]
|
||||||
[string]$WorksheetName,
|
[string]$WorksheetName,
|
||||||
|
|
||||||
[Parameter(Mandatory = $true)]
|
[Parameter(Mandatory = $true, ParameterSetName = 'CsvInput')]
|
||||||
|
[ValidateScript({ Test-Path $_ })]
|
||||||
[string]$CsvPath,
|
[string]$CsvPath,
|
||||||
|
|
||||||
|
[Parameter(Mandatory = $true, ParameterSetName = 'ObjectInput')]
|
||||||
|
[CISAuditResult[]]$AuditResults,
|
||||||
|
|
||||||
[Parameter(Mandatory = $false)]
|
[Parameter(Mandatory = $false)]
|
||||||
[switch]$SkipUpdate
|
[switch]$SkipUpdate
|
||||||
)
|
)
|
||||||
|
|
||||||
process {
|
process {
|
||||||
# Merge Excel and CSV data
|
# Verify ImportExcel module is available
|
||||||
|
$requiredModules = Get-RequiredModule -SyncFunction
|
||||||
|
foreach ($module in $requiredModules) {
|
||||||
|
Assert-ModuleAvailability -ModuleName $module.ModuleName -RequiredVersion $module.RequiredVersion -SubModuleName $module.SubModuleName
|
||||||
|
}
|
||||||
|
|
||||||
|
# Merge Excel and CSV data or Audit Results
|
||||||
|
if ($PSCmdlet.ParameterSetName -eq 'CsvInput') {
|
||||||
$mergedData = Merge-CISExcelAndCsvData -ExcelPath $ExcelPath -WorksheetName $WorksheetName -CsvPath $CsvPath
|
$mergedData = Merge-CISExcelAndCsvData -ExcelPath $ExcelPath -WorksheetName $WorksheetName -CsvPath $CsvPath
|
||||||
|
} else {
|
||||||
|
$mergedData = Merge-CISExcelAndCsvData -ExcelPath $ExcelPath -WorksheetName $WorksheetName -AuditResults $AuditResults
|
||||||
|
}
|
||||||
|
|
||||||
# Output the merged data if the user chooses to skip the update
|
# Output the merged data if the user chooses to skip the update
|
||||||
if ($SkipUpdate) {
|
if ($SkipUpdate) {
|
||||||
@@ -59,3 +85,5 @@ function Sync-CISExcelAndCsvData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -18,8 +18,8 @@
|
|||||||
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
|
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
|
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
|
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,AzureAD | EXO
|
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,AzureAD | EXO | Microsoft Graph
|
||||||
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,AzureAD | 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,AzureAD | EXO | Microsoft Graph
|
||||||
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
|
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
|
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
|
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
|
||||||
|
|
@@ -1,26 +1,43 @@
|
|||||||
function Test-AdministrativeAccountCompliance {
|
function Test-AdministrativeAccountCompliance {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
)
|
)
|
||||||
|
|
||||||
begin {
|
begin {
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
|
||||||
$validLicenses = @('AAD_PREMIUM', 'AAD_PREMIUM_P2')
|
$validLicenses = @('AAD_PREMIUM', 'AAD_PREMIUM_P2')
|
||||||
|
$recnum = "1.1.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
|
# Retrieve all necessary data outside the loops
|
||||||
$adminRoles = Get-MgRoleManagementDirectoryRoleDefinition | Where-Object { $_.DisplayName -like "*Admin*" }
|
$adminRoles = Get-MgRoleManagementDirectoryRoleDefinition | Where-Object { $_.DisplayName -like "*Admin*" }
|
||||||
|
$roleAssignments = Get-MgRoleManagementDirectoryRoleAssignment
|
||||||
|
$principalIds = $roleAssignments.PrincipalId | Select-Object -Unique
|
||||||
|
|
||||||
|
# Fetch user details using filter
|
||||||
|
$userDetailsList = @{}
|
||||||
|
$licensesList = @{}
|
||||||
|
|
||||||
|
$userDetails = Get-MgUser -Filter "id in ('$($principalIds -join "','")')" -Property "DisplayName, UserPrincipalName, Id, OnPremisesSyncEnabled" -ErrorAction SilentlyContinue
|
||||||
|
foreach ($user in $userDetails) {
|
||||||
|
$userDetailsList[$user.Id] = $user
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fetch user licenses for each unique principal ID
|
||||||
|
foreach ($principalId in $principalIds) {
|
||||||
|
$licensesList[$principalId] = Get-MgUserLicenseDetail -UserId $principalId -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
$adminRoleUsers = @()
|
$adminRoleUsers = @()
|
||||||
|
|
||||||
foreach ($role in $adminRoles) {
|
foreach ($role in $adminRoles) {
|
||||||
$roleAssignments = Get-MgRoleManagementDirectoryRoleAssignment -Filter "roleDefinitionId eq '$($role.Id)'"
|
foreach ($assignment in $roleAssignments | Where-Object { $_.RoleDefinitionId -eq $role.Id }) {
|
||||||
|
$userDetails = $userDetailsList[$assignment.PrincipalId]
|
||||||
foreach ($assignment in $roleAssignments) {
|
|
||||||
$userDetails = Get-MgUser -UserId $assignment.PrincipalId -Property "DisplayName, UserPrincipalName, Id, OnPremisesSyncEnabled" -ErrorAction SilentlyContinue
|
|
||||||
if ($userDetails) {
|
if ($userDetails) {
|
||||||
$licenses = Get-MgUserLicenseDetail -UserId $assignment.PrincipalId -ErrorAction SilentlyContinue
|
$licenses = $licensesList[$assignment.PrincipalId]
|
||||||
$licenseString = if ($licenses) { ($licenses.SkuPartNumber -join '|') } else { "No Licenses Found" }
|
$licenseString = if ($licenses) { ($licenses.SkuPartNumber -join '|') } else { "No Licenses Found" }
|
||||||
|
|
||||||
$adminRoleUsers += [PSCustomObject]@{
|
$adminRoleUsers += [PSCustomObject]@{
|
||||||
@@ -50,23 +67,27 @@ function Test-AdministrativeAccountCompliance {
|
|||||||
$failureReasons = $nonCompliantUsers | ForEach-Object {
|
$failureReasons = $nonCompliantUsers | ForEach-Object {
|
||||||
$accountType = if ($_.HybridUser) { "Hybrid" } else { "Cloud-Only" }
|
$accountType = if ($_.HybridUser) { "Hybrid" } else { "Cloud-Only" }
|
||||||
$missingLicenses = $validLicenses | Where-Object { $_ -notin ($_.Licenses -split '\|') }
|
$missingLicenses = $validLicenses | Where-Object { $_ -notin ($_.Licenses -split '\|') }
|
||||||
"$($_.UserName)|$($_.Roles)|$accountType|Missing: $($missingLicenses -join ',')"
|
"$($_.UserName)|$($_.Roles)|$accountType|$($missingLicenses -join ',')"
|
||||||
}
|
}
|
||||||
$failureReasons = $failureReasons -join "`n"
|
$failureReasons = $failureReasons -join "`n"
|
||||||
|
|
||||||
$details = if ($nonCompliantUsers) {
|
$details = if ($nonCompliantUsers) {
|
||||||
"Non-Compliant Accounts: $($nonCompliantUsers.Count)`nDetails:`n" + ($nonCompliantUsers | ForEach-Object { $_.UserName }) -join "`n"
|
"Non-compliant accounts: `nUsername | Roles | HybridStatus | Missing Licence`n$failureReasons"
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
"Compliant Accounts: $($uniqueAdminRoleUsers.Count)"
|
"Compliant Accounts: $($uniqueAdminRoleUsers.Count)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$failureReason = if ($nonCompliantUsers) {
|
||||||
|
"Non-Compliant Accounts: $($nonCompliantUsers.Count)`nDetails:`n" + ($nonCompliantUsers | ForEach-Object { $_.UserName }) -join "`n"
|
||||||
|
} else {
|
||||||
|
"N/A"
|
||||||
|
}
|
||||||
|
|
||||||
$result = $nonCompliantUsers.Count -eq 0
|
$result = $nonCompliantUsers.Count -eq 0
|
||||||
$status = if ($result) { 'Pass' } else { 'Fail' }
|
$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 = @{
|
$params = @{
|
||||||
Rec = "1.1.1"
|
Rec = $recnum
|
||||||
Result = $result
|
Result = $result
|
||||||
Status = $status
|
Status = $status
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -75,9 +96,18 @@ function Test-AdministrativeAccountCompliance {
|
|||||||
|
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
end {
|
end {
|
||||||
# Output the result
|
|
||||||
return $auditResult
|
return $auditResult
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-AntiPhishingPolicy {
|
function Test-AntiPhishingPolicy {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -10,9 +11,12 @@ function Test-AntiPhishingPolicy {
|
|||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
#$auditResults = @()
|
#$auditResults = @()
|
||||||
|
$recnum = "2.1.7"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
|
||||||
|
try {
|
||||||
# 2.1.7 Ensure that an anti-phishing policy has been created
|
# 2.1.7 Ensure that an anti-phishing policy has been created
|
||||||
|
|
||||||
# Retrieve and validate the anti-phishing policies
|
# Retrieve and validate the anti-phishing policies
|
||||||
@@ -61,7 +65,7 @@ function Test-AntiPhishingPolicy {
|
|||||||
|
|
||||||
# Parameter splat for Initialize-CISAuditResult function
|
# Parameter splat for Initialize-CISAuditResult function
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "2.1.7"
|
Rec = $recnum
|
||||||
Result = $nonCompliantItems.Count -eq 0
|
Result = $nonCompliantItems.Count -eq 0
|
||||||
Status = if ($isCompliant) { "Pass" } else { "Fail" }
|
Status = if ($isCompliant) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -71,6 +75,19 @@ function Test-AntiPhishingPolicy {
|
|||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return auditResult
|
# Return auditResult
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-AuditDisabledFalse {
|
function Test-AuditDisabledFalse {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
# Aligned
|
# Aligned
|
||||||
param (
|
param (
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -9,9 +10,12 @@ function Test-AuditDisabledFalse {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "6.1.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
|
||||||
|
try {
|
||||||
# 6.1.1 (L1) Ensure 'AuditDisabled' organizationally is set to 'False'
|
# 6.1.1 (L1) Ensure 'AuditDisabled' organizationally is set to 'False'
|
||||||
|
|
||||||
# Retrieve the AuditDisabled configuration
|
# Retrieve the AuditDisabled configuration
|
||||||
@@ -35,7 +39,7 @@ function Test-AuditDisabledFalse {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "6.1.1"
|
Rec = $recnum
|
||||||
Result = $auditNotDisabled
|
Result = $auditNotDisabled
|
||||||
Status = if ($auditNotDisabled) { "Pass" } else { "Fail" }
|
Status = if ($auditNotDisabled) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -43,6 +47,19 @@ function Test-AuditDisabledFalse {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-AuditLogSearch {
|
function Test-AuditLogSearch {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -9,9 +10,12 @@ function Test-AuditLogSearch {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "3.1.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
|
||||||
|
try {
|
||||||
# 3.1.1 (L1) Ensure Microsoft 365 audit log search is Enabled
|
# 3.1.1 (L1) Ensure Microsoft 365 audit log search is Enabled
|
||||||
|
|
||||||
# Retrieve the audit log configuration
|
# Retrieve the audit log configuration
|
||||||
@@ -35,14 +39,26 @@ function Test-AuditLogSearch {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "3.1.1"
|
Rec = $recnum
|
||||||
Result = $auditLogResult
|
Result = $auditLogResult
|
||||||
Status = if ($auditLogResult) { "Pass" } else { "Fail" }
|
Status = if ($auditLogResult) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
FailureReason = $failureReasons
|
FailureReason = $failureReasons
|
||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-BlockChannelEmails {
|
function Test-BlockChannelEmails {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added here if needed
|
# Parameters can be added here if needed
|
||||||
@@ -9,9 +10,12 @@ function Test-BlockChannelEmails {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "8.1.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
|
||||||
|
try {
|
||||||
# 8.1.2 (L1) Ensure users can't send emails to a channel email address
|
# 8.1.2 (L1) Ensure users can't send emails to a channel email address
|
||||||
|
|
||||||
# Retrieve Teams client configuration
|
# Retrieve Teams client configuration
|
||||||
@@ -35,7 +39,7 @@ function Test-BlockChannelEmails {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "8.1.2"
|
Rec = $recnum
|
||||||
Result = -not $allowEmailIntoChannel
|
Result = -not $allowEmailIntoChannel
|
||||||
Status = if (-not $allowEmailIntoChannel) { "Pass" } else { "Fail" }
|
Status = if (-not $allowEmailIntoChannel) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -43,6 +47,19 @@ function Test-BlockChannelEmails {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
function Test-BlockMailForwarding {
|
function Test-BlockMailForwarding {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned Compare
|
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -9,34 +9,59 @@ function Test-BlockMailForwarding {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "6.2.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 6.2.1 (L1) Ensure all forms of mail forwarding are blocked and/or disabled
|
# 6.2.1 (L1) Ensure all forms of mail forwarding are blocked and/or disabled
|
||||||
|
|
||||||
# Retrieve the transport rules that redirect messages
|
# Step 1: Retrieve the transport rules that redirect messages
|
||||||
$transportRules = Get-TransportRule | Where-Object { $null -ne $_.RedirectMessageTo }
|
$transportRules = Get-TransportRule | Where-Object { $null -ne $_.RedirectMessageTo }
|
||||||
$forwardingBlocked = $transportRules.Count -eq 0
|
$transportForwardingBlocked = $transportRules.Count -eq 0
|
||||||
|
|
||||||
|
# Step 2: Check all anti-spam outbound policies
|
||||||
|
$outboundSpamPolicies = Get-HostedOutboundSpamFilterPolicy
|
||||||
|
$nonCompliantSpamPolicies = $outboundSpamPolicies | Where-Object { $_.AutoForwardingMode -ne 'Off' }
|
||||||
|
$nonCompliantSpamPoliciesArray = @($nonCompliantSpamPolicies)
|
||||||
|
$spamForwardingBlocked = $nonCompliantSpamPoliciesArray.Count -eq 0
|
||||||
|
|
||||||
|
# Determine overall compliance
|
||||||
|
$forwardingBlocked = $transportForwardingBlocked -and $spamForwardingBlocked
|
||||||
|
|
||||||
# Prepare failure reasons and details based on compliance
|
# Prepare failure reasons and details based on compliance
|
||||||
$failureReasons = if ($transportRules.Count -gt 0) {
|
$failureReasons = @()
|
||||||
"Mail forwarding rules found: $($transportRules.Name -join ', ')"
|
$details = @()
|
||||||
|
|
||||||
|
if ($transportRules.Count -gt 0) {
|
||||||
|
$failureReasons += "Mail forwarding rules found: $($transportRules.Name -join ', ')"
|
||||||
|
$details += "Transport Rules Details:`nRule Name|Redirects To"
|
||||||
|
$details += $transportRules | ForEach-Object {
|
||||||
|
"$($_.Name)|$($_.RedirectMessageTo -join ', ')"
|
||||||
}
|
}
|
||||||
else {
|
$details += "`n"
|
||||||
"N/A"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$details = if ($transportRules.Count -gt 0) {
|
if ($nonCompliantSpamPoliciesArray.Count -gt 0) {
|
||||||
$transportRules | ForEach-Object {
|
$failureReasons += "Outbound spam policies allowing automatic forwarding found."
|
||||||
"$($_.Name) redirects to $($_.RedirectMessageTo)"
|
$details += "Outbound Spam Policies Details:`nPolicy|AutoForwardingMode"
|
||||||
} -join " | "
|
$details += $nonCompliantSpamPoliciesArray | ForEach-Object {
|
||||||
|
"$($_.Name)|$($_.AutoForwardingMode)"
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
"Step 1: No forwarding rules found. Please proceed with Step 2 described in CIS Benchmark."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($failureReasons.Count -eq 0) {
|
||||||
|
$failureReasons = "N/A"
|
||||||
|
$details = "Both transport rules and outbound spam policies are configured correctly to block forwarding."
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$failureReasons = $failureReasons -join " | "
|
||||||
|
$details = $details -join "`n"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Populate the audit result
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "6.2.1"
|
Rec = $recnum
|
||||||
Result = $forwardingBlocked
|
Result = $forwardingBlocked
|
||||||
Status = if ($forwardingBlocked) { "Pass" } else { "Fail" }
|
Status = if ($forwardingBlocked) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -44,6 +69,19 @@ function Test-BlockMailForwarding {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-BlockSharedMailboxSignIn {
|
function Test-BlockSharedMailboxSignIn {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -9,9 +10,12 @@ function Test-BlockSharedMailboxSignIn {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "1.2.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
|
||||||
|
try {
|
||||||
# 1.2.2 (L1) Ensure sign-in to shared mailboxes is blocked
|
# 1.2.2 (L1) Ensure sign-in to shared mailboxes is blocked
|
||||||
|
|
||||||
# Retrieve shared mailbox details
|
# Retrieve shared mailbox details
|
||||||
@@ -37,7 +41,7 @@ function Test-BlockSharedMailboxSignIn {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "1.2.2"
|
Rec = $recnum
|
||||||
Result = $allBlocked
|
Result = $allBlocked
|
||||||
Status = if ($allBlocked) { "Pass" } else { "Fail" }
|
Status = if ($allBlocked) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -45,6 +49,19 @@ function Test-BlockSharedMailboxSignIn {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-CommonAttachmentFilter {
|
function Test-CommonAttachmentFilter {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -9,9 +10,11 @@ function Test-CommonAttachmentFilter {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "2.1.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 2.1.2 (L1) Ensure the Common Attachment Types Filter is enabled
|
# 2.1.2 (L1) Ensure the Common Attachment Types Filter is enabled
|
||||||
|
|
||||||
# Retrieve the attachment filter policy
|
# Retrieve the attachment filter policy
|
||||||
@@ -35,7 +38,7 @@ function Test-CommonAttachmentFilter {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "2.1.2"
|
Rec = $recnum
|
||||||
Result = $result
|
Result = $result
|
||||||
Status = if ($result) { "Pass" } else { "Fail" }
|
Status = if ($result) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -43,6 +46,19 @@ function Test-CommonAttachmentFilter {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-CustomerLockbox {
|
function Test-CustomerLockbox {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here if needed
|
# Define your parameters here if needed
|
||||||
@@ -9,9 +10,12 @@ function Test-CustomerLockbox {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "1.3.6"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
|
||||||
|
try {
|
||||||
# 1.3.6 (L2) Ensure the customer lockbox feature is enabled
|
# 1.3.6 (L2) Ensure the customer lockbox feature is enabled
|
||||||
|
|
||||||
# Retrieve the organization configuration
|
# Retrieve the organization configuration
|
||||||
@@ -35,7 +39,7 @@ function Test-CustomerLockbox {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object #
|
# Create and populate the CISAuditResult object #
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "1.3.6"
|
Rec = $recnum
|
||||||
Result = $customerLockboxEnabled
|
Result = $customerLockboxEnabled
|
||||||
Status = if ($customerLockboxEnabled) { "Pass" } else { "Fail" }
|
Status = if ($customerLockboxEnabled) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -43,6 +47,19 @@ function Test-CustomerLockbox {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-DialInBypassLobby {
|
function Test-DialInBypassLobby {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be defined here if needed
|
# Parameters can be defined here if needed
|
||||||
@@ -9,9 +10,12 @@ function Test-DialInBypassLobby {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "8.5.4"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
|
||||||
|
try {
|
||||||
# 8.5.4 (L1) Ensure users dialing in can't bypass the lobby
|
# 8.5.4 (L1) Ensure users dialing in can't bypass the lobby
|
||||||
|
|
||||||
# Retrieve Teams meeting policy for PSTN users
|
# Retrieve Teams meeting policy for PSTN users
|
||||||
@@ -35,7 +39,7 @@ function Test-DialInBypassLobby {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "8.5.4"
|
Rec = $recnum
|
||||||
Result = $PSTNBypassDisabled
|
Result = $PSTNBypassDisabled
|
||||||
Status = if ($PSTNBypassDisabled) { "Pass" } else { "Fail" }
|
Status = if ($PSTNBypassDisabled) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -43,6 +47,19 @@ function Test-DialInBypassLobby {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-DisallowInfectedFilesDownload {
|
function Test-DisallowInfectedFilesDownload {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here if needed
|
# Define your parameters here if needed
|
||||||
@@ -10,9 +11,12 @@ function Test-DisallowInfectedFilesDownload {
|
|||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
|
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "7.3.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
|
||||||
|
try {
|
||||||
# 7.3.1 (L2) Ensure Office 365 SharePoint infected files are disallowed for download
|
# 7.3.1 (L2) Ensure Office 365 SharePoint infected files are disallowed for download
|
||||||
|
|
||||||
# Retrieve the SharePoint tenant configuration
|
# Retrieve the SharePoint tenant configuration
|
||||||
@@ -36,14 +40,26 @@ function Test-DisallowInfectedFilesDownload {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "7.3.1"
|
Rec = $recnum
|
||||||
Result = $isDisallowInfectedFileDownloadEnabled
|
Result = $isDisallowInfectedFileDownloadEnabled
|
||||||
Status = if ($isDisallowInfectedFileDownloadEnabled) { "Pass" } else { "Fail" }
|
Status = if ($isDisallowInfectedFileDownloadEnabled) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
FailureReason = $failureReasons
|
FailureReason = $failureReasons
|
||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-EnableDKIM {
|
function Test-EnableDKIM {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -9,9 +10,12 @@ function Test-EnableDKIM {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "2.1.9"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
|
||||||
|
try {
|
||||||
# 2.1.9 (L1) Ensure DKIM is enabled for all Exchange Online Domains
|
# 2.1.9 (L1) Ensure DKIM is enabled for all Exchange Online Domains
|
||||||
|
|
||||||
# Retrieve DKIM configuration for all domains
|
# Retrieve DKIM configuration for all domains
|
||||||
@@ -36,7 +40,7 @@ function Test-EnableDKIM {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "2.1.9"
|
Rec = $recnum
|
||||||
Result = $dkimResult
|
Result = $dkimResult
|
||||||
Status = if ($dkimResult) { "Pass" } else { "Fail" }
|
Status = if ($dkimResult) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -44,6 +48,19 @@ function Test-EnableDKIM {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-ExternalNoControl {
|
function Test-ExternalNoControl {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be defined here if needed
|
# Parameters can be defined here if needed
|
||||||
@@ -10,9 +11,12 @@ function Test-ExternalNoControl {
|
|||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
|
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "8.5.7"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
|
||||||
|
try {
|
||||||
# 8.5.7 (L1) Ensure external participants can't give or request control
|
# 8.5.7 (L1) Ensure external participants can't give or request control
|
||||||
|
|
||||||
# Retrieve Teams meeting policy for external participant control
|
# Retrieve Teams meeting policy for external participant control
|
||||||
@@ -36,7 +40,7 @@ function Test-ExternalNoControl {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "8.5.7"
|
Rec = $recnum
|
||||||
Result = $externalControlRestricted
|
Result = $externalControlRestricted
|
||||||
Status = if ($externalControlRestricted) { "Pass" } else { "Fail" }
|
Status = if ($externalControlRestricted) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -44,6 +48,19 @@ function Test-ExternalNoControl {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-ExternalSharingCalendars {
|
function Test-ExternalSharingCalendars {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -10,9 +11,12 @@ function Test-ExternalSharingCalendars {
|
|||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
|
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "1.3.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
|
||||||
|
try {
|
||||||
# 1.3.3 (L2) Ensure 'External sharing' of calendars is not available (Automated)
|
# 1.3.3 (L2) Ensure 'External sharing' of calendars is not available (Automated)
|
||||||
|
|
||||||
# Retrieve sharing policies related to calendar sharing
|
# Retrieve sharing policies related to calendar sharing
|
||||||
@@ -45,7 +49,7 @@ function Test-ExternalSharingCalendars {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "1.3.3"
|
Rec = $recnum
|
||||||
Result = $isExternalSharingDisabled
|
Result = $isExternalSharingDisabled
|
||||||
Status = if ($isExternalSharingDisabled) { "Pass" } else { "Fail" }
|
Status = if ($isExternalSharingDisabled) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -53,6 +57,19 @@ function Test-ExternalSharingCalendars {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-GlobalAdminsCount {
|
function Test-GlobalAdminsCount {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here if needed
|
# Define your parameters here if needed
|
||||||
@@ -10,16 +11,20 @@ function Test-GlobalAdminsCount {
|
|||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
|
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "1.1.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 1.1.3 (L1) Ensure that between two and four global admins are designated
|
# 1.1.3 (L1) Ensure that between two and four global admins are designated
|
||||||
|
|
||||||
# Retrieve global admin role and members
|
# Retrieve global admin role and members
|
||||||
$globalAdminRole = Get-MgDirectoryRole -Filter "RoleTemplateId eq '62e90394-69f5-4237-9190-012177145e10'"
|
$globalAdminRole = Get-MgDirectoryRole -Filter "RoleTemplateId eq '62e90394-69f5-4237-9190-012177145e10'"
|
||||||
$globalAdmins = Get-MgDirectoryRoleMember -DirectoryRoleId $globalAdminRole.Id
|
$globalAdmins = Get-MgDirectoryRoleMember -DirectoryRoleId $globalAdminRole.Id
|
||||||
$globalAdminCount = $globalAdmins.AdditionalProperties.Count
|
$globalAdminCount = $globalAdmins.Count
|
||||||
$globalAdminUsernames = ($globalAdmins | ForEach-Object { $_.AdditionalProperties["displayName"] }) -join ', '
|
$globalAdminUsernames = ($globalAdmins | ForEach-Object {
|
||||||
|
"$($_.AdditionalProperties["displayName"]) ($($_.AdditionalProperties["userPrincipalName"]))"
|
||||||
|
}) -join ', '
|
||||||
|
|
||||||
# Prepare failure reasons and details based on compliance
|
# Prepare failure reasons and details based on compliance
|
||||||
$failureReasons = if ($globalAdminCount -lt 2) {
|
$failureReasons = if ($globalAdminCount -lt 2) {
|
||||||
@@ -36,7 +41,7 @@ function Test-GlobalAdminsCount {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "1.1.3"
|
Rec = $recnum
|
||||||
Result = $globalAdminCount -ge 2 -and $globalAdminCount -le 4
|
Result = $globalAdminCount -ge 2 -and $globalAdminCount -le 4
|
||||||
Status = if ($globalAdminCount -ge 2 -and $globalAdminCount -le 4) { "Pass" } else { "Fail" }
|
Status = if ($globalAdminCount -ge 2 -and $globalAdminCount -le 4) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -44,6 +49,19 @@ function Test-GlobalAdminsCount {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-GuestAccessExpiration {
|
function Test-GuestAccessExpiration {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here if needed
|
# Define your parameters here if needed
|
||||||
@@ -10,9 +11,12 @@ function Test-GuestAccessExpiration {
|
|||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
|
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "7.2.9"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
|
||||||
|
try {
|
||||||
# 7.2.9 (L1) Ensure guest access to a site or OneDrive will expire automatically
|
# 7.2.9 (L1) Ensure guest access to a site or OneDrive will expire automatically
|
||||||
|
|
||||||
# Retrieve SharePoint tenant settings related to guest access expiration
|
# Retrieve SharePoint tenant settings related to guest access expiration
|
||||||
@@ -31,7 +35,7 @@ function Test-GuestAccessExpiration {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "7.2.9"
|
Rec = $recnum
|
||||||
Result = $isGuestAccessExpirationConfiguredCorrectly
|
Result = $isGuestAccessExpirationConfiguredCorrectly
|
||||||
Status = if ($isGuestAccessExpirationConfiguredCorrectly) { "Pass" } else { "Fail" }
|
Status = if ($isGuestAccessExpirationConfiguredCorrectly) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -39,6 +43,19 @@ function Test-GuestAccessExpiration {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-GuestUsersBiweeklyReview {
|
function Test-GuestUsersBiweeklyReview {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here if needed
|
# Define your parameters here if needed
|
||||||
@@ -10,9 +11,11 @@ function Test-GuestUsersBiweeklyReview {
|
|||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
|
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "1.1.4"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 1.1.4 (L1) Ensure Guest Users are reviewed at least biweekly
|
# 1.1.4 (L1) Ensure Guest Users are reviewed at least biweekly
|
||||||
|
|
||||||
|
|
||||||
@@ -38,7 +41,7 @@ function Test-GuestUsersBiweeklyReview {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "1.1.4"
|
Rec = $recnum
|
||||||
Result = -not $guestUsers
|
Result = -not $guestUsers
|
||||||
Status = if ($guestUsers) { "Fail" } else { "Pass" }
|
Status = if ($guestUsers) { "Fail" } else { "Pass" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -46,6 +49,19 @@ function Test-GuestUsersBiweeklyReview {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-IdentifyExternalEmail {
|
function Test-IdentifyExternalEmail {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be defined here if needed
|
# Parameters can be defined here if needed
|
||||||
@@ -10,9 +11,12 @@ function Test-IdentifyExternalEmail {
|
|||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
|
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "6.2.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
|
||||||
|
try {
|
||||||
# 6.2.3 (L1) Ensure email from external senders is identified
|
# 6.2.3 (L1) Ensure email from external senders is identified
|
||||||
|
|
||||||
# Retrieve external sender tagging configuration
|
# Retrieve external sender tagging configuration
|
||||||
@@ -31,7 +35,7 @@ function Test-IdentifyExternalEmail {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "6.2.3"
|
Rec = $recnum
|
||||||
Result = $externalTaggingEnabled
|
Result = $externalTaggingEnabled
|
||||||
Status = if ($externalTaggingEnabled) { "Pass" } else { "Fail" }
|
Status = if ($externalTaggingEnabled) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -39,6 +43,19 @@ function Test-IdentifyExternalEmail {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-LinkSharingRestrictions {
|
function Test-LinkSharingRestrictions {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here
|
# Define your parameters here
|
||||||
@@ -10,9 +11,11 @@ function Test-LinkSharingRestrictions {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "7.2.7"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 7.2.7 (L1) Ensure link sharing is restricted in SharePoint and OneDrive
|
# 7.2.7 (L1) Ensure link sharing is restricted in SharePoint and OneDrive
|
||||||
|
|
||||||
# Retrieve link sharing configuration for SharePoint and OneDrive
|
# Retrieve link sharing configuration for SharePoint and OneDrive
|
||||||
@@ -31,13 +34,27 @@ function Test-LinkSharingRestrictions {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "7.2.7"
|
Rec = $recnum
|
||||||
Result = $isLinkSharingRestricted
|
Result = $isLinkSharingRestricted
|
||||||
Status = if ($isLinkSharingRestricted) { "Pass" } else { "Fail" }
|
Status = if ($isLinkSharingRestricted) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
FailureReason = $failureReasons
|
FailureReason = $failureReasons
|
||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
|
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-MailTipsEnabled {
|
function Test-MailTipsEnabled {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -11,9 +12,11 @@ function Test-MailTipsEnabled {
|
|||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
|
||||||
$auditResult = [CISAuditResult]::new()
|
$auditResult = [CISAuditResult]::new()
|
||||||
|
$recnum = "6.5.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 6.5.2 (L2) Ensure MailTips are enabled for end users
|
# 6.5.2 (L2) Ensure MailTips are enabled for end users
|
||||||
|
|
||||||
# Retrieve organization configuration for MailTips settings
|
# Retrieve organization configuration for MailTips settings
|
||||||
@@ -38,7 +41,7 @@ function Test-MailTipsEnabled {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "6.5.2"
|
Rec = $recnum
|
||||||
Result = $allTipsEnabled -and $externalRecipientsTipsEnabled
|
Result = $allTipsEnabled -and $externalRecipientsTipsEnabled
|
||||||
Status = if ($allTipsEnabled -and $externalRecipientsTipsEnabled) { "Pass" } else { "Fail" }
|
Status = if ($allTipsEnabled -and $externalRecipientsTipsEnabled) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -46,6 +49,19 @@ function Test-MailTipsEnabled {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
function Test-MailboxAuditingE3 {
|
function Test-MailboxAuditingE3 {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
|
||||||
# Create Table for Details
|
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,19 +14,20 @@ function Test-MailboxAuditingE3 {
|
|||||||
$DelegateActions = @("ApplyRecord", "Create", "FolderBind", "HardDelete", "Move", "MoveToDeletedItems", "SendAs", "SendOnBehalf", "SoftDelete", "Update", "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")
|
$OwnerActions = @("ApplyRecord", "Create", "HardDelete", "MailboxLogin", "Move", "MoveToDeletedItems", "SoftDelete", "Update", "UpdateCalendarDelegation", "UpdateFolderPermissions", "UpdateInboxRules")
|
||||||
|
|
||||||
|
|
||||||
$allFailures = @()
|
$allFailures = @()
|
||||||
$allUsers = Get-AzureADUser -All $true
|
$allUsers = Get-AzureADUser -All $true
|
||||||
$processedUsers = @{} # Dictionary to track processed users
|
$processedUsers = @{} # Dictionary to track processed users
|
||||||
|
$recnum = "6.1.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
foreach ($user in $allUsers) {
|
foreach ($user in $allUsers) {
|
||||||
if ($processedUsers.ContainsKey($user.UserPrincipalName)) {
|
if ($processedUsers.ContainsKey($user.UserPrincipalName)) {
|
||||||
Write-Verbose "Skipping already processed user: $($user.UserPrincipalName)"
|
Write-Verbose "Skipping already processed user: $($user.UserPrincipalName)"
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
$licenseDetails = Get-MgUserLicenseDetail -UserId $user.UserPrincipalName
|
$licenseDetails = Get-MgUserLicenseDetail -UserId $user.UserPrincipalName
|
||||||
$hasOfficeE3 = ($licenseDetails | Where-Object { $_.SkuPartNumber -in $e3SkuPartNumbers }).Count -gt 0
|
$hasOfficeE3 = ($licenseDetails | Where-Object { $_.SkuPartNumber -in $e3SkuPartNumbers }).Count -gt 0
|
||||||
Write-Verbose "Evaluating user $($user.UserPrincipalName) for Office E3 license."
|
Write-Verbose "Evaluating user $($user.UserPrincipalName) for Office E3 license."
|
||||||
@@ -47,32 +47,33 @@ function Test-MailboxAuditingE3 {
|
|||||||
foreach ($action in $OwnerActions) {
|
foreach ($action in $OwnerActions) {
|
||||||
if ($mailbox.AuditOwner -notcontains $action) { $missingActions += "Owner action '$action' missing" }
|
if ($mailbox.AuditOwner -notcontains $action) { $missingActions += "Owner action '$action' missing" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($missingActions.Count -gt 0) {
|
||||||
|
$formattedActions = Format-MissingAction -missingActions $missingActions
|
||||||
|
$allFailures += "$userUPN|True|$($formattedActions.Admin)|$($formattedActions.Delegate)|$($formattedActions.Owner)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$allFailures += "$userUPN`: AuditEnabled - False"
|
$allFailures += "$userUPN|False|||"
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($missingActions) {
|
|
||||||
$formattedActions = Format-MissingActions $missingActions
|
|
||||||
$allFailures += "$userUPN`: AuditEnabled - True; $formattedActions"
|
|
||||||
}
|
|
||||||
# Mark the user as processed
|
# Mark the user as processed
|
||||||
$processedUsers[$user.UserPrincipalName] = $true
|
$processedUsers[$user.UserPrincipalName] = $true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {
|
|
||||||
Write-Warning "Could not retrieve license details for user $($user.UserPrincipalName): $_"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Prepare failure reasons and details based on compliance
|
# Prepare failure reasons and details based on compliance
|
||||||
$failureReasons = if ($allFailures.Count -eq 0) { "N/A" } else { "Audit issues detected." }
|
$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 " | " }
|
$details = if ($allFailures.Count -eq 0) {
|
||||||
|
"All Office E3 users have correct mailbox audit settings."
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
"UserPrincipalName|AuditEnabled|AdminActionsMissing|DelegateActionsMissing|OwnerActionsMissing`n" + ($allFailures -join "`n")
|
||||||
|
}
|
||||||
|
|
||||||
# Populate the audit result
|
# Populate the audit result
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "6.1.2"
|
Rec = $recnum
|
||||||
Result = $allFailures.Count -eq 0
|
Result = $allFailures.Count -eq 0
|
||||||
Status = if ($allFailures.Count -eq 0) { "Pass" } else { "Fail" }
|
Status = if ($allFailures.Count -eq 0) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -80,35 +81,29 @@ function Test-MailboxAuditingE3 {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
|
#$verbosePreference = 'Continue'
|
||||||
|
$detailsLength = $details.Length
|
||||||
|
Write-Verbose "Character count of the details: $detailsLength"
|
||||||
|
|
||||||
|
if ($detailsLength -gt 32767) {
|
||||||
|
Write-Verbose "Warning: The character count exceeds the limit for Excel cells."
|
||||||
|
}
|
||||||
|
#$verbosePreference = 'SilentlyContinue'
|
||||||
return $auditResult
|
return $auditResult
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Format-MissingActions {
|
|
||||||
param ([array]$missingActions)
|
|
||||||
|
|
||||||
$actionGroups = @{
|
|
||||||
"Admin" = @()
|
|
||||||
"Delegate" = @()
|
|
||||||
"Owner" = @()
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($action in $missingActions) {
|
|
||||||
if ($action -match "(Admin|Delegate|Owner) action '([^']+)' missing") {
|
|
||||||
$type = $matches[1]
|
|
||||||
$actionName = $matches[2]
|
|
||||||
$actionGroups[$type] += $actionName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$formattedResults = @()
|
|
||||||
foreach ($type in $actionGroups.Keys) {
|
|
||||||
if ($actionGroups[$type].Count -gt 0) {
|
|
||||||
$formattedResults += "$($type) actions missing: $($actionGroups[$type] -join ', ')"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $formattedResults -join '; '
|
|
||||||
}
|
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
function Test-MailboxAuditingE5 {
|
function Test-MailboxAuditingE5 {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
|
||||||
# Create Table for Details
|
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,23 +14,24 @@ function Test-MailboxAuditingE5 {
|
|||||||
$DelegateActions = @("ApplyRecord", "Create", "FolderBind", "HardDelete", "MailItemsAccessed", "Move", "MoveToDeletedItems", "SendAs", "SendOnBehalf", "SoftDelete", "Update", "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")
|
$OwnerActions = @("ApplyRecord", "Create", "HardDelete", "MailboxLogin", "Move", "MailItemsAccessed", "MoveToDeletedItems", "Send", "SoftDelete", "Update", "UpdateCalendarDelegation", "UpdateFolderPermissions", "UpdateInboxRules")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$allFailures = @()
|
$allFailures = @()
|
||||||
$allUsers = Get-AzureADUser -All $true
|
$allUsers = Get-AzureADUser -All $true
|
||||||
$processedUsers = @{} # Dictionary to track processed users
|
$processedUsers = @{} # Dictionary to track processed users
|
||||||
|
$recnum = "6.1.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
foreach ($user in $allUsers) {
|
foreach ($user in $allUsers) {
|
||||||
if ($processedUsers.ContainsKey($user.UserPrincipalName)) {
|
if ($processedUsers.ContainsKey($user.UserPrincipalName)) {
|
||||||
|
Write-Verbose "Skipping already processed user: $($user.UserPrincipalName)"
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
$licenseDetails = Get-MgUserLicenseDetail -UserId $user.UserPrincipalName
|
$licenseDetails = Get-MgUserLicenseDetail -UserId $user.UserPrincipalName
|
||||||
$hasOfficeE5 = ($licenseDetails | Where-Object { $_.SkuPartNumber -in $e5SkuPartNumbers }).Count -gt 0
|
$hasOfficeE5 = ($licenseDetails | Where-Object { $_.SkuPartNumber -in $e5SkuPartNumbers }).Count -gt 0
|
||||||
Write-Verbose "Evaluating user $($user.UserPrincipalName) for Office E5 license."
|
Write-Verbose "Evaluating user $($user.UserPrincipalName) for Office E5 license."
|
||||||
|
|
||||||
if ($hasOfficeE5) {
|
if ($hasOfficeE5) {
|
||||||
$userUPN = $user.UserPrincipalName
|
$userUPN = $user.UserPrincipalName
|
||||||
$mailbox = Get-EXOMailbox -Identity $userUPN -PropertySets Audit
|
$mailbox = Get-EXOMailbox -Identity $userUPN -PropertySets Audit
|
||||||
@@ -47,38 +47,33 @@ function Test-MailboxAuditingE5 {
|
|||||||
foreach ($action in $OwnerActions) {
|
foreach ($action in $OwnerActions) {
|
||||||
if ($mailbox.AuditOwner -notcontains $action) { $missingActions += "Owner action '$action' missing" }
|
if ($mailbox.AuditOwner -notcontains $action) { $missingActions += "Owner action '$action' missing" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($missingActions.Count -gt 0) {
|
||||||
|
$formattedActions = Format-MissingAction -missingActions $missingActions
|
||||||
|
$allFailures += "$userUPN|True|$($formattedActions.Admin)|$($formattedActions.Delegate)|$($formattedActions.Owner)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$allFailures += "$userUPN`: AuditEnabled - False"
|
$allFailures += "$userUPN|False|||"
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($missingActions) {
|
# Mark the user as processed
|
||||||
$formattedActions = Format-MissingActions $missingActions
|
|
||||||
$allFailures += "$userUPN`: AuditEnabled - True; $formattedActions"
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Write-Verbose "User $($user.UserPrincipalName) passed the mailbox audit checks."
|
|
||||||
}
|
|
||||||
$processedUsers[$user.UserPrincipalName] = $true
|
$processedUsers[$user.UserPrincipalName] = $true
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
# Adding verbose output to indicate the user does not have an E5 license
|
|
||||||
Write-Verbose "User $($user.UserPrincipalName) does not have an Office E5 license."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
Write-Warning "Could not retrieve license details for user $($user.UserPrincipalName): $_"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Prepare failure reasons and details based on compliance
|
# Prepare failure reasons and details based on compliance
|
||||||
$failureReasons = if ($allFailures.Count -eq 0) { "N/A" } else { "Audit issues detected." }
|
$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 " | " }
|
$details = if ($allFailures.Count -eq 0) {
|
||||||
|
"All Office E5 users have correct mailbox audit settings."
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
"UserPrincipalName|AuditEnabled|AdminActionsMissing|DelegateActionsMissing|OwnerActionsMissing`n" + ($allFailures -join "`n")
|
||||||
|
}
|
||||||
|
|
||||||
# Populate the audit result
|
# Populate the audit result
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "6.1.3"
|
Rec = $recnum
|
||||||
Result = $allFailures.Count -eq 0
|
Result = $allFailures.Count -eq 0
|
||||||
Status = if ($allFailures.Count -eq 0) { "Pass" } else { "Fail" }
|
Status = if ($allFailures.Count -eq 0) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -86,35 +81,29 @@ function Test-MailboxAuditingE5 {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
|
#$verbosePreference = 'Continue'
|
||||||
|
$detailsLength = $details.Length
|
||||||
|
Write-Verbose "Character count of the details: $detailsLength"
|
||||||
|
|
||||||
|
if ($detailsLength -gt 32767) {
|
||||||
|
Write-Verbose "Warning: The character count exceeds the limit for Excel cells."
|
||||||
|
}
|
||||||
|
#$verbosePreference = 'SilentlyContinue'
|
||||||
return $auditResult
|
return $auditResult
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Format-MissingActions {
|
|
||||||
param ([array]$missingActions)
|
|
||||||
|
|
||||||
$actionGroups = @{
|
|
||||||
"Admin" = @()
|
|
||||||
"Delegate" = @()
|
|
||||||
"Owner" = @()
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($action in $missingActions) {
|
|
||||||
if ($action -match "(Admin|Delegate|Owner) action '([^']+)' missing") {
|
|
||||||
$type = $matches[1]
|
|
||||||
$actionName = $matches[2]
|
|
||||||
$actionGroups[$type] += $actionName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$formattedResults = @()
|
|
||||||
foreach ($type in $actionGroups.Keys) {
|
|
||||||
if ($actionGroups[$type].Count -gt 0) {
|
|
||||||
$formattedResults += "$($type) actions missing: $($actionGroups[$type] -join ', ')"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $formattedResults -join '; '
|
|
||||||
}
|
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-ManagedApprovedPublicGroups {
|
function Test-ManagedApprovedPublicGroups {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -9,10 +10,11 @@ function Test-ManagedApprovedPublicGroups {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "1.2.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 1.2.1 (L2) Ensure that only organizationally managed/approved public groups exist (Automated)
|
# 1.2.1 (L2) Ensure that only organizationally managed/approved public groups exist (Automated)
|
||||||
|
|
||||||
# Retrieve all public groups
|
# Retrieve all public groups
|
||||||
@@ -36,7 +38,7 @@ function Test-ManagedApprovedPublicGroups {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "1.2.1"
|
Rec = $recnum
|
||||||
Result = $null -eq $allGroups -or $allGroups.Count -eq 0
|
Result = $null -eq $allGroups -or $allGroups.Count -eq 0
|
||||||
Status = if ($null -eq $allGroups -or $allGroups.Count -eq 0) { "Pass" } else { "Fail" }
|
Status = if ($null -eq $allGroups -or $allGroups.Count -eq 0) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -44,6 +46,19 @@ function Test-ManagedApprovedPublicGroups {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return auditResults
|
# Return auditResults
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-MeetingChatNoAnonymous {
|
function Test-MeetingChatNoAnonymous {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be defined here if needed
|
# Parameters can be defined here if needed
|
||||||
@@ -9,9 +10,11 @@ function Test-MeetingChatNoAnonymous {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "8.5.5"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 8.5.5 (L2) Ensure meeting chat does not allow anonymous users
|
# 8.5.5 (L2) Ensure meeting chat does not allow anonymous users
|
||||||
|
|
||||||
# Connect to Teams PowerShell using Connect-MicrosoftTeams
|
# Connect to Teams PowerShell using Connect-MicrosoftTeams
|
||||||
@@ -32,7 +35,7 @@ function Test-MeetingChatNoAnonymous {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "8.5.5"
|
Rec = $recnum
|
||||||
Result = $chatAnonDisabled
|
Result = $chatAnonDisabled
|
||||||
Status = if ($chatAnonDisabled) { "Pass" } else { "Fail" }
|
Status = if ($chatAnonDisabled) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -40,6 +43,19 @@ function Test-MeetingChatNoAnonymous {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-ModernAuthExchangeOnline {
|
function Test-ModernAuthExchangeOnline {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here
|
# Define your parameters here
|
||||||
@@ -9,6 +10,7 @@ function Test-ModernAuthExchangeOnline {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "6.5.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
@@ -30,7 +32,7 @@ function Test-ModernAuthExchangeOnline {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "6.5.1"
|
Rec = $recnum
|
||||||
Result = $orgConfig.OAuth2ClientProfileEnabled
|
Result = $orgConfig.OAuth2ClientProfileEnabled
|
||||||
Status = if ($orgConfig.OAuth2ClientProfileEnabled) { "Pass" } else { "Fail" }
|
Status = if ($orgConfig.OAuth2ClientProfileEnabled) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -40,8 +42,18 @@ function Test-ModernAuthExchangeOnline {
|
|||||||
|
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Error "An error occurred while testing modern authentication for Exchange Online: $_"
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-ModernAuthSharePoint {
|
function Test-ModernAuthSharePoint {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here
|
# Define your parameters here
|
||||||
@@ -9,9 +10,11 @@ function Test-ModernAuthSharePoint {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "7.2.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 7.2.1 (L1) Ensure modern authentication for SharePoint applications is required
|
# 7.2.1 (L1) Ensure modern authentication for SharePoint applications is required
|
||||||
$SPOTenant = Get-SPOTenant | Select-Object -Property LegacyAuthProtocolsEnabled
|
$SPOTenant = Get-SPOTenant | Select-Object -Property LegacyAuthProtocolsEnabled
|
||||||
$modernAuthForSPRequired = -not $SPOTenant.LegacyAuthProtocolsEnabled
|
$modernAuthForSPRequired = -not $SPOTenant.LegacyAuthProtocolsEnabled
|
||||||
@@ -28,7 +31,7 @@ function Test-ModernAuthSharePoint {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "7.2.1"
|
Rec = $recnum
|
||||||
Result = $modernAuthForSPRequired
|
Result = $modernAuthForSPRequired
|
||||||
Status = if ($modernAuthForSPRequired) { "Pass" } else { "Fail" }
|
Status = if ($modernAuthForSPRequired) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -36,6 +39,19 @@ function Test-ModernAuthSharePoint {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-NoAnonymousMeetingJoin {
|
function Test-NoAnonymousMeetingJoin {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be defined here if needed
|
# Parameters can be defined here if needed
|
||||||
@@ -9,9 +10,11 @@ function Test-NoAnonymousMeetingJoin {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "8.5.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 8.5.1 (L2) Ensure anonymous users can't join a meeting
|
# 8.5.1 (L2) Ensure anonymous users can't join a meeting
|
||||||
|
|
||||||
# Connect to Teams PowerShell using Connect-MicrosoftTeams
|
# Connect to Teams PowerShell using Connect-MicrosoftTeams
|
||||||
@@ -31,7 +34,7 @@ function Test-NoAnonymousMeetingJoin {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "8.5.1"
|
Rec = $recnum
|
||||||
Result = -not $allowAnonymousUsersToJoinMeeting
|
Result = -not $allowAnonymousUsersToJoinMeeting
|
||||||
Status = if (-not $allowAnonymousUsersToJoinMeeting) { "Pass" } else { "Fail" }
|
Status = if (-not $allowAnonymousUsersToJoinMeeting) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -39,6 +42,19 @@ function Test-NoAnonymousMeetingJoin {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-NoAnonymousMeetingStart {
|
function Test-NoAnonymousMeetingStart {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be defined here if needed
|
# Parameters can be defined here if needed
|
||||||
@@ -9,9 +10,11 @@ function Test-NoAnonymousMeetingStart {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "8.5.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 8.5.2 (L1) Ensure anonymous users and dial-in callers can't start a meeting
|
# 8.5.2 (L1) Ensure anonymous users and dial-in callers can't start a meeting
|
||||||
|
|
||||||
# Connect to Teams PowerShell using Connect-MicrosoftTeams
|
# Connect to Teams PowerShell using Connect-MicrosoftTeams
|
||||||
@@ -31,7 +34,7 @@ function Test-NoAnonymousMeetingStart {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "8.5.2"
|
Rec = $recnum
|
||||||
Result = $anonymousStartDisabled
|
Result = $anonymousStartDisabled
|
||||||
Status = if ($anonymousStartDisabled) { "Pass" } else { "Fail" }
|
Status = if ($anonymousStartDisabled) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -39,6 +42,19 @@ function Test-NoAnonymousMeetingStart {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-NoWhitelistDomains {
|
function Test-NoWhitelistDomains {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here
|
# Define your parameters here
|
||||||
@@ -9,9 +10,11 @@ function Test-NoWhitelistDomains {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "6.2.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 6.2.2 (L1) Ensure mail transport rules do not whitelist specific domains
|
# 6.2.2 (L1) Ensure mail transport rules do not whitelist specific domains
|
||||||
|
|
||||||
# Retrieve transport rules that whitelist specific domains
|
# Retrieve transport rules that whitelist specific domains
|
||||||
@@ -35,7 +38,7 @@ function Test-NoWhitelistDomains {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "6.2.2"
|
Rec = $recnum
|
||||||
Result = -not $whitelistedRules
|
Result = -not $whitelistedRules
|
||||||
Status = if ($whitelistedRules) { "Fail" } else { "Pass" }
|
Status = if ($whitelistedRules) { "Fail" } else { "Pass" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -43,6 +46,19 @@ function Test-NoWhitelistDomains {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return auditResult
|
# Return auditResult
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-NotifyMalwareInternal {
|
function Test-NotifyMalwareInternal {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -9,9 +10,11 @@ function Test-NotifyMalwareInternal {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "2.1.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 2.1.3 Ensure notifications for internal users sending malware is Enabled
|
# 2.1.3 Ensure notifications for internal users sending malware is Enabled
|
||||||
|
|
||||||
# Retrieve all 'Custom' malware filter policies and check notification settings
|
# Retrieve all 'Custom' malware filter policies and check notification settings
|
||||||
@@ -44,7 +47,7 @@ function Test-NotifyMalwareInternal {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "2.1.3"
|
Rec = $recnum
|
||||||
Result = $result
|
Result = $result
|
||||||
Status = if ($result) { "Pass" } else { "Fail" }
|
Status = if ($result) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -52,6 +55,19 @@ function Test-NotifyMalwareInternal {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-OneDriveContentRestrictions {
|
function Test-OneDriveContentRestrictions {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here
|
# Define your parameters here
|
||||||
@@ -9,9 +10,11 @@ function Test-OneDriveContentRestrictions {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "7.2.4"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 7.2.4 (L2) Ensure OneDrive content sharing is restricted
|
# 7.2.4 (L2) Ensure OneDrive content sharing is restricted
|
||||||
|
|
||||||
# Retrieve OneDrive sharing capability settings
|
# Retrieve OneDrive sharing capability settings
|
||||||
@@ -35,7 +38,7 @@ function Test-OneDriveContentRestrictions {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "7.2.4"
|
Rec = $recnum
|
||||||
Result = $isOneDriveSharingRestricted
|
Result = $isOneDriveSharingRestricted
|
||||||
Status = if ($isOneDriveSharingRestricted) { "Pass" } else { "Fail" }
|
Status = if ($isOneDriveSharingRestricted) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -43,6 +46,19 @@ function Test-OneDriveContentRestrictions {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return auditResult
|
# Return auditResult
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-OneDriveSyncRestrictions {
|
function Test-OneDriveSyncRestrictions {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here
|
# Define your parameters here
|
||||||
@@ -9,9 +10,11 @@ function Test-OneDriveSyncRestrictions {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "7.3.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 7.3.2 (L2) Ensure OneDrive sync is restricted for unmanaged devices
|
# 7.3.2 (L2) Ensure OneDrive sync is restricted for unmanaged devices
|
||||||
|
|
||||||
# Retrieve OneDrive sync client restriction settings
|
# Retrieve OneDrive sync client restriction settings
|
||||||
@@ -35,7 +38,7 @@ function Test-OneDriveSyncRestrictions {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "7.3.2"
|
Rec = $recnum
|
||||||
Result = $isSyncRestricted
|
Result = $isSyncRestricted
|
||||||
Status = if ($isSyncRestricted) { "Pass" } else { "Fail" }
|
Status = if ($isSyncRestricted) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -43,6 +46,19 @@ function Test-OneDriveSyncRestrictions {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return auditResult
|
# Return auditResult
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-OrgOnlyBypassLobby {
|
function Test-OrgOnlyBypassLobby {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be defined here if needed
|
# Parameters can be defined here if needed
|
||||||
@@ -9,9 +10,11 @@ function Test-OrgOnlyBypassLobby {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "8.5.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 8.5.3 (L1) Ensure only people in my org can bypass the lobby
|
# 8.5.3 (L1) Ensure only people in my org can bypass the lobby
|
||||||
|
|
||||||
# Connect to Teams PowerShell using Connect-MicrosoftTeams
|
# Connect to Teams PowerShell using Connect-MicrosoftTeams
|
||||||
@@ -37,7 +40,7 @@ function Test-OrgOnlyBypassLobby {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "8.5.3"
|
Rec = $recnum
|
||||||
Result = $lobbyBypassRestricted
|
Result = $lobbyBypassRestricted
|
||||||
Status = if ($lobbyBypassRestricted) { "Pass" } else { "Fail" }
|
Status = if ($lobbyBypassRestricted) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -45,6 +48,19 @@ function Test-OrgOnlyBypassLobby {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-OrganizersPresent {
|
function Test-OrganizersPresent {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be defined here if needed
|
# Parameters can be defined here if needed
|
||||||
@@ -9,9 +10,11 @@ function Test-OrganizersPresent {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "8.5.6"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 8.5.6 (L2) Ensure only organizers and co-organizers can present
|
# 8.5.6 (L2) Ensure only organizers and co-organizers can present
|
||||||
|
|
||||||
# Connect to Teams PowerShell using Connect-MicrosoftTeams
|
# Connect to Teams PowerShell using Connect-MicrosoftTeams
|
||||||
@@ -37,7 +40,7 @@ function Test-OrganizersPresent {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "8.5.6"
|
Rec = $recnum
|
||||||
Result = $presenterRoleRestricted
|
Result = $presenterRoleRestricted
|
||||||
Status = if ($presenterRoleRestricted) { "Pass" } else { "Fail" }
|
Status = if ($presenterRoleRestricted) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -45,6 +48,19 @@ function Test-OrganizersPresent {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-PasswordHashSync {
|
function Test-PasswordHashSync {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -9,9 +10,11 @@ function Test-PasswordHashSync {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "5.1.8.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 5.1.8.1 (L1) Ensure password hash sync is enabled for hybrid deployments
|
# 5.1.8.1 (L1) Ensure password hash sync is enabled for hybrid deployments
|
||||||
# Pass if OnPremisesSyncEnabled is True. Fail otherwise.
|
# Pass if OnPremisesSyncEnabled is True. Fail otherwise.
|
||||||
|
|
||||||
@@ -31,7 +34,7 @@ function Test-PasswordHashSync {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "5.1.8.1"
|
Rec = $recnum
|
||||||
Result = $hashSyncResult
|
Result = $hashSyncResult
|
||||||
Status = if ($hashSyncResult) { "Pass" } else { "Fail" }
|
Status = if ($hashSyncResult) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -39,6 +42,19 @@ function Test-PasswordHashSync {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-PasswordNeverExpirePolicy {
|
function Test-PasswordNeverExpirePolicy {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -10,9 +11,11 @@ function Test-PasswordNeverExpirePolicy {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "1.3.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 1.3.1 (L1) Ensure the 'Password expiration policy' is set to 'Set passwords to never expire'
|
# 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.
|
||||||
|
|
||||||
@@ -31,7 +34,7 @@ function Test-PasswordNeverExpirePolicy {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "1.3.1"
|
Rec = $recnum
|
||||||
Result = $passwordPolicy -eq 0
|
Result = $passwordPolicy -eq 0
|
||||||
Status = if ($passwordPolicy -eq 0) { "Pass" } else { "Fail" }
|
Status = if ($passwordPolicy -eq 0) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -39,6 +42,19 @@ function Test-PasswordNeverExpirePolicy {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-ReauthWithCode {
|
function Test-ReauthWithCode {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here
|
# Define your parameters here
|
||||||
@@ -9,9 +10,11 @@ function Test-ReauthWithCode {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "7.2.10"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 7.2.10 (L1) Ensure reauthentication with verification code is restricted
|
# 7.2.10 (L1) Ensure reauthentication with verification code is restricted
|
||||||
|
|
||||||
# Retrieve reauthentication settings for SharePoint Online
|
# Retrieve reauthentication settings for SharePoint Online
|
||||||
@@ -30,7 +33,7 @@ function Test-ReauthWithCode {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "7.2.10"
|
Rec = $recnum
|
||||||
Result = $isReauthenticationRestricted
|
Result = $isReauthenticationRestricted
|
||||||
Status = if ($isReauthenticationRestricted) { "Pass" } else { "Fail" }
|
Status = if ($isReauthenticationRestricted) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -38,6 +41,19 @@ function Test-ReauthWithCode {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return auditResult
|
# Return auditResult
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-ReportSecurityInTeams {
|
function Test-ReportSecurityInTeams {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be defined here if needed
|
# Parameters can be defined here if needed
|
||||||
@@ -9,9 +10,11 @@ function Test-ReportSecurityInTeams {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "8.6.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 8.6.1 (L1) Ensure users can report security concerns in Teams
|
# 8.6.1 (L1) Ensure users can report security concerns in Teams
|
||||||
|
|
||||||
# Retrieve the necessary settings for Teams and Exchange Online
|
# Retrieve the necessary settings for Teams and Exchange Online
|
||||||
@@ -40,7 +43,7 @@ function Test-ReportSecurityInTeams {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "8.6.1"
|
Rec = $recnum
|
||||||
Result = $securityReportEnabled
|
Result = $securityReportEnabled
|
||||||
Status = if ($securityReportEnabled) { "Pass" } else { "Fail" }
|
Status = if ($securityReportEnabled) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -48,6 +51,19 @@ function Test-ReportSecurityInTeams {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return auditResult
|
# Return auditResult
|
||||||
|
@@ -1,36 +1,70 @@
|
|||||||
function Test-RestrictCustomScripts {
|
function Test-RestrictCustomScripts {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
|
||||||
# Define your parameters here if needed
|
# Define your parameters here if needed
|
||||||
)
|
)
|
||||||
|
|
||||||
begin {
|
begin {
|
||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
# . .\source\Classes\CISAuditResult.ps1
|
||||||
|
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "7.3.4"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
|
||||||
|
try {
|
||||||
# 7.3.4 (L1) Ensure custom script execution is restricted on site collections
|
# 7.3.4 (L1) Ensure custom script execution is restricted on site collections
|
||||||
|
|
||||||
# Retrieve 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
|
$SPOSitesCustomScript = Get-SPOSite -Limit All | Select-Object Title, Url, DenyAddAndCustomizePages
|
||||||
|
|
||||||
# Find sites where custom scripts are allowed (DenyAddAndCustomizePages is not 'Enabled')
|
# Replace 'sharepoint.com' with '<SPUrl>'
|
||||||
$customScriptAllowedSites = $SPOSitesCustomScript | Where-Object { $_.DenyAddAndCustomizePages -ne 'Enabled' }
|
$processedUrls = $SPOSitesCustomScript | ForEach-Object {
|
||||||
|
$_.Url = $_.Url -replace 'sharepoint\.com', '<SPUrl>'
|
||||||
|
$_
|
||||||
|
}
|
||||||
|
|
||||||
|
# Find sites where custom scripts are allowed
|
||||||
|
$customScriptAllowedSites = $processedUrls | Where-Object { $_.DenyAddAndCustomizePages -ne 'Enabled' }
|
||||||
|
#$verbosePreference = 'Continue'
|
||||||
|
# Check the total length of URLs
|
||||||
|
$totalUrlLength = ($customScriptAllowedSites.Url -join '').Length
|
||||||
|
Write-Verbose "Total length of URLs: $totalUrlLength"
|
||||||
|
|
||||||
|
# Extract hostnames from allowed sites if the total length exceeds the limit
|
||||||
|
$mostUsedHostname = $null
|
||||||
|
if ($totalUrlLength -gt 20000) {
|
||||||
|
Write-Verbose "Extracting hostnames from URLs..."
|
||||||
|
$hostnames = $customScriptAllowedSites.Url | ForEach-Object {
|
||||||
|
if ($_ -match '^https://([^\.]+)\.') {
|
||||||
|
$matches[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Verbose "Extracted hostnames: $($hostnames -join ', ')"
|
||||||
|
|
||||||
|
# Find the most used hostname using the Get-MostCommonWord function
|
||||||
|
$mostUsedHostname = Get-MostCommonWord -InputStrings $hostnames
|
||||||
|
Write-Verbose "Most used hostname: $mostUsedHostname"
|
||||||
|
}
|
||||||
|
#$verbosePreference = 'SilentlyContinue'
|
||||||
# Compliance is true if no sites allow custom scripts
|
# Compliance is true if no sites allow custom scripts
|
||||||
$complianceResult = $customScriptAllowedSites.Count -eq 0
|
$complianceResult = $customScriptAllowedSites.Count -eq 0
|
||||||
|
|
||||||
# Gather details for non-compliant sites (where custom scripts are allowed)
|
# Gather details for non-compliant sites (where custom scripts are allowed)
|
||||||
$nonCompliantSiteDetails = $customScriptAllowedSites | ForEach-Object {
|
$nonCompliantSiteDetails = $customScriptAllowedSites | ForEach-Object {
|
||||||
"$($_.Title) ($($_.Url)): Custom Script Allowed"
|
$url = $_.Url
|
||||||
|
if ($null -ne $mostUsedHostname -and $url -match "^https://$mostUsedHostname\.<SPUrl>") {
|
||||||
|
$url = $url -replace "^https://$mostUsedHostname\.<SPUrl>", "https://<corp>.<SPUrl>"
|
||||||
|
}
|
||||||
|
"$(if ($_.Title) {$_.Title} else {"NoTitle"})|$url"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Prepare failure reasons and details based on compliance
|
# Prepare failure reasons and details based on compliance
|
||||||
$failureReasons = if (-not $complianceResult) {
|
$failureReasons = if (-not $complianceResult) {
|
||||||
"The following site collections allow custom script execution: " + ($nonCompliantSiteDetails -join "; ")
|
"Some site collections are not restricting custom script execution. Review Details property for sites that are not aligned with the benchmark."
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
"N/A"
|
"N/A"
|
||||||
@@ -40,12 +74,22 @@ function Test-RestrictCustomScripts {
|
|||||||
"All site collections have custom script execution restricted"
|
"All site collections have custom script execution restricted"
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$nonCompliantSiteDetails -join "; "
|
"Title|Url`n" + ($nonCompliantSiteDetails -join "`n")
|
||||||
|
}
|
||||||
|
|
||||||
|
# Convert details to PSObject and check length
|
||||||
|
$detailsPSObject = $details | ConvertFrom-Csv -Delimiter '|'
|
||||||
|
$detailsLength = ($detailsPSObject | ForEach-Object { $_.Url }).Length
|
||||||
|
|
||||||
|
if ($detailsLength -gt 32767) {
|
||||||
|
# Create a preview of the first 10 results
|
||||||
|
$preview = $detailsPSObject | Select-Object -First 10 | ForEach-Object { "$($_.Title)|$($_.Url)" }
|
||||||
|
$details = "The output is too large. Here is a preview of the first 10 results:`n`n" + ($preview -join "`n") + "`n`nPlease run the test with the following commands to get the full details:`n`nGet-SPOSite -Limit All | Where-Object { `$.DenyAddAndCustomizePages -ne 'Enabled' } | Select-Object Title, Url"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "7.3.4"
|
Rec = $recnum
|
||||||
Result = $complianceResult
|
Result = $complianceResult
|
||||||
Status = if ($complianceResult) { "Pass" } else { "Fail" }
|
Status = if ($complianceResult) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -53,8 +97,30 @@ function Test-RestrictCustomScripts {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
|
# Measure the character count of the details
|
||||||
|
#$verbosePreference = 'Continue'
|
||||||
|
$detailsLength = $details.Length
|
||||||
|
Write-Verbose "Character count of the details: $detailsLength"
|
||||||
|
|
||||||
|
if ($detailsLength -gt 32767) {
|
||||||
|
Write-Verbose "Warning: The character count exceeds the limit for Excel cells."
|
||||||
|
}
|
||||||
|
#$verbosePreference = 'SilentlyContinue'
|
||||||
# Return auditResult
|
# Return auditResult
|
||||||
return $auditResult
|
return $auditResult
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-RestrictExternalSharing {
|
function Test-RestrictExternalSharing {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here
|
# Define your parameters here
|
||||||
@@ -9,9 +10,11 @@ function Test-RestrictExternalSharing {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "7.2.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 7.2.3 (L1) Ensure external content sharing is restricted
|
# 7.2.3 (L1) Ensure external content sharing is restricted
|
||||||
|
|
||||||
# Retrieve the SharingCapability setting for the SharePoint tenant
|
# Retrieve the SharingCapability setting for the SharePoint tenant
|
||||||
@@ -30,7 +33,7 @@ function Test-RestrictExternalSharing {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "7.2.3"
|
Rec = $recnum
|
||||||
Result = $isRestricted
|
Result = $isRestricted
|
||||||
Status = if ($isRestricted) { "Pass" } else { "Fail" }
|
Status = if ($isRestricted) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -38,6 +41,19 @@ function Test-RestrictExternalSharing {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return auditResult
|
# Return auditResult
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-RestrictOutlookAddins {
|
function Test-RestrictOutlookAddins {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters could include credentials or other necessary data
|
# Parameters could include credentials or other necessary data
|
||||||
@@ -12,9 +13,11 @@ function Test-RestrictOutlookAddins {
|
|||||||
$customPolicyFailures = @()
|
$customPolicyFailures = @()
|
||||||
$defaultPolicyFailureDetails = @()
|
$defaultPolicyFailureDetails = @()
|
||||||
$relevantRoles = @('My Custom Apps', 'My Marketplace Apps', 'My ReadWriteMailbox Apps')
|
$relevantRoles = @('My Custom Apps', 'My Marketplace Apps', 'My ReadWriteMailbox Apps')
|
||||||
|
$recnum = "6.3.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 6.3.1 (L2) Ensure users installing Outlook add-ins is not allowed
|
# 6.3.1 (L2) Ensure users installing Outlook add-ins is not allowed
|
||||||
|
|
||||||
# Check all mailboxes for custom policies with unallowed add-ins
|
# Check all mailboxes for custom policies with unallowed add-ins
|
||||||
@@ -62,7 +65,7 @@ function Test-RestrictOutlookAddins {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "6.3.1"
|
Rec = $recnum
|
||||||
Result = $isCompliant
|
Result = $isCompliant
|
||||||
Status = if ($isCompliant) { "Pass" } else { "Fail" }
|
Status = if ($isCompliant) { "Pass" } else { "Fail" }
|
||||||
Details = $detailsString
|
Details = $detailsString
|
||||||
@@ -70,6 +73,19 @@ function Test-RestrictOutlookAddins {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-RestrictStorageProvidersOutlook {
|
function Test-RestrictStorageProvidersOutlook {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added here if needed
|
# Parameters can be added here if needed
|
||||||
@@ -9,9 +10,11 @@ function Test-RestrictStorageProvidersOutlook {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "6.5.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 6.5.3 (L2) Ensure additional storage providers are restricted in Outlook on the web
|
# 6.5.3 (L2) Ensure additional storage providers are restricted in Outlook on the web
|
||||||
|
|
||||||
# Retrieve all OwaMailbox policies
|
# Retrieve all OwaMailbox policies
|
||||||
@@ -38,7 +41,7 @@ function Test-RestrictStorageProvidersOutlook {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "6.5.3"
|
Rec = $recnum
|
||||||
Result = $allPoliciesRestricted
|
Result = $allPoliciesRestricted
|
||||||
Status = if ($allPoliciesRestricted) { "Pass" } else { "Fail" }
|
Status = if ($allPoliciesRestricted) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -46,6 +49,19 @@ function Test-RestrictStorageProvidersOutlook {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-RestrictTenantCreation {
|
function Test-RestrictTenantCreation {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -9,9 +10,11 @@ function Test-RestrictTenantCreation {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "5.1.2.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 5.1.2.3 (L1) Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes'
|
# 5.1.2.3 (L1) Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes'
|
||||||
|
|
||||||
# Retrieve the tenant creation policy
|
# Retrieve the tenant creation policy
|
||||||
@@ -30,7 +33,7 @@ function Test-RestrictTenantCreation {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "5.1.2.3"
|
Rec = $recnum
|
||||||
Result = $tenantCreationResult
|
Result = $tenantCreationResult
|
||||||
Status = if ($tenantCreationResult) { "Pass" } else { "Fail" }
|
Status = if ($tenantCreationResult) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -38,6 +41,19 @@ function Test-RestrictTenantCreation {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-SafeAttachmentsPolicy {
|
function Test-SafeAttachmentsPolicy {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -9,9 +10,11 @@ function Test-SafeAttachmentsPolicy {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "2.1.4"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 2.1.4 (L2) Ensure Safe Attachments policy is enabled
|
# 2.1.4 (L2) Ensure Safe Attachments policy is enabled
|
||||||
|
|
||||||
# Retrieve all Safe Attachment policies where Enable is set to True
|
# Retrieve all Safe Attachment policies where Enable is set to True
|
||||||
@@ -35,7 +38,7 @@ function Test-SafeAttachmentsPolicy {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "2.1.4"
|
Rec = $recnum
|
||||||
Result = $result
|
Result = $result
|
||||||
Status = if ($result) { "Pass" } else { "Fail" }
|
Status = if ($result) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -43,6 +46,19 @@ function Test-SafeAttachmentsPolicy {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-SafeAttachmentsTeams {
|
function Test-SafeAttachmentsTeams {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -9,9 +10,11 @@ function Test-SafeAttachmentsTeams {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "2.1.5"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 2.1.5 (L2) Ensure Safe Attachments for SharePoint, OneDrive, and Microsoft Teams is Enabled
|
# 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
|
# Retrieve the ATP policies for Office 365 and check Safe Attachments settings
|
||||||
@@ -42,7 +45,7 @@ function Test-SafeAttachmentsTeams {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "2.1.5"
|
Rec = $recnum
|
||||||
Result = $result
|
Result = $result
|
||||||
Status = if ($result) { "Pass" } else { "Fail" }
|
Status = if ($result) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -50,6 +53,19 @@ function Test-SafeAttachmentsTeams {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-SafeLinksOfficeApps {
|
function Test-SafeLinksOfficeApps {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here if needed
|
# Define your parameters here if needed
|
||||||
@@ -9,9 +10,11 @@ function Test-SafeLinksOfficeApps {
|
|||||||
# Dot source the class script if necessary
|
# Dot source the class script if necessary
|
||||||
#. .\source\Classes\CISAuditResult.ps1
|
#. .\source\Classes\CISAuditResult.ps1
|
||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
$recnum = "2.1.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 2.1.1 (L2) Ensure Safe Links for Office Applications is Enabled
|
# 2.1.1 (L2) Ensure Safe Links for Office Applications is Enabled
|
||||||
|
|
||||||
# Retrieve all Safe Links policies
|
# Retrieve all Safe Links policies
|
||||||
@@ -49,7 +52,7 @@ function Test-SafeLinksOfficeApps {
|
|||||||
|
|
||||||
# Create and populate the CISAuditResult object
|
# Create and populate the CISAuditResult object
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "2.1.1"
|
Rec = $recnum
|
||||||
Result = $result
|
Result = $result
|
||||||
Status = if ($result) { "Pass" } else { "Fail" }
|
Status = if ($result) { "Pass" } else { "Fail" }
|
||||||
Details = $details
|
Details = $details
|
||||||
@@ -57,6 +60,19 @@ function Test-SafeLinksOfficeApps {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return the audit result
|
# Return the audit result
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-SharePointAADB2B {
|
function Test-SharePointAADB2B {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here
|
# Define your parameters here
|
||||||
@@ -11,15 +12,17 @@ function Test-SharePointAADB2B {
|
|||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
|
||||||
$auditResult = [CISAuditResult]::new()
|
$auditResult = [CISAuditResult]::new()
|
||||||
|
$recnum = "7.2.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 7.2.2 (L1) Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled
|
# 7.2.2 (L1) Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled
|
||||||
$SPOTenantAzureADB2B = Get-SPOTenant | Select-Object EnableAzureADB2BIntegration
|
$SPOTenantAzureADB2B = Get-SPOTenant | Select-Object EnableAzureADB2BIntegration
|
||||||
|
|
||||||
# Populate the auditResult object with the required properties
|
# Populate the auditResult object with the required properties
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "7.2.2"
|
Rec = $recnum
|
||||||
Result = $SPOTenantAzureADB2B.EnableAzureADB2BIntegration
|
Result = $SPOTenantAzureADB2B.EnableAzureADB2BIntegration
|
||||||
Status = if ($SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Pass" } else { "Fail" }
|
Status = if ($SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Pass" } else { "Fail" }
|
||||||
Details = "EnableAzureADB2BIntegration: $($SPOTenantAzureADB2B.EnableAzureADB2BIntegration)"
|
Details = "EnableAzureADB2BIntegration: $($SPOTenantAzureADB2B.EnableAzureADB2BIntegration)"
|
||||||
@@ -27,6 +30,19 @@ function Test-SharePointAADB2B {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return auditResult
|
# Return auditResult
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-SharePointExternalSharingDomains {
|
function Test-SharePointExternalSharingDomains {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here
|
# Define your parameters here
|
||||||
@@ -11,16 +12,18 @@ function Test-SharePointExternalSharingDomains {
|
|||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
|
||||||
$auditResult = [CISAuditResult]::new()
|
$auditResult = [CISAuditResult]::new()
|
||||||
|
$recnum = "7.2.6"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 7.2.6 (L2) Ensure SharePoint external sharing is managed through domain whitelist/blacklists
|
# 7.2.6 (L2) Ensure SharePoint external sharing is managed through domain whitelist/blacklists
|
||||||
$SPOTenant = Get-SPOTenant | Select-Object SharingDomainRestrictionMode, SharingAllowedDomainList
|
$SPOTenant = Get-SPOTenant | Select-Object SharingDomainRestrictionMode, SharingAllowedDomainList
|
||||||
$isDomainRestrictionConfigured = $SPOTenant.SharingDomainRestrictionMode -eq 'AllowList'
|
$isDomainRestrictionConfigured = $SPOTenant.SharingDomainRestrictionMode -eq 'AllowList'
|
||||||
|
|
||||||
# Populate the auditResult object with the required properties
|
# Populate the auditResult object with the required properties
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "7.2.6"
|
Rec = $recnum
|
||||||
Result = $isDomainRestrictionConfigured
|
Result = $isDomainRestrictionConfigured
|
||||||
Status = if ($isDomainRestrictionConfigured) { "Pass" } else { "Fail" }
|
Status = if ($isDomainRestrictionConfigured) { "Pass" } else { "Fail" }
|
||||||
Details = "SharingDomainRestrictionMode: $($SPOTenant.SharingDomainRestrictionMode); SharingAllowedDomainList: $($SPOTenant.SharingAllowedDomainList)"
|
Details = "SharingDomainRestrictionMode: $($SPOTenant.SharingDomainRestrictionMode); SharingAllowedDomainList: $($SPOTenant.SharingAllowedDomainList)"
|
||||||
@@ -28,6 +31,19 @@ function Test-SharePointExternalSharingDomains {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return auditResult
|
# Return auditResult
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-SharePointGuestsItemSharing {
|
function Test-SharePointGuestsItemSharing {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Define your parameters here
|
# Define your parameters here
|
||||||
@@ -11,16 +12,18 @@ function Test-SharePointGuestsItemSharing {
|
|||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
|
||||||
$auditResult = [CISAuditResult]::new()
|
$auditResult = [CISAuditResult]::new()
|
||||||
|
$recnum = "7.2.5"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 7.2.5 (L2) Ensure that SharePoint guest users cannot share items they don't own
|
# 7.2.5 (L2) Ensure that SharePoint guest users cannot share items they don't own
|
||||||
$SPOTenant = Get-SPOTenant | Select-Object PreventExternalUsersFromResharing
|
$SPOTenant = Get-SPOTenant | Select-Object PreventExternalUsersFromResharing
|
||||||
$isGuestResharingPrevented = $SPOTenant.PreventExternalUsersFromResharing
|
$isGuestResharingPrevented = $SPOTenant.PreventExternalUsersFromResharing
|
||||||
|
|
||||||
# Populate the auditResult object with the required properties
|
# Populate the auditResult object with the required properties
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "7.2.5"
|
Rec = $recnum
|
||||||
Result = $isGuestResharingPrevented
|
Result = $isGuestResharingPrevented
|
||||||
Status = if ($isGuestResharingPrevented) { "Pass" } else { "Fail" }
|
Status = if ($isGuestResharingPrevented) { "Pass" } else { "Fail" }
|
||||||
Details = "PreventExternalUsersFromResharing: $isGuestResharingPrevented"
|
Details = "PreventExternalUsersFromResharing: $isGuestResharingPrevented"
|
||||||
@@ -28,6 +31,19 @@ function Test-SharePointGuestsItemSharing {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return auditResult
|
# Return auditResult
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-SpamPolicyAdminNotify {
|
function Test-SpamPolicyAdminNotify {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added if needed
|
# Parameters can be added if needed
|
||||||
@@ -11,9 +12,11 @@ function Test-SpamPolicyAdminNotify {
|
|||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
|
||||||
$auditResult = [CISAuditResult]::new()
|
$auditResult = [CISAuditResult]::new()
|
||||||
|
$recnum = "2.1.6"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 2.1.6 Ensure Exchange Online Spam Policies are set to notify administrators
|
# 2.1.6 Ensure Exchange Online Spam Policies are set to notify administrators
|
||||||
|
|
||||||
# Get the default hosted outbound spam filter policy
|
# Get the default hosted outbound spam filter policy
|
||||||
@@ -35,7 +38,7 @@ function Test-SpamPolicyAdminNotify {
|
|||||||
|
|
||||||
# Create an instance of CISAuditResult and populate it
|
# Create an instance of CISAuditResult and populate it
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "2.1.6"
|
Rec = $recnum
|
||||||
Result = $areSettingsEnabled
|
Result = $areSettingsEnabled
|
||||||
Status = if ($areSettingsEnabled) { "Pass" } else { "Fail" }
|
Status = if ($areSettingsEnabled) { "Pass" } else { "Fail" }
|
||||||
Details = if ($areSettingsEnabled) { "Both BccSuspiciousOutboundMail and NotifyOutboundSpam are enabled." } else { $failureDetails -join ' ' }
|
Details = if ($areSettingsEnabled) { "Both BccSuspiciousOutboundMail and NotifyOutboundSpam are enabled." } else { $failureDetails -join ' ' }
|
||||||
@@ -43,6 +46,19 @@ function Test-SpamPolicyAdminNotify {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return auditResult
|
# Return auditResult
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-TeamsExternalAccess {
|
function Test-TeamsExternalAccess {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be defined here if needed
|
# Parameters can be defined here if needed
|
||||||
@@ -11,9 +12,11 @@ function Test-TeamsExternalAccess {
|
|||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
|
||||||
$auditResult = [CISAuditResult]::new()
|
$auditResult = [CISAuditResult]::new()
|
||||||
|
$recnum = "8.2.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 8.2.1 (L1) Ensure 'external access' is restricted in the Teams admin center
|
# 8.2.1 (L1) Ensure 'external access' is restricted in the Teams admin center
|
||||||
|
|
||||||
# Connect to Teams PowerShell using Connect-MicrosoftTeams
|
# Connect to Teams PowerShell using Connect-MicrosoftTeams
|
||||||
@@ -30,7 +33,7 @@ function Test-TeamsExternalAccess {
|
|||||||
|
|
||||||
# Create an instance of CISAuditResult and populate it
|
# Create an instance of CISAuditResult and populate it
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "8.2.1"
|
Rec = $recnum
|
||||||
Result = $isCompliant
|
Result = $isCompliant
|
||||||
Status = if ($isCompliant) { "Pass" } else { "Fail" }
|
Status = if ($isCompliant) { "Pass" } else { "Fail" }
|
||||||
Details = "AllowTeamsConsumer: $($externalAccessConfig.AllowTeamsConsumer); AllowPublicUsers: $($externalAccessConfig.AllowPublicUsers); AllowFederatedUsers: $($externalAccessConfig.AllowFederatedUsers); AllowedDomains limited: $allowedDomainsLimited"
|
Details = "AllowTeamsConsumer: $($externalAccessConfig.AllowTeamsConsumer); AllowPublicUsers: $($externalAccessConfig.AllowPublicUsers); AllowFederatedUsers: $($externalAccessConfig.AllowFederatedUsers); AllowedDomains limited: $allowedDomainsLimited"
|
||||||
@@ -38,6 +41,19 @@ function Test-TeamsExternalAccess {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return auditResult
|
# Return auditResult
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
function Test-TeamsExternalFileSharing {
|
function Test-TeamsExternalFileSharing {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
|
[OutputType([CISAuditResult])]
|
||||||
param (
|
param (
|
||||||
# Aligned
|
# Aligned
|
||||||
# Parameters can be added here if needed
|
# Parameters can be added here if needed
|
||||||
@@ -11,9 +12,11 @@ function Test-TeamsExternalFileSharing {
|
|||||||
# Initialization code, if needed
|
# Initialization code, if needed
|
||||||
|
|
||||||
$auditResult = [CISAuditResult]::new()
|
$auditResult = [CISAuditResult]::new()
|
||||||
|
$recnum = "8.1.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
process {
|
process {
|
||||||
|
try {
|
||||||
# 8.1.1 (L2) Ensure external file sharing in Teams is enabled for only approved cloud storage services
|
# 8.1.1 (L2) Ensure external file sharing in Teams is enabled for only approved cloud storage services
|
||||||
# Connect to Teams PowerShell using Connect-MicrosoftTeams
|
# Connect to Teams PowerShell using Connect-MicrosoftTeams
|
||||||
|
|
||||||
@@ -34,7 +37,7 @@ function Test-TeamsExternalFileSharing {
|
|||||||
|
|
||||||
# Create an instance of CISAuditResult and populate it
|
# Create an instance of CISAuditResult and populate it
|
||||||
$params = @{
|
$params = @{
|
||||||
Rec = "8.1.1"
|
Rec = $recnum
|
||||||
Result = $isCompliant
|
Result = $isCompliant
|
||||||
Status = if ($isCompliant) { "Pass" } else { "Fail" }
|
Status = if ($isCompliant) { "Pass" } else { "Fail" }
|
||||||
Details = if (-not $isCompliant) { "Non-approved providers enabled: $($nonCompliantProviders -join ', ')" } else { "All cloud storage services are approved providers" }
|
Details = if (-not $isCompliant) { "Non-approved providers enabled: $($nonCompliantProviders -join ', ')" } else { "All cloud storage services are approved providers" }
|
||||||
@@ -42,6 +45,19 @@ function Test-TeamsExternalFileSharing {
|
|||||||
}
|
}
|
||||||
$auditResult = Initialize-CISAuditResult @params
|
$auditResult = Initialize-CISAuditResult @params
|
||||||
}
|
}
|
||||||
|
catch {
|
||||||
|
Write-Error "An error occurred during the test: $_"
|
||||||
|
|
||||||
|
# Retrieve the description from the test definitions
|
||||||
|
$testDefinition = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $recnum }
|
||||||
|
$description = if ($testDefinition) { $testDefinition.RecDescription } else { "Description not found" }
|
||||||
|
|
||||||
|
$script:FailedTests.Add([PSCustomObject]@{ Rec = $recnum; Description = $description; Error = $_ })
|
||||||
|
|
||||||
|
# Call Initialize-CISAuditResult with error parameters
|
||||||
|
$auditResult = Initialize-CISAuditResult -Rec $recnum -Failure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end {
|
end {
|
||||||
# Return auditResult
|
# Return auditResult
|
||||||
|
27
tests/Unit/Private/Get-MostCommonWord.tests.ps1
Normal file
27
tests/Unit/Private/Get-MostCommonWord.tests.ps1
Normal 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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
27
tests/Unit/Private/Get-RequiredModule.tests.ps1
Normal file
27
tests/Unit/Private/Get-RequiredModule.tests.ps1
Normal 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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
27
tests/Unit/Private/Invoke-TestFunction.tests.ps1
Normal file
27
tests/Unit/Private/Invoke-TestFunction.tests.ps1
Normal 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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
27
tests/Unit/Private/Measure-AuditResult.tests.ps1
Normal file
27
tests/Unit/Private/Measure-AuditResult.tests.ps1
Normal 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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
27
tests/Unit/Private/New-MergedObject.tests.ps1
Normal file
27
tests/Unit/Private/New-MergedObject.tests.ps1
Normal 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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user