I have a script that calls other scripts that other people manage. It's essentially a CI/CD script that gives users the ability to tap into the pipeline.
The issue I'm running into now is that I would like this calling script to implement a couple new parameters. However, the old scripts don't always implement those parameters.
If I call their script that doesn't implement the parameters, I get an error "A parameter cannot be found that matches parameter name 'newparameter'".
Is there a way to dynamically pass in a parameter so that it doesn't fail if the parameter doesn't exist? I don't mind if they don't implement it. It's a bonus parameter that they don't need to use.
Alternately, can I do something like a Get-Command for a custom .ps1 script, to get a list of accepted parameters? With that, I could confirm that a parameter is implemented before I pass it.
CodePudding user response:
This might help you get started, you could use the Parser Class to get all functions and it's parameters from a script, this answer shows a minimal reproduction. I'll leave it to you to investigate further.
Given myScript.ps1
that has these 3 functions:
function ExampleFunc {
param([int] $param1 = 123, [string] $param2)
}
function ExampleFunc2 {
param([object] $param3, [switch] $param4)
}
function ExampleFunc3 ($param4, $param5) {
}
You can use the parser's ParseFile
Method to get the AST, then you can use the .FindAll
method to filter for all FunctionDefinitionAst.
using namespace System.Management.Automation.Language
$ast = [Parser]::ParseFile('fullpath\to\myScript.ps1', [ref] $null, [ref] $null)
$ast.FindAll({ $args[0] -is [FunctionDefinitionAst] }, $true) | ForEach-Object {
$funcName = $_.Name
if($_.Parameters) {
return $_.Parameters | Select-Object @{N='Function'; E={ $funcName }}, *
}
$_.Body.ParamBlock.Parameters | Select-Object @{N='Function'; E={ $funcName }}, *
} | Format-Table
Above code would result in the following for myScript.ps1
:
Function Attributes Name DefaultValue StaticType Extent Parent
-------- ---------- ---- ------------ ---------- ------ ------
ExampleFunc {int} $param1 123 System.Int32 [int] $param1 = 123 param([int]...
ExampleFunc {string} $param2 System.String [string] $param2 param([int]...
ExampleFunc2 {object} $param3 System.Object [object] $param3 param([obje...
ExampleFunc2 {switch} $param4 System.Management.Automation.SwitchParameter [switch] $param4 param([obje...
ExampleFunc3 {} $param4 System.Object $param4 function Ex...
ExampleFunc3 {} $param5 System.Object $param5 function Ex...
The same could be accomplished using Get-Command
too:
(Get-Command 'fullpath\to\myScript.ps1').ScriptBlock.Ast.FindAll({
# same syntax as before