New paste Repaste Download
<#
Hardened Windows Server 2022 – Tailscale-only RDP
Version 2025-06-26-rev10-ascii-verbose
#>
# ── 0. Variables ────────────────────────────────────────────────────────────
$stamp          = (Get-Date).ToString('yyyyMMdd-HHmmss')
$backupFile     = "C:\FirewallBackup-$stamp.wfw"
$regBackup      = "C:\RegBackup-$stamp.reg"
$logFile        = "$env:SystemRoot\System32\LogFiles\Firewall\pfirewall.log"
$tailSubnet     = '100.64.0.0/10'      # your Tailnet
$fwGroup        = 'CustomHardening'
$disableSpooler = $false               # keep Spooler for RDP printing
$autoReboot     = $false               # disabled automatic reboot
Write-Host "Starting Windows Server 2022 Hardening Script at $(Get-Date)" -ForegroundColor Green
Write-Host "Script timestamp: $stamp" -ForegroundColor Cyan
# ── 0a. Backups ─────────────────────────────────────────────────────────────
Write-Host "`n=== Creating System Backups ===" -ForegroundColor Yellow
try {
    reg.exe export HKLM $regBackup /y | Out-Null
    if (Test-Path $regBackup) {
        Write-Host "SUCCESS: Registry backup created at $regBackup" -ForegroundColor Green
    } else {
        Write-Host "WARNING: Registry backup may not have been created properly" -ForegroundColor Yellow
    }
} catch {
    Write-Host "ERROR: Failed to create registry backup - $($_.Exception.Message)" -ForegroundColor Red
}
try {
    netsh advfirewall export $backupFile | Out-Null
    if (Test-Path $backupFile) {
        Write-Host "SUCCESS: Firewall backup created at $backupFile" -ForegroundColor Green
    } else {
        Write-Host "WARNING: Firewall backup may not have been created properly" -ForegroundColor Yellow
    }
} catch {
    Write-Host "ERROR: Failed to create firewall backup - $($_.Exception.Message)" -ForegroundColor Red
}
# ── 0b. IPv6 preference (0x20) ──────────────────────────────────────────────
Write-Host "`n=== Configuring IPv6 Settings ===" -ForegroundColor Yellow
try {
    $ipv6Reg = 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters'
    if (-not (Test-Path $ipv6Reg)) {
        New-Item -Path $ipv6Reg -Force | Out-Null
        Write-Host "Created IPv6 registry path" -ForegroundColor Cyan
    }
    New-ItemProperty -Path $ipv6Reg -Name DisabledComponents -Type DWord -Value 0x20 -Force | Out-Null
    Write-Host "SUCCESS: IPv6 preference configured (DisabledComponents = 0x20)" -ForegroundColor Green
} catch {
    Write-Host "ERROR: Failed to configure IPv6 settings - $($_.Exception.Message)" -ForegroundColor Red
}
# ── 1. Default-deny inbound ────────────────────────────────────────────────
Write-Host "`n=== Setting Firewall Default Policies ===" -ForegroundColor Yellow
try {
    Set-NetFirewallProfile -Profile Domain,Private,Public -DefaultInboundAction Block -DefaultOutboundAction Allow
    Write-Host "SUCCESS: Set default inbound action to BLOCK and outbound to ALLOW for all profiles" -ForegroundColor Green
} catch {
    Write-Host "ERROR: Failed to set firewall default policies - $($_.Exception.Message)" -ForegroundColor Red
}
# ── 2. Remove previous custom rules ─────────────────────────────────────────
Write-Host "`n=== Removing Previous Custom Rules ===" -ForegroundColor Yellow
try {
    $existingRules = Get-NetFirewallRule | Where-Object { $_.Group -eq $fwGroup }
    if ($existingRules) {
        $ruleCount = ($existingRules | Measure-Object).Count
        $existingRules | Remove-NetFirewallRule
        Write-Host "SUCCESS: Removed $ruleCount existing custom hardening rules" -ForegroundColor Green
    } else {
        Write-Host "INFO: No existing custom hardening rules found to remove" -ForegroundColor Cyan
    }
} catch {
    Write-Host "ERROR: Failed to remove existing custom rules - $($_.Exception.Message)" -ForegroundColor Red
}
# ── 2c. Disable built-in RDP rules ─────────────────────────────────────────
Write-Host "`n=== Disabling Built-in RDP Rules ===" -ForegroundColor Yellow
try {
    $rdpRules = Get-NetFirewallRule -DisplayName 'Remote Desktop - User Mode *'
    if ($rdpRules) {
        $rdpRules | Disable-NetFirewallRule
        $rdpCount = ($rdpRules | Measure-Object).Count
        Write-Host "SUCCESS: Disabled $rdpCount built-in RDP firewall rules" -ForegroundColor Green
    } else {
        Write-Host "INFO: No built-in RDP rules found to disable" -ForegroundColor Cyan
    }
} catch {
    Write-Host "ERROR: Failed to disable built-in RDP rules - $($_.Exception.Message)" -ForegroundColor Red
}
# ── 3. Inbound BLOCK rules ─────────────────────────────────────────────────
Write-Host "`n=== Creating Inbound BLOCK Rules ===" -ForegroundColor Yellow
$blockPorts = @(
    @{ N='TCP 135 RPC'         ; P='TCP' ; Port='135'     }
    @{ N='TCP 139 NetBIOS'     ; P='TCP' ; Port='139'     }
    @{ N='TCP 445 SMB'         ; P='TCP' ; Port='445'     }
    @{ N='UDP 137-138 NetBIOS' ; P='UDP' ; Port='137-138' }
    @{ N='UDP 5355 LLMNR'      ; P='UDP' ; Port='5355'    }
    @{ N='UDP 5357 WSD'        ; P='UDP' ; Port='5357'    }
    @{ N='UDP 1900 SSDP'       ; P='UDP' ; Port='1900'    }
    @{ N='TCP 5985 WinRM'      ; P='TCP' ; Port='5985'    }
    @{ N='TCP 5986 WinRM-SSL'  ; P='TCP' ; Port='5986'    }
)
foreach ($b in $blockPorts) {
    try {
        if (-not (Get-NetFirewallRule -DisplayName "Block $($b.N)" -ErrorAction SilentlyContinue)) {
            New-NetFirewallRule -DisplayName "Block $($b.N)" -Group $fwGroup -Direction Inbound -Protocol $b.P -LocalPort $b.Port -Action Block
            Write-Host "SUCCESS: Created block rule for $($b.N)" -ForegroundColor Green
        } else {
            Write-Host "INFO: Block rule for $($b.N) already exists, skipping" -ForegroundColor Cyan
        }
    } catch {
        Write-Host "ERROR: Failed to create block rule for $($b.N) - $($_.Exception.Message)" -ForegroundColor Red
    }
}
# ── 4. Allow rules (Tailnet only) ───────────────────────────────────────────
Write-Host "`n=== Creating Tailnet Allow Rules ===" -ForegroundColor Yellow
try {
    New-NetFirewallRule -DisplayName 'Allow RDP TCP 3389 (Tailnet)' -Group $fwGroup -Direction Inbound -Protocol TCP -LocalPort 3389 -RemoteAddress $tailSubnet -Action Allow
    Write-Host "SUCCESS: Created RDP TCP 3389 allow rule for Tailnet ($tailSubnet)" -ForegroundColor Green
    
    # Verify the rule was created with correct remote address
    $createdRule = Get-NetFirewallRule -DisplayName 'Allow RDP TCP 3389 (Tailnet)' | Get-NetFirewallAddressFilter
    if ($createdRule.RemoteAddress -eq $tailSubnet) {
        Write-Host "  Verified: Remote address correctly set to $tailSubnet" -ForegroundColor Cyan
    } else {
        Write-Host "  WARNING: Remote address not set correctly. Current: $($createdRule.RemoteAddress)" -ForegroundColor Yellow
    }
} catch {
    Write-Host "ERROR: Failed to create RDP TCP allow rule - $($_.Exception.Message)" -ForegroundColor Red
}
try {
    New-NetFirewallRule -DisplayName 'Allow RDP UDP 3389 (Tailnet)' -Group $fwGroup -Direction Inbound -Protocol UDP -LocalPort 3389 -RemoteAddress $tailSubnet -Action Allow
    Write-Host "SUCCESS: Created RDP UDP 3389 allow rule for Tailnet ($tailSubnet)" -ForegroundColor Green
    
    # Verify the rule was created with correct remote address
    $createdRule = Get-NetFirewallRule -DisplayName 'Allow RDP UDP 3389 (Tailnet)' | Get-NetFirewallAddressFilter
    if ($createdRule.RemoteAddress -eq $tailSubnet) {
        Write-Host "  Verified: Remote address correctly set to $tailSubnet" -ForegroundColor Cyan
    } else {
        Write-Host "  WARNING: Remote address not set correctly. Current: $($createdRule.RemoteAddress)" -ForegroundColor Yellow
    }
} catch {
    Write-Host "ERROR: Failed to create RDP UDP allow rule - $($_.Exception.Message)" -ForegroundColor Red
}
$tsExe = (Get-Command tailscaled.exe -ErrorAction SilentlyContinue).Source
if ($tsExe) {
    Write-Host "Found Tailscale daemon at: $tsExe" -ForegroundColor Cyan
    
    try {
        New-NetFirewallRule -DisplayName 'Allow tailscaled.exe inbound' -Group $fwGroup -Program $tsExe -Direction Inbound -Action Allow
        Write-Host "SUCCESS: Created inbound allow rule for tailscaled.exe" -ForegroundColor Green
    } catch {
        Write-Host "ERROR: Failed to create inbound tailscaled rule - $($_.Exception.Message)" -ForegroundColor Red
    }
    
    if ((Get-NetFirewallProfile -Profile Domain,Private,Public | Where-Object { $_.DefaultOutboundAction -eq 'Block' })) {
        try {
            New-NetFirewallRule -DisplayName 'Allow tailscaled.exe outbound' -Group $fwGroup -Program $tsExe -Direction Outbound -Action Allow
            Write-Host "SUCCESS: Created outbound allow rule for tailscaled.exe" -ForegroundColor Green
        } catch {
            Write-Host "ERROR: Failed to create outbound tailscaled rule - $($_.Exception.Message)" -ForegroundColor Red
        }
    } else {
        Write-Host "INFO: Outbound traffic allowed by default, skipping outbound tailscaled rule" -ForegroundColor Cyan
    }
} else {
    Write-Host "WARNING: Tailscale daemon (tailscaled.exe) not found in PATH" -ForegroundColor Yellow
}
try {
    New-NetFirewallRule -DisplayName 'Allow ICMPv4 Echo (Tailnet)' -Group $fwGroup -Direction Inbound -Protocol ICMPv4 -IcmpType 8 -RemoteAddress $tailSubnet -Action Allow
    Write-Host "SUCCESS: Created ICMPv4 Echo allow rule for Tailnet ($tailSubnet)" -ForegroundColor Green
    
    # Verify the rule was created with correct remote address
    $createdRule = Get-NetFirewallRule -DisplayName 'Allow ICMPv4 Echo (Tailnet)' | Get-NetFirewallAddressFilter
    if ($createdRule.RemoteAddress -eq $tailSubnet) {
        Write-Host "  Verified: Remote address correctly set to $tailSubnet" -ForegroundColor Cyan
    } else {
        Write-Host "  WARNING: Remote address not set correctly. Current: $($createdRule.RemoteAddress)" -ForegroundColor Yellow
    }
} catch {
    Write-Host "ERROR: Failed to create ICMPv4 allow rule - $($_.Exception.Message)" -ForegroundColor Red
}
# ── 5. Service hardening ────────────────────────────────────────────────────
Write-Host "`n=== Service Hardening ===" -ForegroundColor Yellow
$servicesToManual = @(
    'LanmanServer','WMPNetworkSvc','XboxNetApiSvc',
    'CDPSvc','DsSvc','WSDPrintDevice',
    'RemoteRegistry','Fax','TrkWks',
    'SNMP','SNMPTRAP'
)
if ($disableSpooler) { $servicesToManual += 'Spooler' }
foreach ($svc in $servicesToManual) {
    try {
        $s = Get-Service -Name $svc -ErrorAction SilentlyContinue
        if ($s) {
            $originalStatus = $s.Status
            $originalStartType = $s.StartType
            
            if ($s.Status -ne 'Stopped') {
                Stop-Service $s -Force
                Write-Host "  Stopped service: $svc (was $originalStatus)" -ForegroundColor Cyan
            }
            Set-Service -Name $svc -StartupType Manual
            Write-Host "SUCCESS: Configured service $svc - StartType: $originalStartType -> Manual" -ForegroundColor Green
        } else {
            Write-Host "INFO: Service $svc not found on this system" -ForegroundColor Cyan
        }
    } catch {
        Write-Host "ERROR: Failed to configure service $svc - $($_.Exception.Message)" -ForegroundColor Red
    }
}
# ── 5b. Spooler defence (when spooler active)
if (-not $disableSpooler) {
    Write-Host "`n=== Configuring Spooler Security ===" -ForegroundColor Yellow
    
    try {
        $ppReg = 'HKLM:\Software\Policies\Microsoft\Windows NT\Printers\PointAndPrint'
        if (-not (Test-Path $ppReg)) {
            New-Item -Path $ppReg -Force | Out-Null
            Write-Host "Created Point and Print registry path" -ForegroundColor Cyan
        }
        New-ItemProperty -Path $ppReg -Name RestrictDriverInstallationToAdministrators -Type DWord -Value 1 -Force | Out-Null
        New-ItemProperty -Path $ppReg -Name NoWarningNoElevationOnInstall -Type DWord -Value 0 -Force | Out-Null
        Write-Host "SUCCESS: Configured Point and Print security settings" -ForegroundColor Green
        
        $spr = Get-NetFirewallRule -DisplayName 'File and Printer Sharing (Spooler Service - RPC)' -ErrorAction SilentlyContinue
        if ($spr) {
            $spr | Set-NetFirewallRule -RemoteAddress LocalSubnet -Profile Any -Enabled True
            Write-Host "SUCCESS: Updated Spooler Service RPC firewall rule to LocalSubnet only" -ForegroundColor Green
        } else {
            Write-Host "INFO: Spooler Service RPC firewall rule not found" -ForegroundColor Cyan
        }
    } catch {
        Write-Host "ERROR: Failed to configure spooler security - $($_.Exception.Message)" -ForegroundColor Red
    }
}
# ── 6. Disable NetBIOS over TCP/IP ──────────────────────────────────────────
Write-Host "`n=== Disabling NetBIOS over TCP/IP ===" -ForegroundColor Yellow
try {
    $adapters = Get-WmiObject Win32_NetworkAdapterConfiguration -Filter 'IPEnabled=True'
    $adapterCount = 0
    foreach ($adapter in $adapters) {
        $result = $adapter.SetTcpipNetbios(2)
        if ($result.ReturnValue -eq 0) {
            $adapterCount++
        }
    }
    Write-Host "SUCCESS: Disabled NetBIOS over TCP/IP on $adapterCount network adapters" -ForegroundColor Green
} catch {
    Write-Host "ERROR: Failed to disable NetBIOS over TCP/IP - $($_.Exception.Message)" -ForegroundColor Red
}
# ── 7. Remove SMB1 ──────────────────────────────────────────────────────────
Write-Host "`n=== Removing SMB1 Protocol ===" -ForegroundColor Yellow
try {
    $smb1Features = @('SMB1Protocol','SMB1Protocol-Client','SMB1Protocol-Server')
    foreach ($feature in $smb1Features) {
        try {
            $result = Disable-WindowsOptionalFeature -Online -FeatureName $feature -NoRestart -ErrorAction SilentlyContinue
            if ($result) {
                Write-Host "SUCCESS: Disabled Windows feature: $feature" -ForegroundColor Green
            } else {
                Write-Host "INFO: Feature $feature was already disabled or not found" -ForegroundColor Cyan
            }
        } catch {
            Write-Host "WARNING: Could not disable feature $feature - $($_.Exception.Message)" -ForegroundColor Yellow
        }
    }
} catch {
    Write-Host "ERROR: Failed to remove SMB1 protocol - $($_.Exception.Message)" -ForegroundColor Red
}
# ── 8. Disable WSD / SSDP / UPnP services ──────────────────────────────────
Write-Host "`n=== Disabling WSD/SSDP/UPnP Services ===" -ForegroundColor Yellow
$servicesToDisable = @('SSDPSRV','upnphost','WSDSvc','WSDPrintDevice')
foreach ($serviceName in $servicesToDisable) {
    try {
        $reg = "HKLM:\SYSTEM\CurrentControlSet\Services\$serviceName"
        if (Test-Path $reg) {
            Set-ItemProperty $reg -Name Start -Value 4 -Force
            Write-Host "SUCCESS: Disabled service $serviceName (Start = 4)" -ForegroundColor Green
        } else {
            Write-Host "INFO: Service registry key for $serviceName not found" -ForegroundColor Cyan
        }
    } catch {
        Write-Host "ERROR: Failed to disable service $serviceName - $($_.Exception.Message)" -ForegroundColor Red
    }
}
# ── 9. RDP channel hardening ───────────────────────────────────────────────
Write-Host "`n=== Hardening RDP Channel Security ===" -ForegroundColor Yellow
try {
    $rdpReg = 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp'
    Set-ItemProperty $rdpReg -Name SecurityLayer                -Value 2
    Set-ItemProperty $rdpReg -Name fAllowSecProtocolNegotiation -Value 1
    Set-ItemProperty $rdpReg -Name UserAuthentication           -Value 1
    Set-ItemProperty $rdpReg -Name MinEncryptionLevel           -Value 3
    Write-Host "SUCCESS: Configured RDP security settings:" -ForegroundColor Green
    Write-Host "  SecurityLayer = 2 (TLS)" -ForegroundColor Cyan
    Write-Host "  fAllowSecProtocolNegotiation = 1 (Enabled)" -ForegroundColor Cyan
    Write-Host "  UserAuthentication = 1 (NLA Required)" -ForegroundColor Cyan
    Write-Host "  MinEncryptionLevel = 3 (High)" -ForegroundColor Cyan
} catch {
    Write-Host "ERROR: Failed to configure RDP security settings - $($_.Exception.Message)" -ForegroundColor Red
}
# ──10. Schannel: disable TLS 1.0/1.1 & weak ciphers ────────────────────────
Write-Host "`n=== Disabling Weak TLS Protocols ===" -ForegroundColor Yellow
foreach ($proto in 'TLS 1.0','TLS 1.1') {
    foreach ($side in 'Client','Server') {
        try {
            $path = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$proto\$side"
            if (-not (Test-Path $path)) {
                New-Item -Path $path -Force | Out-Null
                Write-Host "Created registry path: $path" -ForegroundColor Cyan
            }
            New-ItemProperty -Path $path -Name Enabled -Type DWord -Value 0 -Force | Out-Null
            New-ItemProperty -Path $path -Name DisabledByDefault -Type DWord -Value 1 -Force | Out-Null
            Write-Host "SUCCESS: Disabled $proto for $side" -ForegroundColor Green
        } catch {
            Write-Host "ERROR: Failed to disable $proto for $side - $($_.Exception.Message)" -ForegroundColor Red
        }
    }
}
Write-Host "`n=== Disabling Weak Cipher Suites ===" -ForegroundColor Yellow
if (Get-Command Disable-TlsCipherSuite -ErrorAction SilentlyContinue) {
    try {
        $weakCiphers = (Get-TlsCipherSuite | Where-Object { $_.Name -match 'RC4|3DES|SHA$' })
        $disabledCount = 0
        foreach ($cipher in $weakCiphers) {
            try {
                Disable-TlsCipherSuite -Name $cipher.Name -ErrorAction SilentlyContinue
                $disabledCount++
                Write-Host "  Disabled cipher suite: $($cipher.Name)" -ForegroundColor Cyan
            } catch {
                Write-Host "  WARNING: Could not disable cipher suite: $($cipher.Name)" -ForegroundColor Yellow
            }
        }
        Write-Host "SUCCESS: Disabled $disabledCount weak cipher suites" -ForegroundColor Green
    } catch {
        Write-Host "ERROR: Failed to disable cipher suites - $($_.Exception.Message)" -ForegroundColor Red
    }
} else {
    Write-Host "INFO: Disable-TlsCipherSuite cmdlet not available, using registry method" -ForegroundColor Cyan
    try {
        $cBase = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers'
        $weakCiphers = @('RC4 128/128','RC4 64/128','RC4 56/128','RC4 40/128','3DES 168/168')
        foreach ($c in $weakCiphers) {
            $cPath = "$cBase\$c"
            if (-not (Test-Path $cPath)) {
                New-Item -Path $cPath -Force | Out-Null
                Write-Host "Created cipher registry path: $cPath" -ForegroundColor Cyan
            }
            New-ItemProperty -Path $cPath -Name Enabled -Type DWord -Value 0 -Force | Out-Null
            Write-Host "SUCCESS: Disabled cipher: $c" -ForegroundColor Green
        }
    } catch {
        Write-Host "ERROR: Failed to disable weak ciphers via registry - $($_.Exception.Message)" -ForegroundColor Red
    }
}
# ──11. Remote Credential Guard ─────────────────────────────────────────────
Write-Host "`n=== Configuring Remote Credential Guard ===" -ForegroundColor Yellow
try {
    $credReg = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\CredentialsDelegation'
    if (-not (Test-Path $credReg)) {
        New-Item -Path $credReg -Force | Out-Null
        Write-Host "Created Credential Delegation registry path" -ForegroundColor Cyan
    }
    Set-ItemProperty $credReg -Name AllowProtectedCreds -Type DWord -Value 1
    Set-ItemProperty $credReg -Name EnableProtection    -Type DWord -Value 1
    Write-Host "SUCCESS: Enabled Remote Credential Guard protection" -ForegroundColor Green
} catch {
    Write-Host "ERROR: Failed to configure Remote Credential Guard - $($_.Exception.Message)" -ForegroundColor Red
}
# ──12. Firewall logging (16 MB) + weekly rotation ──────────────────────────
Write-Host "`n=== Configuring Firewall Logging ===" -ForegroundColor Yellow
try {
    Set-NetFirewallProfile -Profile Domain,Private,Public -LogBlocked True -LogAllowed True -LogFileName $logFile -LogMaxSizeKilobytes 16384
    Write-Host "SUCCESS: Enabled firewall logging (16MB max, blocked and allowed traffic)" -ForegroundColor Green
    Write-Host "  Log file location: $logFile" -ForegroundColor Cyan
} catch {
    Write-Host "ERROR: Failed to configure firewall logging - $($_.Exception.Message)" -ForegroundColor Red
}
Write-Host "`n=== Creating Log Rotation Task ===" -ForegroundColor Yellow
try {
    $taskName = 'Rotate-Firewall-Log'
    if (-not (Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue)) {
        $psCmd  = '& { Set-NetFirewallProfile -LogAllowed 0 -LogBlocked 0; ' +
                  '$ts=(Get-Date).ToString("yyyyMMdd-HHmmss"); ' +
                  "Rename-Item ''$logFile'' (" + '$ts' + " + ''.pfirewall.log''); " +
                  "New-Item ''$logFile'' -ItemType File -Force | Out-Null; " +
                  'Set-NetFirewallProfile -LogAllowed 1 -LogBlocked 1 }'
        $action  = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-NoProfile -ExecutionPolicy Bypass -Command $psCmd"
        $trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At 03:00
        Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -RunLevel Highest -User.SYSTEM
        Write-Host "SUCCESS: Created weekly log rotation scheduled task '$taskName'" -ForegroundColor Green
    } else {
        Write-Host "INFO: Log rotation task '$taskName' already exists" -ForegroundColor Cyan
    }
} catch {
    Write-Host "ERROR: Failed to create log rotation task - $($_.Exception.Message)" -ForegroundColor Red
}
# ──13. Account-lockout policy ──────────────────────────────────────────────
Write-Host "`n=== Configuring Account Lockout Policy ===" -ForegroundColor Yellow
try {
    $result = & net.exe accounts /lockoutthreshold:10 /lockoutduration:15 /lockoutwindow:15 2>&1
    if ($LASTEXITCODE -eq 0) {
        Write-Host "SUCCESS: Configured account lockout policy:" -ForegroundColor Green
        Write-Host "  Lockout threshold: 10 attempts" -ForegroundColor Cyan
        Write-Host "  Lockout duration: 15 minutes" -ForegroundColor Cyan
        Write-Host "  Lockout window: 15 minutes" -ForegroundColor Cyan
    } else {
        Write-Host "WARNING: Account lockout policy command completed with exit code $LASTEXITCODE" -ForegroundColor Yellow
    }
} catch {
    Write-Host "ERROR: Failed to configure account lockout policy - $($_.Exception.Message)" -ForegroundColor Red
}
# ──14. Disable Remote Assistance rules ─────────────────────────────────────
Write-Host "`n=== Disabling Remote Assistance Rules ===" -ForegroundColor Yellow
try {
    $raRules = Get-NetFirewallRule | Where-Object { $_.DisplayName -like '*Remote Assistance*' }
    if ($raRules) {
        $raRules | Disable-NetFirewallRule
        $raCount = ($raRules | Measure-Object).Count
        Write-Host "SUCCESS: Disabled $raCount Remote Assistance firewall rules" -ForegroundColor Green
    } else {
        Write-Host "INFO: No Remote Assistance firewall rules found" -ForegroundColor Cyan
    }
} catch {
    Write-Host "ERROR: Failed to disable Remote Assistance rules - $($_.Exception.Message)" -ForegroundColor Red
}
# ──14b. Remove/Disable unwanted Built-in Rules ─────────────────────────────
# 1) Disable entire rule-groups
$groups = @(
    # Discovery / Multicast
    "mDNS",
    "Netzwerkerkennung",            # contains LLMNR, SSDP, UPnP, WSD rules
    "DIAL-Protokollserver",
    "Cast to Device functionality", # original English group
    "Wiedergabe auf Gerät",         # German group for Play-To
    # File & Print
    "Datei- und Druckerfreigabe",
    # Remote-Management
    "Windows-Remoteverwaltung",
    # Updates / Delivery
    "Übermittlungsoptimierung",
    # Media-Streaming
    "Microsoft Media Foundation-Netzwerkquelle",
    # IoT / Miracast
    "AllJoyn Router",
    # Server Features, if unnecessary
    "Dateiserver-Remoteverwaltung",
    "Dynamic Host Configuration-Protokoll"   # only disable if static IP
)
foreach ($g in $groups) {
    try {
        Get-NetFirewallRule -DisplayGroup $g -ErrorAction SilentlyContinue |
            Disable-NetFirewallRule -ErrorAction Stop
        Write-Host "SUCCESS: Disabled group '$g'" -ForegroundColor Green
    } catch {
        Write-Host "WARNING: Group '$g' not found or could not be disabled" -ForegroundColor Yellow
    }
}
# 2) Disable individual rules (no group tag)
$ruleNames = @(
    # Core-Networking special paths
    "Kernnetzwerk - IP-HTTPS (TCP eingehend)",   # DirectAccess / IP-HTTPS
    "Kernnetzwerk - Teredo (UDP eingehend)"      # Teredo tunneling
)
foreach ($n in $ruleNames) {
    try {
        Get-NetFirewallRule -DisplayName $n -ErrorAction SilentlyContinue |
            Disable-NetFirewallRule -ErrorAction Stop
        Write-Host "SUCCESS: Disabled rule '$n'" -ForegroundColor Green
    } catch {
        Write-Host "WARNING: Rule '$n' not found or could not be disabled" -ForegroundColor Yellow
    }
}
# ──14c. Catch-all for remaining Play-To rules by DisplayName ───────────────
Write-Host "`n=== Disabling remaining 'Wiedergabe auf Gerät' rules by DisplayName pattern ===" -ForegroundColor Yellow
try {
    $playTo = Get-NetFirewallRule -DisplayName '*Wiedergabe auf Gerät*' -ErrorAction SilentlyContinue
    if ($playTo) {
        $playTo | Disable-NetFirewallRule -ErrorAction Stop
        $count = ($playTo | Measure-Object).Count
        Write-Host "SUCCESS: Disabled $count rules matching '*Wiedergabe auf Gerät*'" -ForegroundColor Green
    } else {
        Write-Host "INFO: No more rules matching '*Wiedergabe auf Gerät*' found" -ForegroundColor Cyan
    }
} catch {
    Write-Host "WARNING: Error disabling '*Wiedergabe auf Gerät*' rules – $($_.Exception.Message)" -ForegroundColor Yellow
}
# ──15. Finish ──────────────────────────────────────────────────────────────
Write-Host "`n" + "="*60 -ForegroundColor Yellow
Write-Host "HARDENING SCRIPT COMPLETED SUCCESSFULLY" -ForegroundColor Green
Write-Host "="*60 -ForegroundColor Yellow
Write-Host "Completion time: $(Get-Date)" -ForegroundColor Cyan
Write-Host "Registry backup: $regBackup" -ForegroundColor Cyan
Write-Host "Firewall backup: $backupFile" -ForegroundColor Cyan
Write-Host "`nIMPORTANT: A system reboot is recommended to ensure all changes take effect." -ForegroundColor Yellow
Write-Host "Automatic reboot is DISABLED. Please reboot manually when convenient." -ForegroundColor Yellow
Write-Host "="*60 -ForegroundColor Yellow
Filename: None. Size: 26kb. View raw, , hex, or download this file.

This paste expires on 2025-07-03 22:07:28.753533. Pasted through web.