Quick Reference
Cmdlet Structure
Verb-Noun
Pipeline Operator
|
Help System
Get-Help, Get-Command, Get-Member
Current Version
$PSVersionTable.PSVersion
Profile Location
$PROFILE
Execution Policy
Get-ExecutionPolicy
Core Verb Conventions
PowerShell enforces approved verbs for cmdlets. Knowing the common verbs lets you guess cmdlet names before looking them up.
| Verb | Meaning | Example |
|---|---|---|
Get | Retrieve data, no side effects | Get-Process |
Set | Change existing resource | Set-Item |
New | Create a new resource | New-Item |
Remove | Delete a resource | Remove-Item |
Add | Add to existing resource | Add-Content |
Start | Begin an operation | Start-Service |
Stop | End an operation | Stop-Process |
Restart | Stop then start | Restart-Service |
Enable / Disable | Activate or deactivate | Enable-NetAdapter |
Test | Verify something | Test-Path |
Invoke | Run a command or script | Invoke-Command |
Export / Import | Serialize / deserialize data | Export-Csv |
Select | Choose specific properties or objects | Select-Object |
Where | Filter objects | Where-Object |
Sort | Reorder objects | Sort-Object |
Format | Change display format | Format-Table |
Aliases: Many cmdlets have shorter aliases.
ls, dir → Get-ChildItem. cd → Set-Location. cat, type → Get-Content. ps → Get-Process. Use full cmdlet names in scripts — aliases are for interactive use only.
Help & Discovery
The built-in help system is PowerShell’s most powerful feature. Learn these first.
| Command | What It Does |
|---|---|
Get-Help Get-Process | Show help for a cmdlet |
Get-Help Get-Process -Full | Full help with all parameters and examples |
Get-Help Get-Process -Examples | Show usage examples only |
Get-Help Get-Process -Online | Open official docs in browser |
Get-Help *service* | Find all cmdlets with “service” in name |
Update-Help | Download latest help files from internet |
Get-Command *process* | Find cmdlets matching a pattern |
Get-Command -Verb Get -Noun *network* | Find cmdlets by verb and noun |
Get-Command -Module ActiveDirectory | List all cmdlets in a module |
Get-Process | Get-Member | Show all properties and methods of an object |
Get-Process | Get-Member -MemberType Property | Show properties only |
$PSVersionTable | Show PowerShell version and environment |
Get-Module -ListAvailable | List all installed modules |
Import-Module ActiveDirectory | Load a module into current session |
Find-Module -Name *SQL* | Search PowerShell Gallery for modules |
Install-Module -Name PSReadLine | Install module from PowerShell Gallery |
Filesystem & Files
| Command | What It Does |
|---|---|
Get-Location | Show current directory (pwd) |
Set-Location C:\Temp | Change directory (cd) |
Set-Location .. | Go up one directory |
Get-ChildItem | List files and folders (ls / dir) |
Get-ChildItem -Recurse | List recursively including subdirectories |
Get-ChildItem -Filter *.log | List only .log files |
Get-ChildItem -Hidden | Show hidden files |
New-Item -ItemType File -Name test.txt | Create a new empty file |
New-Item -ItemType Directory -Name logs | Create a new folder |
Copy-Item file.txt C:\Backup\ | Copy file to destination |
Copy-Item C:\Source -Destination C:\Dest -Recurse | Copy folder recursively |
Move-Item file.txt C:\Archive\ | Move file |
Rename-Item old.txt new.txt | Rename file or folder |
Remove-Item file.txt | Delete file |
Remove-Item C:\Temp -Recurse -Force | Delete folder and contents without confirmation |
Test-Path C:\Logs\app.log | Check if path exists (returns True/False) |
Get-Content file.txt | Read file contents (cat / type) |
Get-Content file.txt -Tail 50 | Read last 50 lines |
Get-Content file.txt -Wait | Tail a file live (like tail -f) |
Set-Content file.txt "Hello" | Write text to file (overwrites) |
Add-Content file.txt "New line" | Append text to file |
"Hello" | Out-File file.txt | Write pipeline output to file |
Get-Item file.txt | Select-Object Name, Length, LastWriteTime | Show file metadata |
(Get-Item file.txt).Length / 1MB | Get file size in MB |
Processes & Services
Processes
| Command | What It Does |
|---|---|
Get-Process | List all running processes |
Get-Process -Name chrome | Get specific process by name |
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 | Top 10 processes by CPU |
Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 10 | Top 10 processes by memory |
Stop-Process -Name notepad | Kill process by name |
Stop-Process -Id 1234 | Kill process by PID |
Stop-Process -Name chrome -Force | Force kill without confirmation |
Start-Process notepad.exe | Start a process |
Start-Process cmd.exe -Verb RunAs | Start process as Administrator |
(Get-Process chrome | Measure-Object WorkingSet -Sum).Sum / 1MB | Total memory used by all Chrome processes in MB |
Services
| Command | What It Does |
|---|---|
Get-Service | List all services and their status |
Get-Service -Name wuauserv | Get specific service (Windows Update) |
Get-Service | Where-Object Status -eq 'Running' | List only running services |
Get-Service | Where-Object StartType -eq 'Automatic' | Where-Object Status -eq 'Stopped' | Find auto-start services that are stopped |
Start-Service -Name Spooler | Start a service |
Stop-Service -Name Spooler | Stop a service |
Restart-Service -Name Spooler | Restart a service |
Restart-Service -Name Spooler -Force | Restart even if dependent services are running |
Set-Service -Name Spooler -StartupType Disabled | Change service startup type |
Set-Service -Name Spooler -StartupType Automatic | Set service to auto-start |
Networking
| Command | What It Does |
|---|---|
Get-NetIPAddress | Show all IP addresses on all interfaces |
Get-NetIPAddress -AddressFamily IPv4 | Show IPv4 addresses only |
Get-NetAdapter | List network adapters and status |
Get-NetAdapter | Where-Object Status -eq 'Up' | List only connected adapters |
Get-NetRoute | Show routing table |
Get-NetRoute -DestinationPrefix "0.0.0.0/0" | Show default gateway |
Get-DnsClientServerAddress | Show configured DNS servers |
Resolve-DnsName google.com | DNS lookup (like nslookup) |
Resolve-DnsName google.com -Type MX | Look up MX records |
Test-NetConnection google.com | Test connectivity (ping + traceroute info) |
Test-NetConnection google.com -Port 443 | Test TCP port connectivity |
Test-NetConnection 8.8.8.8 -TraceRoute | Run traceroute |
Get-NetTCPConnection | List all TCP connections and listeners |
Get-NetTCPConnection -State Listen | Show listening ports only |
Get-NetTCPConnection -LocalPort 80 | Find what is using port 80 |
Get-NetTCPConnection | Where-Object State -eq 'Established' | Measure-Object | Count established connections |
Clear-DnsClientCache | Flush DNS cache |
Get-DnsClientCache | View current DNS cache entries |
Enable-NetAdapter -Name "Ethernet" | Enable a network adapter |
Disable-NetAdapter -Name "Ethernet" -Confirm:$false | Disable a network adapter without prompt |
System Information
| Command | What It Does |
|---|---|
Get-ComputerInfo | Comprehensive system information |
Get-ComputerInfo | Select-Object CsName, WindowsVersion, OsArchitecture | Hostname, Windows version, architecture |
$env:COMPUTERNAME | Get hostname quickly |
[System.Environment]::OSVersion | OS version details |
Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, BuildNumber | OS name and build number |
Get-CimInstance Win32_ComputerSystem | Select-Object TotalPhysicalMemory | Total RAM in bytes |
(Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1GB | Total RAM in GB |
Get-CimInstance Win32_Processor | Select-Object Name, NumberOfCores, NumberOfLogicalProcessors | CPU info |
Get-CimInstance Win32_LogicalDisk | Select-Object DeviceID, Size, FreeSpace | Disk size and free space |
Get-CimInstance Win32_LogicalDisk | Select-Object DeviceID, @{N='FreeGB';E={[math]::Round($_.FreeSpace/1GB,2)}}, @{N='SizeGB';E={[math]::Round($_.Size/1GB,2)}} | Disk info in GB |
Get-CimInstance Win32_BIOS | Select-Object Manufacturer, SMBIOSBIOSVersion | BIOS information |
Get-HotFix | Sort-Object InstalledOn -Descending | List installed Windows updates |
Get-HotFix -Id KB5034441 | Check if specific KB is installed |
Get-Date | Current date and time |
(Get-CimInstance Win32_OperatingSystem).LastBootUpTime | Last system boot time |
(Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime | System uptime |
$env:USERNAME | Current user |
[Security.Principal.WindowsIdentity]::GetCurrent().Name | Current user with domain |
whoami /groups | List group memberships of current user |
Local Users & Groups
| Command | What It Does |
|---|---|
Get-LocalUser | List all local user accounts |
Get-LocalUser | Where-Object Enabled -eq $true | List enabled users only |
New-LocalUser -Name "svc_backup" -NoPassword | Create local user without password |
Set-LocalUser -Name "svc_backup" -Password (Read-Host -AsSecureString) | Set password for local user |
Disable-LocalUser -Name "Guest" | Disable a local user |
Enable-LocalUser -Name "Administrator" | Enable a local user |
Remove-LocalUser -Name "olduser" | Delete a local user |
Get-LocalGroup | List all local groups |
Get-LocalGroupMember -Group "Administrators" | List members of Administrators group |
Add-LocalGroupMember -Group "Administrators" -Member "svc_backup" | Add user to local group |
Remove-LocalGroupMember -Group "Administrators" -Member "olduser" | Remove user from local group |
Active Directory: For domain user/group management, use the
ActiveDirectory module (Import-Module ActiveDirectory). Cmdlets follow the same pattern: Get-ADUser, New-ADUser, Add-ADGroupMember, etc.
Event Logs
| Command | What It Does |
|---|---|
Get-EventLog -List | List all classic event logs |
Get-EventLog -LogName System -Newest 50 | Get last 50 System log entries |
Get-EventLog -LogName Application -EntryType Error -Newest 20 | Get last 20 Application errors |
Get-EventLog -LogName System -EntryType Error,Warning -After (Get-Date).AddHours(-24) | Errors and warnings from last 24 hours |
Get-WinEvent -LogName System -MaxEvents 100 | Get events using newer API (supports all logs) |
Get-WinEvent -LogName Security -MaxEvents 50 | Get Security log events (requires admin) |
Get-WinEvent -FilterHashtable @{LogName='System'; Level=2; StartTime=(Get-Date).AddDays(-1)} | Filter by log, severity (2=Error), and time |
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625} -MaxEvents 20 | Get failed login attempts (Event ID 4625) |
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} -MaxEvents 20 | Get successful logins (Event ID 4624) |
Get-WinEvent -LogName System | Where-Object {$_.Message -like "*disk*"} | Search event messages for keyword |
Clear-EventLog -LogName Application | Clear an event log (requires admin) |
| Event ID | Log | Meaning |
|---|---|---|
4624 | Security | Successful logon |
4625 | Security | Failed logon attempt |
4648 | Security | Logon with explicit credentials (RunAs) |
4720 | Security | User account created |
4740 | Security | User account locked out |
4776 | Security | NTLM authentication attempt |
7034 | System | Service crashed unexpectedly |
7036 | System | Service entered started/stopped state |
1102 | Security | Audit log cleared (investigate immediately) |
41 | System | System rebooted without clean shutdown (crash) |
Pipeline & Object Manipulation
The pipeline passes objects, not text. This is what makes PowerShell fundamentally different from Bash.
| Command | What It Does |
|---|---|
Get-Process | Where-Object CPU -gt 10 | Filter: processes using more than 10 CPU seconds |
Get-Process | Where-Object {$_.WorkingSet -gt 100MB} | Filter with script block (more complex conditions) |
Get-Service | Select-Object Name, Status, StartType | Select specific properties only |
Get-Process | Select-Object -First 5 | Take first 5 objects |
Get-Process | Select-Object -Last 5 | Take last 5 objects |
Get-Process | Sort-Object CPU -Descending | Sort by property descending |
Get-Process | Sort-Object Name | Select-Object Name, CPU | Format-Table | Sort, select, display as table |
Get-Process | Measure-Object WorkingSet -Sum -Average -Max | Aggregate statistics on a property |
Get-Process | Group-Object Company | Group objects by property value |
Get-Service | Select-Object Name, Status | Export-Csv services.csv -NoTypeInformation | Export to CSV |
Import-Csv users.csv | ForEach-Object { New-LocalUser $_.Name } | Import CSV and process each row |
Get-Process | ConvertTo-Json | Out-File procs.json | Export to JSON |
Get-Process | Out-GridView | Display in interactive GUI grid (Windows only) |
Get-Process | Format-List * | Show all properties as a list |
Get-Process | Format-Table Name, CPU, WorkingSet -AutoSize | Custom table with auto-sized columns |
1..10 | ForEach-Object { Write-Output "Item $_" } | Loop over a range with ForEach-Object |
Get-ChildItem *.log | ForEach-Object { Remove-Item $_ } | Delete each file matching a pattern |
"a","b","c" | ForEach-Object { $_.ToUpper() } | Transform each string in an array |
Where-Object shorthand:
Where-Object Status -eq 'Running' is equivalent to Where-Object {$_.Status -eq 'Running'}. The simplified syntax works for single conditions. Use the script block form ({}) when you need -and, -or, or more complex logic.
Remoting & Remote Execution
| Command | What It Does |
|---|---|
Enable-PSRemoting -Force | Enable WinRM and PSRemoting on the machine |
Test-WSMan -ComputerName server01 | Test if WinRM is reachable on remote host |
Enter-PSSession -ComputerName server01 | Start interactive remote session |
Enter-PSSession -ComputerName server01 -Credential (Get-Credential) | Connect with alternate credentials |
Exit-PSSession | End interactive remote session |
Invoke-Command -ComputerName server01 -ScriptBlock { Get-Service } | Run a command on a remote machine |
Invoke-Command -ComputerName server01,server02 -ScriptBlock { hostname } | Run command on multiple machines in parallel |
Invoke-Command -ComputerName server01 -FilePath C:\Scripts\deploy.ps1 | Run a local script on a remote machine |
$s = New-PSSession -ComputerName server01 | Create a persistent session |
Invoke-Command -Session $s -ScriptBlock { $result = Get-Process } | Run command in persistent session (keeps state) |
Remove-PSSession $s | Close a persistent session |
Get-PSSession | List all open sessions |
Copy-Item C:\file.txt -ToSession $s -Destination C:\Temp\ | Copy file to remote session |
Invoke-Command -ComputerName (Get-Content servers.txt) -ScriptBlock { Restart-Service Spooler } | Run command on list of servers from file |
WinRM prerequisite: PSRemoting requires WinRM to be running on the target machine and a firewall rule allowing port 5985 (HTTP) or 5986 (HTTPS). In a domain environment this is often configured via GPO. On workgroup machines you may also need to add the remote machine to the
TrustedHosts list.
Scripting Essentials
Variables & Types
| Syntax | Meaning |
|---|---|
$name = "server01" | String variable |
$count = 42 | Integer variable |
[int]$port = "443" | Typed variable — coerces string to int |
$servers = @("srv1","srv2","srv3") | Array |
$servers.Count | Array length |
$map = @{Name="web01"; IP="10.0.0.1"} | Hashtable (key-value) |
$map["Name"] or $map.Name | Access hashtable value |
$null | Null / empty value |
$true / $false | Boolean values |
"Server: $name port $port" | String interpolation (double quotes only) |
'Literal $name' | Literal string — variables NOT expanded |
Control Flow
| Syntax | Meaning |
|---|---|
if ($x -gt 5) { ... } elseif ($x -eq 5) { ... } else { ... } | If/elseif/else |
foreach ($item in $collection) { ... } | Foreach loop |
for ($i = 0; $i -lt 10; $i++) { ... } | For loop |
while ($condition) { ... } | While loop |
do { ... } while ($condition) | Do-while (runs at least once) |
switch ($val) { "a" { ... } "b" { ... } default { ... } } | Switch statement |
break | Exit loop |
continue | Skip to next iteration |
return $value | Return value from function |
Comparison Operators
| Operator | Meaning | Example |
|---|---|---|
-eq / -ne | Equal / not equal | $x -eq 5 |
-gt / -lt | Greater than / less than | $x -gt 10 |
-ge / -le | Greater or equal / less or equal | $x -ge 0 |
-like | Wildcard match | $s -like "web*" |
-notlike | Wildcard non-match | $s -notlike "*test*" |
-match | Regex match | $s -match "^\d{3}" |
-contains | Array contains value | $arr -contains "admin" |
-in | Value is in array | "admin" -in $arr |
-and / -or / -not | Logical operators | $a -and $b |
Error Handling
| Syntax / Command | Meaning |
|---|---|
try { ... } catch { ... } finally { ... } | Structured error handling block |
catch [System.IO.FileNotFoundException] { ... } | Catch specific exception type |
$_.Exception.Message | Get error message inside catch block |
$ErrorActionPreference = 'Stop' | Make all errors terminating (catchable) |
Get-Item missing.txt -ErrorAction SilentlyContinue | Suppress errors for this command |
Get-Item missing.txt -ErrorAction Stop | Force error to be terminating |
$Error[0] | Last error that occurred |
Write-Error "Something went wrong" | Write a non-terminating error |
throw "Fatal error" | Throw a terminating error |
ErrorActionPreference: By default, many PowerShell errors are non-terminating — they display an error message but the script continues. Set
$ErrorActionPreference = 'Stop' at the top of production scripts so that unexpected errors don’t silently pass through.
Execution Policy & Security
| Command | What It Does |
|---|---|
Get-ExecutionPolicy | Show current execution policy |
Get-ExecutionPolicy -List | Show execution policy for all scopes |
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser | Allow local scripts; require signing for downloaded scripts |
Set-ExecutionPolicy Bypass -Scope Process | Bypass policy for current session only (not persistent) |
Unblock-File -Path .\script.ps1 | Remove “downloaded from internet” block from file |
Get-AuthenticodeSignature script.ps1 | Check if a script is digitally signed |
| Policy | Meaning | Recommended For |
|---|---|---|
Restricted | No scripts allowed | Default on Windows clients |
AllSigned | All scripts must be signed | High-security environments |
RemoteSigned | Local scripts run freely; downloaded scripts need signing | Servers and admin workstations |
Unrestricted | All scripts run (prompts for downloaded) | Development only |
Bypass | No restrictions, no prompts | Automation pipelines (CI/CD) |
Common mistake: Running
Set-ExecutionPolicy Unrestricted or Bypass machine-wide (-Scope LocalMachine) to fix a script that won’t run. Instead, use -Scope CurrentUser or -Scope Process to limit the change, or use Unblock-File on the specific script.
FAQ
What is the difference between PowerShell and Windows PowerShell?
Windows PowerShell (5.1) is built into Windows, based on .NET Framework, and will not receive new features — only security fixes. PowerShell 7+ (formerly PowerShell Core) is cross-platform (Windows, Linux, macOS), based on .NET 6+, and is the actively developed version. For new scripts, target PowerShell 7. Both can be installed side-by-side. Check your version with
$PSVersionTable.PSVersion.
What is the difference between Get-WinEvent and Get-EventLog?
Get-EventLog is older and only works with classic Windows event logs (Application, System, Security). Get-WinEvent works with all event logs including modern ETW-based logs, supports powerful hash-based filtering, and performs much better on large logs. Use Get-WinEvent for new scripts — Get-EventLog is deprecated in PowerShell 7.
How do I run a script that won’t execute due to execution policy?
Three safe options: (1)
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser — persistent change for your user only. (2) Unblock-File .\script.ps1 — removes the internet-downloaded flag from this specific file. (3) powershell.exe -ExecutionPolicy Bypass -File script.ps1 — bypasses policy for this one run only without changing settings. Avoid machine-wide unrestricted policies.
What is the difference between Write-Host, Write-Output, and Write-Verbose?
Write-Output sends objects to the pipeline — use this in functions and scripts to return data. Write-Host writes directly to the console and bypasses the pipeline — it cannot be captured or redirected, making it unsuitable for scripts meant to be composed. Write-Verbose writes to the verbose stream, only visible when -Verbose flag is used or $VerbosePreference = 'Continue' is set — ideal for debug/progress messages in reusable scripts.
How do I find which process is using a specific port?
Get-NetTCPConnection -LocalPort 80 | Select-Object LocalAddress, LocalPort, State, OwningProcess gives you the PID. Then use Get-Process -Id <PID> to find the process name. You can combine them: Get-NetTCPConnection -LocalPort 80 | ForEach-Object { Get-Process -Id $_.OwningProcess }.
How do I run a PowerShell command as Administrator without opening a new window?
From a non-admin session, you cannot elevate a running process — Windows requires a new elevated process. The pattern is:
Start-Process powershell.exe -Verb RunAs -ArgumentList "-Command & { ... }". This opens a UAC prompt and runs the command in a new elevated window. For scripting without UI, consider creating a scheduled task that runs as SYSTEM, or use a deployment tool.