Hardening/Set-SecurityBaseline.ps1

function Set-SecurityBaseline {
    <#
    .SYNOPSIS
        Applies Windows security baseline configuration
    .DESCRIPTION
        Configures Windows security settings based on industry best practices and hardening guides
        (CIS benchmarks, Microsoft Security Baselines)
    .PARAMETER BaselineLevel
        Security baseline level: Basic, Recommended, or Strict
    .PARAMETER EnableBitLocker
        Enable BitLocker encryption on system drive
    .PARAMETER DisableSMBv1
        Disable SMBv1 protocol
    .PARAMETER ConfigureFirewall
        Configure Windows Firewall with recommended settings
    .EXAMPLE
        Set-SecurityBaseline -BaselineLevel Recommended
        Set-SecurityBaseline -BaselineLevel Strict -EnableBitLocker -DisableSMBv1
    .OUTPUTS
        PSCustomObject with baseline configuration results
    #>

    
    [CmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter()]
        [ValidateSet('Basic', 'Recommended', 'Strict')]
        [string]$BaselineLevel = 'Recommended',
        
        [Parameter()]
        [switch]$EnableBitLocker,
        
        [Parameter()]
        [switch]$DisableSMBv1,
        
        [Parameter()]
        [switch]$ConfigureFirewall
    )
    
    begin {
        Write-Host "=== WINDOWS SECURITY BASELINE CONFIGURATION ===" -ForegroundColor Cyan
        Write-Host "Baseline Level: $BaselineLevel" -ForegroundColor Yellow
        Write-Host "Start Time: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Yellow
        
        # Check for admin privileges
        $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
        if (-not $isAdmin) {
            throw "This function requires Administrator privileges!"
        }
        
        $results = [PSCustomObject]@{
            ConfigurationDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
            BaselineLevel = $BaselineLevel
            Changes = @()
            Errors = @()
            RequiresReboot = $false
            Categories = @{
                UAC = @{ Status = 'Not Configured' }
                Firewall = @{ Status = 'Not Configured' }
                WindowsDefender = @{ Status = 'Not Configured' }
                NetworkSecurity = @{ Status = 'Not Configured' }
                AccountSecurity = @{ Status = 'Not Configured' }
                SystemSecurity = @{ Status = 'Not Configured' }
                BitLocker = @{ Status = 'Not Configured' }
            }
        }
    }
    
    process {
        try {
            # Category 1: UAC Configuration
            Write-Host "`n[1/7] Configuring User Account Control (UAC)..." -ForegroundColor Cyan
            
            $uacPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
            
            if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, "Apply UAC hardening settings")) {
            try {
                # Enable UAC
                Set-ItemProperty -Path $uacPath -Name "EnableLUA" -Value 1 -Type DWord -Force
                $results.Changes += "UAC enabled"
                
                # Prompt for admin credentials
                Set-ItemProperty -Path $uacPath -Name "ConsentPromptBehaviorAdmin" -Value 2 -Type DWord -Force
                
                # Elevate signed executables
                if ($BaselineLevel -in @('Recommended', 'Strict')) {
                    Set-ItemProperty -Path $uacPath -Name "ValidateAdminCodeSignatures" -Value 1 -Type DWord -Force
                    $results.Changes += "UAC: Require signed executables"
                }
                
                # Secure desktop for elevation prompts
                if ($BaselineLevel -eq 'Strict') {
                    Set-ItemProperty -Path $uacPath -Name "PromptOnSecureDesktop" -Value 1 -Type DWord -Force
                    $results.Changes += "UAC: Secure desktop for prompts"
                }
                
                $results.Categories.UAC = @{
                    Enabled = $true
                    Status = 'Configured'
                }
                
                Write-Host " UAC: Configured" -ForegroundColor Green
            }
            catch {
                $results.Errors += "UAC configuration failed: $_"
                Write-Warning " UAC configuration failed: $_"
            }
            }
            
            # Category 2: Windows Firewall
            Write-Host "`n[2/7] Configuring Windows Firewall..." -ForegroundColor Cyan
            
            if ($ConfigureFirewall -or $BaselineLevel -in @('Recommended', 'Strict')) {
                if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, "Apply Windows Firewall baseline settings")) {
                try {
                    # Enable firewall for all profiles
                    Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
                    $results.Changes += "Windows Firewall enabled for all profiles"
                    
                    # Configure default actions
                    Set-NetFirewallProfile -Profile Domain -DefaultInboundAction Block -DefaultOutboundAction Allow
                    Set-NetFirewallProfile -Profile Public -DefaultInboundAction Block -DefaultOutboundAction Allow
                    Set-NetFirewallProfile -Profile Private -DefaultInboundAction Block -DefaultOutboundAction Allow
                    $results.Changes += "Firewall: Block inbound by default"
                    
                    # Disable firewall notifications for Public profile
                    Set-NetFirewallProfile -Profile Public -NotifyOnListen False
                    
                    if ($BaselineLevel -eq 'Strict') {
                        # Enable logging
                        Set-NetFirewallProfile -Profile Domain,Public,Private -LogAllowed True -LogBlocked True -LogMaxSizeKilobytes 16384
                        $results.Changes += "Firewall: Logging enabled"
                    }
                    
                    $results.Categories.Firewall = @{
                        Enabled = $true
                        Status = 'Configured'
                        Profiles = 'All profiles enabled'
                    }
                    
                    Write-Host " Firewall: Configured" -ForegroundColor Green
                }
                catch {
                    $results.Errors += "Firewall configuration failed: $_"
                    Write-Warning " Firewall configuration failed: $_"
                }
                }
            }
            else {
                Write-Host " Firewall: Skipped" -ForegroundColor Yellow
            }
            
            # Category 3: Windows Defender
            Write-Host "`n[3/7] Configuring Windows Defender..." -ForegroundColor Cyan
            
            if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, "Apply Windows Defender baseline settings")) {
            try {
                # Enable Real-Time Protection
                Set-MpPreference -DisableRealtimeMonitoring $false -ErrorAction Stop
                $results.Changes += "Windows Defender: Real-time protection enabled"
                
                # Enable Cloud Protection
                Set-MpPreference -MAPSReporting Advanced
                Set-MpPreference -SubmitSamplesConsent SendAllSamples
                $results.Changes += "Windows Defender: Cloud protection enabled"
                
                # Enable PUA (Potentially Unwanted Applications) protection
                Set-MpPreference -PUAProtection Enabled
                $results.Changes += "Windows Defender: PUA protection enabled"
                
                if ($BaselineLevel -in @('Recommended', 'Strict')) {
                    # Enable Network Protection
                    Set-MpPreference -EnableNetworkProtection Enabled
                    $results.Changes += "Windows Defender: Network protection enabled"
                    
                    # Enable Controlled Folder Access
                    Set-MpPreference -EnableControlledFolderAccess Enabled
                    $results.Changes += "Windows Defender: Controlled folder access enabled"
                }
                
                # Update definitions
                Update-MpSignature -ErrorAction SilentlyContinue
                $results.Changes += "Windows Defender: Signatures updated"
                
                $results.Categories.WindowsDefender = @{
                    RealTimeProtection = $true
                    CloudProtection = $true
                    Status = 'Configured'
                }
                
                Write-Host " Windows Defender: Configured" -ForegroundColor Green
            }
            catch {
                $results.Errors += "Windows Defender configuration failed: $_"
                Write-Warning " Windows Defender configuration failed: $_"
            }
            }
            
            # Category 4: Network Security
            Write-Host "`n[4/7] Configuring Network Security..." -ForegroundColor Cyan
            
            if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, "Apply network security baseline settings")) {
            try {
                # Disable SMBv1
                if ($DisableSMBv1 -or $BaselineLevel -in @('Recommended', 'Strict')) {
                    Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force -ErrorAction Stop
                    $results.Changes += "SMBv1 protocol disabled"
                    $results.RequiresReboot = $true
                    Write-Host " SMBv1: Disabled (reboot required)" -ForegroundColor Green
                }
                
                # Configure SMBv2/v3 encryption
                if ($BaselineLevel -eq 'Strict') {
                    Set-SmbServerConfiguration -EncryptData $true -Force
                    $results.Changes += "SMB encryption enabled"
                }
                
                # Disable NetBIOS over TCP/IP (Get-WmiObject exists only in Windows PowerShell 5.1 - guard the lookup)
                if ($BaselineLevel -eq 'Strict') {
                    if (Get-Command Get-WmiObject -ErrorAction SilentlyContinue) {
                        $adapters = Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object { $null -ne $_ -and $_.IPEnabled }
                        foreach ($adapter in $adapters) {
                            $adapter.SetTcpipNetbios(2) | Out-Null  # 2 = Disable NetBIOS
                        }
                        $results.Changes += "NetBIOS over TCP/IP disabled"
                    }
                }
                
                # Disable LLMNR
                if ($BaselineLevel -eq 'Strict') {
                    $llmnrPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient"
                    if (-not (Test-Path $llmnrPath)) {
                        New-Item -Path $llmnrPath -Force | Out-Null
                    }
                    Set-ItemProperty -Path $llmnrPath -Name "EnableMulticast" -Value 0 -Type DWord -Force
                    $results.Changes += "LLMNR disabled"
                }
                
                $results.Categories.NetworkSecurity = @{
                    SMBv1Disabled = $true
                    Status = 'Configured'
                }
                
                Write-Host " Network Security: Configured" -ForegroundColor Green
            }
            catch {
                $results.Errors += "Network security configuration failed: $_"
                Write-Warning " Network security configuration failed: $_"
            }
            }
            
            # Category 5: Account Security
            Write-Host "`n[5/7] Configuring Account Security..." -ForegroundColor Cyan
            
            if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, "Apply account security baseline settings")) {
            try {
                # Disable Guest account (well-known SID RID 501 - culture-invariant)
                $guestToDisable = @(Get-LocalUser -ErrorAction SilentlyContinue | Where-Object { $null -ne $_.SID -and $_.SID.Value -match '-501$' }) | Select-Object -First 1
                if ($null -ne $guestToDisable -and $guestToDisable.Enabled) {
                    Disable-LocalUser -SID $guestToDisable.SID -ErrorAction SilentlyContinue
                    $results.Changes += "Guest account disabled"
                }
                
                # Rename Administrator account (if desired in Strict mode)
                if ($BaselineLevel -eq 'Strict') {
                    # Note: This is commented out as renaming admin is risky
                    # Rename-LocalUser -Name "Administrator" -NewName "Admin_SecureAccount"
                    # $results.Changes += "Administrator account renamed"
                }
                
                # Configure account lockout policy
                net accounts /lockoutthreshold:5 /lockoutduration:30 /lockoutwindow:30 | Out-Null
                if ($LASTEXITCODE -ne 0) {
                    Write-Warning " Account lockout policy configuration failed (net accounts exit code $LASTEXITCODE)"
                }
                $results.Changes += "Account lockout policy configured (5 attempts, 30 min lockout)"
                
                # Password policy
                if ($BaselineLevel -in @('Recommended', 'Strict')) {
                    net accounts /minpwlen:12 /maxpwage:90 /minpwage:1 /uniquepw:5 | Out-Null
                    if ($LASTEXITCODE -ne 0) {
                        Write-Warning " Password policy configuration failed (net accounts exit code $LASTEXITCODE)"
                    }
                    $results.Changes += "Password policy: 12 char minimum, 90 day max age"
                }
                
                $results.Categories.AccountSecurity = @{
                    GuestDisabled = $true
                    LockoutPolicy = 'Configured'
                    Status = 'Configured'
                }
                
                Write-Host " Account Security: Configured" -ForegroundColor Green
            }
            catch {
                $results.Errors += "Account security configuration failed: $_"
                Write-Warning " Account security configuration failed: $_"
            }
            }
            
            # Category 6: System Security
            Write-Host "`n[6/7] Configuring System Security..." -ForegroundColor Cyan
            
            if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, "Apply system security baseline settings")) {
            try {
                # Disable AutoRun/AutoPlay
                $autorunPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer"
                if (-not (Test-Path $autorunPath)) {
                    New-Item -Path $autorunPath -Force | Out-Null
                }
                Set-ItemProperty -Path $autorunPath -Name "NoDriveTypeAutoRun" -Value 255 -Type DWord -Force
                $results.Changes += "AutoRun/AutoPlay disabled"
                
                # Disable Remote Assistance
                $raPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Remote Assistance"
                Set-ItemProperty -Path $raPath -Name "fAllowToGetHelp" -Value 0 -Type DWord -Force
                $results.Changes += "Remote Assistance disabled"
                
                # Enable DEP (Data Execution Prevention)
                bcdedit /set nx AlwaysOn | Out-Null
                if ($LASTEXITCODE -ne 0) {
                    Write-Warning " DEP configuration failed (bcdedit exit code $LASTEXITCODE)"
                }
                $results.Changes += "DEP enabled"
                
                # Disable unnecessary services
                if ($BaselineLevel -eq 'Strict') {
                    $servicesToDisable = @(
                        'RemoteRegistry',
                        'RemoteAccess',
                        'Telephony',
                        'SharedAccess'  # Internet Connection Sharing
                    )
                    
                    foreach ($service in $servicesToDisable) {
                        try {
                            Stop-Service -Name $service -Force -ErrorAction SilentlyContinue
                            Set-Service -Name $service -StartupType Disabled -ErrorAction SilentlyContinue
                            $results.Changes += "Service disabled: $service"
                        }
                        catch {
                            # Service might not exist
                        }
                    }
                }
                
                # Enable Windows Update automatic updates
                $wuPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
                if (-not (Test-Path $wuPath)) {
                    New-Item -Path $wuPath -Force | Out-Null
                }
                Set-ItemProperty -Path $wuPath -Name "NoAutoUpdate" -Value 0 -Type DWord -Force
                Set-ItemProperty -Path $wuPath -Name "AUOptions" -Value 4 -Type DWord -Force  # Auto download and install
                $results.Changes += "Windows Update: Automatic updates enabled"
                
                $results.Categories.SystemSecurity = @{
                    AutoRunDisabled = $true
                    RemoteAssistanceDisabled = $true
                    DEPEnabled = $true
                    Status = 'Configured'
                }
                
                Write-Host " System Security: Configured" -ForegroundColor Green
            }
            catch {
                $results.Errors += "System security configuration failed: $_"
                Write-Warning " System security configuration failed: $_"
            }
            }
            
            # Category 7: BitLocker Encryption
            Write-Host "`n[7/7] Configuring BitLocker..." -ForegroundColor Cyan
            
            if ($EnableBitLocker) {
                if ($PSCmdlet.ShouldProcess("C:", "Enable BitLocker encryption on the system drive")) {
                try {
                    $volume = Get-BitLockerVolume -MountPoint "C:" -ErrorAction Stop
                    
                    if ($volume.ProtectionStatus -ne 'On') {
                        Write-Host " Enabling BitLocker on C:..." -ForegroundColor Yellow
                        Write-Warning " This may take several minutes..."
                        
                        # Enable BitLocker with TPM
                        Enable-BitLocker -MountPoint "C:" -EncryptionMethod XtsAes256 -UsedSpaceOnly -TpmProtector -ErrorAction Stop
                        $results.Changes += "BitLocker enabled on system drive"
                        $results.RequiresReboot = $true
                        
                        Write-Host " BitLocker: Enabled (encryption in progress)" -ForegroundColor Green
                    }
                    else {
                        Write-Host " BitLocker: Already enabled" -ForegroundColor Yellow
                    }
                    
                    $results.Categories.BitLocker = @{
                        Enabled = $true
                        Status = 'Enabled'
                    }
                }
                catch {
                    $results.Errors += "BitLocker configuration failed: $_"
                    Write-Warning " BitLocker failed: $_"
                    Write-Warning " Note: TPM may be required, or device may not support BitLocker"
                }
                }
            }
            else {
                Write-Host " BitLocker: Skipped" -ForegroundColor Yellow
                $results.Categories.BitLocker = @{
                    Enabled = $false
                    Status = 'Not Configured'
                }
            }
            
        }
        catch {
            Write-Error "Error during security baseline configuration: $_"
            throw
        }
    }
    
end {
        Write-Host "`n=== BASELINE CONFIGURATION COMPLETE ===" -ForegroundColor Green
        
        Write-Host "`nChanges Applied: $($results.Changes.Count)" -ForegroundColor Cyan
        if ($results.Changes.Count -gt 0) {
            $results.Changes | ForEach-Object {
                Write-Host " + $_" -ForegroundColor White
            }
        }
        
        if ($results.Errors.Count -gt 0) {
            Write-Host "`nErrors Encountered: $($results.Errors.Count)" -ForegroundColor Red
            $results.Errors | ForEach-Object {
                Write-Host " - $_" -ForegroundColor Red
            }
        }
        
        if ($results.RequiresReboot) {
            Write-Host "`n[!] SYSTEM REBOOT REQUIRED" -ForegroundColor Yellow -BackgroundColor Red
            Write-Host "Some changes require a system restart to take effect" -ForegroundColor Yellow
        }
        
        Write-Host "`nSecurity Baseline Status:" -ForegroundColor Cyan
        Write-Host " Level: $($results.BaselineLevel)" -ForegroundColor White
        Write-Host " UAC: $($results.Categories.UAC.Status)" -ForegroundColor White
        Write-Host " Firewall: $($results.Categories.Firewall.Status)" -ForegroundColor White
        Write-Host " Windows Defender: $($results.Categories.WindowsDefender.Status)" -ForegroundColor White
        Write-Host " Network Security: $($results.Categories.NetworkSecurity.Status)" -ForegroundColor White
        Write-Host " Account Security: $($results.Categories.AccountSecurity.Status)" -ForegroundColor White
        Write-Host " System Security: $($results.Categories.SystemSecurity.Status)" -ForegroundColor White
        Write-Host " BitLocker: $($results.Categories.BitLocker.Status)" -ForegroundColor White
        
        Write-Host "`nRecommendations:" -ForegroundColor Cyan
        Write-Host " 1. Review all changes and test system functionality" -ForegroundColor White
        Write-Host " 2. Document the baseline configuration" -ForegroundColor White
        Write-Host " 3. Schedule regular security audits" -ForegroundColor White
        Write-Host " 4. Keep Windows and Defender signatures updated" -ForegroundColor White
        Write-Host " 5. Monitor security logs regularly" -ForegroundColor White
        
        return $results
    }
}