Windows Run Commands
Everything launchable from Win + R, Command Prompt, or PowerShell. Also work from Task Manager → Run new task (check "with administrative privileges" for elevated).
System & Diagnostics
| Command | Opens | Why you care |
|---|---|---|
msconfig | System Configuration | Boot options, Safe Boot toggle, selective startup for troubleshooting |
msinfo32 | System Information | Full hardware/driver/BIOS inventory — export with File → Export for tickets |
dxdiag | DirectX Diagnostics | GPU, driver versions, display info; Save All Information for vendor support |
resmon | Resource Monitor | Per-process disk/network/memory — find what's hammering the disk |
perfmon | Performance Monitor | Counters + Data Collector Sets for long-running perf baselines |
taskmgr | Task Manager | Startup tab, service PIDs (match with netstat -ano) |
eventvwr.msc | Event Viewer | System/Application logs; filter by Event ID (6008 = unexpected shutdown, 41 = kernel-power) |
winver | About Windows | Exact build number for compatibility/patching questions |
cleanmgr | Disk Cleanup | cleanmgr /sageset:1 then /sagerun:1 for scripted cleanup |
mrt | Malicious Software Removal Tool | Quick built-in malware scan |
sigverif | File Signature Verification | Find unsigned drivers |
mdsched | Windows Memory Diagnostic | RAM test on next boot — results in Event Viewer (MemoryDiagnostics-Results) |
Management Consoles (.msc)
| Command | Opens | Why you care |
|---|---|---|
compmgmt.msc | Computer Management | One-stop: events, shares, users, disks, services |
services.msc | Services | Startup type, recovery actions, Log On As accounts |
devmgmt.msc | Device Manager | Driver rollback, hidden devices (View → Show hidden) |
diskmgmt.msc | Disk Management | Partitions, drive letters, extend/shrink volumes |
taskschd.msc | Task Scheduler | Persistence checks during IR — always inspect \Microsoft\Windows too |
gpedit.msc | Local Group Policy | Local policy on Pro+ (not Home) |
secpol.msc | Local Security Policy | Password/lockout/audit policy, user rights assignment |
lusrmgr.msc | Local Users & Groups | Local admin audit (not on Home) |
certlm.msc | Certificates — Local Machine | Machine cert store (use certmgr.msc for current user) |
wf.msc | Windows Defender Firewall (Advanced) | Inbound/outbound rules, logging, connection security |
fsmgmt.msc | Shared Folders | Open files and sessions on a file server |
printmanagement.msc | Print Management | Drivers, ports, deployed printers |
wmimgmt.msc | WMI Control | Repair WMI namespace security |
rsop.msc | Resultant Set of Policy | What GPOs actually applied (or gpresult /h out.html) |
Server / Domain Consoles (RSAT or on the server)
| Command | Opens |
|---|---|
dsa.msc | Active Directory Users & Computers |
dssite.msc | AD Sites & Services |
domain.msc | AD Domains & Trusts |
gpmc.msc | Group Policy Management |
dnsmgmt.msc | DNS Manager |
dhcpmgmt.msc | DHCP Manager |
adsiedit.msc | ADSI Edit — raw AD attribute editing, be careful |
Control Panel Applets (.cpl)
| Command | Opens | Why you care |
|---|---|---|
ncpa.cpl | Network Connections | Fastest path to NIC properties / static IP |
appwiz.cpl | Programs & Features | Uninstall list; optionalfeatures for Windows Features |
sysdm.cpl | System Properties | Rename PC, domain join, remote settings, page file (Advanced) |
firewall.cpl | Firewall (basic) | Quick profile status; use wf.msc for rules |
inetcpl.cpl | Internet Options | Proxy settings (Connections → LAN settings), cert trust |
powercfg.cpl | Power Options | Also see powercfg /batteryreport and powercfg /energy |
timedate.cpl | Date & Time | Kerberos breaks past 5 min skew — check this first on auth errors |
main.cpl | Mouse | |
mmsys.cpl | Sound | Default devices, per-app troubleshooting |
desk.cpl | Display Settings | |
intl.cpl | Region |
Quick Actions & Shell Shortcuts
| Command | Does |
|---|---|
mstsc | Remote Desktop — mstsc /v:server01 /admin for console session |
netplwiz | User Accounts dialog (auto-login checkbox lives here) |
regedit | Registry Editor — export keys before editing |
shell:startup | Current user Startup folder |
shell:common startup | All-users Startup folder |
%temp% | User temp folder — safe to purge contents |
\\server\share | Open UNC path directly |
osk / magnify / charmap | On-screen keyboard / Magnifier / Character Map |
control userpasswords2 | Same as netplwiz |
ms-settings:windowsupdate | Jump straight to a Settings page (ms-settings: URIs) |
Tip: Ctrl+Shift+Enter in the Run box or Start search launches elevated.
DISM / SFC / System Repair
The exact repair sequence, offline variants, and where the logs live. All commands need an elevated prompt.
The Standard Repair Order (memorize this)
DISM repairs the component store that SFC pulls from — so if the store is corrupt, SFC alone will fail. Run DISM first, then SFC, then reboot.
:: 1. Quick check — reads flags only, seconds DISM /Online /Cleanup-Image /CheckHealth :: 2. Deeper scan — checks store for corruption, no repair (few minutes) DISM /Online /Cleanup-Image /ScanHealth :: 3. Repair — pulls known-good files from Windows Update (10-30 min) DISM /Online /Cleanup-Image /RestoreHealth :: 4. Now repair protected system files from the (now healthy) store sfc /scannow :: 5. Reboot, then re-run sfc /scannow to confirm clean
Don't panic if RestoreHealth sits at 62.3% for a long time — that's normal.
RestoreHealth Without Internet / WSUS-Blocked
Point DISM at a known-good install.wim from matching-build ISO media (mounted as X: here).
:: Find the right index in the WIM first DISM /Get-WimInfo /WimFile:X:\sources\install.wim :: Repair using index 1, blocking Windows Update as a fallback source DISM /Online /Cleanup-Image /RestoreHealth /Source:WIM:X:\sources\install.wim:1 /LimitAccess
If the ISO has install.esd instead: /Source:ESD:X:\sources\install.esd:1. Build must match the installed OS (check winver).
Offline Repair (from WinRE / boot media)
:: From Recovery command prompt — target the offline Windows install (often D: in WinRE, verify with dir)
DISM /Image:D:\ /Cleanup-Image /RestoreHealth /Source:WIM:X:\sources\install.wim:1 /LimitAccess
sfc /scannow /offbootdir=D:\ /offwindir=D:\Windows
Component Store Cleanup (reclaim disk on servers)
:: See if cleanup is worthwhile DISM /Online /Cleanup-Image /AnalyzeComponentStore :: Remove superseded updates DISM /Online /Cleanup-Image /StartComponentCleanup :: Aggressive: also removes uninstall ability for current updates DISM /Online /Cleanup-Image /StartComponentCleanup /ResetBase
/ResetBase means you can never uninstall currently-installed updates. Fine on stable servers, think twice right after Patch Tuesday.
Disk & Boot Repair
:: File system check — /f fixes errors, /r also scans for bad sectors (slow) chkdsk C: /f /r :: Boot repair from WinRE bootrec /fixmbr bootrec /fixboot bootrec /scanos bootrec /rebuildbcd :: Modern UEFI BCD rebuild (S = system/EFI partition letter after mounting) bcdboot C:\Windows /s S: /f UEFI
Where the Logs Are
| Log | Path |
|---|---|
| SFC / CBS | %windir%\Logs\CBS\CBS.log — search for "[SR]" lines |
| DISM | %windir%\Logs\DISM\dism.log |
| Setup / upgrade | C:\$WINDOWS.~BT\Sources\Panther\setupact.log |
| Windows Update | PowerShell: Get-WindowsUpdateLog (builds a readable log on the desktop) |
:: Pull just the SFC results out of CBS.log
findstr /c:"[SR]" %windir%\Logs\CBS\CBS.log > "%userprofile%\Desktop\sfcdetails.txt"
Other Repair Tools Worth Remembering
:: Reset Windows Update components (services + rename SoftwareDistribution) net stop wuauserv & net stop bits & net stop cryptsvc ren %systemroot%\SoftwareDistribution SoftwareDistribution.old ren %systemroot%\System32\catroot2 catroot2.old net start cryptsvc & net start bits & net start wuauserv :: In-place upgrade repair: mount matching ISO, run setup.exe, keep files+apps. :: Fixes what DISM/SFC can't, without wiping the machine.
Diskpart / Storage
Diskpart is interactive and unforgiving — it does not ask "are you sure." Always list and select before any destructive verb, and confirm the disk number every single time. All commands need an elevated prompt.
The Golden Rule
Diskpart acts on whatever is "selected." If you select the wrong disk, clean wipes it with zero confirmation and no recycle bin. The #1 cause of accidental data loss with diskpart is running clean against the system disk or a plugged-in backup drive. Verify the size and label in list disk / detail disk before touching anything.
Inspect First (always)
diskpart :: enters the diskpart> prompt list disk :: all physical disks + sizes — identify target by SIZE select disk 1 :: nothing works until something is selected detail disk :: model, volumes on it — CONFIRM this is the right one list partition :: partitions on selected disk list volume :: all volumes + drive letters + filesystem across all disks select volume 3 detail volume exit :: leave diskpart
Wipe & Repartition a Disk (e.g. prep a USB or reused drive)
diskpart list disk select disk 2 :: ← TRIPLE CHECK. This is about to be erased. detail disk :: confirm size/model matches the drive you intend clean :: removes all partitions/formatting (fast) :: clean all ← zeros the ENTIRE disk, hours on big drives, for secure wipe/decommission convert gpt :: or 'convert mbr' for legacy/BIOS boot create partition primary format fs=ntfs quick label="DATA" :: drop 'quick' for a full format (slow, bad-sector scan) assign letter=E exit
clean all is the secure-erase option and can run for hours on a large HDD. Use it for decommissioning; use plain clean for a quick repartition.
Make a Bootable USB (Windows install media, manually)
diskpart list disk select disk 2 :: the USB stick — verify by size (e.g. 32 GB) clean create partition primary select partition 1 active :: MBR only; skip for pure-UEFI GPT media format fs=fat32 quick :: FAT32 for UEFI boot (files must be <4GB) :: For install.wim >4GB use fs=ntfs, or split the wim with dism /Split-Image assign exit
Fix / Assign Drive Letters
diskpart list volume select volume 4 :: the volume missing a letter assign letter=F :: remove a letter (hide a volume): remove letter=F exit
If a whole disk shows "offline" in Disk Management: select disk N then online disk, and clear read-only with attributes disk clear readonly.
Extend / Shrink Volumes
diskpart list volume select volume 2 extend :: grow into adjacent unallocated space (all of it) extend size=10240 :: grow by exactly 10 GB (MB units) shrink desired=20480 :: free up ~20 GB of unallocated space exit
GUI equivalent lives in diskmgmt.msc — right-click the volume → Extend/Shrink. Diskpart wins for scripting or when the GUI greys the option out.
Clear the "Read-Only" / Write-Protected Attribute
:: Classic fix for "The disk is write-protected" on USB drives diskpart list disk select disk 2 attributes disk clear readonly :: per-volume version: select volume N → attributes volume clear readonly exit
Scripted Diskpart (for RMM / automation)
:: Put commands in a text file, then run non-interactively: :: diskpart /s C:\scripts\prep-disk.txt :: prep-disk.txt contents: select disk 2 clean convert gpt create partition primary format fs=ntfs quick label=DATA assign letter=E
A hardcoded select disk N in a script is dangerous — disk numbers change based on what's plugged in. For anything repeatable, prefer PowerShell Storage cmdlets below, which can filter by size/serial/bus type.
PowerShell Storage Cmdlets (the modern, safer way) PS
Get-Disk Get-Partition -DiskNumber 1 Get-Volume # filesystem, size, health, drive letter Get-PhysicalDisk | Select-Object DeviceId, FriendlyName, MediaType, HealthStatus # Full clean + provision, filterable (safer target selection than a bare number) Get-Disk 2 | Clear-Disk -RemoveData -Confirm:$false Initialize-Disk -Number 2 -PartitionStyle GPT New-Partition -DiskNumber 2 -UseMaximumSize -AssignDriveLetter | Format-Volume -FileSystem NTFS -NewFileSystemLabel 'DATA' -Confirm:$false # Resize Resize-Partition -DriveLetter E -Size 200GB Get-PartitionSupportedSize -DriveLetter E # min/max it can be resized to # SMART / health quick check Get-PhysicalDisk | Get-StorageReliabilityCounter | Select-Object DeviceId, Wear, ReadErrorsTotal, Temperature
Other Storage Tools
| Command | Does |
|---|---|
chkdsk C: /f /r | Fix filesystem errors + scan bad sectors (schedules on reboot for the system drive) |
defrag C: /O | Optimize — auto-TRIMs SSDs, defrags HDDs |
fsutil volume diskfree C: | Free space, scriptable |
fsutil dirty query C: | Is the volume flagged dirty (needs chkdsk)? |
manage-bde -status | BitLocker state per drive |
manage-bde -unlock E: -pw | Unlock an encrypted drive with password |
vssadmin list shadows | List Volume Shadow Copies (restore points / backup snapshots) |
wbadmin get versions | Windows Server Backup catalog |
mountvol | Mount points and volume GUIDs (find the EFI partition: mountvol S: /s) |
Admin Toolbox
The grab-bag of native Windows commands that don't fit neatly elsewhere but you reach for constantly — process management, tasks, drivers, activation, files.
Processes & Services (CMD-side)
tasklist :: all processes + PIDs + memory tasklist /svc :: which services run in each PID (svchost breakdown) tasklist /fi "memusage gt 500000" :: processes using >500 MB taskkill /im chrome.exe /f :: kill by name, forcefully taskkill /pid 4820 /f /t :: kill PID + its child processes (/t = tree) sc query wuauserv :: service state sc queryex type=service state=all :: everything, with PIDs sc config Spooler start=disabled :: change startup type (disabled/demand/auto/delayed-auto) sc stop Spooler & sc start Spooler sc qc Spooler :: config: binary path, dependencies, log-on account sc failure Spooler reset=86400 actions=restart/60000/restart/60000/run/1000 :: recovery actions
Scheduled Tasks (CLI)
schtasks /query /fo table /v :: all tasks, verbose (IR persistence sweep) schtasks /query /tn "\Microsoft\Windows\Defrag\ScheduledDefrag" :: one task schtasks /run /tn "TaskName" :: run now schtasks /end /tn "TaskName" :: Create a daily 3 AM task running a script as SYSTEM schtasks /create /tn "Nightly Cleanup" /tr "powershell -File C:\scripts\cleanup.ps1" ^ /sc daily /st 03:00 /ru SYSTEM /rl highest schtasks /delete /tn "TaskName" /f
# PowerShell equivalent — richer, use for anything scripted Get-ScheduledTask | Where-Object State -eq 'Running' Get-ScheduledTask -TaskName '*update*' | Get-ScheduledTaskInfo # last/next run + result
Drivers
driverquery /v /fo table :: all installed drivers, verbose driverquery /si :: signed status pnputil /enum-drivers :: enumerate third-party driver packages in the store pnputil /add-driver C:\drivers\net.inf /install :: stage + install a driver pnputil /delete-driver oem12.inf /uninstall /force :: remove a bad driver package :: DISM driver ops (also work on offline images with /Image:) DISM /Online /Get-Drivers /Format:Table DISM /Online /Add-Driver /Driver:C:\drivers /Recurse
Windows Activation & Licensing
slmgr /dlv :: detailed license state (channel, activation ID) slmgr /xpr :: is it activated + expiry slmgr /ipk XXXXX-XXXXX-XXXXX-XXXXX-XXXXX :: install a product key slmgr /ato :: activate now (online) slmgr /skms kms.corp.local & slmgr /ato :: point to a KMS host then activate slmgr /cpky :: clear key from registry (after activation, for hygiene) :: OEM key baked into firmware wmic path softwarelicensingservice get OA3xOriginalProductKey :: (PowerShell) (Get-CimInstance SoftwareLicensingService).OA3xOriginalProductKey
File Operations Worth Knowing
where python :: like Linux 'which' — where's this exe on PATH fc file1.txt file2.txt :: compare two files takeown /f C:\path /r /d y :: take ownership recursively (locked/orphaned files) icacls C:\path :: view NTFS permissions icacls C:\path /grant Admins:F /t :: grant full control recursively icacls C:\path /reset /t :: reset perms to inherited mklink /d C:\link C:\real\target :: directory symlink (/j = junction, /h = hardlink) attrib -r -h -s file :: clear read-only/hidden/system flags xcopy /e /i /h /k src dst :: legacy recursive copy (robocopy is better — see PowerShell page) compact /c /s:C:\logs :: NTFS compress a folder tree
System Control
shutdown /r /t 0 :: reboot now shutdown /s /t 60 /c "Patching" :: shutdown in 60s with message shutdown /a :: abort a pending shutdown shutdown /r /o /t 0 :: reboot into Advanced Startup (WinRE) shutdown /r /m \\PC01 /t 0 :: reboot a remote machine shutdown /g /t 0 :: reboot + reopen registered apps systeminfo :: full system report (also shows hotfixes, boot time, RAM) systeminfo | findstr /c:"System Boot Time" gpupdate /force && gpresult /r :: reapply policy and confirm wmic bios get serialnumber :: service tag / serial for warranty lookups :: (PowerShell) Get-CimInstance Win32_BIOS | Select SerialNumber
Clipboard, Env, Misc
ipconfig /all | clip :: pipe any output straight to clipboard type file.txt | clip echo %PATH% :: view an env var (CMD) setx TOOLS "C:\tools" /m :: set a PERSISTENT system env var (/m = machine-wide) set :: list all env vars (current session) assoc .log :: file-type association ftype txtfile :: what program opens that type color 0a :: green-on-black console, because why not
setx sets persistent vars but does NOT affect the current window — open a new prompt to see them. Plain set is session-only.
PowerShell Essentials
The commands you reach for daily, plus the discovery trio that makes everything else findable.
The Discovery Trio — learn anything from inside the shell
# What command does X? Get-Command *service* Get-Command -Module ExchangeOnlineManagement # How do I use it? (-Online opens the web docs) Get-Help Get-Service -Examples Get-Help Get-Service -Online # What properties/methods does this object actually have? Get-Service | Get-Member
Get-Member is the answer to "why doesn't my Select-Object show anything" 90% of the time — you guessed a property name that doesn't exist.
Pipeline Fundamentals
# Filter left, format right. Where-Object filters, Select-Object shapes. Get-Service | Where-Object Status -eq 'Running' | Select-Object Name, StartType # Sort and take top N (find disk hogs) Get-ChildItem C:\ -Recurse -ErrorAction SilentlyContinue | Sort-Object Length -Descending | Select-Object -First 20 FullName, @{n='MB';e={[math]::Round($_.Length/1MB,1)}} # ForEach-Object for per-item actions Get-Content .\servers.txt | ForEach-Object { Test-Connection $_ -Count 1 -Quiet } # Export anything to CSV for tickets/reports Get-Process | Sort-Object CPU -Descending | Select-Object -First 15 | Export-Csv C:\temp\top-cpu.csv -NoTypeInformation
Execution Policy & Running Scripts
# Sensible default for your own machine (local scripts run, downloaded need signing) Set-ExecutionPolicy RemoteSigned -Scope CurrentUser # One-off bypass without changing policy (great for RMM deployments) powershell.exe -ExecutionPolicy Bypass -File .\deploy.ps1 # Unblock a downloaded script (removes Zone.Identifier ADS) Unblock-File .\script.ps1
Execution policy is a safety belt, not a security boundary — it stops accidents, not attackers.
System Info & Health One-Liners
# Last boot time (was it really rebooted?) (Get-CimInstance Win32_OperatingSystem).LastBootUpTime # OS, build, architecture Get-ComputerInfo | Select-Object OsName, OsVersion, OsBuildNumber, CsSystemType # Installed hotfixes, newest first Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 10 # Free disk space, all drives Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" | Select-Object DeviceID, @{n='FreeGB';e={[math]::Round($_.FreeSpace/1GB,1)}}, @{n='TotalGB';e={[math]::Round($_.Size/1GB,1)}} # Recent unexpected shutdowns / kernel-power events Get-WinEvent -FilterHashtable @{LogName='System'; Id=6008,41} -MaxEvents 10 # Pending reboot check (common keys) Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired'
Services, Processes, Local Accounts
Get-Service Spooler | Restart-Service -Verbose Get-Process | Sort-Object WorkingSet64 -Descending | Select-Object -First 10 Stop-Process -Name notepad -Force # Local admin audit — who's in the Administrators group? Get-LocalGroupMember -Group 'Administrators' # Create local admin (printer/kiosk/break-glass scenarios) $p = Read-Host -AsSecureString 'Password' New-LocalUser 'la-support' -Password $p -PasswordNeverExpires Add-LocalGroupMember -Group 'Administrators' -Member 'la-support'
Remoting
# Enable on the target (WinRM, port 5985/5986) Enable-PSRemoting -Force # Interactive session Enter-PSSession -ComputerName SERVER01 # Run against many machines at once Invoke-Command -ComputerName SRV01,SRV02 -ScriptBlock { Get-Service Spooler } # Copy a file over the remoting channel (no SMB needed) $s = New-PSSession SERVER01 Copy-Item .\tool.exe -Destination C:\temp\ -ToSession $s
Modules, Profile, Logging
Install-Module ExchangeOnlineManagement -Scope CurrentUser Get-Module -ListAvailable Update-Module # Your profile script — aliases/functions that load every session notepad $PROFILE # Record everything in a session (great for change records) Start-Transcript C:\temp\session.log Stop-Transcript
Strings, Files, Web
# grep for Windows Select-String -Path C:\logs\*.log -Pattern 'error' -Context 1,2 # tail -f equivalent Get-Content C:\logs\app.log -Tail 20 -Wait # REST calls (auto-parses JSON into objects) Invoke-RestMethod https://api.github.com/repos/PowerShell/PowerShell/releases/latest | Select-Object tag_name, published_at # Download a file Invoke-WebRequest -Uri $url -OutFile C:\temp\installer.msi # Robocopy — the real file-move workhorse (mirror, retry once, log) robocopy \\old\share \\new\share /MIR /R:1 /W:1 /LOG:C:\temp\move.log /TEE
/MIR deletes files at the destination that don't exist at the source. Triple-check direction before running.
Networking CLI
Windows-focused with PowerShell equivalents. Ordered roughly by how a connectivity troubleshoot actually flows: local config → DNS → path → sockets.
ARP Cache cmd
:: Show the full ARP cache (IP-to-MAC mappings this host has learned) arp -a :: Show cache for one interface only (-N takes the INTERFACE's IP) arp -a -N 192.168.1.50 :: Delete entire cache (forces re-resolution — needs admin) arp -d * :: Delete one entry / add a static entry arp -d 192.168.1.1 arp -s 192.168.1.1 00-1a-2b-3c-4d-5e
# PowerShell equivalent — filterable objects
Get-NetNeighbor -AddressFamily IPv4 | Where-Object State -ne 'Unreachable'
Remove-NetNeighbor -InterfaceIndex 12 -Confirm:$false
Duplicate MACs across different IPs, or the gateway's MAC suddenly changing, are classic ARP-spoofing/MITM indicators — worth knowing for both IR and your CCNA.
IP Configuration & DNS Client
ipconfig /all :: full config: DHCP server, lease, DNS servers, MAC ipconfig /release :: drop DHCP lease ipconfig /renew :: request new lease ipconfig /flushdns :: clear DNS resolver cache ipconfig /displaydns :: view cached DNS records ipconfig /registerdns :: re-register A/PTR with DNS (fixes stale AD DNS records)
# PowerShell equivalents
Get-NetIPConfiguration -Detailed
Get-NetAdapter | Where-Object Status -eq 'Up'
Get-DnsClientCache
Clear-DnsClientCache
Get-DnsClientServerAddress
DNS Lookups
nslookup contoso.com :: A record via default DNS nslookup contoso.com 8.8.8.8 :: query a specific server (isolates "is it MY dns?") nslookup -type=mx contoso.com :: mail routing nslookup -type=txt contoso.com :: SPF and verification records nslookup -type=srv _ldap._tcp.corp.local :: find domain controllers nslookup 8.8.8.8 :: reverse (PTR) lookup
# PowerShell — richer output, scriptable
Resolve-DnsName contoso.com -Type MX
Resolve-DnsName contoso.com -Server 1.1.1.1 -DnsOnly
Path & Reachability
ping -t 192.168.1.1 :: continuous (Ctrl+C to stop, Ctrl+Break for stats) ping -l 1472 -f 8.8.8.8 :: MTU test: 1472 + 28 header = 1500; -f = don't fragment ping -4 host / ping -6 host :: force IPv4 / IPv6 tracert 8.8.8.8 :: hop-by-hop path pathping 8.8.8.8 :: tracert + per-hop loss stats over time (better for "it's slow")
# The single most useful connectivity test in PowerShell — TCP port check
Test-NetConnection mail.contoso.com -Port 443
Test-NetConnection 10.0.0.5 -Port 3389 -InformationLevel Detailed
Test-NetConnection 8.8.8.8 -TraceRoute
Sockets & Listening Ports
netstat -ano :: all connections + listening, numeric, with PID netstat -ano | findstr :443 :: who's using 443? netstat -anob :: include process NAME (needs admin) tasklist | findstr <PID> :: map PID from netstat to a process
# PowerShell — join connections to process names in one shot
Get-NetTCPConnection -State Listen |
Select-Object LocalAddress, LocalPort, @{n='Process';e={(Get-Process -Id $_.OwningProcess).Name}} |
Sort-Object LocalPort
Routing Table
route print :: full table (0.0.0.0 = default route) route print -4 :: IPv4 only route add 10.50.0.0 mask 255.255.0.0 192.168.1.254 :: temporary route (gone after reboot) route add 10.50.0.0 mask 255.255.0.0 192.168.1.254 -p :: -p = persistent route delete 10.50.0.0
Get-NetRoute -AddressFamily IPv4 | Sort-Object DestinationPrefix New-NetRoute -DestinationPrefix '10.50.0.0/16' -NextHop 192.168.1.254 -InterfaceIndex 12
netsh Grab Bag
:: The classic stack-reset pair for "internet is broken" (reboot after) netsh int ip reset netsh winsock reset :: Saved Wi-Fi networks + reveal a stored password (admin) netsh wlan show profiles netsh wlan show profile name="OfficeWiFi" key=clear :: Firewall profile state on/off (troubleshooting only — turn it back on) netsh advfirewall show allprofiles netsh advfirewall set allprofiles state off :: Interface config without the GUI netsh interface ip show config netsh interface ip set address "Ethernet" static 192.168.1.50 255.255.255.0 192.168.1.1 netsh interface ip set address "Ethernet" dhcp :: Port forward on a Windows box (listen 8080 → forward to 80 on another host) netsh interface portproxy add v4tov4 listenport=8080 connectaddress=10.0.0.5 connectport=80 netsh interface portproxy show all
portproxy entries persist across reboots and are a known persistence trick — check netsh interface portproxy show all during IR.
Misc Worth Keeping
getmac /v :: MAC addresses with adapter names nbtstat -A 192.168.1.20 :: NetBIOS name from an IP net use Z: \\server\share /persistent:yes :: map a drive net use * /delete :: kill all mapped drives/SMB sessions net session :: who's connected to THIS machine over SMB (admin) klist purge :: flush Kerberos tickets (fixes group-membership lag) w32tm /query /status :: time sync source and offset w32tm /resync :: force time sync
Port Reference
The ones that show up in firewall rules, CCNA questions, and 2 AM incident calls.
Core Infrastructure
| Port | Proto | Service | Notes |
|---|---|---|---|
20/21 | TCP | FTP data / control | Cleartext — should be dead; use SFTP |
22 | TCP | SSH / SFTP / SCP | |
23 | TCP | Telnet | Cleartext — finding it open is a finding |
25 | TCP | SMTP (server-to-server) | ISPs often block outbound from clients |
53 | TCP/UDP | DNS | UDP for queries, TCP for zone transfers & large responses |
67/68 | UDP | DHCP server / client | |
80 | TCP | HTTP | |
110 | TCP | POP3 | 995 = POP3S |
123 | UDP | NTP | Kerberos dies without it |
143 | TCP | IMAP | 993 = IMAPS |
161/162 | UDP | SNMP / SNMP traps | v3 or don't |
443 | TCP | HTTPS | Also QUIC/HTTP3 on UDP 443 |
465/587 | TCP | SMTP submission (implicit TLS / STARTTLS) | 587 is the standard client submission port |
514 | UDP | Syslog | 6514 for TLS syslog |
500/4500 | UDP | IPsec IKE / NAT-T | Site-to-site VPN staples |
1194 | UDP | OpenVPN | |
51820 | UDP | WireGuard (default) |
Windows / AD Environment
| Port | Proto | Service | Notes |
|---|---|---|---|
88 | TCP/UDP | Kerberos | |
135 | TCP | RPC endpoint mapper | Plus dynamic 49152–65535 for RPC itself |
137–139 | TCP/UDP | NetBIOS | Legacy; disable where possible |
389 | TCP/UDP | LDAP | 636 = LDAPS |
445 | TCP | SMB | Never expose to the internet. Ever. |
3268/3269 | TCP | Global Catalog / GC over SSL | |
3389 | TCP/UDP | RDP | VPN or gateway in front, always |
5985/5986 | TCP | WinRM HTTP / HTTPS | PowerShell remoting |
9100 | TCP | Raw printing (JetDirect) | Your printer deployment scripts' best friend |
Databases & Apps
| Port | Service |
|---|---|
1433 | Microsoft SQL Server |
3306 | MySQL / MariaDB |
5432 | PostgreSQL |
6379 | Redis |
27017 | MongoDB |
8080 / 8443 | Alt HTTP/HTTPS (proxies, Tomcat, admin UIs) |
5060/5061 | SIP / SIP-TLS (VoIP) |
8006 | Proxmox VE web UI |
Event IDs & Incident Response
The Windows Event IDs that actually matter during triage and IR, plus the first-hour live-response commands. Security log events require an elevated context and appropriate audit policy enabled.
Authentication & Account Events (Security log)
| ID | Meaning | Watch for |
|---|---|---|
4624 | Successful logon | Logon Type: 2=console, 3=network, 4=batch, 5=service, 7=unlock, 8=cleartext, 9=RunAs, 10=RDP, 11=cached |
4625 | Failed logon | Spikes = brute force / password spray. Sub-status codes tell you why (0xC000006A=bad pw, 0xC0000064=no such user) |
4634 / 4647 | Logoff / user-initiated logoff | Session duration correlation |
4648 | Logon using explicit credentials | RunAs / lateral movement with alternate creds |
4672 | Admin/special privileges assigned at logon | Who's getting SeDebug, SeBackup, etc. — high-value account use |
4720 / 4726 | User account created / deleted | Attacker persistence via new accounts |
4728 / 4732 / 4756 | Member added to security-enabled group | Privilege escalation — esp. Domain Admins / Enterprise Admins |
4740 | Account locked out | Logged on the PDC emulator — names the source computer |
4768 / 4769 | Kerberos TGT / service ticket requested | 4769 with weak encryption = Kerberoasting indicator |
4771 | Kerberos pre-auth failed | AS-REP / password guessing against AD |
Execution, Persistence & Tampering
| ID | Log | Meaning |
|---|---|---|
4688 | Security | Process created (enable cmdline auditing to capture args — huge for hunting) |
4697 | Security | Service installed — classic PsExec / malware persistence |
7045 | System | New service installed (System-log counterpart to 4697) |
4698 / 4702 | Security | Scheduled task created / updated |
1102 | Security | Audit log cleared — attackers covering tracks. Alert on this always. |
104 | System | Event log cleared (System log) |
4104 | PS/Operational | PowerShell script block logging — deobfuscated code the attacker ran |
400 / 600 | Windows PowerShell | Engine start / provider start — PS execution evidence |
1116 / 1117 | Defender/Operational | Malware detected / action taken |
4719 | Security | System audit policy changed — someone disabling logging |
Stability & Boot (System log)
| ID | Meaning |
|---|---|
41 | Kernel-Power — system rebooted without clean shutdown (crash, power loss, hard hang) |
6008 | Previous shutdown was unexpected |
1074 | Clean shutdown/restart initiated — names the process/user that triggered it |
6005 / 6006 | Event log service started / stopped = boot / shutdown markers |
7000 / 7001 | Service failed to start / dependency failed |
7034 / 7031 | Service crashed unexpectedly / terminated + recovery |
51 / 7 / 11 | Disk errors (disk source) — failing drive warning signs |
153 / 129 | Storage/adapter resets — SAN/HBA or cabling issues |
Querying Events Fast (PowerShell)
# FilterHashtable is the ONLY fast way — never pipe Get-WinEvent to Where-Object on big logs Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=(Get-Date).AddHours(-24)} # Failed logons grouped by source account (spray detection) Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=(Get-Date).AddDays(-1)} | ForEach-Object { $_.Properties[5].Value } | Group-Object | Sort-Object Count -Descending # New services in the last week (7045) Get-WinEvent -FilterHashtable @{LogName='System'; Id=7045; StartTime=(Get-Date).AddDays(-7)} | Select-Object TimeCreated, Message # Remote query against another host Get-WinEvent -ComputerName SRV01 -FilterHashtable @{LogName='Security'; Id=4740} -MaxEvents 20
:: CMD equivalent with wevtutil (works everywhere, no PS needed) wevtutil qe Security /q:"*[System[(EventID=4625)]]" /c:20 /rd:true /f:text wevtutil cl Security :: clear a log (generates a 1102 — don't do this in prod casually) wevtutil el :: list all log names
First-Hour Live Response (triage a possibly-compromised host)
Work top-to-bottom. Capture output to files (append | Out-File C:\ir\name.txt). Don't reboot — you'll lose volatile evidence.
# 1. Who's logged on / active sessions query user quser /server:SRV01 # 2. Network connections + owning process (exfil / C2) netstat -anob Get-NetTCPConnection -State Established | Select LocalPort,RemoteAddress,RemotePort,@{n='P';e={(Get-Process -Id $_.OwningProcess).Name}} # 3. Running processes with full paths + command lines Get-CimInstance Win32_Process | Select-Object ProcessId, Name, CommandLine, ExecutablePath # 4. Autostart / persistence — the big three Get-CimInstance Win32_StartupCommand | Select Name, Command, Location schtasks /query /fo list /v Get-Service | Where-Object Status -eq 'Running' | Select Name, DisplayName # 5. Recently created executables (dropper artifacts) Get-ChildItem C:\Users\*\AppData -Recurse -Include *.exe,*.ps1,*.bat -EA SilentlyContinue | Where-Object LastWriteTime -gt (Get-Date).AddDays(-3) | Select FullName, LastWriteTime # 6. Local admin membership (did they add themselves?) Get-LocalGroupMember Administrators # 7. Firewall / portproxy persistence checks netsh interface portproxy show all Get-NetFirewallRule -Enabled True -Direction Inbound | Select DisplayName, Action
Containment Actions (once you've confirmed)
# Network-isolate WITHOUT killing your remote session: block all except your admin IP. # (Better: isolate via EDR — Defender/Blackpoint — which keeps the EDR channel open.) New-NetFirewallRule -DisplayName "IR-Block-Out" -Direction Outbound -Action Block -RemoteAddress Any # Disable a compromised local account (don't delete — preserve evidence) Disable-LocalUser -Name compromiseduser # Kill a malicious process by PID Stop-Process -Id 4820 -Force # Force-logoff an RDP session logoff <sessionID> /server:SRV01 # AD side: disable account + revoke Kerberos + reset password Disable-ADAccount jsmith Set-ADAccountPassword jsmith -Reset -NewPassword (Read-Host -AsSecureString) # Cloud side: Revoke-MgUserSignInSession (see Entra page)
Order matters: preserve evidence (memory/disk image if the case warrants) before you start killing processes and clearing artifacts. When in doubt on a real incident, isolate and escalate rather than "cleaning up" — remediation can destroy the forensic timeline.
Sysinternals for IR (run live: live.sysinternals.com)
| Tool | Use |
|---|---|
Autoruns | THE persistence auditor — every autostart location in one view, VirusTotal-integrated |
Procmon | Real-time file/registry/process/network activity — filter heavily or drown |
Procexp | Process Explorer — parent/child tree, VT hashes, "what has this file open" |
TCPView | Live connections GUI (netstat that updates) |
PsExec | Remote execution (also what attackers use — hence 7045/4697 hunting) |
Sigcheck | Verify signatures + VT lookup on files: sigcheck -vt -e C:\Windows\Temp |
Handle / ListDLLs | What has a file locked / injected DLLs |
Active Directory / Entra ID
On-prem AD PowerShell, DC health, GPO, and the Microsoft Graph module for Entra. Requires RSAT (ActiveDirectory module) for the on-prem cmdlets.
User Lookups & Fixes (the daily ones)
# Everything about one user Get-ADUser jsmith -Properties * | Select-Object DisplayName, Enabled, LockedOut, PasswordExpired, PasswordLastSet, LastLogonDate, EmailAddress, MemberOf # Find locked-out accounts, then unlock Search-ADAccount -LockedOut | Select-Object Name, SamAccountName Unlock-ADAccount jsmith # Reset a password + force change at next logon Set-ADAccountPassword jsmith -Reset -NewPassword (Read-Host -AsSecureString 'New pw') Set-ADUser jsmith -ChangePasswordAtLogon $true # Disabled, expired, or stale accounts (offboarding audits) Search-ADAccount -AccountDisabled Search-ADAccount -AccountExpired Search-ADAccount -AccountInactive -TimeSpan 90.00:00:00 -UsersOnly
Where did the lockout come from? Check Event ID 4740 on the PDC emulator — it names the calling computer.
Groups & Computers
Get-ADGroupMember 'Domain Admins' -Recursive | Select-Object Name, SamAccountName Add-ADGroupMember 'VPN Users' -Members jsmith Get-ADPrincipalGroupMembership jsmith | Select-Object Name # groups a user is IN # Stale computer objects (not seen in 90 days) Get-ADComputer -Filter {LastLogonTimeStamp -lt $((Get-Date).AddDays(-90).ToFileTime())} ` -Properties LastLogonTimeStamp | Select-Object Name
DC Health & Replication
dcdiag /v :: full DC health check dcdiag /test:dns :: DNS-specific tests repadmin /replsummary :: replication health at a glance — check the fail column repadmin /showrepl :: per-partner replication status repadmin /syncall /AdeP :: force replication, all partners, all partitions netdom query fsmo :: who holds the five FSMO roles nltest /dsgetdc:corp.local :: which DC is this client actually using
Group Policy
gpupdate /force :: reapply all policy now gpresult /h C:\temp\gp.html :: readable report of what applied and why gpresult /r /scope:computer :: quick console summary Invoke-GPUpdate -Computer PC01 -Force # remote gpupdate (GroupPolicy module) Get-GPOReport -All -ReportType Html -Path C:\temp\all-gpos.html # document every GPO
Entra ID — Microsoft Graph PowerShell Graph
The AzureAD and MSOnline modules are retired — Microsoft Graph PowerShell is the supported path.
Install-Module Microsoft.Graph -Scope CurrentUser # Connect with only the scopes you need Connect-MgGraph -Scopes 'User.Read.All','Group.Read.All' Get-MgUser -Filter "startsWith(displayName,'John')" -Property DisplayName,UserPrincipalName,AccountEnabled Get-MgUser -UserId jsmith@contoso.com -Property SignInActivity | Select-Object -ExpandProperty SignInActivity # last sign-in (needs AuditLog.Read.All) # Group membership Get-MgGroupMember -GroupId <guid> -All # Revoke sessions during offboarding/compromise (forces re-auth everywhere) Revoke-MgUserSignInSession -UserId jsmith@contoso.com
Hybrid Join / Device State
dsregcmd /status :: THE hybrid-join diagnostic. Key fields: :: AzureAdJoined: YES/NO DomainJoined: YES/NO :: AzureAdPrt: YES ← no PRT = SSO/CA problems whoami /all :: current token: groups, privileges, SID klist :: current Kerberos tickets
M365 / Exchange Online
Exchange Online PowerShell, mail flow investigation, and the admin portal map.
Admin Portal Map (bookmark these)
| Portal | URL |
|---|---|
| M365 Admin | admin.microsoft.com |
| Entra ID | entra.microsoft.com |
| Exchange Admin | admin.exchange.microsoft.com |
| Intune | intune.microsoft.com |
| Defender / Security | security.microsoft.com |
| Purview (compliance) | purview.microsoft.com |
| Teams Admin | admin.teams.microsoft.com |
| SharePoint Admin | yourtenant-admin.sharepoint.com |
| Azure | portal.azure.com |
| Service Health | admin.microsoft.com → Health → Service health |
Connect
Install-Module ExchangeOnlineManagement -Scope CurrentUser
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com
# Purview / compliance cmdlets (Compliance Search etc.)
Connect-IPPSSession -UserPrincipalName admin@contoso.com
Mailboxes — the daily requests
# Mailbox size + item count Get-MailboxStatistics jsmith | Select-Object DisplayName, TotalItemSize, ItemCount # All mailboxes over ~45GB (approaching 50GB standard quota) Get-Mailbox -ResultSize Unlimited | Get-MailboxStatistics | Where-Object {$_.TotalItemSize.Value.ToBytes() -gt 45GB} | Select-Object DisplayName, TotalItemSize # Convert to shared mailbox (offboarding — frees the license once converted) Set-Mailbox jsmith -Type Shared # Full Access + Send As (the standard delegate combo) Add-MailboxPermission shared@contoso.com -User jsmith -AccessRights FullAccess -AutoMapping $true Add-RecipientPermission shared@contoso.com -Trustee jsmith -AccessRights SendAs # Who has access to this mailbox? Get-MailboxPermission shared@contoso.com | Where-Object {$_.User -notlike 'NT AUTHORITY\*'} # Forwarding audit — a top BEC persistence check Get-Mailbox -ResultSize Unlimited | Where-Object {$_.ForwardingAddress -or $_.ForwardingSmtpAddress} | Select-Object DisplayName, ForwardingAddress, ForwardingSmtpAddress, DeliverToMailboxAndForward # Inbox rules on one mailbox (BEC check #2 — look for delete/move-to-RSS rules) Get-InboxRule -Mailbox jsmith | Select-Object Name, Enabled, ForwardTo, RedirectTo, DeleteMessage
Message Trace ("where did the email go?")
# Last 10 days live trace Get-MessageTrace -RecipientAddress jsmith@contoso.com -StartDate (Get-Date).AddDays(-5) -EndDate (Get-Date) | Select-Object Received, SenderAddress, Subject, Status # Drill into why a message got the status it did Get-MessageTrace -MessageTraceId <id> -RecipientAddress jsmith@contoso.com | Get-MessageTraceDetail # Older than 10 days → historical search (results in ~1-4 hrs, CSV emailed/downloadable) Start-HistoricalSearch -ReportTitle 'Sept trace' -ReportType MessageTrace ` -StartDate 2026-06-01 -EndDate 2026-06-15 -RecipientAddress jsmith@contoso.com
Statuses: Delivered, FilteredAsSpam (check quarantine at security.microsoft.com → Email & collaboration → Review → Quarantine), Failed (read the detail), Pending.
Transport Rules & Quarantine
Get-TransportRule | Select-Object Name, State, Priority Get-TransportRule 'Block exe attachments' | Format-List Description Get-QuarantineMessage -RecipientAddress jsmith@contoso.com -PageSize 50 Release-QuarantineMessage -Identity <identity> -ReleaseToAll
Compliance / Purview Quick Hits
# Litigation hold (needs Exchange Online Plan 2 or add-on) Set-Mailbox jsmith -LitigationHoldEnabled $true # Content search + purge (phishing removal) — run in Connect-IPPSSession New-ComplianceSearch -Name 'Phish-0716' -ExchangeLocation All ` -ContentMatchQuery 'subject:"Invoice overdue" AND received:2026-07-15' Start-ComplianceSearch 'Phish-0716' Get-ComplianceSearch 'Phish-0716' | Select-Object Status, Items New-ComplianceSearchAction -SearchName 'Phish-0716' -Purge -PurgeType SoftDelete
Purge removes mail from user mailboxes tenant-wide. Confirm hit count and sample the results before running the action.
Email Auth Records (SPF / DKIM / DMARC)
# Verify from any machine Resolve-DnsName contoso.com -Type TXT | Where-Object Strings -match 'spf' Resolve-DnsName selector1._domainkey.contoso.com -Type CNAME Resolve-DnsName _dmarc.contoso.com -Type TXT # Enable DKIM for a domain in EXO Get-DkimSigningConfig contoso.com New-DkimSigningConfig -DomainName contoso.com -Enabled $true
SPF for pure-M365 tenants: v=spf1 include:spf.protection.outlook.com -all. Validate the whole stack at MXToolbox (see Links page).
Intune / Autopilot
Device-side diagnostics, log locations, and enrollment troubleshooting — the parts you can't do from the portal.
Force a Sync
# On the device (fastest): Settings → Accounts → Access work or school # → click the account → Info → Sync # Or restart the Intune Management Extension to force Win32 app re-eval Restart-Service IntuneManagementExtension # Or from the portal: intune.microsoft.com → Devices → [device] → Sync
Log & Registry Locations (memorize the first one)
| What | Where |
|---|---|
| Win32 app installs (IME) | C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\IntuneManagementExtension.log |
| App detection results | Same folder — AppWorkload.log on newer clients |
| MDM event log | Event Viewer → Applications and Services → Microsoft → Windows → DeviceManagement-Enterprise-Diagnostics-Provider → Admin |
| Enrollment registry | HKLM\SOFTWARE\Microsoft\Enrollments |
| Policy CSP state | HKLM\SOFTWARE\Microsoft\PolicyManager\current\device |
| Autopilot profile cache | C:\Windows\ServiceState\wmansvc\AutopilotDDSZTDFile.json |
Read IME logs with CMTrace or the newer Support Center OneTrace — plain Notepad works but you lose the highlighting.
Diagnostics Collection
:: One-shot diagnostic bundle — attach to vendor/escalation tickets mdmdiagnosticstool.exe -area DeviceEnrollment;DeviceProvisioning;Autopilot -zip C:\temp\mdm-diag.zip :: Join/enrollment state (same tool as hybrid join troubleshooting) dsregcmd /status
The portal can also pull this remotely: device → Collect diagnostics.
Autopilot Hash Collection
# From a running machine — uploads directly to the tenant (needs Graph consent) Install-Script Get-WindowsAutopilotInfo -Force Get-WindowsAutopilotInfo -Online # Offline to CSV instead (import at intune.microsoft.com → Devices → Enrollment → Windows Autopilot → Devices) Get-WindowsAutopilotInfo -OutputFile C:\temp\hash.csv # From OOBE: Shift+F10 opens a command prompt, then: powershell -ExecutionPolicy Bypass Install-Script Get-WindowsAutopilotInfo -Force Get-WindowsAutopilotInfo -Online
Win32 App Packaging
# Wrap installers into .intunewin with the Content Prep Tool IntuneWinAppUtil.exe -c C:\source -s setup.exe -o C:\output # Typical silent-install command lines to try, in order: setup.exe /S # NSIS / Inno-style setup.exe /quiet /norestart msiexec /i app.msi /qn /norestart
Content Prep Tool: github.com/microsoft/Microsoft-Win32-Content-Prep-Tool. Detection rules beat "install succeeded" exit codes — prefer file-version or registry detection.
Enrollment Troubleshooting Quick Checklist
1. dsregcmd /status — AzureAdJoined YES? PRT present?
2. Licensing — user has Intune license assigned?
3. Enrollment restrictions — intune.microsoft.com → Devices → Enrollment → restrictions blocking personal/Windows?
4. MDM scope — Entra → Mobility (MDM/MAM) → Microsoft Intune → user scope includes the user?
5. Event log — DeviceManagement-Enterprise-Diagnostics-Provider → Admin for the actual error code
6. Error code lookup — search the hex code (e.g. 0x80180014 = enrollment blocked by restrictions)
Linux Essentials
Debian/Ubuntu-flavored (matches your Proxmox/Ubuntu stack). systemd throughout.
Services & Logs (systemd)
systemctl status nginx # state + last log lines sudo systemctl restart nginx sudo systemctl enable --now nginx # enable at boot AND start now systemctl list-units --failed # anything broken? journalctl -u nginx -f # follow one service's log live journalctl -u nginx --since "1 hour ago" journalctl -b -p err # errors since this boot journalctl --disk-usage # journal eating your disk?
Networking
ip a # interfaces + addresses (replaces ifconfig) ip r # routing table (default route on top) ss -tulpn # listening sockets + owning process (replaces netstat) resolvectl status # which DNS servers systemd-resolved is using ping -c 4 8.8.8.8 curl -I https://site.com # headers only — quick "is the web server alive" curl -v telnet://10.0.0.5:443 # poor man's port test sudo tcpdump -i eth0 port 443 -nn # packet capture (add -w cap.pcap for Wireshark) # Netplan (Ubuntu server IP config) — /etc/netplan/*.yaml sudo netplan try # applies with auto-rollback if you lose connectivity sudo netplan apply
Disk, Memory, Performance
df -h # filesystem usage du -sh /var/* | sort -rh | head # what's eating /var free -h # memory (look at 'available', not 'free') lsblk # block devices / partitions tree htop # interactive top (apt install htop) iostat -xz 2 # disk I/O pressure (sysstat package) ncdu / # interactive disk usage explorer — install it, thank yourself later
Packages (apt)
sudo apt update && sudo apt upgrade -y apt search nginx apt show nginx # version, deps, description sudo apt install nginx sudo apt remove --purge nginx # remove + config files sudo apt autoremove # clean orphaned deps apt list --upgradable dpkg -l | grep nginx # is it installed? dpkg -L nginx # what files did the package put where?
Files, Permissions, Search
ls -la # -rwxr-xr-- = owner rwx, group r-x, other r-- sudo chown www-data:www-data /var/www/site -R chmod 644 file # rw-r--r-- (config files) chmod 755 script.sh # rwxr-xr-x (executables/dirs) chmod 600 ~/.ssh/id_ed25519 # private keys: owner-only or ssh refuses them find /var/log -name "*.log" -mtime -1 # logs modified in last day find / -size +500M -type f 2>/dev/null # big files grep -rin 'error' /var/log/nginx/ # recursive, case-insensitive, line numbers tail -f /var/log/syslog tar -czvf backup.tar.gz /etc/nginx/ # create gzip archive tar -xzvf backup.tar.gz -C /tmp/restore # extract to a path
Users & SSH
sudo adduser deploy sudo usermod -aG sudo deploy # grant sudo groups deploy sudo passwd deploy # Key auth — do this once, never type passwords again ssh-keygen -t ed25519 -C "you@workstation" ssh-copy-id deploy@10.0.0.5 # Hardening basics in /etc/ssh/sshd_config, then: sudo systemctl restart ssh # PasswordAuthentication no # PermitRootLogin no
Firewall (ufw) & Cron
sudo ufw allow 22/tcp # ALLOW SSH BEFORE ENABLING or you lock yourself out sudo ufw allow 80,443/tcp sudo ufw enable sudo ufw status verbose crontab -e # edit current user's cron jobs # ┌min ┬hour ┬day ┬month ┬weekday # 0 2 * * * /usr/local/bin/backup.sh ← daily 2 AM # */15 * * * * /path/check.sh ← every 15 min sudo crontab -l -u root # view root's crontab (also an IR persistence check)
Docker
Container lifecycle, compose workflow, and cleanup. Modern syntax: docker compose (space), not docker-compose.
Containers — daily lifecycle
docker ps # running containers docker ps -a # include stopped (find the crashed one) docker logs -f --tail 100 app # follow logs, last 100 lines docker exec -it app bash # shell inside (try 'sh' if bash missing) docker restart app docker stop app && docker rm app docker inspect app # full config JSON — IPs, mounts, env docker stats # live CPU/mem per container docker top app # processes inside the container
Compose — the real workflow
docker compose up -d # start stack in background docker compose down # stop + remove containers (volumes survive) docker compose down -v # ALSO deletes named volumes — data gone docker compose logs -f app # logs for one service in the stack docker compose ps docker compose restart app # The standard update cycle docker compose pull && docker compose up -d # Rebuild after changing a Dockerfile docker compose up -d --build
down -v destroys volume data. Know which flag you're typing.
Images, Volumes, Networks
docker images docker pull nginx:1.27 # pin versions in production, never :latest docker rmi old-image docker volume ls docker volume inspect app_data # find the host path (Mountpoint) docker network ls docker network inspect bridge # which containers are on it, their IPs
Run Flags Worth Memorizing
docker run -d \ --name app \ --restart unless-stopped \ # survives reboots; 'always' restarts even after manual stop -p 8080:80 \ # host:container -v app_data:/var/lib/app \ # named volume -v /host/config:/etc/app:ro \ # bind mount, read-only -e TZ=America/Detroit \ --env-file .env \ nginx:1.27
Cleanup & Disk Recovery
docker system df # what's using space docker system prune # stopped containers, dangling images, unused networks docker system prune -a # also removes ALL unused images (big reclaim, big re-pull) docker volume prune # unused volumes — check twice docker builder prune # build cache
Debugging a Container That Won't Start
docker logs app # 1. what did it say before dying docker inspect app --format '{{.State.ExitCode}} {{.State.Error}}' # 2. exit code (137 = OOM-killed/SIGKILL) docker events --since 10m # 3. what the daemon saw docker run --rm -it --entrypoint sh image:tag # 4. bypass entrypoint, poke around inside
Git
Daily flow, branching, and — most importantly — the undo table.
Daily Flow
git status git add -A # stage everything (or 'git add -p' to review hunks) git commit -m "Add printer deployment script" git push git pull # fetch + merge; 'git pull --rebase' for linear history git log --oneline --graph --all # readable history git diff # unstaged changes; '--staged' for what's about to commit
Branching
git switch -c feature/dashboard-api # create + move to new branch git switch main git branch -a # all branches incl. remote git merge feature/dashboard-api # merge INTO current branch git branch -d feature/dashboard-api # delete merged branch (-D forces) git push -u origin feature/dashboard-api # first push of a new branch
The Undo Table (bookmark mentally)
| Situation | Fix |
|---|---|
| Unstage a file | git restore --staged file |
| Discard uncommitted changes to a file | git restore file destroys work |
| Fix last commit message / add forgotten file | git commit --amend |
| Undo last commit, keep changes staged | git reset --soft HEAD~1 |
| Undo last commit, discard changes | git reset --hard HEAD~1 destroys work |
| Undo a commit that's already pushed | git revert <hash> — new commit, safe on shared branches |
| "I lost a commit" | git reflog then git reset --hard <hash> — reflog sees everything |
Never reset --hard or force-push on a branch other people use. revert is the shared-branch tool.
Stash — park work mid-task
git stash push -m "wip: hubspot auth" git stash list git stash pop # apply latest + remove from stash git stash apply stash@{1} # apply specific, keep in stash
Setup & .gitignore
git config --global user.name "Your Name" git config --global user.email "you@systems-x.com" git config --global init.defaultBranch main # .gitignore essentials for your stack # .env # *.log # __pycache__/ # venv/ # node_modules/ # *.secrets.json # Already committed a file you meant to ignore? Untrack without deleting: git rm --cached .env && git commit -m "Stop tracking .env"
A secret that has EVER been committed is in history forever unless you rewrite it (git filter-repo) — and you should rotate the credential regardless.
Proxmox / NGINX
Homelab and small-MSP staples: Proxmox VE CLI (qm for VMs, pct for containers) and the NGINX reverse-proxy config you'll copy-paste most.
Proxmox — VMs (qm)
qm list # all VMs on this node + status + IDs qm status 100 qm start 100 / qm shutdown 100 / qm stop 100 # stop = hard power-off qm reboot 100 qm config 100 # full VM config (disks, NICs, resources) qm set 100 -memory 8192 # change RAM live-ish (needs reboot for some) qm set 100 -cores 4 # Snapshots qm snapshot 100 pre-update --description "before patching" qm listsnapshot 100 qm rollback 100 pre-update qm delsnapshot 100 pre-update # Clone (template → new VM) qm clone 9000 105 --name web05 --full qm migrate 100 node2 --online # live-migrate in a cluster
Proxmox — LXC Containers (pct)
pct list pct start 200 / pct stop 200 pct enter 200 # drop into the container's shell (no SSH needed) pct exec 200 -- apt update # run one command inside pct config 200 pct set 200 -memory 2048 pct snapshot 200 clean pct clone 200 201 --hostname test
Proxmox — Storage, Cluster, Updates
pvesm status # storage pools + usage pvesh get /nodes # API from CLI — query anything the GUI shows pvecm status # cluster quorum + node membership pvecm nodes # Backups (vzdump) vzdump 100 --storage local --mode snapshot --compress zstd qmrestore /path/to/dump.vma.zst 110 # restore VM as new ID 110 # Updates (community/no-subscription: comment enterprise repo first) apt update && apt dist-upgrade # Enterprise repo lives in /etc/apt/sources.list.d/pve-enterprise.list
On a no-subscription homelab node, disable the pve-enterprise repo (it 401s) and add the pve-no-subscription repo, or apt update throws errors every time.
NGINX — Service & Config Basics
nginx -t # TEST config before reloading — always do this first sudo systemctl reload nginx # apply config with zero downtime (vs restart) sudo nginx -s reload # same, direct signal nginx -T # dump the FULL merged config (all includes resolved) nginx -V # compiled-in modules + version # Config layout (Debian/Ubuntu): # /etc/nginx/nginx.conf main # /etc/nginx/sites-available/ your site configs live here # /etc/nginx/sites-enabled/ symlinks to enabled sites sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/ # Logs: /var/log/nginx/access.log and error.log
NGINX — Reverse Proxy (the config you'll reuse constantly)
# /etc/nginx/sites-available/app — proxy to a Docker container on :3000 server { listen 80; server_name app.example.com; return 301 https://$host$request_uri; # force HTTPS } server { listen 443 ssl http2; server_name app.example.com; ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem; location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket support (needed for many dashboards/apps) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
Missing the X-Forwarded-* headers is the #1 cause of "app thinks everyone is 127.0.0.1" and broken HTTPS redirects behind the proxy.
NGINX — TLS with Let's Encrypt (Certbot)
sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d app.example.com -d www.app.example.com # auto-edits your config sudo certbot certificates # list certs + expiry sudo certbot renew --dry-run # test auto-renewal (real renewal is a systemd timer) systemctl list-timers | grep certbot
NGINX — Quick Troubleshooting
| Symptom | Check |
|---|---|
nginx -t fails | It prints the exact file:line. Usually a missing ; or unclosed { |
| 502 Bad Gateway | Upstream is down or wrong port — curl http://127.0.0.1:3000 to test the backend directly |
| 504 Gateway Timeout | Backend too slow — raise proxy_read_timeout, or the app is hung |
| 403 Forbidden | File perms or root/index misconfig; check error.log |
| Config change ignored | You edited sites-available but the symlink in sites-enabled points elsewhere, or forgot to reload |
| SELinux (RHEL) blocks proxy | setsebool -P httpd_can_network_connect 1 |
sudo tail -f /var/log/nginx/error.log # the answer is almost always here
Useful Links
Curated for your stack and goals. All open in a new tab.
// microsoft docs
PowerShell Docs
Official cmdlet reference — every parameter, every example.
DISM Image Repair
The canonical DISM /RestoreHealth reference.
Exchange Online PowerShell
Full EXO cmdlet module reference.
Microsoft Graph PowerShell
The Entra automation path now that AzureAD/MSOL are retired.
Intune Docs
Enrollment, app deployment, compliance policies.
Microsoft Troubleshooting Hub
Official KB-style troubleshooting articles across Windows/M365.
M365 Service Health
Check here BEFORE troubleshooting "email is down for everyone."
// command references
SS64
Terse syntax reference for CMD, PowerShell, Bash, and more. The fastest "what was that flag" lookup on the internet.
explainshell
Paste any Linux command line, get every flag explained inline.
crontab.guru
Cron expression builder/decoder.
regex101
Live regex tester with explanation pane — great for Select-String and Python.
PowerShell Gallery
Module repository behind Install-Module.
Devhints
Dense cheat sheets: bash, git, docker-compose, vim, and dozens more.
// networking & ccna
Cisco Networking Academy
Official CCNA-aligned courses and Packet Tracer download.
CCNA 200-301 Exam Topics
The official blueprint — study against this, not rumor.
Jeremy's IT Lab
Free complete CCNA video course + labs — widely regarded as the best free prep.
MXToolbox SuperTool
MX/SPF/DKIM/DMARC/blacklist checks — first stop for mail-flow externals.
Wireshark Docs
Capture filters vs display filters, protocol references.
ipcalc
Fast subnet calculator (also: practice doing it in your head for CCNA).
// security & ir
MITRE ATT&CK
The adversary technique taxonomy every IR report references.
SANS Posters & Cheat Sheets
Windows forensics, IR, and hunt cheat sheets — print-worthy.
CyberChef
Decode/deobfuscate anything: base64, hex, gzip, XOR — the analyst's Swiss Army knife.
VirusTotal
Hash/file/URL reputation. Search the hash rather than uploading client files — uploads become searchable by others.
Have I Been Pwned
Breach exposure checks for user emails and domains.
LOLBAS
Living-off-the-land binaries — what legit Windows tools attackers abuse. Essential hunt knowledge.
Sysinternals
ProcMon, ProcExp, Autoruns, PsExec, TCPView. Run instantly via live.sysinternals.com.
TryHackMe
Guided security labs — good IR/forensics and blue-team paths.
Windows Security Log Encyclopedia
Every Security event ID explained in depth — the definitive lookup for 4624/4625/4688 etc.
Atomic Red Team
Small, safe tests mapped to ATT&CK — validate your detections in the lab.
// linux, docker, homelab
Ubuntu Server Docs
Netplan, systemd, and service configuration references.
Proxmox VE Docs
Official admin guide — storage, clustering, backups.
Docker Docs
Compose file reference lives here — you'll use it constantly.
NGINX Docs
Directive reference for reverse proxy and TLS configs.
Learn Git Branching
Interactive visual git practice — makes rebase finally click.
// status pages
Microsoft 365 Status
Public status page (also @MSFT365Status on X).
Downdetector
"Is it just us?" triage in 10 seconds.