Powershell 如何以正确的参数类型返回参数的默认值?
下面的代码将检索函数或脚本文件中使用的参数的默认值:Powershell 如何以正确的参数类型返回参数的默认值?,powershell,Powershell,下面的代码将检索函数或脚本文件中使用的参数的默认值: Function Get-DefaultParameterValuesHC { [OutputType([hashtable])] Param ( [Parameter(Mandatory)] [String]$Path ) $ast = (Get-Command $Path).ScriptBlock.Ast $selectParams = @{ Pro
Function Get-DefaultParameterValuesHC {
[OutputType([hashtable])]
Param (
[Parameter(Mandatory)]
[String]$Path
)
$ast = (Get-Command $Path).ScriptBlock.Ast
$selectParams = @{
Property = @{
Name = 'Name';
Expression = { $_.Name.VariablePath.UserPath }
},
@{
Name = 'Value';
Expression = {
if ($_.DefaultValue.StaticType.IsArray) {
$_.DefaultValue.SubExpression.Statements.PipelineElements.Expression.Elements.Extent.Text
}
else {
if ($_.DefaultValue.Value) { $_.DefaultValue.Value }
else { $_.DefaultValue.Extent.Text }
}
}
}
}
$result = @{ }
$defaultValueParameters = @($ast.FindAll( {
$args[0] -is [System.Management.Automation.Language.ParameterAst] } ,
$true) | Where-Object { $_.DefaultValue } |
Select-Object @selectParams)
foreach ($d in $defaultValueParameters) {
$result[$d.Name] = foreach ($value in $d.Value) {
# Convert '$env:' variables
$ExecutionContext.InvokeCommand.ExpandString($value) -replace
"^`"|`"$|'$|^'"
}
}
$result
}
但是,所有值的类型均为string
。如何才能使它们具有正确的类型?下面的示例说明了哈希表作为字符串返回的问题
Function Test-Function {
Param (
[String]$ScriptName = 'Get printers',
[HashTable]$Settings = @{ Duplex = 'Yes'}
)
}
Get-DefaultParameterValuesHC -Path 'Test-Function'
# Output:
Name Value
---- -----
ScriptName 'Get printers'
PaperSize '@{ Duplex = 'Yes'}' # String not hashTable
但只有当它不是一种表达时,它才起作用。有没有办法让它也适用于哈希表?首先,可以通过以下方式直接提取参数:
$ast.Body.ParamBlock.Parameters
在这种情况下不需要FindAll()
实现这一点的一种快速而肮脏的方法是让Select Object
参数splat返回文本表示,而不管数据类型如何,并在处理结果时使用该方法对其进行解析:
Name = 'Value';
Expression = {
$_.DefaultValue.Extent.Text
}
请注意,InvokeScript()
将执行传递给它的任何字符串。因此,与调用表达式
一样,无论何时使用,都要小心。例如,如果Test Function
在其param()
块中有此项:
[String]$ScriptName = (& cmd /c "echo This ran >%USERPROFILE%\Desktop\OhNo.txt"),
如上所述运行分析函数将运行cmd
并编写一个文件,即使它没有显式调用目标函数。因此,将此方法用于运行param()
块中命令的函数是有风险的。有必要递归地查看每个DefaultValue
的Pipeline
和SubExpression
属性,以过滤掉不应该解析的任何内容
可以根据每个
DefaultValue
的属性识别大多数类型,并自定义每个数据类型的行为以重新创建原始对象。与问题中的代码已经将数组与其他类型区分开来的方式类似,精致的类型处理是迄今为止最安全的方法。感谢您提供的帮助和见解。需要注意的是,$ast.Body.ParamBlock.Parameters
仅适用于函数,而$ast.ParamBlock.Parameters
仅适用于脚本文件。因此,我们仍然必须坚持使用FindAll()
以获得一致的方法`不客气Get命令
返回扩展脚本、函数等的不同类型的CommandInfo。它们都有一个属性CommandType
,可用于决定选择哪个分支。我用switch语句试过了。
[String]$ScriptName = (& cmd /c "echo This ran >%USERPROFILE%\Desktop\OhNo.txt"),