Cyber Intelligence
Capstone Project · Hands-on project

L10. Capstone: Build a Safe Admin Inventory Runbook

Combine the course into a practical runbook that collects system inventory, exports CSV and JSON, handles errors, supports -WhatIf, logs progress, and can run on a schedule.

Project Goal

You will build a safe inventory runbook that collects host, process, service, and disk data. The point is not to gather every possible field. The point is to write automation that is predictable, readable, and safe to run repeatedly.

Requirements

Your script should:

  1. Accept an output directory parameter.
  2. Create the directory if it does not exist.
  3. Collect host metadata.
  4. Export running services to CSV.
  5. Export top processes to CSV.
  6. Export a JSON summary.
  7. Use try/catch with -ErrorAction Stop.
  8. Support -Verbose.
  9. Use SupportsShouldProcess so file-writing commands can honor -WhatIf.

Starter Script

[CmdletBinding(SupportsShouldProcess)]
param(
  [Parameter(Mandatory)]
  [string]$OutputDirectory
)

try { if (-not (Test-Path $OutputDirectory)) { if ($PSCmdlet.ShouldProcess($OutputDirectory, 'Create output directory')) { New-Item -ItemType Directory -Path $OutputDirectory -ErrorAction Stop | Out-Null } }

$summary = [pscustomobject]@{ ComputerName = $env:COMPUTERNAME PowerShell = $PSVersionTable.PSVersion.ToString() OS = $PSVersionTable.OS Timestamp = (Get-Date).ToString('o') }

$servicesPath = Join-Path $OutputDirectory 'running-services.csv' $processesPath = Join-Path $OutputDirectory 'top-processes.csv' $summaryPath = Join-Path $OutputDirectory 'summary.json'

if ($PSCmdlet.ShouldProcess($servicesPath, 'Export running services')) { Get-Service | Where-Object Status -eq 'Running' | Sort-Object DisplayName | Select-Object Name, DisplayName, Status | Export-Csv -Path $servicesPath -NoTypeInformation -ErrorAction Stop }

if ($PSCmdlet.ShouldProcess($processesPath, 'Export top processes')) { Get-Process | Sort-Object CPU -Descending | Select-Object -First 20 Name, Id, CPU, @{ Name = 'MemoryMB'; Expression = { [math]::Round($_.WorkingSet64 / 1MB, 2) } } | Export-Csv -Path $processesPath -NoTypeInformation -ErrorAction Stop }

if ($PSCmdlet.ShouldProcess($summaryPath, 'Export summary JSON')) { $summary | ConvertTo-Json -Depth 4 | Set-Content -Path $summaryPath -Encoding utf8 -ErrorAction Stop }

Write-Verbose 'Inventory runbook completed.' $summary } catch { Write-Error -ErrorRecord $_ exit 1 }

Test Plan

.\Inventory.ps1 -OutputDirectory .\out -WhatIf
.\Inventory.ps1 -OutputDirectory .\out -Verbose
Get-ChildItem .\out
Import-Csv .\out\running-services.csv | Select-Object -First 5
Get-Content .\out\summary.json -Raw | ConvertFrom-Json

Production Hardening

  • Add a transcript or structured log file.
  • Run under a least-privilege service account.
  • Store output in a controlled directory.
  • Sign scripts if your organization requires AllSigned.
  • Add Pester tests for parameter validation and output files.
  • Document how the runbook is scheduled and who owns it.

Final Checklist

By the end of this course, you should be able to explain the object pipeline, inspect objects, export structured data, write functions, handle errors, organize modules, run background work, and reason clearly about PowerShell security controls.

Exam Focus Points
  • A safe runbook is parameterized, idempotent, logged, and testable
  • SupportsShouldProcess enables -WhatIf and -Confirm behavior for changes
  • Use Join-Path for output paths and -ErrorAction Stop for catchable failures
  • Export both machine-readable summary JSON and analyst-friendly CSV reports
  • Production automation needs ownership, least privilege, secret handling, and scheduling documentation
Knowledge Check

1. What does SupportsShouldProcess enable?

2. Which output pattern is best for an inventory runbook?

Recommended: Pluralsight

This free course covers the theory. Pluralsight adds structured video courses, hands-on Azure labs, and timed practice exams to make it stick before exam day.

Start AZ-500 prep free10-day free trial available