src/public/Orchestration/Get-AitherPlaybook.ps1
|
#Requires -Version 7.0 <# .SYNOPSIS Get playbook definitions and information .DESCRIPTION Retrieves playbook definitions from the playbooks directory. Can list all playbooks, get a specific playbook, or search playbooks. Playbooks define automation workflows including scripts, execution order, dependencies, and success criteria. This cmdlet helps discover and load playbooks for execution or inspection. .PARAMETER Name Name of the playbook to retrieve (without extension). This parameter is REQUIRED when using the Get parameter set. The playbook file must exist in the playbooks directory. Examples: - "test-orchestration" - "pr-validation" - "deployment" The name should match the playbook file name (without .psd1 extension). .PARAMETER List List all available playbooks. This is the default behavior if no parameters are provided. Returns a summary of all playbooks with their names, descriptions, and versions. Use this to discover available playbooks or verify playbook availability. .PARAMETER Search Search playbooks by name or description. Uses pattern matching to find playbooks containing the search term. Case-insensitive search. Examples: - "validation" - Finds playbooks with "validation" in name or description - "test" - Finds all test-related playbooks - "deploy" - Finds deployment playbooks .PARAMETER Path Return only the file path to the playbook instead of loading its contents. Useful when you need the file path for other operations or file manipulation. Returns the full path to the playbook file (e.g., "C:\...\library\playbooks\playbook.psd1"). .INPUTS System.String You can pipe playbook names to Get-AitherPlaybook. .OUTPUTS PSCustomObject Returns playbook objects with properties: - Name: Playbook name - Description: Playbook description - Version: Playbook version - Path: File path (when -List or -Search) - FileName: File name (when -List or -Search) When -Path is used, returns System.String (the file path). When a specific playbook is retrieved, returns the full playbook hashtable. .EXAMPLE Get-AitherPlaybook -List Lists all available playbooks with their basic information. .EXAMPLE $playbook = Get-AitherPlaybook -Name 'test-orchestration' Loads a specific playbook and stores it in a variable for execution. .EXAMPLE Get-AitherPlaybook -Search 'validation' Searches for playbooks containing "validation" in their name or description. .EXAMPLE Get-AitherPlaybook -Name 'deployment' -Path Gets only the file path to the deployment playbook. .EXAMPLE "test-orchestration", "pr-validation" | Get-AitherPlaybook Gets multiple playbooks by piping playbook names. .EXAMPLE $playbook = Get-AitherPlaybook -Name 'deployment' $playbook.Scripts Loads a playbook and inspects its scripts property. .NOTES Playbooks are stored in library/playbooks/ directory as PowerShell Data (.psd1) files. Each playbook file contains a hashtable defining: - Name: Playbook identifier - Description: What the playbook does - Version: Playbook version - Scripts: Array of scripts to execute - ExecutionMode: Parallel, Sequential, or Mixed - Dependencies: Script dependencies - SuccessCriteria: What constitutes success Playbooks can be created manually or using New-AitherPlaybook and Save-AitherPlaybook. .LINK Invoke-AitherPlaybook Save-AitherPlaybook New-AitherPlaybook #> function Get-AitherPlaybook { [OutputType([PSCustomObject], [Hashtable], [System.String])] [CmdletBinding(DefaultParameterSetName = 'List')] param( [Parameter(ParameterSetName = 'Get', Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName, HelpMessage = "Name of the playbook to retrieve (e.g., 'pr-validation').")] [ValidateNotNullOrEmpty()] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) if (Get-Command Get-AitherPlaybook -ErrorAction SilentlyContinue) { Get-AitherPlaybook -List | Where-Object { $_.Name -like "$wordToComplete*" } | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Description) } } })] [string]$Name, [Parameter(ParameterSetName = 'List', HelpMessage = "List all available playbooks.")] [switch]$List, [Parameter(ParameterSetName = 'Search', HelpMessage = "Search playbooks by name or description.")] [string]$Search, [Parameter(ParameterSetName = 'Get', HelpMessage = "Return only the file path to the playbook.")] [switch]$Path, [switch]$ShowOutput ) begin { # Save original log targets $originalLogTargets = $script:AitherLogTargets # Set log targets based on ShowOutput parameter if ($ShowOutput) { # Ensure Console is in the log targets if ($script:AitherLogTargets -notcontains 'Console') { $script:AitherLogTargets += 'Console' } } else { # Remove Console from log targets if present (default behavior) if ($script:AitherLogTargets -contains 'Console') { $script:AitherLogTargets = $script:AitherLogTargets | Where-Object { $_ -ne 'Console' } } } # Use environment variable set by module initialization instead of calling private function $moduleRoot = if ($env:AITHERZERO_ROOT) { $env:AITHERZERO_ROOT } else { Split-Path (Split-Path $PSScriptRoot -Parent) -Parent } $playbooksPath = Join-Path $moduleRoot 'AitherZero' 'library' 'playbooks' } process { try { try { if (-not (Test-Path $playbooksPath)) { Write-AitherLog -Level Warning -Message "Playbooks directory not found: $playbooksPath" -Source 'Get-AitherPlaybook' return @() } $playbooks = Get-ChildItem -Path $playbooksPath -Filter '*.psd1' -ErrorAction SilentlyContinue # List all playbooks if ($List -or $PSCmdlet.ParameterSetName -eq 'List') { return $playbooks | ForEach-Object { try { $content = Get-Content $_.FullName -Raw $scriptBlock = [scriptblock]::Create($content) $playbook = & $scriptBlock [PSCustomObject]@{ Name = $playbook.Name Description = $playbook.Description Version = $playbook.Version Path = $_.FullName FileName = $_.Name } } catch { [PSCustomObject]@{ Name = $_.BaseName Description = "Error loading playbook" Version = $null Path = $_.FullName FileName = $_.Name } } } } # Search playbooks if ($Search) { return $playbooks | ForEach-Object { try { $content = Get-Content $_.FullName -Raw $scriptBlock = [scriptblock]::Create($content) $playbook = & $scriptBlock $searchText = "$($playbook.Name) $($playbook.Description)" -replace '-', ' ' if ($searchText -match $Search) { [PSCustomObject]@{ Name = $playbook.Name Description = $playbook.Description Version = $playbook.Version Path = $_.FullName FileName = $_.Name } } } catch { # Skip playbooks that can't be loaded } } | Where-Object { $_ } } # Get specific playbook if ($Name) { $playbookFile = $playbooks | Where-Object { $_.BaseName -eq $Name -or $_.BaseName -like "*$Name*" } | Select-Object -First 1 if (-not $playbookFile) { throw "Playbook not found: $Name" } if ($Path) { return $playbookFile.FullName } $content = Get-Content $playbookFile.FullName -Raw $scriptBlock = [scriptblock]::Create($content) return & $scriptBlock } } catch { Invoke-AitherErrorHandler -ErrorRecord $_ -Operation "Getting playbook: $Name" -Parameters $PSBoundParameters -ThrowOnError } } finally { # Restore original log targets $script:AitherLogTargets = $originalLogTargets } } } |