[cmdletbinding()] Param( [Parameter( Mandatory= $true )] [ValidateScript({Test-Path $_ -PathType Leaf})] [string]$Path ) begin { $system_types = @('Parameter','ValidatePattern','ValidateScript','ValidateSet') } process { $script_path_raw = Get-Item $Path $script_name = $script_path_raw.Name $script_path = $script_path_raw | Select-Object -ExpandProperty FullName $parse_errors = @() $AST = [System.Management.Automation.Language.Parser]::ParseFile($script_path, [ref]$null, [ref]$parse_errors) if($null -eq $AST.ParamBlock) { throw "No 'Param(...)' block found: $($Path)" } $parameters = @() foreach($param in $AST.ParamBlock.Parameters) { $param_name = $param.Name.Extent.Text $param_type = $null $param_mandatory = $false $param_parameters = @() $param_validations = @() foreach($attr in $param.Attributes) { if($system_types -contains $attr.TypeName.Name) { switch -Wildcard ($attr.TypeName.Name) { "Parameter" { foreach($named_argument in $attr.NamedArguments) { if($named_argument.ArgumentName -eq 'Mandatory') { $param_mandatory = $named_argument.Argument.Extent.Text -eq '$true' } else { $param_parameters += [pscustomobject]@{ name = $named_argument.ArgumentName value = $named_argument.Argument.Extent.Text } } } } "Validate*" { foreach($positional_argument in $attr.PositionalArguments) { if($positional_argument.ScriptBlock) { $value = $positional_argument.ScriptBlock.Extent.Text } else { $value = $positional_argument.Value } $param_validations += [pscustomobject]@{ name = $attr.TypeName.Name value = $value } } } } } else { if($attr.Extent.Text -like '`[*`]') { if($param_type -ne $null) { Write-Warning "Multiple Types found for Parameter: $($attr.TypeName.Name) ($($Path))" continue } $param_type = $attr.TypeName.Name } } } $parameters += [pscustomobject]@{ name = $param_name type = $param_type mandatory = $param_mandatory arguments = $param_parameters validations = $param_validations } } return [pscustomobject]@{ name = $script_name path = $script_path parameters = $parameters } }