diff --git a/source/Private/Invoke-TestFunction.ps1 b/source/Private/Invoke-TestFunction.ps1 index d9a5997..5f6b944 100644 --- a/source/Private/Invoke-TestFunction.ps1 +++ b/source/Private/Invoke-TestFunction.ps1 @@ -3,7 +3,7 @@ function Invoke-TestFunction { [Parameter(Mandatory = $true)] [PSObject]$FunctionFile, - [Parameter(Mandatory = $true)] + [Parameter(Mandatory = $false)] [string]$DomainName ) diff --git a/source/Public/Invoke-M365SecurityAudit.ps1 b/source/Public/Invoke-M365SecurityAudit.ps1 index aa22711..87509c6 100644 --- a/source/Public/Invoke-M365SecurityAudit.ps1 +++ b/source/Public/Invoke-M365SecurityAudit.ps1 @@ -5,8 +5,8 @@ The Invoke-M365SecurityAudit cmdlet performs a comprehensive security audit based on the specified parameters. It allows auditing of various configurations and settings within a Microsoft 365 environment, such as compliance with CIS benchmarks. .PARAMETER TenantAdminUrl The URL of the tenant admin. This parameter is mandatory. - .PARAMETER DomainName - The domain name of the Microsoft 365 environment. This parameter is mandatory. + .PARAMETER M365DomainForPWPolicyTest + The domain name of the Microsoft 365 environment to test. This parameter is not mandatory and by default it will pass/fail all found domains as a group if a specific domain is not specified. .PARAMETER ELevel Specifies the E-Level (E3 or E5) for the audit. This parameter is optional and can be combined with the ProfileLevel parameter. .PARAMETER ProfileLevel @@ -67,9 +67,9 @@ function Invoke-M365SecurityAudit { [ValidatePattern('^https://[a-zA-Z0-9-]+-admin\.sharepoint\.com$')] [string]$TenantAdminUrl, - [Parameter(Mandatory = $true, HelpMessage = "The domain name of your organization, e.g., 'example.com'.")] + [Parameter(Mandatory = $false, HelpMessage = "Specify this to test only the default domain for password expiration policy when '1.3.1' is included in the tests to be run. The domain name of your organization, e.g., 'example.com'.")] [ValidatePattern('^[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$')] - [string]$DomainName, + [string]$M365DomainForPWPolicyTest, # E-Level with optional ProfileLevel selection [Parameter(Mandatory = $true, ParameterSetName = 'ELevelFilter')] @@ -194,7 +194,7 @@ function Invoke-M365SecurityAudit { Write-Progress -Activity "Executing Tests" -Status "Executing $($currentTestIndex) of $($totalTests): $($testFunction.Name)" -PercentComplete (($currentTestIndex / $totalTests) * 100) $functionName = $testFunction.BaseName if ($PSCmdlet.ShouldProcess($functionName, "Execute test")) { - $auditResult = Invoke-TestFunction -FunctionFile $testFunction -DomainName $DomainName + $auditResult = Invoke-TestFunction -FunctionFile $testFunction -DomainName $M365DomainForPWPolicyTest # Add the result to the collection [void]$allAuditResults.Add($auditResult) } diff --git a/source/tests/Test-PasswordNeverExpirePolicy.ps1 b/source/tests/Test-PasswordNeverExpirePolicy.ps1 index a4f9a07..7cf400a 100644 --- a/source/tests/Test-PasswordNeverExpirePolicy.ps1 +++ b/source/tests/Test-PasswordNeverExpirePolicy.ps1 @@ -2,9 +2,8 @@ function Test-PasswordNeverExpirePolicy { [CmdletBinding()] [OutputType([CISAuditResult])] param ( - # Aligned - [Parameter(Mandatory)] - [string]$DomainName # DomainName parameter is now mandatory + [Parameter(Mandatory = $false)] + [string]$DomainName ) begin { @@ -12,33 +11,58 @@ function Test-PasswordNeverExpirePolicy { #. .\source\Classes\CISAuditResult.ps1 # Initialization code, if needed $recnum = "1.3.1" + $overallResult = $true + $detailsList = @() + $failureReasonsList = @() + + # Add headers for the details + $detailsList += "Domain|Validity Period|IsDefault" } process { try { - # 1.3.1 (L1) Ensure the 'Password expiration policy' is set to 'Set passwords to never expire' - # Pass if PasswordValidityPeriodInDays is 0. Fail otherwise. - - # Retrieve password expiration policy - $passwordPolicy = Get-MgDomain -DomainId $DomainName | Select-Object -ExpandProperty PasswordValidityPeriodInDays - - # Prepare failure reasons and details based on compliance - $failureReasons = if ($passwordPolicy -ne 0) { - "Password expiration is not set to never expire" - } - else { - "N/A" + # Retrieve all domains or a specific domain + $domains = if ($DomainName) { + Get-MgDomain -DomainId $DomainName + } else { + Get-MgDomain } - $details = "Validity Period: $passwordPolicy days" + foreach ($domain in $domains) { + $domainName = $domain.Id + $isDefault = $domain.IsDefault + # Retrieve password expiration policy + $passwordPolicy = $domain.PasswordValidityPeriodInDays + + # Determine if the policy is compliant + $isCompliant = $passwordPolicy -eq 0 + $overallResult = $overallResult -and $isCompliant + + # Prepare failure reasons and details based on compliance + $failureReasons = if ($isCompliant) { + "N/A" + } else { + "Password expiration is not set to never expire for domain $domainName. Run the following command to remediate: `nUpdate-MgDomain -DomainId $domainName -PasswordValidityPeriodInDays 2147483647 -PasswordNotificationWindowInDays 30" + } + + $details = "$domainName|$passwordPolicy days|$isDefault" + + # Add details and failure reasons to the lists + $detailsList += $details + $failureReasonsList += $failureReasons + } + + # Prepare the final failure reason and details + $finalFailureReason = $failureReasonsList -join "`n" + $finalDetails = $detailsList -join "`n" # Create and populate the CISAuditResult object $params = @{ Rec = $recnum - Result = $passwordPolicy -eq 0 - Status = if ($passwordPolicy -eq 0) { "Pass" } else { "Fail" } - Details = $details - FailureReason = $failureReasons + Result = $overallResult + Status = if ($overallResult) { "Pass" } else { "Fail" } + Details = $finalDetails + FailureReason = $finalFailureReason } $auditResult = Initialize-CISAuditResult @params }