PowerShell Genie

Write structured audit records

Script 2 min read Windows PowerShell 5.1 and PowerShell 7

Documentation: Microsoft Learn

A [pscustomobject] literal captures the timestamp and host name along with the action, status, and message supplied by the caller.

The script

1PS> $Action = "Inventory"
2PS> $Status = "Healthy"
3PS> $Message = "Sample error message"
4PS> $Log = "C:\Logs\audit.csv"
5PS> [pscustomobject]@{Time= Get-Date;Computer= $env:COMPUTERNAME;Action= $Action;Status= $Status;Message= $Message } | Export-Csv $Log -Append -NoTypeInformation

Script reader

Inspect before you run

Inspection only

Inspect the script below. It does not run in this browser.

Inspection only — no command has run.

    Show reference output
    1 Time Computer Action Status Message
    2 ---- -------- ------ ------ -------
    3 9/10/2026 12:00:00 PM SRV01 Inventory Healthy Sample error message
    Inspect this example’s structure

    Read the command and its supplied arguments. This example requires real PowerShell or its module; this diagram does not execute it.

    $Action = "Inventory" $Status = "Healthy" $Message = "Sample error message" $Log = "C:\Logs\audit.csv" [pscustomobject]@{Time= Get-Date;Computer= $env:COMPUTERNAME;Action= $Action;Status= $Status;Message= $Message } | Export-Csv $Log -Append -NoTypeInformation
    1. Stage 1$ActionPositional values or no named parameters
    2. Stage 2Export-Csv-Append -NoTypeInformation

      How it works

      A [pscustomobject] literal captures the timestamp and host name along with the action, status, and message supplied by the caller. Export-Csv with -Append adds the row to the file in $Log, and -NoTypeInformation keeps the type comment out of it.

      Adapting it

      Swap the CSV for ConvertTo-Json piped into Add-Content when the message field can contain commas or line breaks, which CSV handles badly once anything reads the file back.

      Requirements

      Write access to the log path.

      If the result is unexpected

      Structured audit records are unreadable or lose nested fields.

      Serialization depth, mixed console text and inconsistent object shapes can corrupt the intended record format.

      1. Inspect a raw record and confirm the serializer receives only the expected object.

      Validate the result

      A consumer can parse the record and retrieve the required nested fields.

      Keep the check reliable

      Use a versioned record shape and keep diagnostic output separate from serialized data.

      Primary documentation

      Export-Csv reference

      Continue
      Genie guideWrite structured audit records

      A [pscustomobject] literal captures the timestamp and host name along with the action, status, and message supplied by the caller.