Transpilers/Parameters/ValidateScriptBlock.psx.ps1
<# .SYNOPSIS Validates Script Blocks .DESCRIPTION Validates Script Blocks for a number of common scenarios. .EXAMPLE { param( [ValidateScriptBlock(Safe)] [ScriptBlock] $ScriptBlock ) $ScriptBlock } | .>PipeScript .EXAMPLE { param( [ValidateScriptBlock(NoBlock,NoParameters)] [ScriptBlock] $ScriptBlock ) $ScriptBlock } | .>PipeScript .EXAMPLE { param( [ValidateScriptBlock(OnlyParameters)] [ScriptBlock] $ScriptBlock ) $ScriptBlock } | .>PipeScript #> [CmdletBinding(DefaultParameterSetName='Parameter')] param( # If set, will validate that ScriptBlock is "safe". # This will attempt to recreate the Script Block as a datalanguage block and execute it. [Alias('Safe')] [switch] $DataLanguage, # If set, will ensure that the [ScriptBlock] only has parameters [Alias('OnlyParameters')] [switch] $ParameterOnly, # If set, will ensure that the [ScriptBlock] has no named blocks. [Alias('NoBlocks')] [switch] $NoBlock, # If set, will ensure that the [ScriptBlock] has no parameters. [Alias('NoParameters','NoParam')] [switch] $NoParameter, # A VariableExpression. If provided, the Validation attributes will apply to this variable. [Parameter(Mandatory,ValueFromPipeline,ParameterSetName='VariableExpressionAST')] [Management.Automation.Language.VariableExpressionAST] $VariableAST ) process { $validateScripts = @( if ($DataLanguage) { @' [ValidateScript({ if ($_ -isnot [ScriptBlock]) { return $true } $sbCopy = "data { $_ }" try { $dataOutput = & ([ScriptBlock]::Create($sbCopy)) return $true } catch { throw } })] '@ } if ($ParameterOnly) { @' [ValidateScript({ if ($_ -isnot [ScriptBlock]) { return $true } $statementCount = 0 $statementCount += $_.Ast.DynamicParamBlock.Statements.Count $statementCount += $_.Ast.BeginBlock.Statements.Count $statementCount += $_.Ast.ProcessBlock.Statements.Count $statementCount += $_.Ast.EndBlock.Statements.Count if ($statementCount) { throw "ScriptBlock should have no statements" } else { return $true } })] '@ } if ($NoBlock) { @' [ValidateScript({ if ($_ -isnot [ScriptBlock]) { return $true } if ($_.Ast.DynamicParamBlock -or $_.Ast.BeginBlock -or $_.Ast.ProcessBlock) { throw "ScriptBlock should not have any named blocks" } return $true })] '@ } if ($NoParameter) { @' [ValidateScript({ if ($_ -isnot [ScriptBlock]) { return $true } if ($_.Ast.ParamBlock.Parameters.Count) { throw "ScriptBlock should not have parameters" } return $true })] '@ } ) if (-not $validateScripts) { return } [scriptblock]::Create(@" $($validateScripts -join [Environment]::NewLine)$( if ($psCmdlet.ParameterSetName -eq 'Parameter') { 'param()' } else { '$' + $VariableAST.variablePath.ToString() } ) "@.Trim()) } |