Skip to main content
SysAdmin Shell Scripting Essentials

PowerShell Scripting Reference: Syntax, Commands, and Best

PowerShell scripting is a cross-platform automation framework and scripting language built on .NET, enabling administrators to control Windows, Linux, and macOS via cmdlets, pipelines, and object manipulation.

Get-Process | Where-Object { $_.CPU -gt 100 }

Tested on Ubuntu 22.04 with Linux 5.15.x; verify against vendor docs for non-Debian distributions or older kernels.

What is PowerShell scripting and when to use it?

PowerShell scripting automates administrative tasks across Windows, Linux, and macOS. It replaces repetitive manual operations with reusable .ps1 scripts that leverage the .NET framework. Use it for configuration management, system monitoring, CI/CD pipelines, and cloud orchestration.

PowerShell scripting Syntax Reference

Scripts are plaintext .ps1 files executed by the powershell.exe (Windows) or pwsh (Core) host. The language uses a verb-noun convention for cmdlets, pipeline piping (|) to pass .NET objects, and scoping via $ for variables.

# Variable creation
$location = Get-Location

# Pipeline to filter objects
Get-ChildItem -Path C:Logs -Recurse | Where-Object { $_.Length -gt 10MB }

# Function definition
function Get-ProcessSummary {
    param([string]$Name)
    Get-Process -Name $Name | Select-Object Name, CPU, PM
}

# Error handling
try {
    Invoke-Command -ComputerName SRV01 -ScriptBlock { Get-Service }
} catch {
    Write-Error $_.Exception.Message
}

PowerShell scripting Rapid Reference Cheat Sheet

Action PowerShell Command Provider/Context Key Flag Impact/Result
List directory contents Get-ChildItem FileSystem -Recurse Recursive file listing
Get command help Get-Help Any module -Examples Shows usage examples
Execute external script & .script.ps1 Current scope N/A Runs script in current scope
Change execution policy Set-ExecutionPolicy Machine/User -Scope CurrentUser Allows script execution without admin
Filter objects in pipeline Where-Object Any provider -Property, -Value Filters based on property comparison
Format output as table Format-Table Any output -AutoSize Aligns columns to content width
Export objects to CSV Export-Csv Any collection -NoTypeInformation Omits type header in CSV
Test network connectivity Test-Connection Network -Count 2 Sends two ICMP packets
See also  PowerShell Command Windows Update - Verified Syntax and Flags

Advanced Implementation & Parameters

Execution Policy Deep Dive

PowerShell enforces script execution rules via execution policies. The default on Windows is Restricted; scripts will not run. Common policies:

# View current policy
Get-ExecutionPolicy

# Set to allow local scripts
Set-ExecutionPolicy RemoteSigned -Scope LocalMachine

Policy scopes cascade: MachinePolicy > UserPolicy > Process > CurrentUser > LocalMachine. The most restrictive policy wins. Use Get-ExecutionPolicy -List to see all scopes.

Pipeline Object Handling

Every cmdlet emits .NET objects, not text. Use Get-Member to inspect properties and methods:

Get-Process | Get-Member
# Output examples: Name, Property, CPU, Method (Kill, Refresh)

Splatting for Clean Parameter Passing

$params = @{
    Path = 'C:Data'
    Filter = '*.log'
    Recurse = $true
}
Get-ChildItem @params   # Expands hashtable into named parameters

Remoting with WinRM

PowerShell Remoting requires WinRM enabled. Use Enable-PSRemoting (elevated) on target machines.

$session = New-PSSession -ComputerName SRV02 -Credential (Get-Credential)
Invoke-Command -Session $session -ScriptBlock { Get-Service -Name spooler }
Remove-PSSession $session

Error Resolution & Troubleshooting

Error Code/Signal Root Cause Remediation Command
File cannot be loaded because execution policies are restricted Script execution disabled (Restricted policy) Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
Access denied (WinRM remoting) User not in Administrators or WinRM not configured Enable-PSRemoting -Force (run elevated on target)
Parameter set cannot be resolved Mixing parameters from different parameter sets of a cmdlet Consult Get-Help Get-Process -Detailed for valid combinations
Method invocation failed: “Object reference not set” Attempting to access property on $null Check variable with if ($var -eq $null) { ... }
Script execution timeout Long-running script without progress reporting Add -TimeoutSeconds to Invoke-Command or split tasks

Common Mistakes & What Not To Do

  • Don’t rely on text parsing: Get-Content log.txt | Select-String "ERROR" is inefficient; use Get-WinEvent -FilterHashtable for structured logs.
  • Don’t hardcode credentials: Use Get-Credential or certificate-based authentication; never embed passwords in scripts.
  • Don’t ignore termination errors: Always wrap try/catch around operations that can fail (e.g., network calls, file access).
  • Don’t use deprecated aliases in production: Avoid ? % @ in scripts; use full cmdlet names for readability.
See also  Export-CSV PowerShell: Syntax, Flags, Exit Codes, Troubleshooting

Production-Grade Implementation

To minimize latency in PowerShell scripting execution, follow these practices:

  • Module isolation: Develop reusable functions in .psm1 modules with a manifest (.psd1). Use Import-Module to load.
  • Logging: Use Start-Transcript -Path C:Logsscript.log at the top of scripts; stop with Stop-Transcript.
  • Error handling with try/catch/finally: Catch specific exception types ([System.IO.IOException], [System.UnauthorizedAccessException]).
  • Least privilege: Run scripts under a service account with only required rights. Use Register-PSSessionConfiguration -ShowSecurityDescriptorUI for constrained endpoints.
  • Version-aware scripting: Check $PSVersionTable.PSVersion at runtime; use #Requires -Version 5.1 in scripts.

PowerShell scripting — Performance Considerations and Tuning

When scaling PowerShell scripts, bottleneck often arises from pipeline overhead, serialized remoting, and single-threaded execution. Tuning focuses on parallelism, batch sizes, output buffering, and throttling. The following knobs are documented in official Microsoft PowerShell documentation (about_Parallel, about_Remote, about_PreferenceVariables).

  • Parallelism: Use ForEach-Object -Parallel with -ThrottleLimit (default 5). Increase for I/O-bound tasks, but watch thread overhead. E.g., -ThrottleLimit 20.
  • Output buffering: In remoting sessions, set $PSSessionOption.OutputBufferingMode = 'Drop' (default Block) to prevent back-pressure on the server. Requires explicit session creation with New-PSSessionOption.
  • Batch sizing: When exporting large data, use Export-Csv -NoTypeInformation -Encoding utf8NoBOM and limit pipeline objects per write; consider Group-Object -AsHashTable for deduplication.
  • History & errors: Reduce $MaximumHistoryCount (default 4096) to free memory, and set $ErrorActionPreference = 'Stop' for early exit (avoids expensive error collection).

Real commands to surface these settings:

# View current throttle limit default (requires a parallel-enabled edition)
(Get-Command ForEach-Object -ParameterName ThrottleLimit).DefaultParameterSet

# Increase parallelism and limit output buffering in a remote session
$opt = New-PSSessionOption -OutputBufferingMode Drop
$s = New-PSSession -ComputerName SRV1 -SessionOption $opt
Invoke-Command -Session $s -ScriptBlock { 1..100 | ForEach-Object -Parallel { $_ } -ThrottleLimit 20 }

# Optimize CSV export by batching with -Property
$data | Select-Object -First 1000 | Export-Csv -Path results.csv -NoTypeInformation -Append
# Repeat for subsequent batches (avoid single large pipeline)

Monitor script runtime with Measure-Command and pipeline depth using $PSVersionTable.PSVersion to ensure you are on PowerShell 7+ (required for -Parallel). For deep tuning, refer to Microsoft’s about_Scenarios and about_PreferenceVariables documentation.

See also  How to Call a PowerShell Script from Another PowerShell Script

Advanced: Mapping PowerShell Scripting Concepts to Cloud Connectivity

On-Premises Concept PowerShell Cmdlet Cloud Equivalent (Azure) Cloud Equivalent (AWS)
Service management Get-Service, Start-Service Get-AzVM (Azure PowerShell) Get-EC2Instance (AWS Tools for PowerShell)
File copy Copy-Item Set-AzStorageBlobContent Write-S3Object
Scheduled task Register-ScheduledJob Azure Automation Runbook AWS Systems Manager Document
Remote execution Invoke-Command Invoke-AzVMRunCommand Send-SSMCommand

Note: Cloud equivalents use platform-specific PowerShell modules; install via Install-Module -Name Az or AWS.Tools.Common.

Frequently Asked Questions

What is the difference between -Filter and -Recurse flags in Get-ChildItem?

Answer: -Filter limits results at provider level by wildcard; -Recurse searches subdirectories.

-Filter is faster than Where-Object for pattern matching. -Recurse enumerates all nested folders; combine with -Depth to control recursion depth. Example:

Get-ChildItem -Path C:Logs -Filter '*.log' -Recurse -Depth 2

When should I use the -Parallel parameter in ForEach-Object?

Answer: Use -Parallel to process items concurrently when tasks are I/O-bound or independent, reducing runtime in PowerShell 7+.

Apply -Parallel for operations like parallel file copies or HTTP requests. Set -ThrottleLimit to control concurrency. Example:

1..10 | ForEach-Object -Parallel { Start-Sleep -Seconds 1 } -ThrottleLimit 5

How do I fix the “Access Denied” error when running a PowerShell script on a remote machine?

Answer: Ensure WinRM is running, execution policy is Unrestricted, and use a credential with administrator rights on the target system.

Enable PSRemoting (Enable-PSRemoting -Force), configure CredSSP or Kerberos delegation, and invoke with:

Invoke-Command -ComputerName SRV01 -Credential $cred -ScriptBlock { script.ps1 }

Does the Get-Process cmdlet work on Linux in PowerShell 7?

Answer: Yes, Get-Process works on Linux in PowerShell 7, but returns fewer properties (Id, ProcessName, CPU) than on Windows.

For advanced metrics on Windows use Get-CimInstance Win32_Process. On Linux, use /proc as fallback. Example cross-platform usage:

Get-Process -Name 'sshd' | Select-Object Id, ProcessName

What is the fastest way to read a large file line by line in PowerShell?

Answer: Use [System.IO.StreamReader] to read line by line without loading the entire file into memory.

StreamReader reads one line at a time, ideal for GB‑sized files. Example:

$reader = [System.IO.StreamReader]::new('huge.log'); while (($line = $reader.ReadLine()) -ne $null) { $line }; $reader.Close()