PowerShell Automation and Scripting
Turn repeatable administration tasks into inspectable scripts that return objects, handle errors, and can be tested safely.
Before you start
Who is this for?
For Windows users and administrators who want more reliable automation than copying commands from a search result.
Prerequisites
- Basic Windows administration
- Basic command-line use
What you'll be able to do
- Explain the pipeline object model
- Write parameterised functions
- Handle terminating errors
- Filter and export results
- Test scripts in a disposable environment
Practical outcome
You can create a structured diagnostic report without formatting data too early.
1. Objects, not text
Section titled “1. Objects, not text”PowerShell commands normally emit .NET objects. Inspect them with Get-Member and select properties explicitly:
Get-Service | Get-MemberGet-Service | Where-Object Status -eq 'Running' | Select-Object Name, StatusThe pipeline passes objects from one command to the next. Format-Table is for the final display; do not use formatted output as input to another command.
2. Parameters make intent visible
Section titled “2. Parameters make intent visible”[CmdletBinding()]param( [Parameter(Mandatory)] [string] $ComputerName)
Get-CimInstance Win32_OperatingSystem -ComputerName $ComputerName | Select-Object CSName, Caption, LastBootUpTimeValidate input where useful, use clear names, and avoid hard-coding production targets. A script should make its scope and assumptions obvious.
3. Errors must be tested
Section titled “3. Errors must be tested”Many cmdlets emit non-terminating errors. Use -ErrorAction Stop when a failure must enter catch:
try { $result = Test-NetConnection -ComputerName $ComputerName -Port 443 -WarningAction SilentlyContinue -ErrorAction Stop [pscustomobject]@{ Target = $ComputerName Port = 443 Open = $result.TcpTestSucceeded }}catch { Write-Error "The connectivity test failed: $($_.Exception.Message)"}Do not catch an error only to hide it. Return enough context for the operator to decide what to do next.
4. Filter, measure, and export
Section titled “4. Filter, measure, and export”$services = Get-Service$stopped = $services | Where-Object Status -eq 'Stopped'$stopped | Sort-Object DisplayName | Export-Csv ./stopped-services.csv -NoTypeInformation$services | Group-Object StatusUse ForEach-Object when each object needs an action or calculated property. Prefer Select-Object for projection and Where-Object for filtering. Test with sample data before changing services.
5. Network report exercise
Section titled “5. Network report exercise”Create a function with a mandatory Target parameter that returns one object containing timestamp, target, ping success, TCP 443 result, and a short error message. Run it against an authorised lab target, inspect it with Format-List, filter failures, and export the objects to JSON.
A failed ping does not prove TCP is blocked, and a successful TCP connection does not prove the application is healthy. Keep those results separate.
Common mistakes
Section titled “Common mistakes”- Formatting objects before filtering or exporting them.
- Running a script with administrator rights without a reason.
- Assuming a missing module or cmdlet behaves identically on Windows PowerShell 5.1 and PowerShell 7.
- Ignoring
$LASTEXITCODEwhen calling native programs. - Catching errors and returning a misleading success result.
- Testing against systems without permission.
What you should be able to do now
Section titled “What you should be able to do now”You should be able to inspect objects, build a parameterised pipeline, handle a failure deliberately, and produce output that another tool can consume.
Related: Windows Fundamentals and Event Logs covers the host and event channels behind these diagnostics.