Public/Common/Invoke-FixStep.ps1
|
function Invoke-FixStep { <# .SYNOPSIS Runs a named runbook step once, with optional verification, recording completion in a checkpoint file so re-running the runbook skips steps that already succeeded. .DESCRIPTION Designed for fix.ps1-style runbooks that must be executed a bit at a time against a live collection. Each step is a scriptblock; when it completes (and the optional -Verify scriptblock passes) the step name and timestamp are written to the checkpoint JSON. Running the same step again reports SKIP unless -Force is passed, so the whole runbook can be re-run top-to-bottom safely after a partial pass. A -Verify scriptblock fails the step if it throws or returns $false; the checkpoint is only written after verification passes. .EXAMPLE Invoke-FixStep -Name 'myproject-feedback-types' -Action { Install-FeedbackWorkItemTypes -Project 'MyProject' -TypeDefinitionsPath $agileTypeDefinitions } -Verify { (Get-WitWorkItemType -Project 'MyProject') -contains 'Feedback Request' } #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Name, [Parameter(Mandatory)] [scriptblock]$Action, [scriptblock]$Verify, [string]$CheckpointPath = '.\fix-steps.checkpoint.json', [switch]$Force ) $checkpoints = @{} if (Test-Path -LiteralPath $CheckpointPath -PathType Leaf) { $json = Get-Content -LiteralPath $CheckpointPath -Raw | ConvertFrom-Json foreach ($property in $json.PSObject.Properties) { $checkpoints[$property.Name] = $property.Value } } if (-not $Force -and $checkpoints.ContainsKey($Name)) { Write-FixStep "SKIP '$Name' - completed $($checkpoints[$Name]) (use -Force to re-run)" return } Write-FixStep "STEP '$Name' starting" & $Action if ($Verify) { Write-FixStep "STEP '$Name' verifying" $result = & $Verify if ($result -is [bool] -and -not $result) { throw "Step '$Name' failed verification." } Write-FixStep "STEP '$Name' verified" } $checkpoints[$Name] = (Get-Date).ToString('o') $parent = Split-Path -Parent $CheckpointPath if ($parent -and -not (Test-Path -LiteralPath $parent)) { New-Item -ItemType Directory -Path $parent -Force | Out-Null } Set-Content -LiteralPath $CheckpointPath -Value ($checkpoints | ConvertTo-Json) Write-FixStep "STEP '$Name' complete - checkpoint written" } |