1---2name: windows-ps-security3description: Use when hardening Windows systems via PowerShell — Windows Firewall (NetSecurity), Windows Defender/Microsoft Defender, BitLocker drive encryption, audit policy and event log analysis, local security policy, credential management (SecureString, Windows Credential Manager), AppLocker, Windows Update management, and security compliance scanning. Part of the windows-ps-* skill family.4---56# Windows Security Administration via PowerShell78Companion skill to `windows-powershell` (parent). Focused on security hardening, compliance, and threat mitigation on Windows 10/11 and Windows Server 2019/2022/2025.910<HARD-RULE>11FIREWALL LOCKOUT PREVENTION: Never disable all firewall profiles or remove all inbound rules on a remote system without first ensuring an allow rule exists for your management port (RDP 3389, WinRM 5985/5986, or SSH 22). Always test firewall changes on a single machine before deploying broadly. Use `-WhatIf` before applying destructive rule changes.12```powershell13# ALWAYS verify management access rule exists before bulk changes14Get-NetFirewallRule -DisplayName "*Remote Desktop*" | Get-NetFirewallPortFilter15Get-NetFirewallRule -DisplayName "*WinRM*" | Get-NetFirewallPortFilter16```17</HARD-RULE>1819<HARD-RULE>20BITLOCKER RECOVERY KEY BACKUP: Always back up BitLocker recovery keys to Active Directory, Azure AD, or a secure file BEFORE enabling encryption. A lost recovery key means permanent data loss if the TPM is cleared or the drive is moved to another machine.21```powershell22# Back up recovery key BEFORE encrypting23$BLV = Get-BitLockerVolume -MountPoint "C:"24Backup-BitLockerKeyProtector -MountPoint "C:" -KeyProtectorId $BLV.KeyProtector[1].KeyProtectorId25# Also export to file as secondary backup26(Get-BitLockerVolume -MountPoint "C:").KeyProtector | Where-Object { $_.KeyProtectorType -eq 'RecoveryPassword' } |27 Select-Object -ExpandProperty RecoveryPassword | Out-File "\\SecureShare\BitLockerKeys\$env:COMPUTERNAME.txt"28```29</HARD-RULE>3031<HARD-RULE>32CREDENTIAL STORAGE SAFETY: Never store passwords in plain text in scripts. Use `ConvertTo-SecureString`, `Export-Clixml`, or Windows Credential Manager. SecureString encrypted with `Export-Clixml` is tied to the user AND machine that created it — it cannot be decrypted by another user or on another machine. Never commit credential files to version control.33```powershell34# CORRECT: Secure credential storage35$cred = Get-Credential36$cred | Export-Clixml -Path "$env:USERPROFILE\safe-cred.xml"37# WRONG: Plain text password in script (NEVER do this)38# $password = "MyP@ssw0rd!" # <-- NEVER39```40</HARD-RULE>4142---4344## Reference Files4546Detailed code examples, patterns, and configuration are in the reference files below. Read the relevant file when working on that area.4748| File | Covers |49|---|---|50| [credentials-applocker-compliance.md](credentials-applocker-compliance.md) | credential management, AppLocker, local security policy, Windows Update management, security compliance, network security, user account security, and the quick security audit script |51| [firewall-defender-bitlocker-audit.md](firewall-defender-bitlocker-audit.md) | Windows Firewall (NetSecurity), Windows Defender/Microsoft Defender, BitLocker drive encryption, and audit policy/event log analysis |5253---5455---5657## Anti-Patterns5859| Anti-Pattern | Why It Fails | Correct Approach |60|---|---|---|61| Disabling UAC or Windows Defender for "convenience" | Removes primary defense layers; malware runs with full privileges; fails every security audit | Configure exclusions for specific paths/processes; use GPO to manage settings rather than disabling wholesale |62| Storing passwords in scripts as plain text | Scripts in SCM, shared drives, or backup tapes expose credentials; single compromise escalates to domain admin | Use `Get-Credential`, `SecureString`, or external vaults (Azure Key Vault, CyberArk); never hardcode credentials |63| Not enabling PowerShell ScriptBlock logging | No visibility into what scripts execute; incident response has no forensic trail; attackers operate undetected | Enable ScriptBlock and Module logging via GPO; forward to SIEM; essential for detecting encoded/obfuscated attacks |64| Using NTLM authentication instead of Kerberos | NTLM is vulnerable to relay attacks, pass-the-hash, and brute force; cannot use modern security features | Restrict NTLM via GPO (Network security: Restrict NTLM); audit NTLM usage first, then block progressively |65| Running PowerShell remoting without JEA (Just Enough Administration) | Full administrative sessions over WinRM; any command can be executed; no command-level access control | Configure JEA endpoints with role capabilities; limit available cmdlets and parameters per role |6667---6869## Related Skills7071| Skill | Scope |72|---|---|73| `windows-powershell` | Parent skill — core PowerShell syntax, modules, remoting, scripting patterns |74| `windows-ps-server-admin` | Windows Server roles (AD DS, DNS, DHCP, IIS, Hyper-V, clustering) |75| `windows-cmd` | Legacy CMD commands, batch scripting, low-level system tools |