Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
904e36c376 | ||
|
d68ae22982 | ||
|
50c94485e7 | ||
|
a80e26f089 | ||
|
5d11b46d96 | ||
|
5ef32eb4b8 | ||
|
0e2e779c82 | ||
|
1240f74450 | ||
|
063124eef3 | ||
|
14f3889378 | ||
|
3790ec00de | ||
|
c1171ddca5 | ||
|
fc7c8ec88f | ||
|
2fc814205d | ||
|
7309925e89 | ||
|
5637855c8b | ||
|
ac98307ed1 |
36
CHANGELOG.md
36
CHANGELOG.md
@@ -4,6 +4,42 @@ The format is based on and uses the types of changes according to [Keep a Change
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
# Fixed
|
||||
|
||||
- SPO tests formatting and output.
|
||||
|
||||
## [0.1.22] - 2024-07-01
|
||||
|
||||
### Added
|
||||
|
||||
- Added hash and compress steps to `Export-M365SecurityAuditTable` function.
|
||||
|
||||
## [0.1.21] - 2024-07-01
|
||||
|
||||
### Fixed
|
||||
|
||||
- SPO tests formatting and output.
|
||||
|
||||
## [0.1.22] - 2024-07-01
|
||||
|
||||
### Added
|
||||
|
||||
- Added hash and compress steps to `Export-M365SecurityAuditTable` function.
|
||||
|
||||
## [0.1.21] - 2024-07-01
|
||||
|
||||
### Fixed
|
||||
|
||||
- Formatting for MgGraph tests.
|
||||
|
||||
## [0.1.20] - 2024-06-30
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed parameter validation for new parameters in `Invoke-M365SecurityAudit` function
|
||||
|
||||
## [0.1.19] - 2024-06-30
|
||||
|
||||
### Added
|
||||
|
||||
- Added `ApprovedCloudStorageProviders` parameter to `Invoke-M365SecurityAudit` to allow for testing of approved cloud storage providers for 8.1.1.
|
||||
|
BIN
docs/index.html
BIN
docs/index.html
Binary file not shown.
@@ -190,10 +190,11 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
|
||||
|
||||
## INPUTS
|
||||
|
||||
### [CISAuditResult[]], [string]
|
||||
### [CISAuditResult[]] - An array of CISAuditResult objects.
|
||||
### [string] - A path to a CSV file.
|
||||
## OUTPUTS
|
||||
|
||||
### [PSCustomObject]
|
||||
### [PSCustomObject] - A custom object containing the path to the zip file and its hash.
|
||||
## NOTES
|
||||
|
||||
## RELATED LINKS
|
||||
|
@@ -4,7 +4,7 @@ Import-Module .\output\module\M365FoundationsCISReport\*\*.psd1
|
||||
|
||||
|
||||
<#
|
||||
$ver = "v0.1.18"
|
||||
$ver = "v0.1.22"
|
||||
git checkout main
|
||||
git pull origin main
|
||||
git tag -a $ver -m "Release version $ver refactor Update"
|
||||
@@ -59,6 +59,5 @@ Set-Secret -Name "GitHubToken" -Vault ModuleBuildCreds
|
||||
$GalleryApiToken = Get-Secret -Name "GalleryApiToken" -Vault ModuleBuildCreds -AsPlainText
|
||||
$GitHubToken = Get-Secret -Name "GitHubToken" -Vault ModuleBuildCreds -AsPlainText
|
||||
|
||||
|
||||
$GalleryApiToken
|
||||
$GitHubToken
|
@@ -42,10 +42,12 @@ function Get-CISMgOutput {
|
||||
switch ($rec) {
|
||||
'1.1.1' {
|
||||
# 1.1.1
|
||||
# Test-AdministrativeAccountCompliance
|
||||
$AdminRoleAssignmentsAndUsers = Get-AdminRoleUserAndAssignment
|
||||
return $AdminRoleAssignmentsAndUsers
|
||||
}
|
||||
'1.1.3' {
|
||||
# Test-GlobalAdminsCount
|
||||
# Step: Retrieve global admin role
|
||||
$globalAdminRole = Get-MgDirectoryRole -Filter "RoleTemplateId eq '62e90394-69f5-4237-9190-012177145e10'"
|
||||
# Step: Retrieve global admin members
|
||||
@@ -53,6 +55,7 @@ function Get-CISMgOutput {
|
||||
return $globalAdmins
|
||||
}
|
||||
'1.2.1' {
|
||||
# Test-ManagedApprovedPublicGroups
|
||||
$allGroups = Get-MgGroup -All | Where-Object { $_.Visibility -eq "Public" } | Select-Object DisplayName, Visibility
|
||||
return $allGroups
|
||||
}
|
||||
@@ -67,16 +70,19 @@ function Get-CISMgOutput {
|
||||
return $domains
|
||||
}
|
||||
'5.1.2.3' {
|
||||
# Test-RestrictTenantCreation
|
||||
# Retrieve the tenant creation policy
|
||||
$tenantCreationPolicy = (Get-MgPolicyAuthorizationPolicy).DefaultUserRolePermissions | Select-Object AllowedToCreateTenants
|
||||
return $tenantCreationPolicy
|
||||
}
|
||||
'5.1.8.1' {
|
||||
# Test-PasswordHashSync
|
||||
# Retrieve password hash sync status (Condition A and C)
|
||||
$passwordHashSync = Get-MgOrganization | Select-Object -ExpandProperty OnPremisesSyncEnabled
|
||||
return $passwordHashSync
|
||||
}
|
||||
'6.1.2' {
|
||||
# Test-MailboxAuditingE3
|
||||
$tenantSkus = Get-MgSubscribedSku -All
|
||||
$e3SkuPartNumber = "SPE_E3"
|
||||
$founde3Sku = $tenantSkus | Where-Object { $_.SkuPartNumber -eq $e3SkuPartNumber }
|
||||
@@ -89,6 +95,7 @@ function Get-CISMgOutput {
|
||||
}
|
||||
}
|
||||
'6.1.3' {
|
||||
# Test-MailboxAuditingE5
|
||||
$tenantSkus = Get-MgSubscribedSku -All
|
||||
$e5SkuPartNumber = "SPE_E5"
|
||||
$founde5Sku = $tenantSkus | Where-Object { $_.SkuPartNumber -eq $e5SkuPartNumber }
|
||||
|
@@ -40,12 +40,24 @@ function Get-CISSpoOutput {
|
||||
switch ($Rec) {
|
||||
'7.2.1' {
|
||||
# Test-ModernAuthSharePoint.ps1
|
||||
# $SPOTenant Mock Object
|
||||
<#
|
||||
$SPOTenant = [PSCustomObject]@{
|
||||
LegacyAuthProtocolsEnabled = $true
|
||||
}
|
||||
#>
|
||||
$SPOTenant = Get-SPOTenant | Select-Object -Property LegacyAuthProtocolsEnabled
|
||||
return $SPOTenant
|
||||
}
|
||||
'7.2.2' {
|
||||
# Test-SharePointAADB2B.ps1
|
||||
# 7.2.2 (L1) Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled
|
||||
# $SPOTenantAzureADB2B Mock Object
|
||||
<#
|
||||
$SPOTenantAzureADB2B = [PSCustomObject]@{
|
||||
EnableAzureADB2BIntegration = $false
|
||||
}
|
||||
#>
|
||||
$SPOTenantAzureADB2B = Get-SPOTenant | Select-Object EnableAzureADB2BIntegration
|
||||
return $SPOTenantAzureADB2B
|
||||
}
|
||||
@@ -53,35 +65,75 @@ function Get-CISSpoOutput {
|
||||
# Test-RestrictExternalSharing.ps1
|
||||
# 7.2.3 (L1) Ensure external content sharing is restricted
|
||||
# Retrieve the SharingCapability setting for the SharePoint tenant
|
||||
# $SPOTenantSharingCapability Mock Object
|
||||
<#
|
||||
$SPOTenantSharingCapability = [PSCustomObject]@{
|
||||
SharingCapability = "ExternalUserAndGuestSharing"
|
||||
}
|
||||
#>
|
||||
$SPOTenantSharingCapability = Get-SPOTenant | Select-Object SharingCapability
|
||||
return $SPOTenantSharingCapability
|
||||
}
|
||||
'7.2.4' {
|
||||
# Test-OneDriveContentRestrictions.ps1
|
||||
# 7.2.4 (L2) Ensure OneDrive content sharing is restricted
|
||||
# $SPOTenant Mock Object
|
||||
<#
|
||||
$SPOTenant = [PSCustomObject]@{
|
||||
OneDriveSharingCapability = "ExternalUserAndGuestSharing"
|
||||
}
|
||||
#>
|
||||
$SPOTenant = Get-SPOTenant | Select-Object OneDriveSharingCapability
|
||||
return $SPOTenant
|
||||
}
|
||||
'7.2.5' {
|
||||
# Test-SharePointGuestsItemSharing.ps1
|
||||
# 7.2.5 (L2) Ensure that SharePoint guest users cannot share items they don't own
|
||||
# $SPOTenant Mock Object
|
||||
<#
|
||||
$SPOTenant = [PSCustomObject]@{
|
||||
PreventExternalUsersFromResharing = $false
|
||||
}
|
||||
#>
|
||||
$SPOTenant = Get-SPOTenant | Select-Object PreventExternalUsersFromResharing
|
||||
return $SPOTenant
|
||||
}
|
||||
'7.2.6' {
|
||||
# Test-SharePointExternalSharingDomains.ps1
|
||||
# 7.2.6 (L2) Ensure SharePoint external sharing is managed through domain whitelist/blacklists
|
||||
# Add Authorized Domains?
|
||||
# $SPOTenant Mock Object
|
||||
<#
|
||||
$SPOTenant = [PSCustomObject]@{
|
||||
SharingDomainRestrictionMode = "AllowList"
|
||||
SharingAllowedDomainList = "domain1.com", "domain2.com"
|
||||
}
|
||||
#>
|
||||
$SPOTenant = Get-SPOTenant | Select-Object SharingDomainRestrictionMode, SharingAllowedDomainList
|
||||
return $SPOTenant
|
||||
}
|
||||
'7.2.7' {
|
||||
# Test-LinkSharingRestrictions.ps1
|
||||
# Retrieve link sharing configuration for SharePoint and OneDrive
|
||||
# $SPOTenantLinkSharing Mock Object
|
||||
<#
|
||||
$$SPOTenantLinkSharing = [PSCustomObject]@{
|
||||
DefaultSharingLinkType = "Direct"
|
||||
}
|
||||
#>
|
||||
$SPOTenantLinkSharing = Get-SPOTenant | Select-Object DefaultSharingLinkType
|
||||
return $SPOTenantLinkSharing
|
||||
}
|
||||
'7.2.9' {
|
||||
# Test-GuestAccessExpiration.ps1
|
||||
# Retrieve SharePoint tenant settings related to guest access expiration
|
||||
# $SPOTenantGuestAccess Mock Object
|
||||
<#
|
||||
$SPOTenantGuestAccess = [PSCustomObject]@{
|
||||
ExternalUserExpirationRequired = "$false"
|
||||
ExternalUserExpireInDays = "60"
|
||||
}
|
||||
#>
|
||||
$SPOTenantGuestAccess = Get-SPOTenant | Select-Object ExternalUserExpirationRequired, ExternalUserExpireInDays
|
||||
return $SPOTenantGuestAccess
|
||||
}
|
||||
@@ -89,24 +141,53 @@ function Get-CISSpoOutput {
|
||||
# Test-ReauthWithCode.ps1
|
||||
# 7.2.10 (L1) Ensure reauthentication with verification code is restricted
|
||||
# Retrieve reauthentication settings for SharePoint Online
|
||||
# $SPOTenantReauthentication Mock Object
|
||||
<#
|
||||
$SPOTenantReauthentication = [PSCustomObject]@{
|
||||
EmailAttestationRequired = "$false"
|
||||
EmailAttestationReAuthDays = "30"
|
||||
}
|
||||
#>
|
||||
$SPOTenantReauthentication = Get-SPOTenant | Select-Object EmailAttestationRequired, EmailAttestationReAuthDays
|
||||
return $SPOTenantReauthentication
|
||||
}
|
||||
'7.3.1' {
|
||||
# Test-DisallowInfectedFilesDownload.ps1
|
||||
# Retrieve the SharePoint tenant configuration
|
||||
# $SPOTenantDisallowInfectedFileDownload Mock Object
|
||||
<#
|
||||
$SPOTenantDisallowInfectedFileDownload = [PSCustomObject]@{
|
||||
DisallowInfectedFileDownload = $false
|
||||
}
|
||||
#>
|
||||
$SPOTenantDisallowInfectedFileDownload = Get-SPOTenant | Select-Object DisallowInfectedFileDownload
|
||||
return $SPOTenantDisallowInfectedFileDownload
|
||||
}
|
||||
'7.3.2' {
|
||||
# Test-OneDriveSyncRestrictions.ps1
|
||||
# Retrieve OneDrive sync client restriction settings
|
||||
# Add isHybrid paramter?
|
||||
# $SPOTenantSyncClientRestriction Mock Object
|
||||
<#
|
||||
$SPOTenantSyncClientRestriction = [PSCustomObject]@{
|
||||
TenantRestrictionEnabled = $true
|
||||
AllowedDomainList = "786548DD-877B-4760-A749-6B1EFBC1190A", "877564FF-877B-4760-A749-6B1EFBC1190A"
|
||||
}
|
||||
#>
|
||||
$SPOTenantSyncClientRestriction = Get-SPOTenantSyncClientRestriction | Select-Object TenantRestrictionEnabled, AllowedDomainList
|
||||
return $SPOTenantSyncClientRestriction
|
||||
}
|
||||
'7.3.4' {
|
||||
# Test-RestrictCustomScripts.ps1
|
||||
# Retrieve all site collections and select necessary properties
|
||||
# $SPOSitesCustomScript Mock Object
|
||||
<#
|
||||
$SPOSitesCustomScript = [PSCustomObject]@{
|
||||
Title = "Site Collection 1"
|
||||
Url = "https://contoso.sharepoint.com/sites/site1"
|
||||
DenyAddAndCustomizePages = "Enabled"
|
||||
}
|
||||
#>
|
||||
$SPOSitesCustomScript = Get-SPOSite -Limit All | Select-Object Title, Url, DenyAddAndCustomizePages
|
||||
return $SPOSitesCustomScript
|
||||
}
|
||||
|
@@ -1,47 +1,52 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Exports M365 security audit results to a CSV file or outputs a specific test result as an object.
|
||||
Exports Microsoft 365 security audit results to CSV or Excel files and supports outputting specific test results as objects.
|
||||
.DESCRIPTION
|
||||
This function exports M365 security audit results from either an array of CISAuditResult objects or a CSV file.
|
||||
It can export all results to a specified path or output a specific test result as an object.
|
||||
The Export-M365SecurityAuditTable function exports Microsoft 365 security audit results from an array of CISAuditResult objects or a CSV file.
|
||||
It can export all results to a specified path, output a specific test result as an object, and includes options for exporting results to Excel.
|
||||
Additionally, it computes hashes for the exported files and includes them in the zip archive for verification purposes.
|
||||
.PARAMETER AuditResults
|
||||
An array of CISAuditResult objects containing the audit results.
|
||||
An array of CISAuditResult objects containing the audit results. This parameter is mandatory when exporting from audit results.
|
||||
.PARAMETER CsvPath
|
||||
The path to a CSV file containing the audit results.
|
||||
The path to a CSV file containing the audit results. This parameter is mandatory when exporting from a CSV file.
|
||||
.PARAMETER OutputTestNumber
|
||||
The test number to output as an object. Valid values are "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4".
|
||||
The test number to output as an object. Valid values are "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4". This parameter is used to output a specific test result.
|
||||
.PARAMETER ExportAllTests
|
||||
Switch to export all test results.
|
||||
Switch to export all test results. When specified, all test results are exported to the specified path.
|
||||
.PARAMETER ExportPath
|
||||
The path where the CSV files will be exported.
|
||||
The path where the CSV or Excel files will be exported. This parameter is mandatory when exporting all tests.
|
||||
.PARAMETER ExportOriginalTests
|
||||
Switch to export the original audit results to a CSV file.
|
||||
Switch to export the original audit results to a CSV file. When specified, the original test results are exported along with the processed results.
|
||||
.PARAMETER ExportToExcel
|
||||
Switch to export the results to an Excel file.
|
||||
Switch to export the results to an Excel file. When specified, results are exported in Excel format.
|
||||
.INPUTS
|
||||
[CISAuditResult[]], [string]
|
||||
[CISAuditResult[]] - An array of CISAuditResult objects.
|
||||
[string] - A path to a CSV file.
|
||||
.OUTPUTS
|
||||
[PSCustomObject]
|
||||
[PSCustomObject] - A custom object containing the path to the zip file and its hash.
|
||||
.EXAMPLE
|
||||
Export-M365SecurityAuditTable -AuditResults $object -OutputTestNumber 6.1.2
|
||||
# Output object for a single test number from audit results
|
||||
Export-M365SecurityAuditTable -AuditResults $object -OutputTestNumber 6.1.2
|
||||
# Outputs the result of test number 6.1.2 from the provided audit results as an object.
|
||||
.EXAMPLE
|
||||
Export-M365SecurityAuditTable -ExportAllTests -AuditResults $object -ExportPath "C:\temp"
|
||||
# Export all results from audit results to the specified path
|
||||
Export-M365SecurityAuditTable -ExportAllTests -AuditResults $object -ExportPath "C:\temp"
|
||||
# Exports all audit results to the specified path in CSV format.
|
||||
.EXAMPLE
|
||||
Export-M365SecurityAuditTable -CsvPath "C:\temp\auditresultstoday1.csv" -OutputTestNumber 6.1.2
|
||||
# Output object for a single test number from CSV
|
||||
Export-M365SecurityAuditTable -CsvPath "C:\temp\auditresultstoday1.csv" -OutputTestNumber 6.1.2
|
||||
# Outputs the result of test number 6.1.2 from the CSV file as an object.
|
||||
.EXAMPLE
|
||||
Export-M365SecurityAuditTable -ExportAllTests -CsvPath "C:\temp\auditresultstoday1.csv" -ExportPath "C:\temp"
|
||||
# Export all results from CSV to the specified path
|
||||
Export-M365SecurityAuditTable -ExportAllTests -CsvPath "C:\temp\auditresultstoday1.csv" -ExportPath "C:\temp"
|
||||
# Exports all audit results from the CSV file to the specified path in CSV format.
|
||||
.EXAMPLE
|
||||
Export-M365SecurityAuditTable -ExportAllTests -AuditResults $object -ExportPath "C:\temp" -ExportOriginalTests
|
||||
# Export all results from audit results to the specified path along with the original tests
|
||||
Export-M365SecurityAuditTable -ExportAllTests -AuditResults $object -ExportPath "C:\temp" -ExportOriginalTests
|
||||
# Exports all audit results along with the original test results to the specified path in CSV format.
|
||||
.EXAMPLE
|
||||
Export-M365SecurityAuditTable -ExportAllTests -CsvPath "C:\temp\auditresultstoday1.csv" -ExportPath "C:\temp" -ExportOriginalTests
|
||||
# Export all results from CSV to the specified path along with the original tests
|
||||
Export-M365SecurityAuditTable -ExportAllTests -CsvPath "C:\temp\auditresultstoday1.csv" -ExportPath "C:\temp" -ExportOriginalTests
|
||||
# Exports all audit results from the CSV file along with the original test results to the specified path in CSV format.
|
||||
.EXAMPLE
|
||||
Export-M365SecurityAuditTable -ExportAllTests -AuditResults $object -ExportPath "C:\temp" -ExportToExcel
|
||||
# Exports all audit results to the specified path in Excel format.
|
||||
.LINK
|
||||
https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Export-M365SecurityAuditTable
|
||||
https://criticalsolutionsnetwork.github.io/M365FoundationsCISReport/#Export-M365SecurityAuditTable
|
||||
#>
|
||||
function Export-M365SecurityAuditTable {
|
||||
[CmdletBinding()]
|
||||
@@ -50,179 +55,206 @@ function Export-M365SecurityAuditTable {
|
||||
[Parameter(Mandatory = $true, Position = 1, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
||||
[Parameter(Mandatory = $true, Position = 2, ParameterSetName = "OutputObjectFromAuditResultsSingle")]
|
||||
[CISAuditResult[]]$AuditResults,
|
||||
|
||||
[Parameter(Mandatory = $true, Position = 1, ParameterSetName = "ExportAllResultsFromCsv")]
|
||||
[Parameter(Mandatory = $true, Position = 2, ParameterSetName = "OutputObjectFromCsvSingle")]
|
||||
[ValidateScript({ (Test-Path $_) -and ((Get-Item $_).PSIsContainer -eq $false) })]
|
||||
[string]$CsvPath,
|
||||
|
||||
[Parameter(Mandatory = $true, Position = 1, ParameterSetName = "OutputObjectFromAuditResultsSingle")]
|
||||
[Parameter(Mandatory = $true, Position = 1, ParameterSetName = "OutputObjectFromCsvSingle")]
|
||||
[ValidateSet("1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4")]
|
||||
[string]$OutputTestNumber,
|
||||
|
||||
[Parameter(Mandatory = $false, Position = 0, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
||||
[Parameter(Mandatory = $false, Position = 0, ParameterSetName = "ExportAllResultsFromCsv")]
|
||||
[switch]$ExportAllTests,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "ExportAllResultsFromCsv")]
|
||||
[string]$ExportPath,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
||||
[Parameter(Mandatory = $true, ParameterSetName = "ExportAllResultsFromCsv")]
|
||||
[switch]$ExportOriginalTests,
|
||||
|
||||
[Parameter(Mandatory = $false, ParameterSetName = "ExportAllResultsFromAuditResults")]
|
||||
[Parameter(Mandatory = $false, ParameterSetName = "ExportAllResultsFromCsv")]
|
||||
[switch]$ExportToExcel
|
||||
)
|
||||
if ($ExportToExcel) {
|
||||
Assert-ModuleAvailability -ModuleName ImportExcel -RequiredVersion "7.8.9"
|
||||
}
|
||||
if ($PSCmdlet.ParameterSetName -like "ExportAllResultsFromCsv" -or $PSCmdlet.ParameterSetName -eq "OutputObjectFromCsvSingle") {
|
||||
$AuditResults = Import-Csv -Path $CsvPath | ForEach-Object {
|
||||
$params = @{
|
||||
Rec = $_.Rec
|
||||
Result = [bool]$_.Result
|
||||
Status = $_.Status
|
||||
Details = $_.Details
|
||||
FailureReason = $_.FailureReason
|
||||
Begin {
|
||||
$createdFiles = @() # Initialize an array to keep track of created files
|
||||
if ($ExportToExcel) {
|
||||
Assert-ModuleAvailability -ModuleName ImportExcel -RequiredVersion "7.8.9"
|
||||
}
|
||||
if ($PSCmdlet.ParameterSetName -like "ExportAllResultsFromCsv" -or $PSCmdlet.ParameterSetName -eq "OutputObjectFromCsvSingle") {
|
||||
$AuditResults = Import-Csv -Path $CsvPath | ForEach-Object {
|
||||
$params = @{
|
||||
Rec = $_.Rec
|
||||
Result = [bool]$_.Result
|
||||
Status = $_.Status
|
||||
Details = $_.Details
|
||||
FailureReason = $_.FailureReason
|
||||
}
|
||||
Initialize-CISAuditResult @params
|
||||
}
|
||||
Initialize-CISAuditResult @params
|
||||
}
|
||||
}
|
||||
|
||||
if ($ExportAllTests) {
|
||||
$TestNumbers = "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4"
|
||||
}
|
||||
|
||||
$results = @()
|
||||
|
||||
$testsToProcess = if ($OutputTestNumber) { @($OutputTestNumber) } else { $TestNumbers }
|
||||
|
||||
foreach ($test in $testsToProcess) {
|
||||
$auditResult = $AuditResults | Where-Object { $_.Rec -eq $test }
|
||||
if (-not $auditResult) {
|
||||
Write-Information "No audit results found for the test number $test."
|
||||
continue
|
||||
if ($ExportAllTests) {
|
||||
$TestNumbers = "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4"
|
||||
}
|
||||
|
||||
switch ($test) {
|
||||
"6.1.2" {
|
||||
$details = $auditResult.Details
|
||||
if ($details -ne "No M365 E3 licenses found.") {
|
||||
$csv = $details | ConvertFrom-Csv -Delimiter '|'
|
||||
}
|
||||
else {
|
||||
$csv = $null
|
||||
}
|
||||
|
||||
if ($null -ne $csv) {
|
||||
foreach ($row in $csv) {
|
||||
$row.AdminActionsMissing = (Get-Action -AbbreviatedActions $row.AdminActionsMissing.Split(',') -ReverseActionType Admin | Where-Object { $_ -notin @("MailItemsAccessed", "Send") }) -join ','
|
||||
$row.DelegateActionsMissing = (Get-Action -AbbreviatedActions $row.DelegateActionsMissing.Split(',') -ReverseActionType Delegate | Where-Object { $_ -notin @("MailItemsAccessed") }) -join ','
|
||||
$row.OwnerActionsMissing = (Get-Action -AbbreviatedActions $row.OwnerActionsMissing.Split(',') -ReverseActionType Owner | Where-Object { $_ -notin @("MailItemsAccessed", "Send") }) -join ','
|
||||
$results = @()
|
||||
$testsToProcess = if ($OutputTestNumber) { @($OutputTestNumber) } else { $TestNumbers }
|
||||
}
|
||||
Process {
|
||||
foreach ($test in $testsToProcess) {
|
||||
$auditResult = $AuditResults | Where-Object { $_.Rec -eq $test }
|
||||
if (-not $auditResult) {
|
||||
Write-Information "No audit results found for the test number $test."
|
||||
continue
|
||||
}
|
||||
switch ($test) {
|
||||
"6.1.2" {
|
||||
$details = $auditResult.Details
|
||||
if ($details -ne "No M365 E3 licenses found.") {
|
||||
$csv = $details | ConvertFrom-Csv -Delimiter '|'
|
||||
}
|
||||
$newObjectDetails = $csv
|
||||
}
|
||||
else {
|
||||
$newObjectDetails = $details
|
||||
}
|
||||
$results += [PSCustomObject]@{ TestNumber = $test; Details = $newObjectDetails }
|
||||
}
|
||||
"6.1.3" {
|
||||
$details = $auditResult.Details
|
||||
if ($details -ne "No M365 E5 licenses found.") {
|
||||
$csv = $details | ConvertFrom-Csv -Delimiter '|'
|
||||
}
|
||||
else {
|
||||
$csv = $null
|
||||
}
|
||||
|
||||
if ($null -ne $csv) {
|
||||
foreach ($row in $csv) {
|
||||
$row.AdminActionsMissing = (Get-Action -AbbreviatedActions $row.AdminActionsMissing.Split(',') -ReverseActionType Admin) -join ','
|
||||
$row.DelegateActionsMissing = (Get-Action -AbbreviatedActions $row.DelegateActionsMissing.Split(',') -ReverseActionType Delegate) -join ','
|
||||
$row.OwnerActionsMissing = (Get-Action -AbbreviatedActions $row.OwnerActionsMissing.Split(',') -ReverseActionType Owner) -join ','
|
||||
else {
|
||||
$csv = $null
|
||||
}
|
||||
$newObjectDetails = $csv
|
||||
}
|
||||
else {
|
||||
$newObjectDetails = $details
|
||||
}
|
||||
$results += [PSCustomObject]@{ TestNumber = $test; Details = $newObjectDetails }
|
||||
}
|
||||
Default {
|
||||
$details = $auditResult.Details
|
||||
$csv = $details | ConvertFrom-Csv -Delimiter '|'
|
||||
$results += [PSCustomObject]@{ TestNumber = $test; Details = $csv }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($ExportPath) {
|
||||
$timestamp = (Get-Date).ToString("yyyy.MM.dd_HH.mm.ss")
|
||||
$exportedTests = @()
|
||||
|
||||
foreach ($result in $results) {
|
||||
$testDef = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $result.TestNumber }
|
||||
if ($testDef) {
|
||||
$fileName = "$ExportPath\$($timestamp)_$($result.TestNumber).$($testDef.TestFileName -replace '\.ps1$').csv"
|
||||
if ($result.Details.Count -eq 0) {
|
||||
Write-Information "No results found for test number $($result.TestNumber)." -InformationAction Continue
|
||||
}
|
||||
else {
|
||||
if (($result.Details -ne "No M365 E3 licenses found.") -and ($result.Details -ne "No M365 E5 licenses found.")) {
|
||||
if ($ExportToExcel) {
|
||||
$xlsxPath = [System.IO.Path]::ChangeExtension($fileName, '.xlsx')
|
||||
$result.Details | Export-Excel -Path $xlsxPath -WorksheetName Table -TableName Table -AutoSize -TableStyle Medium2
|
||||
if ($null -ne $csv) {
|
||||
foreach ($row in $csv) {
|
||||
$row.AdminActionsMissing = (Get-Action -AbbreviatedActions $row.AdminActionsMissing.Split(',') -ReverseActionType Admin | Where-Object { $_ -notin @("MailItemsAccessed", "Send") }) -join ','
|
||||
$row.DelegateActionsMissing = (Get-Action -AbbreviatedActions $row.DelegateActionsMissing.Split(',') -ReverseActionType Delegate | Where-Object { $_ -notin @("MailItemsAccessed") }) -join ','
|
||||
$row.OwnerActionsMissing = (Get-Action -AbbreviatedActions $row.OwnerActionsMissing.Split(',') -ReverseActionType Owner | Where-Object { $_ -notin @("MailItemsAccessed", "Send") }) -join ','
|
||||
}
|
||||
else {
|
||||
$result.Details | Export-Csv -Path $fileName -NoTypeInformation
|
||||
}
|
||||
$exportedTests += $result.TestNumber
|
||||
$newObjectDetails = $csv
|
||||
}
|
||||
else {
|
||||
$newObjectDetails = $details
|
||||
}
|
||||
$results += [PSCustomObject]@{ TestNumber = $test; Details = $newObjectDetails }
|
||||
}
|
||||
"6.1.3" {
|
||||
$details = $auditResult.Details
|
||||
if ($details -ne "No M365 E5 licenses found.") {
|
||||
$csv = $details | ConvertFrom-Csv -Delimiter '|'
|
||||
}
|
||||
else {
|
||||
$csv = $null
|
||||
}
|
||||
if ($null -ne $csv) {
|
||||
foreach ($row in $csv) {
|
||||
$row.AdminActionsMissing = (Get-Action -AbbreviatedActions $row.AdminActionsMissing.Split(',') -ReverseActionType Admin) -join ','
|
||||
$row.DelegateActionsMissing = (Get-Action -AbbreviatedActions $row.DelegateActionsMissing.Split(',') -ReverseActionType Delegate) -join ','
|
||||
$row.OwnerActionsMissing = (Get-Action -AbbreviatedActions $row.OwnerActionsMissing.Split(',') -ReverseActionType Owner) -join ','
|
||||
}
|
||||
$newObjectDetails = $csv
|
||||
}
|
||||
else {
|
||||
$newObjectDetails = $details
|
||||
}
|
||||
$results += [PSCustomObject]@{ TestNumber = $test; Details = $newObjectDetails }
|
||||
}
|
||||
Default {
|
||||
$details = $auditResult.Details
|
||||
$csv = $details | ConvertFrom-Csv -Delimiter '|'
|
||||
$results += [PSCustomObject]@{ TestNumber = $test; Details = $csv }
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($exportedTests.Count -gt 0) {
|
||||
Write-Information "The following tests were exported: $($exportedTests -join ', ')" -InformationAction Continue
|
||||
}
|
||||
else {
|
||||
}
|
||||
End {
|
||||
if ($ExportPath) {
|
||||
$timestamp = (Get-Date).ToString("yyyy.MM.dd_HH.mm.ss")
|
||||
$exportedTests = @()
|
||||
foreach ($result in $results) {
|
||||
$testDef = $script:TestDefinitionsObject | Where-Object { $_.Rec -eq $result.TestNumber }
|
||||
if ($testDef) {
|
||||
$fileName = "$ExportPath\$($timestamp)_$($result.TestNumber).$($testDef.TestFileName -replace '\.ps1$').csv"
|
||||
if ($result.Details.Count -eq 0) {
|
||||
Write-Information "No results found for test number $($result.TestNumber)." -InformationAction Continue
|
||||
}
|
||||
else {
|
||||
if (($result.Details -ne "No M365 E3 licenses found.") -and ($result.Details -ne "No M365 E5 licenses found.")) {
|
||||
if ($ExportToExcel) {
|
||||
$xlsxPath = [System.IO.Path]::ChangeExtension($fileName, '.xlsx')
|
||||
$result.Details | Export-Excel -Path $xlsxPath -WorksheetName Table -TableName Table -AutoSize -TableStyle Medium2
|
||||
$createdFiles += $xlsxPath # Add the created file to the array
|
||||
}
|
||||
else {
|
||||
$result.Details | Export-Csv -Path $fileName -NoTypeInformation
|
||||
$createdFiles += $fileName # Add the created file to the array
|
||||
}
|
||||
$exportedTests += $result.TestNumber
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($exportedTests.Count -gt 0) {
|
||||
Write-Information "The following tests were exported: $($exportedTests -join ', ')" -InformationAction Continue
|
||||
}
|
||||
else {
|
||||
if ($ExportOriginalTests) {
|
||||
Write-Information "Full audit results exported however, none of the following tests had exports: `n1.1.1, 1.3.1, 6.1.2, 6.1.3, 7.3.4" -InformationAction Continue
|
||||
}
|
||||
else {
|
||||
Write-Information "No specified tests were included in the export." -InformationAction Continue
|
||||
}
|
||||
}
|
||||
if ($ExportOriginalTests) {
|
||||
Write-Information "Full audit results exported however, none of the following tests had exports: `n1.1.1, 1.3.1, 6.1.2, 6.1.3, 7.3.4" -InformationAction Continue
|
||||
# Define the test numbers to check
|
||||
$TestNumbersToCheck = "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4"
|
||||
# Check for large details and update the AuditResults array
|
||||
$updatedAuditResults = Get-ExceededLengthResultDetail -AuditResults $AuditResults -TestNumbersToCheck $TestNumbersToCheck -ExportedTests $exportedTests -DetailsLengthLimit 30000 -PreviewLineCount 25
|
||||
$originalFileName = "$ExportPath\$timestamp`_M365FoundationsAudit.csv"
|
||||
if ($ExportToExcel) {
|
||||
$xlsxPath = [System.IO.Path]::ChangeExtension($originalFileName, '.xlsx')
|
||||
$updatedAuditResults | Export-Excel -Path $xlsxPath -WorksheetName Table -TableName Table -AutoSize -TableStyle Medium2
|
||||
$createdFiles += $xlsxPath # Add the created file to the array
|
||||
}
|
||||
else {
|
||||
$updatedAuditResults | Export-Csv -Path $originalFileName -NoTypeInformation
|
||||
$createdFiles += $originalFileName # Add the created file to the array
|
||||
}
|
||||
}
|
||||
# Hash each file and add it to a dictionary
|
||||
# Hash each file and save the hashes to a text file
|
||||
$hashFilePath = "$ExportPath\$timestamp`_Hashes.txt"
|
||||
$fileHashes = @()
|
||||
foreach ($file in $createdFiles) {
|
||||
$hash = Get-FileHash -Path $file -Algorithm SHA256
|
||||
$fileHashes += "$($file): $($hash.Hash)"
|
||||
}
|
||||
$fileHashes | Set-Content -Path $hashFilePath
|
||||
$createdFiles += $hashFilePath # Add the hash file to the array
|
||||
|
||||
# Create a zip file and add all the created files
|
||||
$zipFilePath = "$ExportPath\$timestamp`_M365FoundationsAudit.zip"
|
||||
Compress-Archive -Path $createdFiles -DestinationPath $zipFilePath
|
||||
|
||||
# Remove the original files after they have been added to the zip
|
||||
foreach ($file in $createdFiles) {
|
||||
Remove-Item -Path $file -Force
|
||||
}
|
||||
|
||||
# Compute the hash for the zip file and rename it
|
||||
$zipHash = Get-FileHash -Path $zipFilePath -Algorithm SHA256
|
||||
$newZipFilePath = "$ExportPath\$timestamp`_M365FoundationsAudit_$($zipHash.Hash.Substring(0, 8)).zip"
|
||||
Rename-Item -Path $zipFilePath -NewName $newZipFilePath
|
||||
|
||||
# Output the zip file path with hash
|
||||
[PSCustomObject]@{
|
||||
ZipFilePath = $newZipFilePath
|
||||
}
|
||||
} # End of ExportPath
|
||||
elseif ($OutputTestNumber) {
|
||||
if ($results[0].Details) {
|
||||
return $results[0].Details
|
||||
}
|
||||
else {
|
||||
Write-Information "No specified tests were included in the export." -InformationAction Continue
|
||||
Write-Information "No results found for test number $($OutputTestNumber)." -InformationAction Continue
|
||||
}
|
||||
}
|
||||
|
||||
if ($ExportOriginalTests) {
|
||||
# Define the test numbers to check
|
||||
$TestNumbersToCheck = "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4"
|
||||
|
||||
# Check for large details and update the AuditResults array
|
||||
$updatedAuditResults = Get-ExceededLengthResultDetail -AuditResults $AuditResults -TestNumbersToCheck $TestNumbersToCheck -ExportedTests $exportedTests -DetailsLengthLimit 30000 -PreviewLineCount 25
|
||||
$originalFileName = "$ExportPath\$timestamp`_M365FoundationsAudit.csv"
|
||||
if ($ExportToExcel) {
|
||||
$xlsxPath = [System.IO.Path]::ChangeExtension($originalFileName, '.xlsx')
|
||||
$updatedAuditResults | Export-Excel -Path $xlsxPath -WorksheetName Table -TableName Table -AutoSize -TableStyle Medium2
|
||||
}
|
||||
else {
|
||||
$updatedAuditResults | Export-Csv -Path $originalFileName -NoTypeInformation
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($OutputTestNumber) {
|
||||
if ($results[0].Details) {
|
||||
return $results[0].Details
|
||||
}
|
||||
else {
|
||||
Write-Information "No results found for test number $($OutputTestNumber)." -InformationAction Continue
|
||||
Write-Error "No valid operation specified. Please provide valid parameters."
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Error "No valid operation specified. Please provide valid parameters."
|
||||
# Output the created files at the end
|
||||
#if ($createdFiles.Count -gt 0) {
|
||||
########### $createdFiles
|
||||
#}
|
||||
}
|
||||
}
|
@@ -132,30 +132,23 @@ function Invoke-M365SecurityAudit {
|
||||
[Parameter(Mandatory = $false, HelpMessage = "The SharePoint tenant admin URL, which should end with '-admin.sharepoint.com'. If not specified none of the Sharepoint Online tests will run.")]
|
||||
[ValidatePattern('^https://[a-zA-Z0-9-]+-admin\.sharepoint\.com$')]
|
||||
[string]$TenantAdminUrl,
|
||||
|
||||
[Parameter(Mandatory = $false, HelpMessage = "Specify this to test only the default domain for password expiration and DKIM Config for tests '1.3.1' and 2.1.9. The domain name of your organization, e.g., 'example.com'.")]
|
||||
[ValidatePattern('^[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$')]
|
||||
[string]$DomainName,
|
||||
|
||||
# E-Level with optional ProfileLevel selection
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'ELevelFilter', HelpMessage = "Specifies the E-Level (E3 or E5) for the audit.")]
|
||||
[ValidateSet('E3', 'E5')]
|
||||
[string]$ELevel,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'ELevelFilter', HelpMessage = "Specifies the profile level (L1 or L2) for the audit.")]
|
||||
[ValidateSet('L1', 'L2')]
|
||||
[string]$ProfileLevel,
|
||||
|
||||
# IG Filters, one at a time
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'IG1Filter', HelpMessage = "Includes tests where IG1 is true.")]
|
||||
[switch]$IncludeIG1,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'IG2Filter', HelpMessage = "Includes tests where IG2 is true.")]
|
||||
[switch]$IncludeIG2,
|
||||
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'IG3Filter', HelpMessage = "Includes tests where IG3 is true.")]
|
||||
[switch]$IncludeIG3,
|
||||
|
||||
# Inclusion of specific recommendation numbers
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'RecFilter', HelpMessage = "Specifies specific recommendations to include in the audit. Accepts an array of recommendation numbers.")]
|
||||
[ValidateSet(
|
||||
@@ -168,7 +161,6 @@ function Invoke-M365SecurityAudit {
|
||||
'8.5.7', '8.6.1'
|
||||
)]
|
||||
[string[]]$IncludeRecommendation,
|
||||
|
||||
# Exclusion of specific recommendation numbers
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'SkipRecFilter', HelpMessage = "Specifies specific recommendations to exclude from the audit. Accepts an array of recommendation numbers.")]
|
||||
[ValidateSet(
|
||||
@@ -181,26 +173,21 @@ function Invoke-M365SecurityAudit {
|
||||
'8.5.7', '8.6.1'
|
||||
)]
|
||||
[string[]]$SkipRecommendation,
|
||||
|
||||
# Common parameters for all parameter sets
|
||||
[Parameter(Mandatory = $false, HelpMessage = "Specifies the approved cloud storage providers for the audit. Accepts an array of cloud storage provider names.")]
|
||||
[ValidateSet(
|
||||
'GoogleDrive', 'ShareFile', 'Box', 'DropBox', 'Egnyte'
|
||||
)]
|
||||
[string[]]$ApprovedCloudStorageProviders = @(),
|
||||
|
||||
[Parameter(Mandatory = $false, HelpMessage = "Specifies the approved federated domains for the audit test 8.2.1. Accepts an array of allowed domain names.")]
|
||||
[ValidatePattern('^[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$')]
|
||||
[string[]]$ApprovedFederatedDomains,
|
||||
|
||||
[Parameter(Mandatory = $false, HelpMessage = "Specifies that the cmdlet will not establish a connection to Microsoft 365 services.")]
|
||||
[switch]$DoNotConnect,
|
||||
|
||||
[Parameter(Mandatory = $false, HelpMessage = "Specifies that the cmdlet will not disconnect from Microsoft 365 services after execution.")]
|
||||
[switch]$DoNotDisconnect,
|
||||
|
||||
[Parameter(Mandatory = $false, HelpMessage = "Specifies that the cmdlet will not check for the presence of required modules.")]
|
||||
[switch]$NoModuleCheck,
|
||||
|
||||
[Parameter(Mandatory = $false, HelpMessage = "Specifies that the cmdlet will not prompt for confirmation before proceeding with established connections and will disconnect from all of them.")]
|
||||
[switch]$DoNotConfirmConnections
|
||||
)
|
||||
@@ -210,10 +197,8 @@ function Invoke-M365SecurityAudit {
|
||||
}
|
||||
# Ensure required modules are installed
|
||||
$requiredModules = Get-RequiredModule -AuditFunction
|
||||
|
||||
# Format the required modules list
|
||||
$requiredModulesFormatted = Format-RequiredModuleList -RequiredModules $requiredModules
|
||||
|
||||
# Check and install required modules if necessary
|
||||
if (!($NoModuleCheck) -and $PSCmdlet.ShouldProcess("Check for required modules: $requiredModulesFormatted", "Check")) {
|
||||
Write-Host "Checking for and installing required modules..." -ForegroundColor DarkMagenta
|
||||
@@ -221,13 +206,11 @@ function Invoke-M365SecurityAudit {
|
||||
Assert-ModuleAvailability -ModuleName $module.ModuleName -RequiredVersion $module.RequiredVersion -SubModules $module.SubModules
|
||||
}
|
||||
}
|
||||
|
||||
# Load test definitions from CSV
|
||||
$testDefinitionsPath = Join-Path -Path $PSScriptRoot -ChildPath "helper\TestDefinitions.csv"
|
||||
$testDefinitions = Import-Csv -Path $testDefinitionsPath
|
||||
# Load the Test Definitions into the script scope for use in other functions
|
||||
$script:TestDefinitionsObject = $testDefinitions
|
||||
|
||||
# Apply filters based on parameter sets
|
||||
$params = @{
|
||||
TestDefinitions = $testDefinitions
|
||||
@@ -256,17 +239,14 @@ function Invoke-M365SecurityAudit {
|
||||
# Initialize a collection to hold failed test details
|
||||
$script:FailedTests = [System.Collections.ArrayList]::new()
|
||||
} # End Begin
|
||||
|
||||
Process {
|
||||
$allAuditResults = [System.Collections.ArrayList]::new() # Initialize a collection to hold all results
|
||||
# Dynamically dot-source the test scripts
|
||||
$testsFolderPath = Join-Path -Path $PSScriptRoot -ChildPath "tests"
|
||||
$testFiles = Get-ChildItem -Path $testsFolderPath -Filter "Test-*.ps1" |
|
||||
Where-Object { $testsToLoad -contains $_.BaseName }
|
||||
|
||||
$totalTests = $testFiles.Count
|
||||
$currentTestIndex = 0
|
||||
|
||||
# Establishing connections if required
|
||||
try {
|
||||
$actualUniqueConnections = Get-UniqueConnection -Connections $requiredConnections
|
||||
@@ -279,8 +259,6 @@ function Invoke-M365SecurityAudit {
|
||||
Write-Host "Connection execution aborted: $_" -ForegroundColor Red
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
Write-Host "A total of $($totalTests) tests were selected to run..." -ForegroundColor DarkMagenta
|
||||
# Import the test functions
|
||||
@@ -297,7 +275,6 @@ function Invoke-M365SecurityAudit {
|
||||
$script:FailedTests.Add([PSCustomObject]@{ Test = $_.Name; Error = $_ })
|
||||
}
|
||||
}
|
||||
|
||||
$currentTestIndex = 0
|
||||
# Execute each test function from the prepared list
|
||||
foreach ($testFunction in $testFiles) {
|
||||
@@ -330,7 +307,6 @@ function Invoke-M365SecurityAudit {
|
||||
# Return all collected audit results
|
||||
# Define the test numbers to check
|
||||
$TestNumbersToCheck = "1.1.1", "1.3.1", "6.1.2", "6.1.3", "7.3.4"
|
||||
|
||||
# Check for large details in the audit results
|
||||
$exceedingTests = Get-ExceededLengthResultDetail -AuditResults $allAuditResults -TestNumbersToCheck $TestNumbersToCheck -ReturnExceedingTestsOnly -DetailsLengthLimit 30000
|
||||
if ($exceedingTests.Count -gt 0) {
|
||||
@@ -342,6 +318,3 @@ function Invoke-M365SecurityAudit {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -277,7 +277,15 @@
|
||||
<command:inputTypes>
|
||||
<command:inputType>
|
||||
<dev:type>
|
||||
<maml:name>[CISAuditResult[]], [string]</maml:name>
|
||||
<maml:name>[CISAuditResult[]] - An array of CISAuditResult objects.</maml:name>
|
||||
</dev:type>
|
||||
<maml:description>
|
||||
<maml:para></maml:para>
|
||||
</maml:description>
|
||||
</command:inputType>
|
||||
<command:inputType>
|
||||
<dev:type>
|
||||
<maml:name>[string] - A path to a CSV file.</maml:name>
|
||||
</dev:type>
|
||||
<maml:description>
|
||||
<maml:para></maml:para>
|
||||
@@ -287,7 +295,7 @@
|
||||
<command:returnValues>
|
||||
<command:returnValue>
|
||||
<dev:type>
|
||||
<maml:name>[PSCustomObject]</maml:name>
|
||||
<maml:name>[PSCustomObject] - A custom object containing the path to the zip file and its hash.</maml:name>
|
||||
</dev:type>
|
||||
<maml:description>
|
||||
<maml:para></maml:para>
|
||||
|
@@ -1,7 +1,6 @@
|
||||
function Test-AdministrativeAccountCompliance {
|
||||
[CmdletBinding()]
|
||||
param ()
|
||||
|
||||
begin {
|
||||
# The following conditions are checked:
|
||||
# Condition A: The administrative account is cloud-only (not synced).
|
||||
@@ -11,16 +10,12 @@ function Test-AdministrativeAccountCompliance {
|
||||
$recnum = "1.1.1"
|
||||
Write-Verbose "Starting Test-AdministrativeAccountCompliance with Rec: $recnum"
|
||||
}
|
||||
|
||||
process {
|
||||
|
||||
try {
|
||||
# Retrieve admin roles, assignments, and user details including licenses
|
||||
Write-Verbose "Retrieving admin roles, assignments, and user details including licenses"
|
||||
$adminRoleAssignments = Get-CISMgOutput -Rec $recnum
|
||||
|
||||
$adminRoleUsers = @()
|
||||
|
||||
foreach ($roleName in $adminRoleAssignments.Keys) {
|
||||
$assignments = $adminRoleAssignments[$roleName]
|
||||
foreach ($assignment in $assignments) {
|
||||
@@ -29,21 +24,16 @@ function Test-AdministrativeAccountCompliance {
|
||||
$userPrincipalName = $userDetails.UserPrincipalName
|
||||
$licenses = $assignment.Licenses
|
||||
$licenseString = if ($licenses) { ($licenses.SkuPartNumber -join '|') } else { "No Licenses Found" }
|
||||
|
||||
# Condition A: Check if the account is cloud-only
|
||||
$cloudOnlyStatus = if ($userDetails.OnPremisesSyncEnabled) { "Fail" } else { "Pass" }
|
||||
|
||||
# Condition B: Check if the account has valid licenses
|
||||
$hasValidLicense = $licenses.SkuPartNumber | ForEach-Object { $validLicenses -contains $_ }
|
||||
$validLicensesStatus = if ($hasValidLicense) { "Pass" } else { "Fail" }
|
||||
|
||||
# Condition C: Check if the account has no other licenses
|
||||
$hasInvalidLicense = $licenses.SkuPartNumber | ForEach-Object { $validLicenses -notcontains $_ }
|
||||
$invalidLicenses = $licenses.SkuPartNumber | Where-Object { $validLicenses -notcontains $_ }
|
||||
$applicationAssignmentStatus = if ($hasInvalidLicense) { "Fail" } else { "Pass" }
|
||||
|
||||
Write-Verbose "User: $userPrincipalName, Cloud-Only: $cloudOnlyStatus, Valid Licenses: $validLicensesStatus, Invalid Licenses: $($invalidLicenses -join ', ')"
|
||||
|
||||
# Collect user information
|
||||
$adminRoleUsers += [PSCustomObject]@{
|
||||
UserName = $userPrincipalName
|
||||
@@ -57,17 +47,14 @@ function Test-AdministrativeAccountCompliance {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Group admin role users by UserName and collect unique roles and licenses
|
||||
Write-Verbose "Grouping admin role users by UserName"
|
||||
$uniqueAdminRoleUsers = $adminRoleUsers | Group-Object -Property UserName | ForEach-Object {
|
||||
$first = $_.Group | Select-Object -First 1
|
||||
$roles = ($_.Group.RoleName -join ', ')
|
||||
$licenses = (($_.Group | Select-Object -ExpandProperty Licenses) -join ',').Split(',') | Select-Object -Unique
|
||||
|
||||
$first | Select-Object UserName, UserId, HybridUser, @{Name = 'Roles'; Expression = { $roles } }, @{Name = 'Licenses'; Expression = { $licenses -join '|' } }, CloudOnlyStatus, ValidLicensesStatus, ApplicationAssignmentStatus
|
||||
}
|
||||
|
||||
# Identify non-compliant users based on conditions A, B, and C
|
||||
Write-Verbose "Identifying non-compliant users based on conditions"
|
||||
$nonCompliantUsers = $uniqueAdminRoleUsers | Where-Object {
|
||||
@@ -75,7 +62,6 @@ function Test-AdministrativeAccountCompliance {
|
||||
$_.ValidLicensesStatus -eq "Fail" -or # Fails Condition B
|
||||
$_.ApplicationAssignmentStatus -eq "Fail" # Fails Condition C
|
||||
}
|
||||
|
||||
# Generate failure reasons
|
||||
Write-Verbose "Generating failure reasons for non-compliant users"
|
||||
$failureReasons = $nonCompliantUsers | ForEach-Object {
|
||||
@@ -88,13 +74,10 @@ function Test-AdministrativeAccountCompliance {
|
||||
else {
|
||||
"Compliant Accounts: $($uniqueAdminRoleUsers.Count)"
|
||||
}
|
||||
|
||||
$result = $nonCompliantUsers.Count -eq 0
|
||||
$status = if ($result) { 'Pass' } else { 'Fail' }
|
||||
$details = if ($nonCompliantUsers) { "Username | Roles | Cloud-Only Status | EntraID P1/P2 License Status | Other Applications Assigned Status`n$failureReasons" } else { "N/A" }
|
||||
|
||||
Write-Verbose "Assessment completed. Result: $status"
|
||||
|
||||
# Create the parameter splat
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
@@ -103,7 +86,6 @@ function Test-AdministrativeAccountCompliance {
|
||||
Details = $details
|
||||
FailureReason = $failureReason
|
||||
}
|
||||
|
||||
$auditResult = Initialize-CISAuditResult @params
|
||||
}
|
||||
catch {
|
||||
@@ -111,7 +93,6 @@ function Test-AdministrativeAccountCompliance {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Output the result
|
||||
return $auditResult
|
||||
|
@@ -5,17 +5,14 @@ function Test-DisallowInfectedFilesDownload {
|
||||
# Aligned
|
||||
# Define your parameters here if needed
|
||||
)
|
||||
|
||||
begin {
|
||||
# Dot source the class script if necessary
|
||||
#. .\source\Classes\CISAuditResult.ps1
|
||||
|
||||
# Initialization code, if needed
|
||||
$recnum = "7.3.1"
|
||||
Write-Verbose "Running Test-DisallowInfectedFilesDownload for $recnum..."
|
||||
}
|
||||
|
||||
process {
|
||||
|
||||
try {
|
||||
# 7.3.1 (L2) Ensure Office 365 SharePoint infected files are disallowed for download
|
||||
#
|
||||
@@ -32,28 +29,30 @@ function Test-DisallowInfectedFilesDownload {
|
||||
# - Condition A: The `DisallowInfectedFileDownload` setting is not set to `True`.
|
||||
# - Condition B: The setting does not prevent users from downloading infected files.
|
||||
# - Condition C: Verification using the PowerShell command indicates that the setting is incorrectly configured.
|
||||
|
||||
# Retrieve the SharePoint tenant configuration
|
||||
# $SPOTenantDisallowInfectedFileDownload Mock Object
|
||||
<#
|
||||
$SPOTenantDisallowInfectedFileDownload = [PSCustomObject]@{
|
||||
DisallowInfectedFileDownload = $false
|
||||
}
|
||||
#>
|
||||
$SPOTenantDisallowInfectedFileDownload = Get-CISSpoOutput -Rec $recnum
|
||||
|
||||
# Condition A: The `DisallowInfectedFileDownload` setting is set to `True`
|
||||
$isDisallowInfectedFileDownloadEnabled = $SPOTenantDisallowInfectedFileDownload.DisallowInfectedFileDownload
|
||||
|
||||
# Prepare failure reasons and details based on compliance
|
||||
$failureReasons = if (-not $isDisallowInfectedFileDownloadEnabled) {
|
||||
"Downloading infected files is not disallowed." # Condition B: The setting does not prevent users from downloading infected files
|
||||
"Downloading infected files is not disallowed. To ensure infected files cannot be downloaded, use the following command:`n" + ` # Condition B: The setting does not prevent users from downloading infected files
|
||||
"Set-SPOTenant -DisallowInfectedFileDownload `$true"
|
||||
}
|
||||
else {
|
||||
"N/A"
|
||||
}
|
||||
|
||||
$details = if ($isDisallowInfectedFileDownloadEnabled) {
|
||||
"DisallowInfectedFileDownload: True" # Condition C: Verification confirms the setting is correctly configured
|
||||
}
|
||||
else {
|
||||
"DisallowInfectedFileDownload: False" # Condition C: Verification indicates the setting is incorrectly configured
|
||||
}
|
||||
|
||||
# Create and populate the CISAuditResult object
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
@@ -69,7 +68,6 @@ function Test-DisallowInfectedFilesDownload {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return the audit result
|
||||
return $auditResult
|
||||
|
@@ -4,7 +4,6 @@ function Test-GlobalAdminsCount {
|
||||
param (
|
||||
# Define your parameters here if needed
|
||||
)
|
||||
|
||||
begin {
|
||||
# Dot source the class script if necessary
|
||||
#. .\source\Classes\CISAuditResult.ps1
|
||||
@@ -23,23 +22,19 @@ function Test-GlobalAdminsCount {
|
||||
# - Condition A: The number of global admins is less than 2.
|
||||
# - Condition B: The number of global admins is more than 4.
|
||||
# - Condition C: Any discrepancies or errors in retrieving the list of global admin usernames.
|
||||
|
||||
# Initialization code, if needed
|
||||
$recnum = "1.1.3"
|
||||
Write-Verbose "Starting Test-GlobalAdminsCount with Rec: $recnum"
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
$globalAdmins = Get-CISMgOutput -Rec $recnum
|
||||
|
||||
# Step: Count the number of global admins
|
||||
$globalAdminCount = $globalAdmins.Count
|
||||
|
||||
# Step: Retrieve and format the usernames of global admins
|
||||
$globalAdminUsernames = ($globalAdmins | ForEach-Object {
|
||||
"$($_.AdditionalProperties["displayName"]) ($($_.AdditionalProperties["userPrincipalName"]))"
|
||||
}) -join ', '
|
||||
|
||||
# Step: Determine failure reasons based on global admin count
|
||||
$failureReasons = if ($globalAdminCount -lt 2) {
|
||||
"Less than 2 global admins: $globalAdminUsernames"
|
||||
@@ -50,10 +45,8 @@ function Test-GlobalAdminsCount {
|
||||
else {
|
||||
"N/A"
|
||||
}
|
||||
|
||||
# Step: Prepare details for the audit result
|
||||
$details = "Count: $globalAdminCount; Users: $globalAdminUsernames"
|
||||
|
||||
# Step: Create and populate the CISAuditResult object
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
@@ -69,7 +62,6 @@ function Test-GlobalAdminsCount {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return the audit result
|
||||
return $auditResult
|
||||
|
@@ -5,17 +5,14 @@ function Test-GuestAccessExpiration {
|
||||
# Aligned
|
||||
# Define your parameters here if needed
|
||||
)
|
||||
|
||||
begin {
|
||||
# Dot source the class script if necessary
|
||||
#. .\source\Classes\CISAuditResult.ps1
|
||||
|
||||
# Initialization code, if needed
|
||||
$recnum = "7.2.9"
|
||||
Write-Verbose "Running Test-GuestAccessExpiration for $recnum..."
|
||||
}
|
||||
|
||||
process {
|
||||
|
||||
try {
|
||||
# 7.2.9 (L1) Ensure guest access to a site or OneDrive will expire automatically
|
||||
#
|
||||
@@ -32,21 +29,25 @@ function Test-GuestAccessExpiration {
|
||||
# - Condition A: The ExternalUserExpirationRequired setting in SharePoint is not set to True.
|
||||
# - Condition B: The ExternalUserExpireInDays setting in SharePoint is configured to more than 30 days.
|
||||
# - Condition C: Verification using the SharePoint Admin Center indicates that guest access is not set to expire automatically after the specified number of days.
|
||||
|
||||
# Retrieve SharePoint tenant settings related to guest access expiration
|
||||
# $SPOTenantGuestAccess Mock Object
|
||||
<#
|
||||
$SPOTenantGuestAccess = [PSCustomObject]@{
|
||||
ExternalUserExpirationRequired = "$false"
|
||||
ExternalUserExpireInDays = "60"
|
||||
}
|
||||
#>
|
||||
$SPOTenantGuestAccess = Get-CISSpoOutput -Rec $recnum
|
||||
$isGuestAccessExpirationConfiguredCorrectly = $SPOTenantGuestAccess.ExternalUserExpirationRequired -and $SPOTenantGuestAccess.ExternalUserExpireInDays -le 30
|
||||
|
||||
# Prepare failure reasons and details based on compliance
|
||||
$failureReasons = if (-not $isGuestAccessExpirationConfiguredCorrectly) {
|
||||
"Guest access expiration is not configured to automatically expire within 30 days or less."
|
||||
"Guest access expiration is not configured to automatically expire within 30 days or less. To remediate this setting, use the Set-SPOTenant command:`n`n" + `
|
||||
"Set-SPOTenant -ExternalUserExpirationRequired `$true -ExternalUserExpireInDays 30"
|
||||
}
|
||||
else {
|
||||
"N/A"
|
||||
}
|
||||
|
||||
$details = "ExternalUserExpirationRequired: $($SPOTenantGuestAccess.ExternalUserExpirationRequired); ExternalUserExpireInDays: $($SPOTenantGuestAccess.ExternalUserExpireInDays)"
|
||||
|
||||
# Create and populate the CISAuditResult object
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
@@ -62,7 +63,6 @@ function Test-GuestAccessExpiration {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return the audit result
|
||||
return $auditResult
|
||||
|
@@ -6,14 +6,13 @@ function Test-LinkSharingRestrictions {
|
||||
# Define your parameters here
|
||||
# Test behavior in prod
|
||||
)
|
||||
|
||||
begin {
|
||||
# Dot source the class script if necessary
|
||||
#. .\source\Classes\CISAuditResult.ps1
|
||||
# Initialization code, if needed
|
||||
$recnum = "7.2.7"
|
||||
Write-Verbose "Running Test-LinkSharingRestrictions for $recnum..."
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
# 7.2.7 (L1) Ensure link sharing is restricted in SharePoint and OneDrive
|
||||
@@ -31,21 +30,24 @@ function Test-LinkSharingRestrictions {
|
||||
# - Condition A: The `DefaultSharingLinkType` setting in SharePoint and OneDrive is not set to `Direct`.
|
||||
# - Condition B: The setting `Choose the type of link that's selected by default when users share files and folders in SharePoint and OneDrive` is not set to `Specific people (only the people the user specifies)`.
|
||||
# - Condition C: Verification using the UI indicates that the link sharing settings are not configured as recommended.
|
||||
|
||||
# Retrieve link sharing configuration for SharePoint and OneDrive
|
||||
# $SPOTenantLinkSharing Mock Object
|
||||
<#
|
||||
$$SPOTenantLinkSharing = [PSCustomObject]@{
|
||||
DefaultSharingLinkType = "Direct"
|
||||
}
|
||||
#>
|
||||
$SPOTenantLinkSharing = Get-CISSpoOutput -Rec $recnum
|
||||
$isLinkSharingRestricted = $SPOTenantLinkSharing.DefaultSharingLinkType -eq 'Direct' # Or 'SpecificPeople' as per the recommendation
|
||||
|
||||
# Prepare failure reasons and details based on compliance
|
||||
$failureReasons = if (-not $isLinkSharingRestricted) {
|
||||
"Link sharing is not restricted to 'Specific people'. Current setting: $($SPOTenantLinkSharing.DefaultSharingLinkType)"
|
||||
"Link sharing is not restricted to 'Specific people'. Current setting: $($SPOTenantLinkSharing.DefaultSharingLinkType). To remediate this setting, use the Set-SPOTenant command:`n`n" + `
|
||||
"Set-SPOTenant -DefaultSharingLinkType Direct"
|
||||
}
|
||||
else {
|
||||
"N/A"
|
||||
}
|
||||
|
||||
$details = "DefaultSharingLinkType: $($SPOTenantLinkSharing.DefaultSharingLinkType)"
|
||||
|
||||
# Create and populate the CISAuditResult object
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
@@ -55,14 +57,12 @@ function Test-LinkSharingRestrictions {
|
||||
FailureReason = $failureReasons
|
||||
}
|
||||
$auditResult = Initialize-CISAuditResult @params
|
||||
|
||||
}
|
||||
catch {
|
||||
$LastError = $_
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return the audit result
|
||||
return $auditResult
|
||||
|
@@ -4,14 +4,12 @@ function Test-ManagedApprovedPublicGroups {
|
||||
param (
|
||||
# Parameters can be added if needed
|
||||
)
|
||||
|
||||
begin {
|
||||
# Dot source the class script if necessary
|
||||
#. .\source\Classes\CISAuditResult.ps1
|
||||
|
||||
# Initialization code, if needed
|
||||
$recnum = "1.2.1"
|
||||
|
||||
Write-Verbose "Starting Test-ManagedApprovedPublicGroups with Rec: $recnum"
|
||||
# Conditions for 1.2.1 (L2) Ensure that only organizationally managed/approved public groups exist (Automated)
|
||||
#
|
||||
# Validate test for a pass:
|
||||
@@ -26,12 +24,10 @@ function Test-ManagedApprovedPublicGroups {
|
||||
# - Condition A: One or more groups have the status 'Public' in the privacy column on the Active teams and groups page.
|
||||
# - Condition B: Using Microsoft Graph PowerShell, one or more groups return a status of 'Public' when checked.
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
# Step: Retrieve all groups with visibility set to 'Public'
|
||||
$allGroups = Get-CISMgOutput -Rec $recnum
|
||||
|
||||
# Step: Determine failure reasons based on the presence of public groups
|
||||
$failureReasons = if ($null -ne $allGroups -and $allGroups.Count -gt 0) {
|
||||
"There are public groups present that are not organizationally managed/approved."
|
||||
@@ -39,7 +35,6 @@ function Test-ManagedApprovedPublicGroups {
|
||||
else {
|
||||
"N/A"
|
||||
}
|
||||
|
||||
# Step: Prepare details for the audit result
|
||||
$details = if ($null -eq $allGroups -or $allGroups.Count -eq 0) {
|
||||
"No public groups found."
|
||||
@@ -48,7 +43,6 @@ function Test-ManagedApprovedPublicGroups {
|
||||
$groupDetails = $allGroups | ForEach-Object { $_.DisplayName + " (" + $_.Visibility + ")" }
|
||||
"Public groups found: $($groupDetails -join ', ')"
|
||||
}
|
||||
|
||||
# Step: Create and populate the CISAuditResult object
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
@@ -64,7 +58,6 @@ function Test-ManagedApprovedPublicGroups {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return the audit result
|
||||
return $auditResult
|
||||
|
@@ -12,16 +12,14 @@ function Test-ModernAuthSharePoint {
|
||||
|
||||
# Initialization code, if needed
|
||||
$recnum = "7.2.1"
|
||||
|
||||
Write-Verbose "Running Test-ModernAuthSharePoint for $recnum..."
|
||||
<#
|
||||
# Conditions for 7.2.1 (L1) Ensure modern authentication for SharePoint applications is required
|
||||
|
||||
## Validate test for a pass:
|
||||
# - Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark.
|
||||
# - Specific conditions to check:
|
||||
# - Condition A: The setting "Apps that don't use modern authentication" is set to "Block access" in the SharePoint admin center.
|
||||
# - Condition B: The PowerShell command `Get-SPOTenant | ft LegacyAuthProtocolsEnabled` returns `False`.
|
||||
|
||||
## Validate test for a fail:
|
||||
# - Confirm that the failure conditions in the automated test are consistent with the manual audit results.
|
||||
# - Specific conditions to check:
|
||||
@@ -29,23 +27,25 @@ function Test-ModernAuthSharePoint {
|
||||
# - Condition B: The PowerShell command `Get-SPOTenant | ft LegacyAuthProtocolsEnabled` returns `True`.
|
||||
#>
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
# 7.2.1 (L1) Ensure modern authentication for SharePoint applications is required
|
||||
# $SPOTenant Mock Object
|
||||
<#
|
||||
$SPOTenant = [PSCustomObject]@{
|
||||
LegacyAuthProtocolsEnabled = $true
|
||||
}
|
||||
#>
|
||||
$SPOTenant = Get-CISSpoOutput -Rec $recnum
|
||||
$modernAuthForSPRequired = -not $SPOTenant.LegacyAuthProtocolsEnabled
|
||||
|
||||
# Prepare failure reasons and details based on compliance
|
||||
$failureReasons = if (-not $modernAuthForSPRequired) {
|
||||
"Legacy authentication protocols are enabled" # Fail Condition B
|
||||
"Legacy authentication protocols are enabled. The following command can be used to disable:`nSet-SPOTenant -LegacyAuthProtocolsEnabled `$false" # Fail Condition B
|
||||
}
|
||||
else {
|
||||
"N/A"
|
||||
}
|
||||
|
||||
$details = "LegacyAuthProtocolsEnabled: $($SPOTenant.LegacyAuthProtocolsEnabled)" # Details for Condition B
|
||||
|
||||
# Create and populate the CISAuditResult object
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
@@ -61,7 +61,6 @@ function Test-ModernAuthSharePoint {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return the audit result
|
||||
return $auditResult
|
||||
|
@@ -5,7 +5,6 @@ function Test-OneDriveContentRestrictions {
|
||||
# Aligned
|
||||
# Define your parameters here
|
||||
)
|
||||
|
||||
begin {
|
||||
# 7.2.4 (L2) Ensure OneDrive content sharing is restricted
|
||||
#
|
||||
@@ -22,36 +21,38 @@ function Test-OneDriveContentRestrictions {
|
||||
# - Condition A: The OneDriveSharingCapability setting is not configured to "Disabled" using the PowerShell cmdlet `Get-SPOTenant | fl OneDriveSharingCapability`.
|
||||
# - Condition B: The OneDriveSharingCapability is not set to "Only people in your organization" in the SharePoint admin center under Policies > Sharing > OneDrive.
|
||||
# - Condition C: OneDrive content sharing is more permissive than SharePoint content sharing.
|
||||
|
||||
# Dot source the class script if necessary
|
||||
#. .\source\Classes\CISAuditResult.ps1
|
||||
# Initialization code, if needed
|
||||
$recnum = "7.2.4"
|
||||
Write-Verbose "Running Test-OneDriveContentRestrictions for $recnum..."
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
# 7.2.4 (L2) Ensure OneDrive content sharing is restricted
|
||||
|
||||
# Retrieve OneDrive sharing capability settings
|
||||
# $SPOTenant Mock Object
|
||||
<#
|
||||
$SPOTenant = [PSCustomObject]@{
|
||||
OneDriveSharingCapability = "ExternalUserAndGuestSharing"
|
||||
}
|
||||
#>
|
||||
$SPOTenant = Get-CISSpoOutput -Rec $recnum
|
||||
$isOneDriveSharingRestricted = $SPOTenant.OneDriveSharingCapability -eq 'Disabled'
|
||||
|
||||
# Prepare failure reasons and details based on compliance
|
||||
$failureReasons = if (-not $isOneDriveSharingRestricted) {
|
||||
"OneDrive content sharing is not restricted to 'Disabled'. Current setting: $($SPOTenant.OneDriveSharingCapability)"
|
||||
"OneDrive content sharing is not restricted to 'Disabled'. To remediate this setting, use the Set-SPOTenant command.`n`n" + `
|
||||
"Set-SPOTenant -OneDriveSharingCapability Disabled"
|
||||
}
|
||||
else {
|
||||
"N/A"
|
||||
}
|
||||
|
||||
$details = if ($isOneDriveSharingRestricted) {
|
||||
"OneDrive content sharing is restricted."
|
||||
}
|
||||
else {
|
||||
"OneDriveSharingCapability: $($SPOTenant.OneDriveSharingCapability)"
|
||||
}
|
||||
|
||||
# Create and populate the CISAuditResult object
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
@@ -67,7 +68,6 @@ function Test-OneDriveContentRestrictions {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return auditResult
|
||||
return $auditResult
|
||||
|
@@ -5,14 +5,13 @@ function Test-OneDriveSyncRestrictions {
|
||||
# Aligned
|
||||
# Define your parameters here
|
||||
)
|
||||
|
||||
begin {
|
||||
# Dot source the class script if necessary
|
||||
#. .\source\Classes\CISAuditResult.ps1
|
||||
# Initialization code, if needed
|
||||
$recnum = "7.3.2"
|
||||
Write-Verbose "Running Test-OneDriveSyncRestrictions for $recnum..."
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
# 7.3.2 (L2) Ensure OneDrive sync is restricted for unmanaged devices
|
||||
@@ -30,20 +29,20 @@ function Test-OneDriveSyncRestrictions {
|
||||
# - Condition A: "Allow syncing only on computers joined to specific domains" is not enabled.
|
||||
# - Condition B: "TenantRestrictionEnabled" is set to False.
|
||||
# - Condition C: "AllowedDomainList" does not contain the trusted domain GUIDs from the on-premises environment.
|
||||
|
||||
# Retrieve OneDrive sync client restriction settings
|
||||
$SPOTenantSyncClientRestriction = Get-CISSpoOutput -Rec $recnum
|
||||
$isSyncRestricted = $SPOTenantSyncClientRestriction.TenantRestrictionEnabled -and $SPOTenantSyncClientRestriction.AllowedDomainList
|
||||
|
||||
# Condition A: Check if TenantRestrictionEnabled is True
|
||||
# Condition B: Ensure AllowedDomainList contains trusted domains GUIDs
|
||||
$failureReasons = if (-not $isSyncRestricted) {
|
||||
"OneDrive sync is not restricted to managed devices. TenantRestrictionEnabled should be True and AllowedDomainList should contain trusted domains GUIDs."
|
||||
"OneDrive sync is not restricted to managed devices. For hybrid devices, TenantRestrictionEnabled should be True and AllowedDomainList should contain trusted domains GUIDs.`n" + `
|
||||
"To remediate this setting, edit and use the Set-SPOTenantSyncClientRestriction command below:`n" + `
|
||||
"Set-SPOTenantSyncClientRestriction -TenantRestrictionEnabled `$true -AllowedDomainList `"<GUID1>`",`"<GUID2>`"`n`n" + `
|
||||
"Note: Utilize the -BlockMacSync:`$true parameter if you are not using conditional access to ensure Macs cannot sync."
|
||||
}
|
||||
else {
|
||||
"N/A"
|
||||
}
|
||||
|
||||
# Condition C: Prepare details based on whether sync is restricted
|
||||
$details = if ($isSyncRestricted) {
|
||||
"OneDrive sync is restricted for unmanaged devices."
|
||||
@@ -51,7 +50,6 @@ function Test-OneDriveSyncRestrictions {
|
||||
else {
|
||||
"TenantRestrictionEnabled: $($SPOTenantSyncClientRestriction.TenantRestrictionEnabled); AllowedDomainList: $($SPOTenantSyncClientRestriction.AllowedDomainList -join ', ')"
|
||||
}
|
||||
|
||||
# Create and populate the CISAuditResult object
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
@@ -67,7 +65,6 @@ function Test-OneDriveSyncRestrictions {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return auditResult
|
||||
return $auditResult
|
||||
|
@@ -5,7 +5,6 @@ function Test-PasswordHashSync {
|
||||
# Aligned
|
||||
# Parameters can be added if needed
|
||||
)
|
||||
|
||||
begin {
|
||||
# Conditions for 5.1.8.1 (L1) Ensure password hash sync is enabled for hybrid deployments
|
||||
#
|
||||
@@ -22,21 +21,18 @@ function Test-PasswordHashSync {
|
||||
# - Condition A: Password hash sync is not enabled in the Azure AD Connect tool on the on-premises server.
|
||||
# - Condition B: Password hash sync is not verified as enabled in the Azure AD Connect Sync section in the Microsoft Entra admin center.
|
||||
# - Condition C: Using Microsoft Graph PowerShell, the verification command returns no result indicating that password sync is not enabled for the on-premises AD.
|
||||
|
||||
# Dot source the class script if necessary
|
||||
#. .\source\Classes\CISAuditResult.ps1
|
||||
# Initialization code, if needed
|
||||
$recnum = "5.1.8.1"
|
||||
Write-Verbose "Starting Test-PasswordHashSync with Rec: $recnum"
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
# 5.1.8.1 (L1) Ensure password hash sync is enabled for hybrid deployments
|
||||
|
||||
# Retrieve password hash sync status (Condition A and C)
|
||||
$passwordHashSync = Get-CISMgOutput -Rec $recnum
|
||||
$hashSyncResult = $passwordHashSync
|
||||
|
||||
# Prepare failure reasons and details based on compliance
|
||||
$failureReasons = if (-not $hashSyncResult) {
|
||||
"Password hash sync for hybrid deployments is not enabled"
|
||||
@@ -44,9 +40,7 @@ function Test-PasswordHashSync {
|
||||
else {
|
||||
"N/A"
|
||||
}
|
||||
|
||||
$details = "OnPremisesSyncEnabled: $($passwordHashSync)"
|
||||
|
||||
# Create and populate the CISAuditResult object
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
@@ -62,7 +56,6 @@ function Test-PasswordHashSync {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return the audit result
|
||||
return $auditResult
|
||||
|
@@ -5,7 +5,6 @@ function Test-ReauthWithCode {
|
||||
# Aligned
|
||||
# Define your parameters here
|
||||
)
|
||||
|
||||
begin {
|
||||
<#
|
||||
Conditions for 7.2.10 (L1) Ensure reauthentication with verification code is restricted
|
||||
@@ -22,31 +21,34 @@ function Test-ReauthWithCode {
|
||||
# - Condition A: The `EmailAttestationRequired` property is set to `False`.
|
||||
# - Condition B: The `EmailAttestationReAuthDays` property is set to more than `15`.
|
||||
#>
|
||||
|
||||
# Dot source the class script if necessary
|
||||
#. .\source\Classes\CISAuditResult.ps1
|
||||
# Initialization code, if needed
|
||||
$recnum = "7.2.10"
|
||||
Write-Verbose "Running Test-ReauthWithCode for $recnum..."
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
# 7.2.10 (L1) Ensure reauthentication with verification code is restricted
|
||||
|
||||
# Retrieve reauthentication settings for SharePoint Online
|
||||
# $SPOTenantReauthentication Mock Object
|
||||
<#
|
||||
$SPOTenantReauthentication = [PSCustomObject]@{
|
||||
EmailAttestationRequired = "$false"
|
||||
EmailAttestationReAuthDays = "30"
|
||||
}
|
||||
#>
|
||||
$SPOTenantReauthentication = Get-CISSpoOutput -Rec $recnum
|
||||
$isReauthenticationRestricted = $SPOTenantReauthentication.EmailAttestationRequired -and $SPOTenantReauthentication.EmailAttestationReAuthDays -le 15
|
||||
|
||||
# Prepare failure reasons and details based on compliance
|
||||
$failureReasons = if (-not $isReauthenticationRestricted) {
|
||||
"Reauthentication with verification code does not require reauthentication within 15 days or less."
|
||||
"Reauthentication with verification code does not require reauthentication within 15 days or less. To remediate this setting, use the Set-SPOTenant command:`n" + `
|
||||
"Set-SPOTenant -EmailAttestationRequired `$true -EmailAttestationReAuthDays 15"
|
||||
}
|
||||
else {
|
||||
"N/A"
|
||||
}
|
||||
|
||||
$details = "EmailAttestationRequired: $($SPOTenantReauthentication.EmailAttestationRequired); EmailAttestationReAuthDays: $($SPOTenantReauthentication.EmailAttestationReAuthDays)"
|
||||
|
||||
# Create and populate the CISAuditResult object
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
@@ -62,7 +64,6 @@ function Test-ReauthWithCode {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return auditResult
|
||||
return $auditResult
|
||||
|
@@ -4,15 +4,13 @@ function Test-RestrictCustomScripts {
|
||||
param (
|
||||
# Define your parameters here if needed
|
||||
)
|
||||
|
||||
begin {
|
||||
# Dot source the class script if necessary
|
||||
# . .\source\Classes\CISAuditResult.ps1
|
||||
|
||||
# Initialization code, if needed
|
||||
$recnum = "7.3.4"
|
||||
Write-Verbose "Running Test-RestrictCustomScripts for $recnum..."
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
# 7.3.4 (L1) Ensure custom script execution is restricted on site collections
|
||||
@@ -30,23 +28,27 @@ function Test-RestrictCustomScripts {
|
||||
# - Condition A: The `DenyAddAndCustomizePages` setting is not set to `Enabled` for any site collection.
|
||||
# - Condition B: The setting is not validated through PowerShell commands, indicating misconfiguration.
|
||||
# - Condition C: Verification using the SharePoint Admin Center indicates that the `DenyAddAndCustomizePages` setting is not enforced.
|
||||
|
||||
# Retrieve all site collections and select necessary properties
|
||||
# $SPOSitesCustomScript Mock Object
|
||||
<#
|
||||
$SPOSitesCustomScript = [PSCustomObject]@{
|
||||
Title = "Site Collection 1"
|
||||
Url = "https://contoso.sharepoint.com/sites/site1"
|
||||
DenyAddAndCustomizePages = "Enabled"
|
||||
}
|
||||
#>
|
||||
$SPOSitesCustomScript = Get-CISSpoOutput -Rec $recnum
|
||||
|
||||
# Process URLs to replace 'sharepoint.com' with '<SPUrl>'
|
||||
$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) {
|
||||
@@ -57,7 +59,6 @@ function Test-RestrictCustomScripts {
|
||||
}
|
||||
}
|
||||
Write-Verbose "Extracted hostnames: $($hostnames -join ', ')"
|
||||
|
||||
# Find the most used hostname using the Get-MostCommonWord function
|
||||
$mostUsedHostname = Get-MostCommonWord -InputStrings $hostnames
|
||||
Write-Verbose "Most used hostname: $mostUsedHostname"
|
||||
@@ -65,7 +66,6 @@ function Test-RestrictCustomScripts {
|
||||
#$verbosePreference = 'SilentlyContinue'
|
||||
# Compliance is true if no sites allow custom scripts
|
||||
$complianceResult = $customScriptAllowedSites.Count -eq 0
|
||||
|
||||
# Gather details for non-compliant sites (where custom scripts are allowed)
|
||||
$nonCompliantSiteDetails = $customScriptAllowedSites | ForEach-Object {
|
||||
$url = $_.Url
|
||||
@@ -74,32 +74,29 @@ function Test-RestrictCustomScripts {
|
||||
}
|
||||
"$(if ($_.Title) {$_.Title} else {"NoTitle"})|$url"
|
||||
}
|
||||
|
||||
# Prepare failure reasons and details based on compliance
|
||||
$failureReasons = if (-not $complianceResult) {
|
||||
"Some site collections are not restricting custom script execution. Review Details property for sites that are not aligned with the benchmark."
|
||||
"Some site collections are not restricting custom script execution. Review Details property for sites that are not aligned with the benchmark.`n" + `
|
||||
"To remediate this setting, use the following command:`n" + `
|
||||
"Set-SPOSite -Identity <SiteUrl> -DenyAddAndCustomizePages `$true"
|
||||
}
|
||||
else {
|
||||
"N/A"
|
||||
}
|
||||
|
||||
$details = if ($complianceResult) {
|
||||
"All site collections have custom script execution restricted"
|
||||
}
|
||||
else {
|
||||
"Title|Url`n" + ($nonCompliantSiteDetails -join "`n")
|
||||
}
|
||||
|
||||
# Convert details to PSObject and check length
|
||||
$detailsPSObject = $details | ConvertFrom-Csv -Delimiter '|'
|
||||
$detailsLength = ($detailsPSObject | ForEach-Object { $_.Url }).Length
|
||||
|
||||
if ($detailsLength -gt 32767) {
|
||||
# Create a preview of the first 10 results
|
||||
$preview = $detailsPSObject | Select-Object -First 10 | ForEach-Object { "$($_.Title)|$($_.Url)" }
|
||||
$details = "The output is too large. Here is a preview of the first 10 results:`n`n" + ($preview -join "`n") + "`n`nPlease run the test with the following commands to get the full details:`n`nGet-SPOSite -Limit All | Where-Object { `$.DenyAddAndCustomizePages -ne 'Enabled' } | Select-Object Title, Url"
|
||||
}
|
||||
|
||||
# Create and populate the CISAuditResult object
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
|
@@ -5,18 +5,15 @@ function Test-RestrictExternalSharing {
|
||||
# Aligned
|
||||
# Define your parameters here
|
||||
)
|
||||
|
||||
begin {
|
||||
<#
|
||||
Conditions for 7.2.3 (L1) Ensure external content sharing is restricted
|
||||
|
||||
Validate test for a pass:
|
||||
- Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark.
|
||||
- Specific conditions to check:
|
||||
- Condition A: The SharingCapability is set to "ExternalUserSharingOnly" or more restrictive in the SharePoint admin center.
|
||||
- Condition B: Using PowerShell, the SharingCapability property for the SharePoint tenant is set to "ExternalUserSharingOnly", "ExistingExternalUserSharingOnly", or "Disabled".
|
||||
- Condition C: The external sharing settings in SharePoint Online and OneDrive are set to the same or a more restrictive level than the organization’s sharing settings.
|
||||
|
||||
Validate test for a fail:
|
||||
- Confirm that the failure conditions in the automated test are consistent with the manual audit results.
|
||||
- Specific conditions to check:
|
||||
@@ -24,34 +21,37 @@ function Test-RestrictExternalSharing {
|
||||
- Condition B: Using PowerShell, the SharingCapability property for the SharePoint tenant is set to "Anyone" or "ExternalUserAndGuestSharing".
|
||||
- Condition C: The external sharing settings in SharePoint Online and OneDrive are set to a more permissive level than the organization’s sharing settings.
|
||||
#>
|
||||
|
||||
# Dot source the class script if necessary
|
||||
#. .\source\Classes\CISAuditResult.ps1
|
||||
# Initialization code, if needed
|
||||
$recnum = "7.2.3"
|
||||
Write-Verbose "Running Test-RestrictExternalSharing for $recnum..."
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
# 7.2.3 (L1) Ensure external content sharing is restricted
|
||||
|
||||
# Retrieve the SharingCapability setting for the SharePoint tenant
|
||||
<#
|
||||
$SPOTenantSharingCapability = [PSCustomObject]@{
|
||||
SharingCapability = "ExternalUserAndGuestSharing"
|
||||
}
|
||||
#>
|
||||
$SPOTenantSharingCapability = Get-CISSpoOutput -Rec $recnum
|
||||
$isRestricted = $SPOTenantSharingCapability.SharingCapability -in @('ExternalUserSharingOnly', 'ExistingExternalUserSharingOnly', 'Disabled')
|
||||
|
||||
# Prepare failure reasons and details based on compliance
|
||||
# Condition B: Using PowerShell, the SharingCapability property for the SharePoint tenant is set to "ExternalUserSharingOnly", "ExistingExternalUserSharingOnly", or "Disabled".
|
||||
$failureReasons = if (-not $isRestricted) {
|
||||
"External content sharing is not adequately restricted. Current setting: $($SPOTenantSharingCapability.SharingCapability)"
|
||||
"External content sharing is not adequately restricted. Current setting: $($SPOTenantSharingCapability.SharingCapability)`n" + `
|
||||
"The acceptable values for SharingCapability are: 'ExternalUserSharingOnly', 'ExistingExternalUserSharingOnly', or 'Disabled'.`n" + `
|
||||
"To remediate this setting, use the Set-SPOTenant cmdlet to set the SharingCapability property to an acceptable value:`n`n" + `
|
||||
"Set-SPOTenant -SharingCapability <acceptable value from above>"
|
||||
}
|
||||
else {
|
||||
"N/A"
|
||||
}
|
||||
|
||||
# Condition A: The SharingCapability is set to "ExternalUserSharingOnly" or more restrictive in the SharePoint admin center.
|
||||
# Condition C: The external sharing settings in SharePoint Online and OneDrive are set to the same or a more restrictive level than the organization’s sharing settings.
|
||||
$details = "SharingCapability: $($SPOTenantSharingCapability.SharingCapability)"
|
||||
|
||||
# Create and populate the CISAuditResult object
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
@@ -67,7 +67,6 @@ function Test-RestrictExternalSharing {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return auditResult
|
||||
return $auditResult
|
||||
|
@@ -5,23 +5,19 @@ function Test-RestrictTenantCreation {
|
||||
# Aligned
|
||||
# Parameters can be added if needed
|
||||
)
|
||||
|
||||
begin {
|
||||
# Dot source the class script if necessary
|
||||
#. .\source\Classes\CISAuditResult.ps1
|
||||
|
||||
# Initialization code, if needed
|
||||
$recnum = "5.1.2.3"
|
||||
|
||||
Write-Verbose "Starting Test-RestrictTenantCreation with Rec: $recnum"
|
||||
<#
|
||||
Conditions for 5.1.2.3 (L1) Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes'
|
||||
|
||||
Validate test for a pass:
|
||||
- Confirm that the automated test results align with the manual audit steps outlined in the CIS benchmark.
|
||||
- Specific conditions to check:
|
||||
- Condition A: Restrict non-admin users from creating tenants is set to 'Yes' in the Azure AD and Entra administration portal.
|
||||
- Condition B: Using PowerShell, the setting for restricting non-admin users from creating tenants is set to 'Yes'.
|
||||
|
||||
Validate test for a fail:
|
||||
- Confirm that the failure conditions in the automated test are consistent with the manual audit results.
|
||||
- Specific conditions to check:
|
||||
@@ -29,15 +25,12 @@ function Test-RestrictTenantCreation {
|
||||
- Condition B: Using PowerShell, the setting for restricting non-admin users from creating tenants is not set to 'Yes'.
|
||||
#>
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
# 5.1.2.3 (L1) Ensure 'Restrict non-admin users from creating tenants' is set to 'Yes'
|
||||
|
||||
# Retrieve the tenant creation policy
|
||||
$tenantCreationPolicy = Get-CISMgOutput -Rec $recnum
|
||||
$tenantCreationResult = -not $tenantCreationPolicy.AllowedToCreateTenants
|
||||
|
||||
# Prepare failure reasons and details based on compliance
|
||||
$failureReasons = if ($tenantCreationResult) {
|
||||
"N/A"
|
||||
@@ -45,9 +38,7 @@ function Test-RestrictTenantCreation {
|
||||
else {
|
||||
"Non-admin users can create tenants"
|
||||
}
|
||||
|
||||
$details = "AllowedToCreateTenants: $($tenantCreationPolicy.AllowedToCreateTenants)"
|
||||
|
||||
# Create and populate the CISAuditResult object
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
@@ -63,7 +54,6 @@ function Test-RestrictTenantCreation {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return the audit result
|
||||
return $auditResult
|
||||
|
@@ -5,7 +5,6 @@ function Test-SharePointAADB2B {
|
||||
# Aligned
|
||||
# Define your parameters here
|
||||
)
|
||||
|
||||
begin {
|
||||
# Conditions for 7.2.2 (L1) Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled
|
||||
#
|
||||
@@ -22,26 +21,29 @@ function Test-SharePointAADB2B {
|
||||
# - Condition A: The `EnableAzureADB2BIntegration` property is set to `False` for the SharePoint tenant.
|
||||
# - Condition B: The integration between SharePoint, OneDrive, and Azure AD B2B is not active.
|
||||
# - Condition C: Guest accounts are not managed in Azure AD and are not subject to access policies.
|
||||
|
||||
# Dot source the class script if necessary
|
||||
#. .\source\Classes\CISAuditResult.ps1
|
||||
# Initialization code, if needed
|
||||
|
||||
$recnum = "7.2.2"
|
||||
Write-Verbose "Running Test-SharePointAADB2B for $recnum..."
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
# 7.2.2 (L1) Ensure SharePoint and OneDrive integration with Azure AD B2B is enabled
|
||||
# $SPOTenantAzureADB2B Mock Object
|
||||
<#
|
||||
$SPOTenantAzureADB2B = [PSCustomObject]@{
|
||||
EnableAzureADB2BIntegration = $false
|
||||
}
|
||||
#>
|
||||
$SPOTenantAzureADB2B = Get-CISSpoOutput -Rec $recnum
|
||||
|
||||
# Populate the auditResult object with the required properties
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
Result = $SPOTenantAzureADB2B.EnableAzureADB2BIntegration
|
||||
Status = if ($SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Pass" } else { "Fail" }
|
||||
Details = "EnableAzureADB2BIntegration: $($SPOTenantAzureADB2B.EnableAzureADB2BIntegration)"
|
||||
FailureReason = if (-not $SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Azure AD B2B integration is not enabled" } else { "N/A" }
|
||||
FailureReason = if (-not $SPOTenantAzureADB2B.EnableAzureADB2BIntegration) { "Azure AD B2B integration is not enabled. The following command can be used to enable:`nSet-SPOTenant -EnableAzureADB2BIntegration `$true" } else { "N/A" }
|
||||
}
|
||||
$auditResult = Initialize-CISAuditResult @params
|
||||
}
|
||||
@@ -50,7 +52,6 @@ function Test-SharePointAADB2B {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return auditResult
|
||||
return $auditResult
|
||||
|
@@ -5,14 +5,12 @@ function Test-SharePointExternalSharingDomains {
|
||||
# Aligned
|
||||
# Define your parameters here
|
||||
)
|
||||
|
||||
begin {
|
||||
# Dot source the class script if necessary
|
||||
#. .\source\Classes\CISAuditResult.ps1
|
||||
|
||||
# Initialization code, if needed
|
||||
$recnum = "7.2.6"
|
||||
|
||||
Write-Verbose "Running Test-SharePointExternalSharingDomains for $recnum..."
|
||||
# Conditions for 7.2.6 (L2) Ensure SharePoint external sharing is managed through domain whitelist/blacklists
|
||||
#
|
||||
# Validate test for a pass:
|
||||
@@ -29,13 +27,18 @@ function Test-SharePointExternalSharingDomains {
|
||||
# - Condition B: The "SharingDomainRestrictionMode" is not set to "AllowList" using PowerShell.
|
||||
# - Condition C: The "SharingAllowedDomainList" does not contain the domains trusted by the organization for external sharing.
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
# 7.2.6 (L2) Ensure SharePoint external sharing is managed through domain whitelist/blacklists
|
||||
$SPOTenant = Get-CISSpoOutput -Rec $recnum
|
||||
# $SPOTenant Mock Object
|
||||
<#
|
||||
$SPOTenant = [PSCustomObject]@{
|
||||
SharingDomainRestrictionMode = "AllowList"
|
||||
SharingAllowedDomainList = "domain1.com", "domain2.com"
|
||||
}
|
||||
#>
|
||||
$isDomainRestrictionConfigured = $SPOTenant.SharingDomainRestrictionMode -eq 'AllowList'
|
||||
|
||||
# Populate the auditResult object with the required properties
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
@@ -51,7 +54,6 @@ function Test-SharePointExternalSharingDomains {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return auditResult
|
||||
return $auditResult
|
||||
|
@@ -5,14 +5,12 @@ function Test-SharePointGuestsItemSharing {
|
||||
# Aligned
|
||||
# Define your parameters here
|
||||
)
|
||||
|
||||
begin {
|
||||
# Dot source the class script if necessary
|
||||
#. .\source\Classes\CISAuditResult.ps1
|
||||
# Initialization code, if needed
|
||||
|
||||
$recnum = "7.2.5"
|
||||
|
||||
Write-Verbose "Running Test-SharePointGuestsItemSharing for $recnum..."
|
||||
# Conditions for 7.2.5 (L2) Ensure that SharePoint guest users cannot share items they don't own
|
||||
#
|
||||
# Validate test for a pass:
|
||||
@@ -29,20 +27,24 @@ function Test-SharePointGuestsItemSharing {
|
||||
# - Condition B: The SharePoint admin center setting "Allow guests to share items they don't own" is checked.
|
||||
# - Condition C: Ensure that external users can re-share items they don't own.
|
||||
}
|
||||
|
||||
process {
|
||||
try {
|
||||
# 7.2.5 (L2) Ensure that SharePoint guest users cannot share items they don't own
|
||||
# $SPOTenant Mock Object
|
||||
<#
|
||||
$SPOTenant = [PSCustomObject]@{
|
||||
PreventExternalUsersFromResharing = $false
|
||||
}
|
||||
#>
|
||||
$SPOTenant = Get-CISSpoOutput -Rec $recnum
|
||||
$isGuestResharingPrevented = $SPOTenant.PreventExternalUsersFromResharing
|
||||
|
||||
# Populate the auditResult object with the required properties
|
||||
$params = @{
|
||||
Rec = $recnum
|
||||
Result = $isGuestResharingPrevented
|
||||
Status = if ($isGuestResharingPrevented) { "Pass" } else { "Fail" }
|
||||
Details = "PreventExternalUsersFromResharing: $isGuestResharingPrevented"
|
||||
FailureReason = if (-not $isGuestResharingPrevented) { "Guest users can reshare items they don't own." } else { "N/A" }
|
||||
FailureReason = if (-not $isGuestResharingPrevented) { "Guest users can reshare items they don't own. To prevent external users from resharing content they don't own,`nuse the following command:`nSet-SPOTenant -PreventExternalUsersFromResharing `$True" } else { "N/A" }
|
||||
}
|
||||
$auditResult = Initialize-CISAuditResult @params
|
||||
}
|
||||
@@ -51,7 +53,6 @@ function Test-SharePointGuestsItemSharing {
|
||||
$auditResult = Get-TestError -LastError $LastError -recnum $recnum
|
||||
}
|
||||
}
|
||||
|
||||
end {
|
||||
# Return auditResult
|
||||
return $auditResult
|
||||
|
Reference in New Issue
Block a user