Skip to content
BytePath v0.0.35

PowerShell Automation and Scripting

Windows administration pathAvailable

Turn repeatable administration tasks into inspectable scripts that return objects, handle errors, and can be tested safely.

Difficulty
Beginner to Intermediate
Time
120 min
Practice
Build a network report
Assessment
Knowledge check

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.

PowerShell commands normally emit .NET objects. Inspect them with Get-Member and select properties explicitly:

Terminal window
Get-Service | Get-Member
Get-Service | Where-Object Status -eq 'Running' | Select-Object Name, Status

The 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.

Terminal window
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string] $ComputerName
)
Get-CimInstance Win32_OperatingSystem -ComputerName $ComputerName |
Select-Object CSName, Caption, LastBootUpTime

Validate input where useful, use clear names, and avoid hard-coding production targets. A script should make its scope and assumptions obvious.

Many cmdlets emit non-terminating errors. Use -ErrorAction Stop when a failure must enter catch:

Terminal window
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.

Terminal window
$services = Get-Service
$stopped = $services | Where-Object Status -eq 'Stopped'
$stopped | Sort-Object DisplayName | Export-Csv ./stopped-services.csv -NoTypeInformation
$services | Group-Object Status

Use 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.

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.

  • 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 $LASTEXITCODE when calling native programs.
  • Catching errors and returning a misleading success result.
  • Testing against systems without permission.

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.