PowerShell/01intro10 min

Basics: cmdlets, pipeline, objects

PowerShell powers the on-premises ZEUS probes — scripts for LDAP inventory, performance collection and AD forests. To write them well, you need to understand the foundation: PowerShell passes objects, not text.

Cmdlets — the Verb-Noun scheme

PowerShell commands (cmdlets) have a Verb-Noun name. The verbs are standardized (Get, Set, New, Remove, Invoke).

Get-Process
Get-Service -Name WinRM
Get-ADForest -Identity corp.local

ProfessNet standard: we name our own functions Verb-Noun too, with an approved verb (Get-Verb shows the list). Hence the names of the real ZEUS scripts: Get-LsnForest, Get-LsnInventory, Get-LsnPerf.

The pipeline passes objects

The most important difference from bash: | passes objects with properties, not lines of text. That's why you can filter and sort by fields.

# filtering by an object property, not by text
Get-Service |
  Where-Object Status -eq "Running" |
  Sort-Object Name |
  Select-Object Name, Status
# bash would think in text; PowerShell knows the .WorkingSet64 field
Get-Process |
  Where-Object { $_.WorkingSet64 -gt 100MB } |
  Select-Object Name, @{ N = "MemMB"; E = { [math]::Round($_.WorkingSet64 / 1MB) } }

$_ (or $PSItem) is the current object in the pipeline.

Select, Where, ForEach

CmdletRole
Where-Objectfilters objects by a condition
Select-Objectselects/transforms properties
Sort-Objectsorts by a field
ForEach-Objectruns an action on each object
Group-Objectgroups by a field value

We build result objects explicitly

In the ZEUS probe scripts we create our own result objects with [pscustomobject] — these are the ones that later become JSON.

$result = [pscustomobject]@{
    Host    = $env:COMPUTERNAME
    Forest  = $forest
    Hosts   = $hostCount
    Scanned = (Get-Date).ToString("o")
}

Why this matters for JSON

Because the pipeline is objects, conversion to JSON is trivial and faithful — the object's fields become the JSON keys. This is the basis of the -AsJson pattern in the ZEUS probes (we return a structured result on stdout that the backend reads).

$result | ConvertTo-Json -Depth 5 -Compress

Tip: don't build JSON by hand from strings ("{ ""host"":..."). Create a [pscustomobject] and use ConvertTo-Json. Escaping, types and nesting take care of themselves.

Getting help

Get-Help Get-Service -Examples
Get-Member -InputObject (Get-Process | Select-Object -First 1)

Get-Member shows what properties and methods an object has — invaluable when writing filters.


Verb-Noun cmdlets, the object pipeline and [pscustomobject] as a result are the ABCs of PowerShell. When you think in objects, not text, probe scripts become simple and the JSON output becomes reliable.