Private/Invoke-CISCheckSafely.ps1
|
function Invoke-CISCheckSafely { [CmdletBinding()] param( [Parameter(Mandatory)] [hashtable]$ControlDef, [Parameter(Mandatory)] [hashtable]$ResourceCache, [Parameter()] [hashtable]$EnvironmentInfo ) try { $result = Invoke-CISControlCheck -ControlDef $ControlDef -ResourceCache $ResourceCache -EnvironmentInfo $EnvironmentInfo # Ensure result has required fields from definition # Always overlay definition metadata so controls carry correct metadata if ($result) { if (-not $result.Section) { $result.Section = $ControlDef.Section } if (-not $result.Subsection) { $result.Subsection = $ControlDef.Subsection } $result.Severity = $ControlDef.Severity # Always set from definition (defaults in New-CISCheckResult mask actual values) $result.ProfileLevel = $ControlDef.ProfileLevel $result.AssessmentStatus = $ControlDef.AssessmentStatus if (-not $result.Description) { $result.Description = $ControlDef.Description } if (-not $result.Remediation) { $result.Remediation = $ControlDef.Remediation } if (-not $result.References -or $result.References.Count -eq 0) { $result.References = $ControlDef.References } if (-not $result.CISControls -or $result.CISControls.Count -eq 0) { $result.CISControls = $ControlDef.CISControls } } return $result } catch { return New-CISCheckResult ` -ControlId $ControlDef.ControlId ` -Title $ControlDef.Title ` -Status 'ERROR' ` -Severity $ControlDef.Severity ` -Section $ControlDef.Section ` -Subsection $ControlDef.Subsection ` -AssessmentStatus $ControlDef.AssessmentStatus ` -ProfileLevel $ControlDef.ProfileLevel ` -Description $ControlDef.Description ` -Details "Check failed with error: $(Format-CISErrorMessage -Message $_.Exception.Message)" ` -Remediation $ControlDef.Remediation ` -References $ControlDef.References ` -CISControls $ControlDef.CISControls } } function Invoke-CISControlCheck { [CmdletBinding()] param( [Parameter(Mandatory)] [hashtable]$ControlDef, [Parameter(Mandatory)] [hashtable]$ResourceCache, [Parameter()] [hashtable]$EnvironmentInfo ) switch ($ControlDef.CheckPattern) { 'DefenderPlan' { Invoke-DefenderPlanCheck -ControlDef $ControlDef } 'ActivityLogAlert' { Invoke-ActivityLogAlertCheck -ControlDef $ControlDef -CachedAlerts $ResourceCache.ActivityLogAlerts } 'NSGPortCheck' { Invoke-NSGPortCheck -ControlDef $ControlDef -CachedNSGs $ResourceCache.NSGs } 'StorageAccountProperty' { Invoke-StorageAccountPropertyCheck -ControlDef $ControlDef -CachedStorageAccounts $ResourceCache.StorageAccounts } 'StorageBlobProperty' { Invoke-StorageBlobPropertyCheck -ControlDef $ControlDef -CachedStorageAccounts $ResourceCache.StorageAccounts -CachedBlobProperties $ResourceCache.BlobServiceProperties } 'StorageFileProperty' { Invoke-StorageFilePropertyCheck -ControlDef $ControlDef -CachedStorageAccounts $ResourceCache.StorageAccounts -CachedFileProperties $ResourceCache.FileServiceProperties } 'KeyVaultProperty' { Invoke-KeyVaultPropertyCheck -ControlDef $ControlDef -CachedKeyVaults $ResourceCache.KeyVaults -CachedKeyVaultDetails $ResourceCache.KeyVaultDetails } 'KeyVaultKeyExpiry' { Invoke-KeyVaultKeyExpiryCheck -ControlDef $ControlDef -CachedKeyVaults $ResourceCache.KeyVaults -CachedKeyVaultDetails $ResourceCache.KeyVaultDetails } 'KeyVaultSecretExpiry' { Invoke-KeyVaultSecretExpiryCheck -ControlDef $ControlDef -CachedKeyVaults $ResourceCache.KeyVaults -CachedKeyVaultDetails $ResourceCache.KeyVaultDetails } 'DiagnosticSetting' { Invoke-DiagnosticSettingCheck -ControlDef $ControlDef -ResourceCache $ResourceCache } 'GraphAPIProperty' { Invoke-GraphAPIPropertyCheck -ControlDef $ControlDef -EnvironmentInfo $EnvironmentInfo } 'ManualCheck' { Invoke-ManualCheck -ControlDef $ControlDef } 'Custom' { $fnName = $ControlDef.CheckFunction if ($fnName -and $fnName -match '^(Test-CIS|Invoke-CIS)' -and (Get-Command $fnName -ErrorAction SilentlyContinue)) { & $fnName -ControlDef $ControlDef -ResourceCache $ResourceCache } else { New-CISCheckResult ` -ControlId $ControlDef.ControlId ` -Title $ControlDef.Title ` -Status 'ERROR' ` -Details "Custom check function '$fnName' not found or does not match allowed naming convention (Test-CIS*/Invoke-CIS*)." } } default { New-CISCheckResult ` -ControlId $ControlDef.ControlId ` -Title $ControlDef.Title ` -Status 'ERROR' ` -Details "Unknown check pattern: $($ControlDef.CheckPattern)" } } } |