Core/Get-SecurityBaseline.ps1
|
function Get-SecurityBaseline { <# .SYNOPSIS Gets the current security baseline status of the Windows system .DESCRIPTION Retrieves comprehensive security configuration including Windows Defender, Firewall, UAC, BitLocker, and Windows Update status .PARAMETER ComputerName Name of the computer to check (default: local computer) .PARAMETER ExportPath Path to export the results as JSON .EXAMPLE Get-SecurityBaseline Get-SecurityBaseline -ComputerName "SERVER01" -ExportPath "C:\Audits" .OUTPUTS PSCustomObject with security baseline information #> [CmdletBinding()] param( [Parameter(Position = 0)] [string]$ComputerName = $env:COMPUTERNAME, [Parameter(Position = 1)] [string]$ExportPath ) begin { Write-Verbose "Starting security baseline check for $ComputerName" $results = [PSCustomObject]@{ ComputerName = $ComputerName ScanDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss" WindowsDefender = $null Firewall = $null UAC = $null BitLocker = $null WindowsUpdate = $null SecurityScore = 0 } } process { try { # Check Windows Defender Status Write-Verbose "Checking Windows Defender status..." try { $defenderStatus = Get-MpComputerStatus -ErrorAction Stop $results.WindowsDefender = [PSCustomObject]@{ AntivirusEnabled = $defenderStatus.AntivirusEnabled RealTimeProtectionEnabled = $defenderStatus.RealTimeProtectionEnabled BehaviorMonitorEnabled = $defenderStatus.BehaviorMonitorEnabled IoavProtectionEnabled = $defenderStatus.IoavProtectionEnabled SignatureLastUpdated = $defenderStatus.AntivirusSignatureLastUpdated SignatureVersion = $defenderStatus.AntivirusSignatureVersion } if ($defenderStatus.RealTimeProtectionEnabled) { $results.SecurityScore += 20 } } catch { Write-Warning "Could not retrieve Windows Defender status: $_" $results.WindowsDefender = "Not available or not installed" } # Check Firewall Status Write-Verbose "Checking Windows Firewall status..." try { $firewallProfiles = Get-NetFirewallProfile -ErrorAction Stop $results.Firewall = @() foreach ($profile in $firewallProfiles) { $results.Firewall += [PSCustomObject]@{ Profile = $profile.Name Enabled = $profile.Enabled DefaultInboundAction = $profile.DefaultInboundAction.ToString() DefaultOutboundAction = $profile.DefaultOutboundAction.ToString() } if ($profile.Enabled) { $results.SecurityScore += 10 } } } catch { Write-Warning "Could not retrieve Firewall status: $_" $results.Firewall = "Error retrieving firewall status" } # Check UAC Settings Write-Verbose "Checking UAC settings..." try { $uacKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" $uacSettings = Get-ItemProperty -Path $uacKey -ErrorAction Stop $enableLUA = if ($null -ne $uacSettings.PSObject.Properties['EnableLUA']) { $uacSettings.EnableLUA } else { $null } $results.UAC = [PSCustomObject]@{ EnableLUA = $enableLUA ConsentPromptBehaviorAdmin = if ($null -ne $uacSettings.PSObject.Properties['ConsentPromptBehaviorAdmin']) { $uacSettings.ConsentPromptBehaviorAdmin } else { $null } ConsentPromptBehaviorUser = if ($null -ne $uacSettings.PSObject.Properties['ConsentPromptBehaviorUser']) { $uacSettings.ConsentPromptBehaviorUser } else { $null } EnableSecureUIAPaths = if ($null -ne $uacSettings.PSObject.Properties['EnableSecureUIAPaths']) { $uacSettings.EnableSecureUIAPaths } else { $null } EnableVirtualization = if ($null -ne $uacSettings.PSObject.Properties['EnableVirtualization']) { $uacSettings.EnableVirtualization } else { $null } } if ($enableLUA -eq 1) { $results.SecurityScore += 15 } } catch { Write-Warning "Could not retrieve UAC settings: $_" $results.UAC = "Error retrieving UAC settings" } # Check BitLocker Status Write-Verbose "Checking BitLocker status..." try { $bitlockerVolumes = Get-BitLockerVolume -ErrorAction Stop $results.BitLocker = @() foreach ($volume in $bitlockerVolumes) { $results.BitLocker += [PSCustomObject]@{ MountPoint = $volume.MountPoint VolumeStatus = $volume.VolumeStatus.ToString() ProtectionStatus = $volume.ProtectionStatus.ToString() EncryptionPercentage = $volume.EncryptionPercentage EncryptionMethod = if ($volume.EncryptionMethod) { $volume.EncryptionMethod.ToString() } else { "None" } } if ($volume.ProtectionStatus -eq "On") { $results.SecurityScore += 10 } } } catch { Write-Warning "Could not retrieve BitLocker status: $_" $results.BitLocker = "BitLocker not available or access denied" } # Check Windows Update Status Write-Verbose "Checking Windows Update status..." try { # Try to get pending updates count $updateSession = New-Object -ComObject Microsoft.Update.Session $updateSearcher = $updateSession.CreateUpdateSearcher() $searchResult = $updateSearcher.Search("IsInstalled=0") $pendingCount = $searchResult.Updates.Count # Try to get last update check date $lastCheck = $null try { $auKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\Results\Detect" if (Test-Path $auKey) { $lastCheckProp = Get-ItemProperty -Path $auKey -Name "LastSuccessTime" -ErrorAction SilentlyContinue if ($lastCheckProp -and $lastCheckProp.LastSuccessTime) { $lastCheck = $lastCheckProp.LastSuccessTime } } } catch { Write-Verbose "Could not retrieve last update check time" } # Check if auto updates are enabled $autoUpdateEnabled = $true try { $wuKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" if (Test-Path $wuKey) { $auSettings = Get-ItemProperty -Path $wuKey -ErrorAction SilentlyContinue if ($auSettings -and $auSettings.PSObject.Properties['NoAutoUpdate'] -and $auSettings.NoAutoUpdate -eq 1) { $autoUpdateEnabled = $false } } } catch { Write-Verbose "Could not determine auto update settings" } $results.WindowsUpdate = [PSCustomObject]@{ PendingUpdates = $pendingCount LastUpdateCheck = $lastCheck AutoUpdateEnabled = $autoUpdateEnabled } if ($pendingCount -eq 0) { $results.SecurityScore += 15 } } catch { Write-Warning "Could not retrieve Windows Update status: $_" $results.WindowsUpdate = [PSCustomObject]@{ PendingUpdates = "Unable to determine" LastUpdateCheck = "Unknown" AutoUpdateEnabled = "Unknown" } } # Calculate final security score $results.SecurityScore = [Math]::Min($results.SecurityScore, 100) } catch { Write-Error "Error during security baseline check: $_" throw } } end { # Export results if path specified if ($ExportPath) { if (-not (Test-Path $ExportPath)) { New-Item -Path $ExportPath -ItemType Directory -Force | Out-Null } $exportFile = Join-Path -Path $ExportPath -ChildPath "SecurityBaseline_$ComputerName_$(Get-Date -Format 'yyyyMMdd_HHmmss').json" $results | ConvertTo-Json -Depth 5 | Out-File -FilePath $exportFile -Encoding UTF8 Write-Verbose "Results exported to: $exportFile" } # Return results return $results } } |