Public/Get-RunbookStatus.ps1
|
function Get-RunbookStatus { <# .SYNOPSIS Retrieves runbook execution status and history. .DESCRIPTION Queries the execution log directory ($env:USERPROFILE\.runbookengine\executions\) for past and current runbook executions. Supports filtering by execution ID, computer name, status, and time range. Returns execution summary objects. .PARAMETER ExecutionId Specific execution ID (GUID) to retrieve. .PARAMETER ComputerName Filter executions by target computer name. .PARAMETER Last Return only the last N executions. .PARAMETER Status Filter by execution status: All, Running, Completed, Failed, Escalated. .PARAMETER Since Return only executions since this datetime. .EXAMPLE Get-RunbookStatus -Last 10 Get the 10 most recent runbook executions. .EXAMPLE Get-RunbookStatus -ComputerName 'SERVER01' -Status Failed Get all failed executions targeting SERVER01. .EXAMPLE Get-RunbookStatus -ExecutionId 'abc12345-...' Get details for a specific execution. .EXAMPLE Get-RunbookStatus -Since (Get-Date).AddHours(-8) -Status Escalated Get all escalated executions from the last 8 hours. #> [CmdletBinding()] param( [Parameter()] [string]$ExecutionId, [Parameter()] [string]$ComputerName, [Parameter()] [int]$Last, [Parameter()] [ValidateSet('All', 'Running', 'Completed', 'Failed', 'Escalated')] [string]$Status = 'All', [Parameter()] [datetime]$Since ) $executionsPath = Join-Path $env:USERPROFILE '.runbookengine\executions' if (-not (Test-Path $executionsPath)) { Write-Verbose "No executions directory found." return @() } # If specific execution ID requested if ($ExecutionId) { $execFile = Join-Path $executionsPath "$ExecutionId.json" if (Test-Path $execFile) { try { $exec = Get-Content -Path $execFile -Raw | ConvertFrom-Json return $exec } catch { Write-Warning "Failed to parse execution file: $_" return $null } } else { # Search by partial ID $matchingFiles = Get-ChildItem -Path $executionsPath -Filter "$ExecutionId*.json" -ErrorAction SilentlyContinue if ($matchingFiles) { $results = foreach ($file in $matchingFiles) { try { Get-Content -Path $file.FullName -Raw | ConvertFrom-Json } catch { Write-Verbose "Failed to parse $($file.Name): $_" } } return $results } Write-Warning "Execution not found: $ExecutionId" return $null } } # Load all execution files $executionFiles = Get-ChildItem -Path $executionsPath -Filter '*.json' -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending if (-not $executionFiles -or $executionFiles.Count -eq 0) { Write-Verbose "No execution records found." return @() } $executions = foreach ($file in $executionFiles) { try { $exec = Get-Content -Path $file.FullName -Raw | ConvertFrom-Json -ErrorAction Stop # Create summary object $stepCount = if ($exec.StepResults) { @($exec.StepResults).Count } else { 0 } $failedSteps = if ($exec.StepResults) { @($exec.StepResults | Where-Object { $_.Status -eq 'Failed' }).Count } else { 0 } $exec | Add-Member -NotePropertyName 'StepCount' -NotePropertyValue $stepCount -Force $exec | Add-Member -NotePropertyName 'FailedStepCount' -NotePropertyValue $failedSteps -Force $exec | Add-Member -NotePropertyName '_FileTime' -NotePropertyValue $file.LastWriteTime -Force $exec } catch { Write-Verbose "Failed to parse execution file $($file.Name): $_" } } # Apply filters if ($ComputerName) { $executions = $executions | Where-Object { $_.ComputerName -eq $ComputerName -or ($_.Parameters -and $_.Parameters.ComputerName -eq $ComputerName) } } if ($Status -ne 'All') { $executions = $executions | Where-Object { $_.Status -eq $Status } } if ($Since) { $executions = $executions | Where-Object { $execTime = if ($_.StartTime) { try { [DateTime]::Parse($_.StartTime) } catch { $null } } else { $_._FileTime } $execTime -and $execTime -ge $Since } } # Sort by start time descending $executions = $executions | Sort-Object { if ($_.StartTime) { try { [DateTime]::Parse($_.StartTime) } catch { [DateTime]::MinValue } } else { $_._FileTime } } -Descending # Apply Last limit if ($Last -and $Last -gt 0) { $executions = $executions | Select-Object -First $Last } # Return summary objects $executions | ForEach-Object { [PSCustomObject]@{ ExecutionId = $_.ExecutionId RunbookName = $_.RunbookName ComputerName = $_.ComputerName Status = $_.Status StartTime = $_.StartTime EndTime = $_.EndTime Duration = $_.Duration StepCount = $_.StepCount FailedSteps = $_.FailedStepCount WhatIf = $_.WhatIf StepResults = $_.StepResults ApprovalLog = $_.ApprovalLog VerificationResults = $_.VerificationResults Correlations = $_.Correlations } } } |