Resources/Samples/Script-Complex.ps1
|
#requires -version 5 <# .SYNOPSIS Complex PowerShell script with advanced features and proper structure. .DESCRIPTION This script demonstrates complex PowerShell patterns including begin/process/end blocks, comprehensive error handling, pipeline support, and advanced parameter validation. .PARAMETER InputObject Objects to process via pipeline or direct parameter input. .PARAMETER Path File or directory path for processing. .PARAMETER Action The action to perform on the input objects. .PARAMETER Force Forces the operation without confirmation prompts. .PARAMETER WhatIf Shows what would happen without actually performing the operation. .INPUTS Objects can be piped to this script for processing. .OUTPUTS PSCustomObject containing processing results and status information. .NOTES Version: 1.0 Author: Your Name Creation Date: $(Get-Date -Format 'yyyy-MM-dd') Purpose/Change: Initial complex script development .EXAMPLE .\ScriptName.ps1 -Path "C:\Data" -Action "Process" Processes files in the specified directory. .EXAMPLE Get-ChildItem "C:\Data" | .\ScriptName.ps1 -Action "Validate" -Verbose Processes piped objects with verbose output. .LINK Related documentation or resources #> #region Script Parameters [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Path')] param ( [Parameter(Mandatory = $false, Position = 0, ValueFromPipeline = $true, ParameterSetName = 'Pipeline')] [ValidateNotNull()] [object[]]$InputObject, [Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'Path')] [ValidateScript({ if (-not (Test-Path $_)) { throw "Path '$_' does not exist." } return $true })] [string]$Path, [Parameter(Mandatory = $false)] [ValidateSet('Process', 'Validate', 'Report', 'Cleanup')] [string]$Action = 'Process', [Parameter(Mandatory = $false)] [switch]$Force ) #endregion Script Parameters begin { #region Initialization Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $ProgressPreference = 'Continue' Write-Debug "Script started at $(Get-Date)" Write-Verbose "Parameter Set: $($PSCmdlet.ParameterSetName)" Write-Verbose "Action: $Action" # Initialize counters and collections $processedCount = 0 $errorCount = 0 $results = [System.Collections.Generic.List[PSCustomObject]]::new() # Validate prerequisites try { Write-Verbose "Validating script prerequisites..." # Add any required validation here if ($PSCmdlet.ParameterSetName -eq 'Path') { Write-Verbose "Validating path: $Path" if (-not (Test-Path $Path)) { throw "Specified path does not exist: $Path" } } Write-Verbose "Prerequisites validated successfully" } catch { Write-Error "Prerequisites validation failed: $($_.Exception.Message)" exit 1 } #endregion Initialization } process { try { Write-Debug "Processing block started" # Determine input source $itemsToProcess = switch ($PSCmdlet.ParameterSetName) { 'Pipeline' { Write-Verbose "Processing pipeline input" $InputObject } 'Path' { Write-Verbose "Processing path input: $Path" Get-ChildItem -Path $Path -ErrorAction Stop } } # Process each item foreach ($item in $itemsToProcess) { try { Write-Debug "Processing item: $($item.Name ?? $item.ToString())" # Construct operation description for ShouldProcess $target = $item.Name ?? $item.ToString() $operation = "Perform $Action operation" if ($PSCmdlet.ShouldProcess($target, $operation)) { # Main processing logic based on action $result = switch ($Action) { 'Process' { Write-Verbose "Processing item: $target" [PSCustomObject]@{ Item = $target Action = $Action Status = 'Processed' Timestamp = Get-Date Details = "Successfully processed $target" } } 'Validate' { Write-Verbose "Validating item: $target" $isValid = $true # Add validation logic here [PSCustomObject]@{ Item = $target Action = $Action Status = if ($isValid) { 'Valid' } else { 'Invalid' } Timestamp = Get-Date Details = "Validation completed for $target" } } 'Report' { Write-Verbose "Reporting on item: $target" [PSCustomObject]@{ Item = $target Action = $Action Status = 'Reported' Timestamp = Get-Date Details = "Report generated for $target" } } 'Cleanup' { Write-Verbose "Cleaning up item: $target" if ($Force -or $PSCmdlet.ShouldContinue("Clean up $target?", "Confirm Cleanup")) { [PSCustomObject]@{ Item = $target Action = $Action Status = 'Cleaned' Timestamp = Get-Date Details = "Cleanup completed for $target" } } else { [PSCustomObject]@{ Item = $target Action = $Action Status = 'Skipped' Timestamp = Get-Date Details = "Cleanup skipped for $target" } } } } # Add result to collection and output $results.Add($result) Write-Output $result $processedCount++ # Update progress if ($itemsToProcess.Count -gt 1) { $percentComplete = [math]::Round(($processedCount / $itemsToProcess.Count) * 100, 2) Write-Progress -Activity "Processing Items" -Status "Processed $processedCount of $($itemsToProcess.Count)" -PercentComplete $percentComplete } } else { Write-Verbose "Operation cancelled by user for: $target" } } catch { $errorCount++ $errorResult = [PSCustomObject]@{ Item = $item.Name ?? $item.ToString() Action = $Action Status = 'Error' Timestamp = Get-Date Details = "Error: $($_.Exception.Message)" } $results.Add($errorResult) Write-Error "Failed to process item '$($item.Name ?? $item.ToString())': $($_.Exception.Message)" # Continue processing other items unless in strict mode if ($ErrorActionPreference -eq 'Stop') { throw } } } } |