Windows Shell Scripting: Complete Guide from Basic to Advanced
Master CMD, PowerShell & WSL Bash for Windows Automation & Security
Windows Shell Scripting: Complete Guide from Basic to Advanced
Windows Shell Scripting: Complete Guide from Basic to Advanced
Windows Shell Scripting: Complete Guide from Basic to Advanced
Master CMD, PowerShell & WSL Bash for Windows Automation & Security
OVERVIEW: Windows Shell Options
| Shell | Use Case | Learning Curve |
|---|---|---|
| CMD | Legacy batch files, simple automation | Easy |
| PowerShell | Modern, object-oriented, security-focused | Medium |
| WSL Bash | Linux-like scripting on Windows | Medium (if know Linux) |
Recommendation: Start with PowerShell (built-in, powerful). Use WSL for Linux tools.
SECTION 1: CMD BATCH SCRIPTING (BASIC)
1.1 Hello World Batch File
@echo off
echo Hello, Windows World!
pause
Save as: hello.bat → Double-click to run.
1.2 Variables & User Input
@echo off
set /p name=Enter your name:
echo Hello, %name%!
if "%name%"=="admin" (
echo Welcome, Administrator!
) else (
echo Hello, User!
)
pause
1.3 Loops & Conditions
@echo off
echo Counting 1-5:
for /l %%i in (1,1,5) do (
echo %%i
)
echo Check if file exists:
if exist C:\Windows\system32\notepad.exe (
echo Notepad found!
) else (
echo Notepad missing!
)
pause
1.4 File Operations
@echo off
echo Creating backup...
mkdir C:\backup 2>nul
copy C:\important.txt C:\backup\ 2>nul
echo Backup complete!
dir C:\backup
pause
SECTION 2: POWERSELL (INTERMEDIATE)
2.1 Basic PowerShell Script
# hello.ps1
Write-Host "Hello, PowerShell!" -ForegroundColor Green
$username = Read-Host "Enter username"
Write-Host "Welcome, $username!" -ForegroundColor Yellow
Run: powershell -ExecutionPolicy Bypass -File hello.ps1
2.2 Variables, Arrays & Hashtables
# data_types.ps1
$ip = "192.168.1.1"
$ports = @(80, 443, 22)
$services = @{
"80" = "HTTP"
"443" = "HTTPS"
"22" = "SSH"
}
Write-Host "Scanning $ip on ports: $ports"
foreach ($port in $ports) {
Write-Host "Port $port : $($services[$port])"
}
2.3 Functions & Parameters
# functions.ps1
function Test-Port {
param(
[string]$ComputerName,
[int]$Port
)
$tcp = New-Object System.Net.Sockets.TcpClient
try {
$tcp.Connect($ComputerName, $Port)
Write-Host "$ComputerName`:$Port OPEN" -ForegroundColor Green
$tcp.Close()
return $true
} catch {
Write-Host "$ComputerName`:$Port CLOSED" -ForegroundColor Red
return $false
}
}
# Usage
Test-Port -ComputerName "localhost" -Port 80
2.4 Error Handling & Logging
# error_handling.ps1
try {
$result = Get-Process -Name "nonexistent" -ErrorAction Stop
} catch {
Write-Warning "Process not found: $($_.Exception.Message)"
Add-Content -Path "C:\logs\errors.log" -Value "$(Get-Date): $($_.Exception.Message)"
}
# Continue script
Write-Host "Script continues..." -ForegroundColor Cyan
SECTION 3: ADVANCED POWERSHELL (SECURITY-FOCUSED)
3.1 System Reconnaissance
# recon.ps1
Write-Host "=== Windows System Recon ===" -ForegroundColor Magenta
# Basic info
$os = Get-CimInstance Win32_OperatingSystem
$cpu = Get-CimInstance Win32_Processor
$hostname = $env:COMPUTERNAME
Write-Host "Hostname: $hostname" -ForegroundColor Yellow
Write-Host "OS: $($os.Caption)" -ForegroundColor Yellow
Write-Host "CPU: $($cpu.Name)" -ForegroundColor Yellow
# Network adapters
Get-NetAdapter | Where-Object {$_.Status -eq "Up"} | Select Name, InterfaceDescription, LinkSpeed
# Running services (suspicious)
Get-Service | Where-Object {$_.Status -eq "Running" -and $_.StartType -eq "Manual"} |
Select Name, DisplayName | Format-Table
3.2 Network Scanning & Discovery
# network_scan.ps1
function Scan-Network {
param([string]$Network = "192.168.1.0/24")
Write-Host "Scanning $Network..." -ForegroundColor Cyan
$ips = 1..254 | ForEach-Object { "192.168.1.$_" }
$results = @()
foreach ($ip in $ips) {
if (Test-Connection -ComputerName $ip -Count 1 -Quiet -ErrorAction SilentlyContinue) {
$results += [PSCustomObject]@{
IP = $ip
Status = "UP"
Timestamp = Get-Date
}
Write-Host "$ip is UP" -ForegroundColor Green
}
}
return $results
}
# Usage
$liveHosts = Scan-Network
$liveHosts | Export-Csv -Path "C:\scans\network_scan.csv" -NoTypeInformation
3.3 Event Log Analysis
# event_analysis.ps1
Write-Host "=== Security Event Analysis ===" -ForegroundColor Magenta
# Failed logins (Event ID 4625)
$failedLogins = Get-WinEvent -FilterHashtable @{
LogName = 'Security'
ID = 4625
} -MaxEvents 50 -ErrorAction SilentlyContinue
if ($failedLogins) {
$failedLogins | Select-Object TimeCreated, Id, LevelDisplayName, @{Name="Message";Expression={$_.Message -replace "`n"," " -replace "`r"," "}} |
Format-Table -Wrap
} else {
Write-Host "No recent failed logins found" -ForegroundColor Yellow
}
# Export to JSON
$failedLogins | ConvertTo-Json | Out-File "C:\logs\failed_logins.json"
3.4 File System Auditing
# file_audit.ps1
$targetPath = "C:\Users"
$auditReport = @()
Write-Host "Auditing $targetPath..." -ForegroundColor Cyan
Get-ChildItem -Path $targetPath -Recurse -File -ErrorAction SilentlyContinue |
ForEach-Object {
$file = $_
$acl = Get-Acl $file.FullName
$auditReport += [PSCustomObject]@{
Path = $file.FullName
Size = $file.Length
Modified = $file.LastWriteTime
Owner = $acl.Owner
Access = ($acl.Access | Select-Object -First 1).FileSystemRights
}
}
$auditReport | Export-Csv -Path "C:\audits\file_system_audit.csv" -NoTypeInformation
Write-Host "Audit complete. Report saved." -ForegroundColor Green
3.5 Active Directory Enumeration
# ad_enum.ps1
# Requires RSAT tools or domain context
Import-Module ActiveDirectory -ErrorAction SilentlyContinue
if (Get-Module -ListAvailable -Name ActiveDirectory) {
Write-Host "=== AD Enumeration ===" -ForegroundColor Magenta
# Domain users with passwords not expiring
Get-ADUser -Filter {PasswordNeverExpires -eq $true -and Enabled -eq $true} |
Select Name, SamAccountName, LastLogonDate |
Format-Table
# Domain admins
Get-ADGroupMember -Identity "Domain Admins" -Recursive |
Select Name, SamAccountName, DistinguishedName
} else {
Write-Warning "ActiveDirectory module not available. Install RSAT."
}
SECTION 4: WSL BASH ON WINDOWS (ADVANCED)
4.1 Setup WSL + Kali
# Enable WSL
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
# Install WSL2
wsl --set-default-version 2
wsl --install -d kali-linux
# Update Kali
wsl -d kali-linux
sudo apt update && sudo apt upgrade -y
4.2 Hybrid PowerShell + WSL Script
# hybrid_scan.ps1
$target = "192.168.1.100"
Write-Host "Windows recon + WSL nmap..." -ForegroundColor Cyan
# Windows: Check connectivity
if (Test-Connection -ComputerName $target -Count 1 -Quiet) {
Write-Host "$target is reachable from Windows" -ForegroundColor Green
# WSL: Run nmap
$nmapResult = wsl -d kali-linux nmap -sV -p 22,80,443 $target
Write-Host "`nNmap Results:" -ForegroundColor Yellow
Write-Host $nmapResult
} else {
Write-Host "$target is not reachable" -ForegroundColor Red
}
4.3 WSL Bash Network Scanner
#!/bin/bash
# save as: scan.sh in WSL Kali
target=$1
if [ -z "$target" ]; then
echo "Usage: ./scan.sh <IP>"
exit 1
fi
echo "=== WSL Kali Scan on $target ==="
sudo nmap -sC -sV -p- $target -oN scan_$(date +%F).txt
# Parse results
echo "`nOpen ports:"
grep "open" scan_$(date +%F).txt
# Quick web recon
if sudo nmap -p 80,443 $target | grep -q "open"; then
echo "`nWeb enumeration:"
curl -I http://$target 2>/dev/null || echo "HTTP failed"
curl -I https://$target 2>/dev/null || echo "HTTPS failed"
fi
Run from PowerShell: wsl -d kali-linux /path/to/scan.sh 192.168.1.100
SECTION 5: SECURITY-SPECIFIC SCRIPTS
5.1 Windows Defender Quick Scan
# defender_scan.ps1
Write-Host "Running Windows Defender Quick Scan..." -ForegroundColor Cyan
$scanResult = Start-MpScan -ScanType QuickScan -ErrorAction SilentlyContinue
if ($scanResult) {
Write-Host "Scan completed. Checking threats..." -ForegroundColor Yellow
Get-MpThreat | Select-Object ThreatID, ThreatName, SeverityID, ProcessName |
Format-Table -AutoSize
} else {
Write-Host "No threats detected" -ForegroundColor Green
}
5.2 Scheduled Task Auditor
# task_audit.ps1
Write-Host "=== Scheduled Task Audit ===" -ForegroundColor Magenta
Get-ScheduledTask | Where-Object {$_.State -eq "Ready"} |
Select TaskName, TaskPath, State, @{Name="Triggers";Expression={$_.Triggers.Count}},
@{Name="Actions";Expression={$_.Actions.Execute}} |
Format-Table -AutoSize
# Suspicious tasks (non-Microsoft)
Get-ScheduledTask | Where-Object {$_.Actions.Execute -notlike "*Windows*" -and $_.Actions.Execute -notlike "*Microsoft*"} |
Select TaskName, Actions | Format-Table
5.3 USB Device Logger
# usb_monitor.ps1
# Run as scheduled task for monitoring
$logPath = "C:\logs\usb_events.log"
$event = Get-WinEvent -FilterHashtable @{LogName='System'; ID=2003} -MaxEvents 1 -ErrorAction SilentlyContinue
if ($event) {
$usbInfo = [PSCustomObject]@{
Timestamp = Get-Date
DeviceID = $event.Properties[0].Value
Message = $event.Message
}
$usbInfo | Export-Csv -Path $logPath -Append -NoTypeInformation
Write-Host "USB event logged: $($usbInfo.DeviceID)" -ForegroundColor Yellow
}
SECTION 6: AUTOMATION FRAMEWORKS
6.1 Modular Security Toolkit
# toolkit.ps1
function Show-Menu {
Clear-Host
Write-Host "=== Windows Security Toolkit v1.0 ===" -ForegroundColor Magenta
Write-Host "1. System Reconnaissance"
Write-Host "2. Network Discovery"
Write-Host "3. Event Log Analysis"
Write-Host "4. File System Audit"
Write-Host "5. Defender Scan"
Write-Host "6. Exit"
$choice = Read-Host "Select option"
return $choice
}
function Run-Recon { .\modules\recon.ps1 }
function Run-Network { .\modules\network.ps1 }
function Run-Events { .\modules\events.ps1 }
function Run-Files { .\modules\files.ps1 }
function Run-Defender { .\modules\defender.ps1 }
do {
$selection = Show-Menu
switch ($selection) {
1 { Run-Recon }
2 { Run-Network }
3 { Run-Events }
4 { Run-Files }
5 { Run-Defender }
6 { Write-Host "Goodbye!" -ForegroundColor Green; exit }
default { Write-Warning "Invalid option" }
}
Read-Host "Press Enter to continue"
} while ($selection -ne 6)
6.2 Scheduled Automation
# Create scheduled task for daily recon
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-File C:\scripts\daily_recon.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "2:00AM"
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
Register-ScheduledTask -TaskName "DailySecurityRecon" -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Force
Write-Host "Scheduled task created!" -ForegroundColor Green
SECTION 7: BEST PRACTICES & TROUBLESHOOTING
Execution Policies
# Check current policy
Get-ExecutionPolicy -List
# Set for current user (recommended)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
# Bypass for single script
powershell -ExecutionPolicy Bypass -File script.ps1
Error Handling Patterns
# Try-Catch-Finally
try {
# Risky operation
$result = Invoke-WebRequest -Uri "http://example.com" -ErrorAction Stop
} catch [System.Net.WebException] {
Write-Error "Network error: $($_.Exception.Message)"
} catch {
Write-Error "Unexpected error: $($_.Exception.Message)"
} finally {
Write-Host "Cleanup complete" -ForegroundColor Gray
}
Logging & Output
# Structured logging
function Write-Log {
param([string]$Message, [string]$Level = "INFO")
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logEntry = "$timestamp [$Level] $Message"
Write-Host $logEntry
Add-Content -Path "C:\logs\app.log" -Value $logEntry
}
# Usage
Write-Log "Scan started" "INFO"
Write-Log "Error occurred" "ERROR"
CHEAT SHEET: COMMON COMMANDS
| Task | CMD | PowerShell | WSL Bash |
|---|---|---|---|
| List Files | dir |
Get-ChildItem or ls |
ls -la |
| Copy File | copy src dest |
Copy-Item |
cp src dest |
| Network Ping | ping host |
Test-Connection |
ping host |
| Process List | tasklist |
Get-Process |
ps aux |
| Kill Process | taskkill /PID 1234 |
Stop-Process -Id 1234 |
kill 1234 |
| System Info | systeminfo |
Get-ComputerInfo |
uname -a |
LEARNING ROADMAP
| Week | Focus | Scripts to Build |
|---|---|---|
| 1 | CMD Basics | Hello world, file ops |
| 2 | PowerShell Intro | Variables, functions |
| 3 | System Admin | Recon, process management |
| 4 | Network Security | Port scanning, discovery |
| 5 | Advanced PS | AD, events, auditing |
| 6 | WSL Integration | Hybrid scripts, Linux tools |
| 7 | Automation | Scheduled tasks, toolkits |
Want specific expansions?
- Full security toolkit with modules
- WSL + PowerShell hybrid examples
- Active Directory deep dive
- Malware analysis scripts
Just ask!
Stay Secure. Script Smart. Windows Mastered. 🔒
Windows Shell Scripting: Complete Guide from Basic to Advanced
Master CMD, PowerShell & WSL Bash for Windows Automation & Security
Windows Shell Scripting: Complete Guide from Basic to Advanced
Windows Shell Scripting: Complete Guide from Basic to Advanced
Windows Shell Scripting: Complete Guide from Basic to Advanced
Master CMD, PowerShell & WSL Bash for Windows Automation & Security
OVERVIEW: Windows Shell Options
| Shell | Use Case | Learning Curve |
|---|---|---|
| CMD | Legacy batch files, simple automation | Easy |
| PowerShell | Modern, object-oriented, security-focused | Medium |
| WSL Bash | Linux-like scripting on Windows | Medium (if know Linux) |
Recommendation: Start with PowerShell (built-in, powerful). Use WSL for Linux tools.
SECTION 1: CMD BATCH SCRIPTING (BASIC)
1.1 Hello World Batch File
@echo off
echo Hello, Windows World!
pause
Save as: hello.bat → Double-click to run.
1.2 Variables & User Input
@echo off
set /p name=Enter your name:
echo Hello, %name%!
if "%name%"=="admin" (
echo Welcome, Administrator!
) else (
echo Hello, User!
)
pause
1.3 Loops & Conditions
@echo off
echo Counting 1-5:
for /l %%i in (1,1,5) do (
echo %%i
)
echo Check if file exists:
if exist C:\Windows\system32\notepad.exe (
echo Notepad found!
) else (
echo Notepad missing!
)
pause
1.4 File Operations
@echo off
echo Creating backup...
mkdir C:\backup 2>nul
copy C:\important.txt C:\backup\ 2>nul
echo Backup complete!
dir C:\backup
pause
SECTION 2: POWERSELL (INTERMEDIATE)
2.1 Basic PowerShell Script
# hello.ps1
Write-Host "Hello, PowerShell!" -ForegroundColor Green
$username = Read-Host "Enter username"
Write-Host "Welcome, $username!" -ForegroundColor Yellow
Run: powershell -ExecutionPolicy Bypass -File hello.ps1
2.2 Variables, Arrays & Hashtables
# data_types.ps1
$ip = "192.168.1.1"
$ports = @(80, 443, 22)
$services = @{
"80" = "HTTP"
"443" = "HTTPS"
"22" = "SSH"
}
Write-Host "Scanning $ip on ports: $ports"
foreach ($port in $ports) {
Write-Host "Port $port : $($services[$port])"
}
2.3 Functions & Parameters
# functions.ps1
function Test-Port {
param(
[string]$ComputerName,
[int]$Port
)
$tcp = New-Object System.Net.Sockets.TcpClient
try {
$tcp.Connect($ComputerName, $Port)
Write-Host "$ComputerName`:$Port OPEN" -ForegroundColor Green
$tcp.Close()
return $true
} catch {
Write-Host "$ComputerName`:$Port CLOSED" -ForegroundColor Red
return $false
}
}
# Usage
Test-Port -ComputerName "localhost" -Port 80
2.4 Error Handling & Logging
# error_handling.ps1
try {
$result = Get-Process -Name "nonexistent" -ErrorAction Stop
} catch {
Write-Warning "Process not found: $($_.Exception.Message)"
Add-Content -Path "C:\logs\errors.log" -Value "$(Get-Date): $($_.Exception.Message)"
}
# Continue script
Write-Host "Script continues..." -ForegroundColor Cyan
SECTION 3: ADVANCED POWERSHELL (SECURITY-FOCUSED)
3.1 System Reconnaissance
# recon.ps1
Write-Host "=== Windows System Recon ===" -ForegroundColor Magenta
# Basic info
$os = Get-CimInstance Win32_OperatingSystem
$cpu = Get-CimInstance Win32_Processor
$hostname = $env:COMPUTERNAME
Write-Host "Hostname: $hostname" -ForegroundColor Yellow
Write-Host "OS: $($os.Caption)" -ForegroundColor Yellow
Write-Host "CPU: $($cpu.Name)" -ForegroundColor Yellow
# Network adapters
Get-NetAdapter | Where-Object {$_.Status -eq "Up"} | Select Name, InterfaceDescription, LinkSpeed
# Running services (suspicious)
Get-Service | Where-Object {$_.Status -eq "Running" -and $_.StartType -eq "Manual"} |
Select Name, DisplayName | Format-Table
3.2 Network Scanning & Discovery
# network_scan.ps1
function Scan-Network {
param([string]$Network = "192.168.1.0/24")
Write-Host "Scanning $Network..." -ForegroundColor Cyan
$ips = 1..254 | ForEach-Object { "192.168.1.$_" }
$results = @()
foreach ($ip in $ips) {
if (Test-Connection -ComputerName $ip -Count 1 -Quiet -ErrorAction SilentlyContinue) {
$results += [PSCustomObject]@{
IP = $ip
Status = "UP"
Timestamp = Get-Date
}
Write-Host "$ip is UP" -ForegroundColor Green
}
}
return $results
}
# Usage
$liveHosts = Scan-Network
$liveHosts | Export-Csv -Path "C:\scans\network_scan.csv" -NoTypeInformation
3.3 Event Log Analysis
# event_analysis.ps1
Write-Host "=== Security Event Analysis ===" -ForegroundColor Magenta
# Failed logins (Event ID 4625)
$failedLogins = Get-WinEvent -FilterHashtable @{
LogName = 'Security'
ID = 4625
} -MaxEvents 50 -ErrorAction SilentlyContinue
if ($failedLogins) {
$failedLogins | Select-Object TimeCreated, Id, LevelDisplayName, @{Name="Message";Expression={$_.Message -replace "`n"," " -replace "`r"," "}} |
Format-Table -Wrap
} else {
Write-Host "No recent failed logins found" -ForegroundColor Yellow
}
# Export to JSON
$failedLogins | ConvertTo-Json | Out-File "C:\logs\failed_logins.json"
3.4 File System Auditing
# file_audit.ps1
$targetPath = "C:\Users"
$auditReport = @()
Write-Host "Auditing $targetPath..." -ForegroundColor Cyan
Get-ChildItem -Path $targetPath -Recurse -File -ErrorAction SilentlyContinue |
ForEach-Object {
$file = $_
$acl = Get-Acl $file.FullName
$auditReport += [PSCustomObject]@{
Path = $file.FullName
Size = $file.Length
Modified = $file.LastWriteTime
Owner = $acl.Owner
Access = ($acl.Access | Select-Object -First 1).FileSystemRights
}
}
$auditReport | Export-Csv -Path "C:\audits\file_system_audit.csv" -NoTypeInformation
Write-Host "Audit complete. Report saved." -ForegroundColor Green
3.5 Active Directory Enumeration
# ad_enum.ps1
# Requires RSAT tools or domain context
Import-Module ActiveDirectory -ErrorAction SilentlyContinue
if (Get-Module -ListAvailable -Name ActiveDirectory) {
Write-Host "=== AD Enumeration ===" -ForegroundColor Magenta
# Domain users with passwords not expiring
Get-ADUser -Filter {PasswordNeverExpires -eq $true -and Enabled -eq $true} |
Select Name, SamAccountName, LastLogonDate |
Format-Table
# Domain admins
Get-ADGroupMember -Identity "Domain Admins" -Recursive |
Select Name, SamAccountName, DistinguishedName
} else {
Write-Warning "ActiveDirectory module not available. Install RSAT."
}
SECTION 4: WSL BASH ON WINDOWS (ADVANCED)
4.1 Setup WSL + Kali
# Enable WSL
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
# Install WSL2
wsl --set-default-version 2
wsl --install -d kali-linux
# Update Kali
wsl -d kali-linux
sudo apt update && sudo apt upgrade -y
4.2 Hybrid PowerShell + WSL Script
# hybrid_scan.ps1
$target = "192.168.1.100"
Write-Host "Windows recon + WSL nmap..." -ForegroundColor Cyan
# Windows: Check connectivity
if (Test-Connection -ComputerName $target -Count 1 -Quiet) {
Write-Host "$target is reachable from Windows" -ForegroundColor Green
# WSL: Run nmap
$nmapResult = wsl -d kali-linux nmap -sV -p 22,80,443 $target
Write-Host "`nNmap Results:" -ForegroundColor Yellow
Write-Host $nmapResult
} else {
Write-Host "$target is not reachable" -ForegroundColor Red
}
4.3 WSL Bash Network Scanner
#!/bin/bash
# save as: scan.sh in WSL Kali
target=$1
if [ -z "$target" ]; then
echo "Usage: ./scan.sh <IP>"
exit 1
fi
echo "=== WSL Kali Scan on $target ==="
sudo nmap -sC -sV -p- $target -oN scan_$(date +%F).txt
# Parse results
echo "`nOpen ports:"
grep "open" scan_$(date +%F).txt
# Quick web recon
if sudo nmap -p 80,443 $target | grep -q "open"; then
echo "`nWeb enumeration:"
curl -I http://$target 2>/dev/null || echo "HTTP failed"
curl -I https://$target 2>/dev/null || echo "HTTPS failed"
fi
Run from PowerShell: wsl -d kali-linux /path/to/scan.sh 192.168.1.100
SECTION 5: SECURITY-SPECIFIC SCRIPTS
5.1 Windows Defender Quick Scan
# defender_scan.ps1
Write-Host "Running Windows Defender Quick Scan..." -ForegroundColor Cyan
$scanResult = Start-MpScan -ScanType QuickScan -ErrorAction SilentlyContinue
if ($scanResult) {
Write-Host "Scan completed. Checking threats..." -ForegroundColor Yellow
Get-MpThreat | Select-Object ThreatID, ThreatName, SeverityID, ProcessName |
Format-Table -AutoSize
} else {
Write-Host "No threats detected" -ForegroundColor Green
}
5.2 Scheduled Task Auditor
# task_audit.ps1
Write-Host "=== Scheduled Task Audit ===" -ForegroundColor Magenta
Get-ScheduledTask | Where-Object {$_.State -eq "Ready"} |
Select TaskName, TaskPath, State, @{Name="Triggers";Expression={$_.Triggers.Count}},
@{Name="Actions";Expression={$_.Actions.Execute}} |
Format-Table -AutoSize
# Suspicious tasks (non-Microsoft)
Get-ScheduledTask | Where-Object {$_.Actions.Execute -notlike "*Windows*" -and $_.Actions.Execute -notlike "*Microsoft*"} |
Select TaskName, Actions | Format-Table
5.3 USB Device Logger
# usb_monitor.ps1
# Run as scheduled task for monitoring
$logPath = "C:\logs\usb_events.log"
$event = Get-WinEvent -FilterHashtable @{LogName='System'; ID=2003} -MaxEvents 1 -ErrorAction SilentlyContinue
if ($event) {
$usbInfo = [PSCustomObject]@{
Timestamp = Get-Date
DeviceID = $event.Properties[0].Value
Message = $event.Message
}
$usbInfo | Export-Csv -Path $logPath -Append -NoTypeInformation
Write-Host "USB event logged: $($usbInfo.DeviceID)" -ForegroundColor Yellow
}
SECTION 6: AUTOMATION FRAMEWORKS
6.1 Modular Security Toolkit
# toolkit.ps1
function Show-Menu {
Clear-Host
Write-Host "=== Windows Security Toolkit v1.0 ===" -ForegroundColor Magenta
Write-Host "1. System Reconnaissance"
Write-Host "2. Network Discovery"
Write-Host "3. Event Log Analysis"
Write-Host "4. File System Audit"
Write-Host "5. Defender Scan"
Write-Host "6. Exit"
$choice = Read-Host "Select option"
return $choice
}
function Run-Recon { .\modules\recon.ps1 }
function Run-Network { .\modules\network.ps1 }
function Run-Events { .\modules\events.ps1 }
function Run-Files { .\modules\files.ps1 }
function Run-Defender { .\modules\defender.ps1 }
do {
$selection = Show-Menu
switch ($selection) {
1 { Run-Recon }
2 { Run-Network }
3 { Run-Events }
4 { Run-Files }
5 { Run-Defender }
6 { Write-Host "Goodbye!" -ForegroundColor Green; exit }
default { Write-Warning "Invalid option" }
}
Read-Host "Press Enter to continue"
} while ($selection -ne 6)
6.2 Scheduled Automation
# Create scheduled task for daily recon
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-File C:\scripts\daily_recon.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At "2:00AM"
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
Register-ScheduledTask -TaskName "DailySecurityRecon" -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Force
Write-Host "Scheduled task created!" -ForegroundColor Green
SECTION 7: BEST PRACTICES & TROUBLESHOOTING
Execution Policies
# Check current policy
Get-ExecutionPolicy -List
# Set for current user (recommended)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
# Bypass for single script
powershell -ExecutionPolicy Bypass -File script.ps1
Error Handling Patterns
# Try-Catch-Finally
try {
# Risky operation
$result = Invoke-WebRequest -Uri "http://example.com" -ErrorAction Stop
} catch [System.Net.WebException] {
Write-Error "Network error: $($_.Exception.Message)"
} catch {
Write-Error "Unexpected error: $($_.Exception.Message)"
} finally {
Write-Host "Cleanup complete" -ForegroundColor Gray
}
Logging & Output
# Structured logging
function Write-Log {
param([string]$Message, [string]$Level = "INFO")
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logEntry = "$timestamp [$Level] $Message"
Write-Host $logEntry
Add-Content -Path "C:\logs\app.log" -Value $logEntry
}
# Usage
Write-Log "Scan started" "INFO"
Write-Log "Error occurred" "ERROR"
CHEAT SHEET: COMMON COMMANDS
| Task | CMD | PowerShell | WSL Bash |
|---|---|---|---|
| List Files | dir |
Get-ChildItem or ls |
ls -la |
| Copy File | copy src dest |
Copy-Item |
cp src dest |
| Network Ping | ping host |
Test-Connection |
ping host |
| Process List | tasklist |
Get-Process |
ps aux |
| Kill Process | taskkill /PID 1234 |
Stop-Process -Id 1234 |
kill 1234 |
| System Info | systeminfo |
Get-ComputerInfo |
uname -a |
LEARNING ROADMAP
| Week | Focus | Scripts to Build |
|---|---|---|
| 1 | CMD Basics | Hello world, file ops |
| 2 | PowerShell Intro | Variables, functions |
| 3 | System Admin | Recon, process management |
| 4 | Network Security | Port scanning, discovery |
| 5 | Advanced PS | AD, events, auditing |
| 6 | WSL Integration | Hybrid scripts, Linux tools |
| 7 | Automation | Scheduled tasks, toolkits |
Want specific expansions?
- Full security toolkit with modules
- WSL + PowerShell hybrid examples
- Active Directory deep dive
- Malware analysis scripts
Just ask!
Stay Secure. Script Smart. Windows Mastered. 🔒