How I audited, hardened, and reviewed my Windows laptop security using built-in tools, PowerShell, and Windows Firewall. Every change was tested and reversible.
Before You Start: Requirements for This Windows Security Audit
Before running any commands in this guide, prepare your system and verify the following requirements. These checks ensure commands return accurate results and that you can safely roll back changes if needed.
Administrator Access
You need a local administrator account to perform most checks in this guide. Open PowerShell using “Run as Administrator” and confirm the window title shows administrator privileges before continuing.
PowerShell 5.1 or Later
Check your version:
$PSVersionTable.PSVersion Major version should be 5 or higher. Windows 10 and 11 ship with PowerShell 5.1 by default.
Windows 11 or Windows 10
This audit is designed for supported Windows 11 and Windows 10 systems. Some security settings and commands may differ on older versions.
winver Backup Location
Create a dedicated folder before making any changes:
New-Item -ItemType Directory -Path "C:\Security-Audit" -Force All backups, logs, and rollback scripts will reference this path.
System Restore Enabled
Verify System Protection is active on your system drive:
Get-ComputerRestorePoint | Select-Object -First 1 If no output appears, enable it in System Properties before proceeding.
Stable Internet Connection
Some verification steps require DNS resolution. Do not perform this audit on a metered or unstable connection where you cannot verify results.
Do not run these commands on a production machine or corporate laptop without approval. Some firewall changes will block file sharing and remote management. Always test on a personal device first.
Why I Started a Windows Laptop Security Audit
I have worked across Windows, Linux, macOS, and server environments, building applications, managing systems, and configuring networks. That experience gave me confidence that I understood the basics of keeping systems secure.
However, security knowledge and security verification are different things. A system can appear secure while still running unnecessary services, exposed network listeners, or outdated configurations in the background. That led me to perform a complete security audit of a Windows laptop to understand what was actually running, listening, and communicating.
Then I ran one command:
netstat -ano | findstr LISTENING The output changed my mind. My laptop was listening on seventeen ports. I recognized three of them. The other fourteen were a mix of Windows services, development tools, and background applications I had forgotten about. Some were bound to 0.0.0.0, meaning any device on the same network could reach them.
I was not hacked. But I was exposed. Exposure is not the same as compromise, but it is the precondition. An unnecessary listening port deserves review because it may expose a service you do not need. Unknown services should be identified before deciding whether they require action.
This Windows laptop security audit documents the checks performed, the findings, the changes applied, and the rollback options. Each recommendation includes the reason behind the change.
Check Open Ports and Network Exposure on Windows
Before changing anything, you need to know what your laptop looks like from the network perspective. This first review shows which connections and services need attention before making security changes.
1.1 Capture All Listening Ports
Open PowerShell as Administrator. Run:
netstat -ano | findstr LISTENING | Out-File "C:\Security-Audit\ports-baseline.txt" Then read the file:
Get-Content "C:\Security-Audit\ports-baseline.txt" Break down the command:
netstat– Network statistics-a– All connections and listening ports-n– Numeric addresses (no DNS resolution)-o– Owning process IDfindstr LISTENING– Filter to only listening sockets
1.2 What the Output Means
Each line follows this format:
Protocol Local Address Foreign Address State PID
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4
TCP 127.0.0.1:9222 0.0.0.0:0 LISTENING 9208 | Local Address | Exposure Level | Action Required |
|---|---|---|
127.0.0.1 | None – localhost only | Verify the owning process is legitimate |
0.0.0.0 | Full – all interfaces | Identify process. Block in firewall if not needed |
:: | Full – IPv6 all interfaces | Same as 0.0.0.0 |
192.168.x.x | Local network only | Check if intentional for LAN sharing |
1.3 Map PIDs to Process Names
Port numbers are meaningless without knowing which process owns them. Use the PID from netstat:
tasklist /fi "PID eq 9208" For a cleaner PowerShell view:
Get-Process -Id 9208 | Select-Object Name, Path, Company If the path is inside C:\Windows\System32 and the company is Microsoft Corporation, it is likely legitimate. If the path is in a user folder, temp directory, or has no company signature, investigate deeper.
1.4 Get Full Process Details
Get-CimInstance Win32_Process -Filter "ProcessId = 9208" |
Select-Object Name, ExecutablePath, CommandLine, ProcessId The CommandLine property shows startup arguments. A legitimate service will have standard arguments. A suspicious process may have encoded commands, unusual paths, or network-related parameters.
1.5 Verify Digital Signatures
Never trust a filename. Trust a signature.
Get-AuthenticodeSignature "C:\Windows\System32\svchost.exe" |
Select-Object Status, Path, SignerCertificate Expected result:
Status : Valid If the status is NotSigned, HashMismatch, or UnknownError, the file has been modified or was never signed by the publisher. Do not trust it until you verify the source.
Check all running executables at once:
Get-Process | Where-Object {$_.Path} |
ForEach-Object { Get-AuthenticodeSignature $_.Path } |
Where-Object {$_.Status -ne "Valid"} |
Select-Object Path, Status Understanding Windows Services and svchost.exe
When you run netstat, you will see multiple svchost.exe entries with different PIDs. This confuses most users. Here is what is actually happening.
Windows does not run every service as a separate process. Instead, it groups services into shared process hosts. svchost.exe is that host. One svchost.exe process can contain multiple services.
2.1 List Services Inside Each svchost.exe
tasklist /svc /fi "imagename eq svchost.exe" Output example:
Image Name PID Services
========================= ======== ============================================
svchost.exe 1234 Dhcp, Dnscache, NlaSvc
svchost.exe 5678 RpcSs, TermService
svchost.exe 9012 W32Time, WinHttpAutoProxySvc 2.2 PowerShell Method for Service Details
Get-CimInstance Win32_Service |
Where-Object {$_.ProcessId -eq 1234} |
Select-Object Name, DisplayName, StartMode, State Replace 1234 with the PID you are investigating.
2.3 Why This Matters for Security
svchost.exe runs as SYSTEM. Any service inside it inherits that privilege level. If a malicious service were injected into a svchost.exe group, it would have full system access.
Modern Windows versions increasingly isolate services into their own svchost.exe processes. You can check isolation status:
Get-CimInstance Win32_Service |
Where-Object {$_.Name -eq "NameOfService"} |
Select-Object Name, ProcessId, StartMode Terminating svchost.exe will crash every service inside it. If a service needs to stop, use Stop-Service or the Services Manager. Never use Task Manager to end the process.
Configure Windows Firewall for Better Laptop Security
Windows Firewall controls which network connections can reach your laptop. Reviewing its rules helps identify unnecessary access while keeping required services available.
3.1 Verify Current Firewall State
Get-NetFirewallProfile |
Select-Object Name, Enabled, DefaultInboundAction, DefaultOutboundAction Expected secure baseline:
| Profile | Enabled | DefaultInboundAction | DefaultOutboundAction |
|---|---|---|---|
| Domain | True | Block | Allow |
| Private | True | Block | Allow |
| Public | True | Block | Allow |
If DefaultInboundAction is Allow or NotConfigured, your firewall is not blocking unsolicited inbound traffic. Fix it:
Set-NetFirewallProfile -Profile Domain,Private,Public -DefaultInboundAction Block 3.2 Export Firewall Configuration Before Changes
netsh advfirewall export "C:\Security-Audit\firewall-backup-$(Get-Date -Format yyyyMMdd).wfw" Verify the file exists:
Get-Item "C:\Security-Audit\firewall-backup-*.wfw" 3.3 Block SMB and NetBIOS Inbound
SMB (port 445) and NetBIOS (ports 137-139) are the most commonly exploited Windows protocols on local networks. WannaCry, EternalBlue, and numerous lateral movement techniques depend on these ports.
If you do not actively share files from your laptop to other devices, these should be blocked.
# Block SMB TCP 445
New-NetFirewallRule `
-DisplayName "AUDIT-Block-SMB-TCP-445-Inbound" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 445 `
-Action Block `
-Profile Any `
-Group "SecurityAudit"
# Block NetBIOS TCP 139
New-NetFirewallRule `
-DisplayName "AUDIT-Block-NetBIOS-TCP-139-Inbound" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 139 `
-Action Block `
-Profile Any `
-Group "SecurityAudit"
# Block NetBIOS UDP 137,138
New-NetFirewallRule `
-DisplayName "AUDIT-Block-NetBIOS-UDP-137-Inbound" `
-Direction Inbound `
-Protocol UDP `
-LocalPort 137 `
-Action Block `
-Profile Any `
-Group "SecurityAudit"
New-NetFirewallRule `
-DisplayName "AUDIT-Block-NetBIOS-UDP-138-Inbound" `
-Direction Inbound `
-Protocol UDP `
-LocalPort 138 `
-Action Block `
-Profile Any `
-Group "SecurityAudit" I prefix all custom rules with AUDIT- so I can identify them later. The -Group parameter makes bulk removal easier.
3.4 Disable SMBv1 (Legacy Protocol)
SMBv1 is a 30-year-old protocol with no security features. It should not exist on any modern system.
Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol If the state is Enabled, disable it:
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart Verify after reboot:
Get-SmbServerConfiguration | Select-Object EnableSMB1Protocol This should return False.
3.5 Block Remote Desktop Protocol (RDP)
RDP on port 3389 is one of the most attacked services. If you do not use it, block it.
New-NetFirewallRule `
-DisplayName "AUDIT-Block-RDP-TCP-3389-Inbound" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 3389 `
-Action Block `
-Profile Any `
-Group "SecurityAudit"
New-NetFirewallRule `
-DisplayName "AUDIT-Block-RDP-UDP-3389-Inbound" `
-Direction Inbound `
-Protocol UDP `
-LocalPort 3389 `
-Action Block `
-Profile Any `
-Group "SecurityAudit" Also disable the service:
Set-ItemProperty `
"HKLM:\System\CurrentControlSet\Control\Terminal Server" `
-Name fDenyTSConnections -Value 1
Set-Service TermService -StartupType Disabled
Stop-Service TermService -Force 3.6 Disable LLMNR and NetBIOS Over TCP/IP
LLMNR (Link-Local Multicast Name Resolution) and NetBIOS over TCP/IP are legacy name resolution protocols. Attackers use them for man-in-the-middle attacks, credential relaying, and spoofing. If you are on a modern network with DNS, you do not need these.
Disable LLMNR via Registry
New-ItemProperty `
"HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" `
-Name EnableMulticast -Value 0 -PropertyType DWord -Force Disable NetBIOS Over TCP/IP on All Adapters
$adapters = Get-WmiObject Win32_NetworkAdapterConfiguration -Filter "IPEnabled = 'True'"
foreach ($adapter in $adapters) {
$adapter.SetTcpipNetbios(2)
} Value 2 disables NetBIOS over TCP/IP. Value 1 enables it. Value 0 uses DHCP settings.
Disable NetBIOS via Registry (Persistent)
$regPath = "HKLM:\SYSTEM\CurrentControlSet\Services\NetBT\Parameters\Interfaces"
Get-ChildItem $regPath | ForEach-Object {
Set-ItemProperty -Path $_.PSPath -Name "NetbiosOptions" -Value 2
} Disabling LLMNR and NetBIOS may break name resolution on older networks that rely on these protocols. If you lose access to network shares or printers, re-enable LLMNR by setting EnableMulticast to 1 and NetBIOS options to 0.
3.7 Disable WPAD (Web Proxy Auto-Discovery)
WPAD allows browsers to discover proxy settings automatically. It is also a known attack vector for man-in-the-middle attacks. If you do not use a corporate proxy, disable it.
New-ItemProperty `
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttp" `
-Name DisableWpad -Value 1 -PropertyType DWord -Force
New-ItemProperty `
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" `
-Name AutoDetect -Value 0 -PropertyType DWord -Force 3.8 Verify Firewall Rules Are Applied
Get-NetFirewallRule |
Where-Object {$_.DisplayName -like "AUDIT-*"} |
Select-Object DisplayName, Direction, Action, Enabled, Profile All rules should show Action: Block and Enabled: True.
Review Windows Services, Startup Apps, and Scheduled Tasks
Services run with elevated privileges. Startup items run every time you log in. Scheduled tasks run on triggers you may not notice. All three are persistence mechanisms.
4.1 Audit Running Services
Get-Service |
Where-Object {$_.Status -eq "Running"} |
Select-Object Name, DisplayName, StartType |
Export-Csv "C:\Security-Audit\services-baseline.csv" -NoTypeInformation Review the CSV. Look for:
- Services with
StartType: Automaticthat you do not recognize - Third-party services from unknown publishers
- Services related to software you uninstalled but left behind
4.2 High-Value Services to Review
| Service | Purpose | Recommendation |
|---|---|---|
DoSvc | Delivery Optimization (Windows Update P2P) | Disable if you do not want P2P updates |
CDPSvc | Connected Devices Platform | Disable if no cross-device features needed |
DiagTrack | Connected User Experiences and Telemetry | Disable for privacy |
dmwappushservice | WAP Push Message Routing | Disable on non-mobile devices |
RemoteRegistry | Remote Registry access | Disable immediately |
TermService | Remote Desktop Services | Disable if RDP not used |
TrkWks | Distributed Link Tracking | Disable on single-user laptops |
SharedAccess | Internet Connection Sharing | Disable unless sharing connection |
4.3 Disable a Service Safely
Never disable a service without checking dependencies:
Get-Service -Name "DoSvc" |
Select-Object -ExpandProperty ServicesDependedOn If no critical services depend on it, disable:
Set-Service -Name "DoSvc" -StartupType Disabled
Stop-Service -Name "DoSvc" -Force Document the change:
Add-Content "C:\Security-Audit\changes.log" "$(Get-Date): Disabled DoSvc (Delivery Optimization) - no dependencies found" 4.4 Audit Startup Applications
Get-CimInstance Win32_StartupCommand |
Select-Object Name, Command, Location, User |
Export-Csv "C:\Security-Audit\startup-baseline.csv" -NoTypeInformation Cross-reference with Task Manager > Startup tab. Disable anything you do not need:
Remove-ItemProperty `
"HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" `
-Name "UnwantedApp" 4.5 Audit Scheduled Tasks
Get-ScheduledTask |
Where-Object {$_.State -eq "Ready" -or $_.State -eq "Running"} |
Select-Object TaskName, TaskPath, Author, State |
Export-Csv "C:\Security-Audit\tasks-baseline.csv" -NoTypeInformation Pay attention to tasks with no author or an author you do not recognize. Microsoft tasks typically show Author: Microsoft Corporation.
Disable a suspicious task:
Disable-ScheduledTask -TaskName "\SuspiciousVendor\TaskName" Improve Windows DNS Security and Network Filtering
DNS is an important part of the connection process because it decides where domain names point. A compromised DNS path can redirect users before encryption protects the connection, which makes DNS configuration worth reviewing.
5.1 Check Current DNS Configuration
Get-DnsClientServerAddress -AddressFamily IPv4 |
Where-Object {$_.ServerAddresses} |
Select-Object InterfaceAlias, ServerAddresses Most users see their router’s IP (e.g., 192.168.1.1) or their ISP’s DNS servers. Neither provides filtering.
5.2 Switch to a Filtered DNS Resolver
I use Quad9 for malware blocking. It is operated by a non-profit, requires no account, and blocks known malicious domains at the DNS level.
| Provider | Primary | Secondary | Filters |
|---|---|---|---|
| Quad9 | 9.9.9.9 | 149.112.112.112 | Malware, phishing |
| Cloudflare Malware | 1.1.1.2 | 1.0.0.2 | Malware, adult content optional |
| Cloudflare Standard | 1.1.1.1 | 1.0.0.1 | Privacy only, no filtering |
| OpenDNS | 208.67.222.222 | 208.67.220.220 | Custom filtering, account required |
5.3 Apply DNS via PowerShell
$adapter = Get-NetAdapter | Where-Object {$_.Status -eq "Up"} | Select-Object -First 1
Set-DnsClientServerAddress `
-InterfaceIndex $adapter.ifIndex `
-ServerAddresses ("9.9.9.9","149.112.112.112") Verify:
Resolve-DnsName -Name "google.com" -Type A If you get a valid IP response, DNS is working. If not, check the adapter index and connection status.
5.4 Enable DNS Over HTTPS (Windows 11)
DNS over HTTPS (DoH) encrypts DNS queries so they cannot be intercepted by your ISP or network observers.
$adapter = Get-NetAdapter | Where-Object {$_.Status -eq "Up"} | Select-Object -First 1
Set-DnsClientDohServerAddress `
-ServerAddress "9.9.9.9" `
-DohTemplate "https://dns.quad9.net/dns-query" `
-AllowFallbackToUdp $false `
-AutoUpgrade $true Verify DoH is active:
Get-DnsClientDohServerAddress 5.5 Flush DNS Cache
After changing DNS, clear the cache to remove stale entries:
Clear-DnsClientCache
ipconfig /flushdns 5.6 DNS Rollback
If DNS changes break connectivity:
$adapter = Get-NetAdapter | Where-Object {$_.Status -eq "Up"} | Select-Object -First 1
Set-DnsClientServerAddress -InterfaceIndex $adapter.ifIndex -ResetServerAddresses Configure Windows Defender Security Settings
Windows Defender includes several security controls beyond traditional malware scanning. Features such as Attack Surface Reduction, Exploit Guard, and tamper protection provide additional protection when configured correctly.
6.1 Verify Tamper Protection
Tamper protection prevents malware from disabling Windows Defender. If this is off, your antivirus can be silently neutered.
Get-MpComputerStatus | Select-Object IsTamperProtected If this returns False, enable it in Windows Security > Virus & threat protection > Manage settings. This specific setting cannot be changed via PowerShell for security reasons.
6.2 Enable Attack Surface Reduction (ASR) Rules
ASR rules block common malware behaviors. These are enterprise-grade controls available on all Windows editions.
# Block Office apps from creating child processes
Set-MpPreference -AttackSurfaceReductionRules_Ids D4F940AB-401B-4EFC-AADC-AD5F3C50688A -AttackSurfaceReductionRules_Actions Enabled
# Block Office apps from creating executable content
Set-MpPreference -AttackSurfaceReductionRules_Ids 3B576869-A4EC-4529-8536-B80A7769E899 -AttackSurfaceReductionRules_Actions Enabled
# Block Office apps from injecting code into other processes
Set-MpPreference -AttackSurfaceReductionRules_Ids 75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84 -AttackSurfaceReductionRules_Actions Enabled
# Block JavaScript and VBScript from launching downloaded executable content
Set-MpPreference -AttackSurfaceReductionRules_Ids D3E037E1-3EB8-44C8-A917-57927947596D -AttackSurfaceReductionRules_Actions Enabled
# Block execution of potentially obfuscated scripts
Set-MpPreference -AttackSurfaceReductionRules_Ids 5BEB7EFE-FD9A-4556-801D-275E5FFC04CC -AttackSurfaceReductionRules_Actions Enabled
# Block Win32 API calls from Office macros
Set-MpPreference -AttackSurfaceReductionRules_Ids 92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B -AttackSurfaceReductionRules_Actions Enabled Verify all rules:
Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionRules_Ids 6.3 Enable Exploit Guard Network Protection
Set-MpPreference -EnableNetworkProtection Enabled This blocks outbound connections to malicious IPs and domains at the network layer, complementing your DNS filtering.
6.4 Enable Cloud-Delivered Protection
Set-MpPreference -MAPSReporting Advanced
Set-MpPreference -SubmitSamplesConsent SendAllSamples Cloud protection sends suspicious files to Microsoft for analysis. This improves detection of zero-day threats.
Cloud-delivered protection sends file metadata and potentially full files to Microsoft. If you have strict privacy requirements, set -SubmitSamplesConsent NeverSend instead. Detection quality will be lower.
6.5 Schedule Quick Scans and Update Signatures
Set-MpPreference -ScanScheduleQuickScanTime 02:00
Set-MpPreference -SignatureUpdateInterval 4 This sets quick scans for 2:00 AM and updates signatures every 4 hours.
6.6 Run a Full Scan
Start-MpScan -ScanType FullScan This will take time. Run it overnight. Check results:
Get-MpThreatDetection Phase 7: Registry and System Hardening
These are one-time registry changes that close common attack vectors. All changes are reversible with the rollback commands provided.
7.1 Disable Autorun for All Drives
Autorun is a legacy feature that executes code automatically when removable media is inserted. It has been a malware vector for decades.
New-ItemProperty `
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" `
-Name NoDriveTypeAutoRun -Value 255 -PropertyType DWord -Force Value 255 disables Autorun for all drive types.
7.2 Enable Windows Defender Potentially Unwanted Application (PUA) Protection
New-ItemProperty `
"HKLM:\Software\Policies\Microsoft\Windows Defender\MpEngine" `
-Name MpEnablePus -Value 1 -PropertyType DWord -Force 7.3 Disable Remote Assistance
New-ItemProperty `
"HKLM:\System\CurrentControlSet\Control\Remote Assistance" `
-Name fAllowToGetHelp -Value 0 -PropertyType DWord -Force 7.4 Disable Windows Script Host (If Not Needed)
Windows Script Host executes VBScript and JScript files. Many malware strains use these. If you do not need legacy scripting, disable it.
New-ItemProperty `
"HKLM:\Software\Microsoft\Windows Script Host\Settings" `
-Name Enabled -Value 0 -PropertyType DWord -Force Disabling Windows Script Host will break legacy administrative scripts and some older software installers. If you encounter errors, re-enable by setting the value to 1.
7.5 Export Registry Before Changes
reg export "HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" "C:\Security-Audit\explorer-policies.reg"
reg export "HKLM\System\CurrentControlSet\Control\Remote Assistance" "C:\Security-Audit\remote-assistance.reg"
reg export "HKLM\Software\Microsoft\Windows Script Host\Settings" "C:\Security-Audit\wsh-settings.reg" Phase 8: Account Security and UAC
User accounts are the final boundary. If an attacker reaches this layer, your configuration determines whether they gain full control or hit a wall.
8.1 Audit Administrator Accounts
net localgroup administrators Every account listed has full system access. Remove any that are unnecessary:
net localgroup administrators "OldAccount" /delete 8.2 Verify UAC Settings
UAC should not be disabled. Check the registry:
Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System" -Name EnableLUA Value should be 1. If it is 0, UAC is disabled. Re-enable:
Set-ItemProperty `
"HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System" `
-Name EnableLUA -Value 1 8.3 Enable Credential Guard (Windows 10/11 Pro/Enterprise)
Credential Guard uses virtualization to isolate credential storage. Even if malware gains admin access, it cannot extract cached credentials.
bcdedit /set {0cb3b571-2f2e-4343-a879-cc86edf4596e} loadoptions DISABLE-LSA-ISO,DISABLE-LSA
bcdedit /set {0cb3b571-2f2e-4343-a879-cc86edf4596e} device loadoptions DISABLE-LSA-ISO,DISABLE-LSA
bcdedit /set vsmlaunchtype auto
bcdedit /set loadoptions ENABLE-LSA-ISO Reboot required. Verify after restart:
Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard |
Select-Object LsaCfgCredGuardPolicyStatus Should return Running or Secured.
Credential Guard requires UEFI Secure Boot, virtualization support (Intel VT-x or AMD-V), and Windows Pro/Enterprise. It is not available on Windows Home editions.
Phase 9: Browser and WiFi Security
Browsers are the primary attack surface for most users. WiFi is the primary network boundary for laptops. Both need hardening.
9.1 Browser Extension Audit
Chrome extensions have full access to every page you visit. A malicious or compromised extension is a keylogger, credential harvester, and ad injector all in one.
Open Chrome and navigate to:
chrome://extensions/ For each extension, check:
- Permissions: Does it need
Read and change all your data on all websites? - Developer: Is the publisher a known company or an unknown individual?
- Reviews: Recent negative reviews mentioning malware or unwanted behavior
- Update date: Extensions that have not updated in years may be abandoned
Remove any extension you do not actively use. The risk of a supply chain compromise on an unused extension is not worth the convenience.
For Edge, use:
edge://extensions/ 9.2 Disable Browser Password Saving
Browser password managers are convenient but less secure than dedicated password managers. If you use Bitwarden, 1Password, or KeePass, disable the browser’s built-in password manager to prevent credential confusion.
Chrome: Settings > Autofill > Passwords > Offer to save passwords = Off
9.3 WiFi Network Profile Hardening
Windows assigns a network profile (Public or Private) to every WiFi connection. The profile determines firewall rules, file sharing, and network discovery.
Get-NetConnectionProfile Check the NetworkCategory for each active connection.
| Profile | Firewall Behavior | When to Use |
|---|---|---|
| Public | Blocks file sharing, network discovery, and most inbound | All unknown networks (coffee shops, airports, hotels) |
| Private | Allows file sharing and network discovery within the network | Only trusted home networks |
| Domain | Controlled by Group Policy | Corporate environments |
Never set a public network to Private. If Windows incorrectly categorizes a network, change it manually:
Set-NetConnectionProfile -Name "WiFiNetworkName" -NetworkCategory Public 9.4 Disable WiFi Sense (Windows 10)
WiFi Sense automatically shares your WiFi passwords with Outlook, Skype, and Facebook contacts. It should be disabled.
New-ItemProperty `
"HKLM:\Software\Microsoft\WcmSvc\wifinetworkmanager\config" `
-Name AutoConnectAllowedOEM -Value 0 -PropertyType DWord -Force 9.5 Forget Old WiFi Networks
Windows automatically connects to known networks. An attacker can create a rogue access point with the same SSID and your laptop will connect automatically.
netsh wlan show profiles Delete networks you no longer use:
netsh wlan delete profile name="OldNetworkName" Phase 10: Event Log and Security Monitoring
Windows Event Logs record security events, authentication attempts, service changes, and privilege escalations. Most users never look at them. A power user uses them to detect anomalies.
10.1 Enable PowerShell Script Block Logging
PowerShell is a common attack vector. Script block logging records every PowerShell command executed, including obfuscated scripts.
New-ItemProperty `
"HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" `
-Name EnableScriptBlockLogging -Value 1 -PropertyType DWord -Force
New-ItemProperty `
"HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" `
-Name EnableScriptBlockInvocationLogging -Value 1 -PropertyType DWord -Force Logs are written to: Event Viewer > Applications and Services Logs > Microsoft > Windows > PowerShell > Operational
10.2 Enable PowerShell Transcription
Transcription records the full input and output of every PowerShell session to a text file.
New-ItemProperty `
"HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription" `
-Name EnableTranscripting -Value 1 -PropertyType DWord -Force
New-ItemProperty `
"HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription" `
-Name OutputDirectory -Value "C:\Security-Audit\PS-Logs" -PropertyType String -Force
New-ItemProperty `
"HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription" `
-Name EnableInvocationHeader -Value 1 -PropertyType DWord -Force 10.3 Key Security Event IDs to Monitor
Open Event Viewer (eventvwr.msc) and navigate to Windows Logs > Security. Filter for these Event IDs:
| Event ID | Description | Why It Matters |
|---|---|---|
| 4624 | Successful logon | Detect unauthorized access, unusual logon types |
| 4625 | Failed logon | Brute force attempts, password spraying |
| 4648 | Explicit credential logon | Pass-the-hash or credential reuse attempts |
| 4672 | Special privileges assigned | Admin logons, service starts |
| 4688 | Process creation | New processes, suspicious command lines |
| 4697 | Service installed | New persistence mechanism |
| 4698 | Scheduled task created | New persistence mechanism |
| 4702 | Scheduled task updated | Task modification for evasion |
| 4720 | User account created | Backdoor account creation |
| 4724 | Password reset attempt | Account takeover attempts |
| 4732 | Member added to local group | Privilege escalation |
| 4740 | Account locked out | Brute force detection |
| 4768 | Kerberos authentication ticket requested | Pass-the-ticket detection |
| 4769 | Kerberos service ticket requested | Lateral movement detection |
| 4771 | Kerberos pre-authentication failed | Password guessing on domain |
| 4776 | NTLM authentication | Legacy protocol usage |
| 7045 | Service installed (System log) | Cross-reference with 4697 |
10.4 Query Security Events via PowerShell
Instead of scrolling through Event Viewer, query specific events:
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4624,4625,4648,4672,4688,4697,4698,4720,4724,4732,4740} |
Select-Object TimeCreated, Id, LevelDisplayName, Message |
Sort-Object TimeCreated -Descending |
Select-Object -First 50 Export to CSV for analysis:
Get-WinEvent -FilterHashtable @{LogName='Security'; ID=4625} |
Select-Object TimeCreated, Id, Message |
Export-Csv "C:\Security-Audit\failed-logons.csv" -NoTypeInformation 10.5 Monitor for New Local Admin Accounts
Check for recently created accounts with admin rights:
Get-LocalUser | Where-Object {$_.Enabled -eq $true} |
Select-Object Name, SID, PasswordLastSet, LastLogon |
Sort-Object PasswordLastSet -Descending Cross-reference with the administrators group:
Get-LocalGroupMember -Group "Administrators" |
Select-Object Name, SID, PrincipalSource Phase 11: Verification and Testing
Every change must be verified. A security configuration that breaks your workflow is worse than no configuration at all.
11.1 Re-check Listening Ports
netstat -ano | findstr LISTENING | Out-File "C:\Security-Audit\ports-hardened.txt" Compare with baseline:
Compare-Object `
(Get-Content "C:\Security-Audit\ports-baseline.txt") `
(Get-Content "C:\Security-Audit\ports-hardened.txt") Look for reductions in 0.0.0.0 listeners. Localhost-only ports (127.0.0.1) are expected to remain.
11.2 Test Firewall Rules
Get-NetFirewallRule -Group "SecurityAudit" |
Select-Object DisplayName, Direction, Action, Enabled 11.3 Test DNS Resolution
Resolve-DnsName -Name "google.com"
Resolve-DnsName -Name "microsoft.com" Both should return IP addresses. If they fail, your DNS configuration is wrong.
11.4 Test Network Connectivity
Test-NetConnection -ComputerName "google.com" -Port 443 TcpTestSucceeded should be True. If not, your firewall may be blocking outbound HTTPS.
11.5 Verify Windows Defender Status
Get-MpComputerStatus |
Select-Object AntivirusEnabled, RealTimeProtectionEnabled, BehaviorMonitorEnabled, OnAccessProtectionEnabled All four should be True.
11.6 Create a System Restore Point
Now that everything is hardened, create a restore point labeled for this state:
Checkpoint-Computer -Description "Post-Security-Hardening" -RestorePointType "MODIFY_SETTINGS" Complete Rollback Reference
Every command in this guide has a corresponding undo. Store this section in your C:\Security-Audit folder as rollback.ps1.
Firewall Rollback
# Restore firewall from backup
netsh advfirewall import "C:\Security-Audit\firewall-backup-.wfw"
# Or remove custom audit rules only
Get-NetFirewallRule -Group "SecurityAudit" | Remove-NetFirewallRule
# Reset default inbound action
Set-NetFirewallProfile -Profile Domain,Private,Public -DefaultInboundAction NotConfigured Service Rollback
Set-Service -Name "DoSvc" -StartupType Automatic
Start-Service -Name "DoSvc"
Set-Service -Name "CDPSvc" -StartupType Automatic
Start-Service -Name "CDPSvc"
Set-Service -Name "DiagTrack" -StartupType Automatic
Start-Service -Name "DiagTrack" DNS Rollback
$adapter = Get-NetAdapter | Where-Object {$_.Status -eq "Up"} | Select-Object -First 1
Set-DnsClientServerAddress -InterfaceIndex $adapter.ifIndex -ResetServerAddresses
Clear-DnsClientCache Registry Rollback
reg import "C:\Security-Audit\explorer-policies.reg"
reg import "C:\Security-Audit\remote-assistance.reg"
reg import "C:\Security-Audit\wsh-settings.reg" LLMNR and NetBIOS Rollback
Remove-ItemProperty `
"HKLM:\Software\Policies\Microsoft\Windows NT\DNSClient" `
-Name EnableMulticast
$adapters = Get-WmiObject Win32_NetworkAdapterConfiguration -Filter "IPEnabled = 'True'"
foreach ($adapter in $adapters) {
$adapter.SetTcpipNetbios(0)
} RDP Rollback
Set-ItemProperty `
"HKLM:\System\CurrentControlSet\Control\Terminal Server" `
-Name fDenyTSConnections -Value 0
Set-Service -Name "TermService" -StartupType Automatic
Start-Service -Name "TermService" SMBv1 Rollback
Enable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart ASR Rules Rollback
Set-MpPreference -AttackSurfaceReductionRules_Actions Disabled PowerShell Logging Rollback
Remove-ItemProperty `
"HKLM:\Software\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" `
-Name EnableScriptBlockLogging
Remove-ItemProperty `
"HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Transcription" `
-Name EnableTranscripting Monthly Security Audit Routine
Security is not a one-time configuration. It is a maintenance task. I run this routine on the first Sunday of every month. It takes approximately 20 minutes.
Monthly Commands
Save this as C:\Security-Audit\monthly-audit.ps1:
$date = Get-Date -Format "yyyy-MM-dd"
$folder = "C:\Security-Audit"
# Export current state
netstat -ano | findstr LISTENING | Out-File "$folder\ports-$date.txt"
Get-Process | Sort-Object ProcessName | Out-File "$folder\processes-$date.txt"
Get-Service | Select-Object Name, Status, StartType | Export-Csv "$folder\services-$date.csv" -NoTypeInformation
Get-NetFirewallRule | Where-Object {$_.Enabled -eq "True"} | Select-Object DisplayName, Direction, Action | Export-Csv "$folder\firewall-$date.csv" -NoTypeInformation
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, Publisher, InstallDate | Export-Csv "$folder\software-$date.csv" -NoTypeInformation
# Compare with previous month
$prev = Get-ChildItem "$folder\ports-*.txt" | Sort-Object LastWriteTime | Select-Object -Last 2
if ($prev.Count -eq 2) {
Compare-Object (Get-Content $prev[0]) (Get-Content $prev[1]) | Out-File "$folder\diff-$date.txt"
Write-Host "Diff saved to $folder\diff-$date.txt"
} What to Look For Each Month
- New listening ports: Any
0.0.0.0listener that was not there last month - New processes: Applications running that you did not install
- New firewall rules: Allow rules created by software installers
- New software: Entries in the uninstall registry you do not recognize
- Service changes: Automatic services that were manual last month
After Installing New Software
Always run these checks immediately after installing anything:
Get-NetFirewallRule | Where-Object {$_.DisplayName -notlike "AUDIT-*" -and $_.Enabled -eq "True" -and $_.Direction -eq "Inbound"} | Select-Object DisplayName, Program, Action
Get-ScheduledTask | Where-Object {$_.Date -gt (Get-Date).AddDays(-1)} | Select-Object TaskName, Author, Date
Get-CimInstance Win32_StartupCommand | Where-Object {$_.Location -notmatch "Microsoft"} | Select-Object Name, Command Security Decision Framework
When you find an unknown port, process, or service, use this decision tree before taking action:
- Identify: What is the process name and executable path?
- Verify: Is it signed by a trusted publisher?
- Classify: Is it a system component, installed software, or unknown?
- Evaluate: Does it need network access to function?
- Decide: Allow, block, or disable. Document the reason.
- Test: Verify your workflow still works after the change.
Final Hardening Checklist
Use this checklist to verify nothing was missed. Every item should be checked before considering the audit complete.
Network Exposure
- Baseline listening ports captured and saved
- All
0.0.0.0listeners identified and justified - SMB (445) blocked inbound or disabled
- NetBIOS (137-139) blocked inbound
- RDP (3389) blocked and service disabled
- LLMNR disabled via registry
- NetBIOS over TCP/IP disabled on all adapters
- WPAD disabled
Firewall
- Default inbound action set to Block for all profiles
- Custom audit rules created and verified
- Firewall configuration exported to backup
- Unknown inbound allow rules reviewed
Services
- Running services exported to CSV
- Unnecessary auto-start services disabled
- Service dependencies checked before stopping
- Changes logged to
changes.log
Startup and Persistence
- Startup applications reviewed and exported
- Scheduled tasks audited for unknown authors
- Registry run keys reviewed
DNS and Network
- DNS changed to filtered resolver (Quad9/Cloudflare)
- DNS resolution verified with
Resolve-DnsName - DNS cache cleared
- DoH enabled if on Windows 11
Windows Defender
- Tamper protection enabled
- ASR rules configured
- Network protection enabled
- Cloud-delivered protection enabled
- Full scan completed
System Hardening
- Autorun disabled for all drives
- Remote Assistance disabled
- Windows Script Host disabled (if compatible)
- UAC enabled and verified
- Administrator accounts audited
- Credential Guard enabled (if supported)
Browser and WiFi
- Browser extensions audited and unused removed
- Browser password saving disabled
- WiFi profiles set to Public on unknown networks
- Old WiFi networks forgotten
- WiFi Sense disabled
Monitoring
- PowerShell script block logging enabled
- PowerShell transcription enabled
- Security event IDs reviewed
- Local admin accounts audited
Documentation
C:\Security-Auditfolder created and populated- Firewall backup saved
- Registry backups exported
- Rollback script created
- System restore point created post-hardening
Common Mistakes to Avoid
These are mistakes I made or observed during the process. Learn from them.
Mistake 1: Blocking All Inbound Traffic Without Exceptions
If you block everything, Windows Update, network printing, and some VPN clients may break. Set the default to Block, then create explicit allow rules for what you need.
Mistake 2: Disabling Services Without Checking Dependencies
I once disabled CDPSvc without checking and lost the ability to use Windows clipboard sync across devices. Always check ServicesDependedOn before stopping a service.
Mistake 3: Trusting Filenames
update.exe, helper.exe, and service.exe are common malware names. Always verify the path and signature. A file in C:\Users\You\AppData\Local\Temp with no signature is not legitimate.
Mistake 4: Ignoring IPv6
:: in netstat means the same as 0.0.0.0 but for IPv6. If you only check IPv4, you miss half the exposure. Always check both.
Mistake 5: Making Changes Without a Baseline
If you do not save the netstat output before hardening, you cannot prove you improved anything. Documentation is not optional. It is the difference between controlled security and guesswork.
Mistake 6: Forgetting to Test After Changes
Every firewall rule, every disabled service, every DNS change must be followed by a connectivity test. A broken laptop is not secure. It is unusable.
Mistake 7: Leaving Old WiFi Networks Saved
An attacker with a rogue access point using your old hotel WiFi SSID can trick your laptop into connecting automatically. Delete every network you no longer use.
Final Thoughts
The biggest improvement to my laptop security was not a new tool. It was understanding what was already running.
Windows is a complex operating system. It has background services, network listeners, scheduled tasks, cloud connections, and legacy protocols that most users never see. The majority of these are legitimate. The danger is not the services themselves. The danger is not knowing they exist.
A secure laptop is not one with nothing running. It is one where every running component has a known purpose and a controlled boundary. The firewall blocks what should not enter. DNS filtering blocks where you should not go. ASR rules block what should not execute. Service control limits what runs automatically. Event monitoring detects what should not happen. Verification ensures nothing changed without your knowledge.
All of this is achievable with the tools already installed on your system. PowerShell, Windows Firewall, Windows Defender, and the Services Manager are enough to build a security posture that exceeds most default configurations.
The only missing piece is the time to use them. Set aside one hour for the initial audit, twenty minutes each month for maintenance, and five minutes after every software installation. That is the difference between assuming you are secure and knowing you are.
Windows Laptop Security Audit FAQ
How do I perform a Windows laptop security audit?
A Windows laptop security audit starts by checking open ports, firewall rules, running services, startup programs, DNS settings, and Windows Defender security settings.
What should I check first to secure a Windows laptop?
Start with network exposure. Check which services are listening, identify unknown processes, and review firewall rules before changing system settings.
Is Windows Defender enough for laptop security?
Windows Defender provides strong built-in protection when security features are configured correctly. Good security also depends on updates, safe browsing habits, and system configuration.
Should I disable Windows services to improve security?
Only disable services you understand and do not need. Some Windows services support other features, so check dependencies before making changes.