PowerShell Cheat Sheet
Cmdlets, object pipeline and one-liners
Navigation
Lists files and directories. Aliases ls, gci, dir. -Recurse walks the tree, -Force includes hidden.
Get-ChildItem Get-ChildItem -Recurse -Filter *.ts Get-ChildItem -Force gci -Directory
Changes the current directory. Alias cd. Supports - for the previous path and ~ for home.
Set-Location s:\MaisTools cd ~ cd ..
Shows the current path. Alias pwd.
Get-Location pwd
Checks if a path exists. Returns $true or $false.
Test-Path .\file.txt
Test-Path .\src -PathType Container
if (Test-Path .\dir) { 'existe' }Pushes the current directory onto a stack (Push) and returns to it later (Pop). Handy in scripts.
Push-Location C:\Temp # ...trabalho aqui... Pop-Location
Resolves a relative path to absolute, or the inverse with -Relative.
Resolve-Path .\src Resolve-Path -Relative C:\Temp\file.txt
Files
Creates files, directories or symlinks. -ItemType sets the type. -Force on an existing file truncates it.
New-Item -ItemType File novo.txt New-Item -ItemType Directory -Force pasta\sub New-Item -ItemType SymbolicLink -Path link -Target target
Copies files or directories. -Recurse for trees, -Force overwrites the destination.
Copy-Item a.txt b.txt Copy-Item -Recurse src\ dest\ Copy-Item *.log -Destination archive\
Moves or renames files and directories.
Move-Item old.txt new.txt Move-Item *.log archive\
Deletes files or directories. -Recurse -Force removes without confirmation (dangerous).
Remove-Item file.txt Remove-Item -Recurse -Force node_modules Remove-Item *.tmp
Renames files. Accepts a ScriptBlock in -NewName for bulk renaming.
Rename-Item old.txt new.txt
Get-ChildItem *.txt | Rename-Item -NewName { $_.Name -replace '\.txt$','.md' }Gets info about an item (Length, LastWriteTime, etc). Does not read content, only metadata.
Get-Item .\file.txt (Get-Item file.txt).Length Get-Item file.txt | Select-Object Name, Length, LastWriteTime
Content
Reads file contents. -TotalCount like head, -Tail like tail, -Wait follows like tail -f.
Get-Content file.txt Get-Content file.txt -TotalCount 10 Get-Content file.txt -Tail 20 Get-Content app.log -Wait -Tail 100
Writes content to a file, overwriting it. -Encoding utf8 avoids the PS 5.1 default of UTF-16 with BOM.
Set-Content out.txt 'linha' 'a','b','c' | Set-Content lista.txt -Encoding utf8
Appends content to an existing file. Equivalent to >> in bash.
Add-Content log.txt 'nova entrada' Get-Date | Add-Content log.txt
Redirects output to a file. -Append appends, -Encoding controls the encoding.
Get-Process | Out-File processes.txt Get-Service | Out-File -Append -Encoding utf8 services.log
Empties a file's content without deleting the file.
Clear-Content log.txt Clear-Content *.tmp
Pipeline
Filters objects in the pipeline by a condition. Aliases ? and where. Supports shorthand Property -op Value.
Get-Process | Where-Object { $_.CPU -gt 10 }
Get-Service | Where-Object Status -eq Running
gci | ? { $_.Length -gt 1MB }Sorts objects by property. -Descending reverses, -Unique removes duplicates.
Get-Process | Sort-Object CPU -Descending Get-ChildItem | Sort-Object Length -Descending 'b','a','c' | Sort-Object
Selects N objects from the pipeline or properties from each object. -ExpandProperty extracts the value.
Get-Process | Select-Object -First 5 Get-Process | Select-Object Name, CPU, WS Get-Service | Select-Object -ExpandProperty Name
Iterates the pipeline, applying a block to each object. Aliases % and foreach. -Parallel runs in parallel (PS 7+).
Get-ChildItem | ForEach-Object { $_.Name.ToUpper() }
1..5 | %{ $_ * 2 }
$urls | ForEach-Object -Parallel { Invoke-WebRequest $_ }Counts, sums, averages, maxes or mins a collection. -Line, -Word, -Character for text.
Get-Process | Measure-Object -Property WS -Sum -Average Get-Content file.txt | Measure-Object -Line Get-ChildItem | Measure-Object
Groups objects by property. Useful to count occurrences or build dictionaries with -AsHashTable.
Get-Process | Group-Object ProcessName Get-ChildItem | Group-Object Extension -NoElement
Search
Searches patterns in strings or files. The grep equivalent. -Pattern accepts regex, -SimpleMatch disables it.
Select-String 'TODO' *.ts Select-String -Path src\*.ts -Pattern 'error' -CaseSensitive Get-ChildItem -Recurse | Select-String 'API_KEY'
Shows available cmdlets with filters by name, module or type. (Get-Command npm).Source returns the path.
Get-Command npm Get-Command *process* (Get-Command npm).Source Get-Command -Module Microsoft.PowerShell.Utility
Shows properties and methods of an object. Indispensable for exploring what a type can do.
Get-Process | Get-Member (Get-Date) | Get-Member -MemberType Method 'abc' | Get-Member
Shows help for cmdlets or about_* topics. -Examples shows examples, -Online opens the web version.
Get-Help Get-ChildItem Get-Help Get-Process -Examples Get-Help about_Variables Get-Help Set-Content -Online
Variables
Variables start with $ and need no declaration. Support arrays (@()) and hashtables (@{}).
$nome = 'Bruno'
$idade = 30
$lista = @(1, 2, 3)
$hash = @{ a = 1; b = 2 }Reads and sets environment variables. Get-ChildItem env: lists them all. Changes only last for the session.
$env:PATH $env:USERPROFILE $env:DEBUG = 'true' Get-ChildItem env:
Null value. In comparisons place $null on the left ($null -eq $x) to avoid surprises with arrays.
if ($null -eq $var) { 'vazio' }
$lista = @($null, 1, 2)
[string]::IsNullOrEmpty($x)Type casting with [type]. Works for int, string, datetime, typed arrays, regex.
[int]'42' [datetime]'2026-01-15' [int[]]$nums = 1,2,3 [regex]::Escape($pattern)
Sets variable scope: global (whole session), script (this file) or local (this function).
$global:config = @{}
$script:contador = 0
function f { $local:tmp = 1 }Strings
Double quotes expand $var and $(expr). Single quotes are literal and expand nothing.
$nome = "Bruno" "Olá $nome" "Caminho: $($obj.Property)" 'literal $nome' # sem expansão
Multi-line strings (here-strings). @"..."@ expands variables, @'...'@ is literal. Closing token must be at column 0.
@" linha 1 com $nome linha 2 "@ @' literal $nome '@
Printf-style format operator. Supports numbers, dates and alignment ({0,5:N2}).
'{0} tem {1} anos' -f $nome, $idade
'{0:N2}' -f 1234.5678 # 1,234.57
'{0:yyyy-MM-dd}' -f (Get-Date)String operations: -replace uses regex, -split splits into an array, -join joins an array into a string.
'abc123' -replace '\d', 'X'
'a,b,c' -split ','
@('a','b','c') -join ', 'Control
Conditional structure. Uses PowerShell operators (-eq, -lt) instead of == or <.
if (Test-Path .\file) {
'existe'
} elseif ($x -gt 0) {
'positivo'
} else {
'outro'
}Alternative to chained if. -Regex and -Wildcard enable patterns, -File reads lines from a file.
switch ($x) {
1 { 'um' }
2 { 'dois' }
default { 'outro' }
}
switch -Regex ($texto) {
'^\d+$' { 'número' }
}Loops over collections (foreach), with counter (for), while condition (while), or at least once (do/while).
foreach ($f in Get-ChildItem) { $f.Name }
for ($i = 0; $i -lt 5; $i++) { $i }
while ($cond) { ... }
do { ... } while ($cond)Error capture. To catch non-terminating errors use -ErrorAction Stop on the cmdlet.
try {
Cmdlet -ErrorAction Stop
} catch [System.IO.IOException] {
Write-Error "IO: $_"
} catch {
Write-Error $_
} finally {
Cleanup
}break exits the loop, continue skips to the next iteration, return exits the function.
foreach ($x in 1..10) {
if ($x -eq 5) { break }
if ($x % 2 -eq 0) { continue }
$x
}Operators
Comparison operators. There is no == in PowerShell, always use -eq, -ne, -lt, -gt, -le, -ge.
$x -eq 5 # igual $x -ne 5 # diferente $x -lt 10 # menor $x -gt 0 # maior $x -le 10 # menor ou igual $x -ge 0 # maior ou igual
Other operators: -like uses wildcards, -match uses regex, -contains tests membership in an array, -in is the inverse.
'file.txt' -like '*.txt' # wildcards 'abc123' -match '\d+' # regex @(1,2,3) -contains 2 # pertença 2 -in @(1,2,3) # pertença (invertido)
Logical operators. -and, -or, -not, -xor. ! is an alias for -not.
($x -gt 0) -and ($x -lt 10) ($a -eq 1) -or ($b -eq 2) -not (Test-Path .\file) !$cond
Processes
Lists processes with properties (CPU, WS, Id, ProcessName). With no arguments, lists all.
Get-Process Get-Process node, chrome Get-Process -Id 1234
Stops processes by name or Id. -Force avoids confirmation. Can receive objects from the pipeline.
Stop-Process -Name node Stop-Process -Id 1234 -Force Get-Process node | Stop-Process
Starts a program. -Wait blocks until it finishes, -NoNewWindow runs in the current console, -Verb RunAs elevates.
Start-Process notepad Start-Process npm -ArgumentList 'run','dev' Start-Process pwsh -Verb RunAs
Waits for a process to end. -Timeout aborts after N seconds.
Wait-Process -Name node Wait-Process -Id 1234 -Timeout 30
Runs a command or script. Required when the path has spaces or to call executables dynamically.
& 'C:\Program Files\App\app.exe' arg1 arg2
& $cmd
& { Get-Process; Get-Service }Data
Converts JSON to PowerShell objects. -AsHashtable returns a hashtable (PS 6+) instead of PSCustomObject.
Get-Content pkg.json | ConvertFrom-Json
'{"a":1}' | ConvertFrom-Json
$obj.dependenciesConverts PowerShell objects to JSON. -Depth controls the depth (default 2, often too low).
$obj | ConvertTo-Json -Depth 10
@{a=1; b=2} | ConvertTo-Json -Compress
Get-Process | Select-Object Name,Id | ConvertTo-JsonReads a CSV into objects with properties. -Delimiter for ; or others, -Header if the file has no header row.
Import-Csv users.csv Import-Csv data.csv -Delimiter ';' -Encoding utf8
Exports objects to CSV. -NoTypeInformation removes the type line at the top (default in PS 6+).
Get-Process | Export-Csv processes.csv -NoTypeInformation $data | Export-Csv out.csv -Encoding utf8 -Delimiter ';'
Network
Full HTTP client. Returns the response as an object with .Content, .StatusCode, .Headers. Alias iwr.
Invoke-WebRequest https://example.com iwr https://api.example.com -OutFile data.json iwr -Uri $url -Method POST -Body $body
HTTP client that automatically parses JSON or XML into objects. Most common for REST APIs. Alias irm.
Invoke-RestMethod https://api.github.com/users/octocat irm $url -Method POST -Body ($obj | ConvertTo-Json) -ContentType 'application/json'
Tests TCP connectivity to a host and port. Windows only. On Linux/macOS use Test-Connection -TcpPort (PS 7+).
Test-NetConnection google.com -Port 443 Test-NetConnection -ComputerName 8.8.8.8 -TraceRoute
Ping equivalent. -Count limits packets, -Quiet returns just $true or $false.
Test-Connection google.com -Count 4 Test-Connection 8.8.8.8 -Quiet # bool
Modules
Lists modules. -ListAvailable shows everything installed, not just what is currently loaded.
Get-Module Get-Module -ListAvailable Get-Module -Name Pester
Loads a module into the current session. -Force reloads it if already imported.
Import-Module Pester Import-Module .\MeuModulo.psm1 -Force
Installs modules from the PowerShell Gallery. -Scope CurrentUser avoids needing admin rights.
Install-Module Pester -Scope CurrentUser Install-Module Az -Force -AllowClobber
Searches for modules available on the PowerShell Gallery.
Find-Module Az* Find-Module -Tag azure
Advanced
Runs code in the background. Receive-Job collects the results, -Wait blocks until ready.
$j = Start-Job { Get-Process }
Receive-Job $j -Wait -AutoRemoveJob
Get-Job | Remove-JobLightweight thread-based background jobs (faster than Start-Job). Built into PS 7+, on 5.1 install via Install-Module ThreadJob.
$j = Start-ThreadJob { 1..10 | %{ $_ * 2 } }
$urls | ForEach-Object -Parallel { iwr $_ } -ThrottleLimit 5Measures execution time of a block. Returns a TimeSpan with TotalSeconds, TotalMilliseconds, etc.
Measure-Command { Get-ChildItem -Recurse }
(Measure-Command { ./script.ps1 }).TotalSecondsRuns commands on a remote machine via WinRM. Supports persistent sessions with -Session.
Invoke-Command -ComputerName server01 -ScriptBlock { Get-Service }
Invoke-Command -Session $s -ScriptBlock { hostname }Pauses execution for N seconds or milliseconds.
Start-Sleep -Seconds 5 Start-Sleep -Milliseconds 250
Reference
Unlike bash, the PowerShell pipeline carries objects with properties and methods. Each cmdlet can access .Length, .Name, .CPU directly without parsing text.
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 # objectos fluem entre comandos com propriedades preservadas Get-ChildItem | Where-Object Length -gt 1MB # Each item retains its full type — pode aceder a .Length, .Name, etc. Get-Service | Group-Object Status | Format-Table Name, Count
The default encoding changed between versions. Knowing which one is active prevents BOMs and garbled characters in scripts and logs shared with other tools.
- Default varies by cmdlet: Out-File uses UTF-16 LE with BOM, Set-Content uses Default (ANSI/Windows-1252).
- Neither produces UTF-8 without -Encoding. Always pass -Encoding utf8 for files shared with Unix tools.
- Default: UTF-8 without BOM.
- Behaviour aligned with the broader ecosystem. In both, -Encoding utf8 guarantees UTF-8.
Set-Content file.txt 'texto' -Encoding utf8
Out-File log.txt -Encoding utf8 -InputObject $data
[System.IO.File]::WriteAllText('file.txt', 'texto', [System.Text.UTF8Encoding]::new($false))PowerShell distinguishes terminating from non-terminating errors. Cmdlets fail silently by default, use -ErrorAction Stop to force try/catch to catch them.
Continue— default behaviour, prints the error and keeps going.Stop— turns it into a terminating error (catchable).SilentlyContinue— hides the error but $? becomes $false.Ignore— hides and does not record it in $Error.
$?— $true if the last command succeeded.$LASTEXITCODE— exit code of the last native executable.$Error[0]— object of the last error recorded.
try {
Get-Item .\file -ErrorAction Stop
} catch [System.IO.FileNotFoundException] {
Write-Warning "ficheiro não encontrado"
} catch {
Write-Error $_.Exception.Message
}
# verificar saída de processo nativo
git status
if ($LASTEXITCODE -ne 0) { throw "git falhou" }Windows PowerShell 5.1 (powershell.exe) and PowerShell 7+ (pwsh.exe) have different syntax and features. These details break scripts when moving between versions.
A && B / A || B— Operators && and || only exist in PS 7+. On 5.1 use: A; if ($?) { B }$x ? a : b— Ternary operator ?: only exists in PS 7+. On 5.1 use if/else.$x ?? y— Null-coalescing operator ?? only exists in PS 7+.ConvertFrom-Json -AsHashtable— ConvertFrom-Json -AsHashtable only exists in PS 6+.ForEach-Object -Parallel— ForEach-Object -Parallel only exists in PS 7+.
Common combinations for automation and administration. Each solves a specific task in a single pipeline.
- 01.Find files larger than 100MB recursively.
Get-ChildItem -Recurse -File | Where-Object Length -gt 100MB - 02.List the 10 largest files in the current directory.
Get-ChildItem | Sort-Object Length -Descending | Select-Object -First 10 - 03.Show the 10 processes consuming the most memory.
Get-Process | Sort-Object WS -Descending | Select-Object -First 10 - 04.Show the 10 processes consuming the most CPU.
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 - 05.Count total files recursively.
Get-ChildItem -Recurse -File | Measure-Object | Select-Object -ExpandProperty Count - 06.Delete every .tmp file recursively.
Get-ChildItem -Recurse -Filter *.tmp | Remove-Item - 07.Search for TODO across all TypeScript files.
Get-ChildItem -Recurse -File | Where-Object Extension -in '.ts','.tsx' | Select-String 'TODO' - 08.Get the current machine's external public IP.
(Invoke-WebRequest ifconfig.me -UseBasicParsing).Content.Trim() - 09.List listening TCP ports with the owning process.
Get-NetTCPConnection -State Listen | Select-Object LocalAddress,LocalPort,OwningProcess - 10.Follow a log live starting from the last 100 lines.
Get-Content app.log -Wait -Tail 100 - 11.Get current date and time in a filename-ready format.
Get-Date -Format 'yyyy-MM-dd_HH-mm-ss' - 12.Create a zip backup with the date in the filename.
Compress-Archive -Path .\src -DestinationPath "backup-$(Get-Date -Format yyyy-MM-dd).zip" - 13.Format and print JSON expanded for maximum readability.
Get-Content data.json | ConvertFrom-Json | ConvertTo-Json -Depth 10 - 14.List all environment variables sorted by name.
Get-ChildItem env: | Sort-Object Name - 15.List every service currently running.
Get-Service | Where-Object Status -eq 'Running' - 16.Test whether a TCP port is open on a remote host.
Test-NetConnection google.com -Port 443 - 17.Show free space on every disk on the system.
Get-Volume | Select-Object DriveLetter, SizeRemaining, Size - 18.Show the last 20 commands from the session history.
Get-History | Select-Object -Last 20 - 19.Show the full path of a command (which equivalent).
(Get-Command npm).Source - 20.List files modified in the last 7 days.
Get-ChildItem -Recurse | Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-7) }