[英]How to call a powershell function from a variable
我想创建一个函数来使用参数调用函数并输出被调用函数的结果。
工作代码:
$MockDataPath = 'C:\temp'
$MockDataFunctionName = 'Get-SomeFunction'
$Results = Get-SomeFunction -Parameter1 'SomeParameter'
$Results | Export-CliXML "$MockDataPath\$MockDataFunctionName.xml"
我想做什么:第一个$Results =
行是我遇到问题的地方。 我知道它不起作用,但是我一直无法在线找到解决方案。 我也不确定$MockFunctionParameters
是否是传递参数的正确方法。
Function Get-MockedData {
[CmdletBinding()]
param(
[Parameter(
Position = 0,
Mandatory = $true,
ValueFromPipelineByPropertyName = $true,
HelpMessage = "Enter the name of the function you want to get mock data from. Ex: Get-GenericCredential")]
[ValidateNotNullOrEmpty()]
[string]
$MockFunctionName,
[Parameter(
Mandatory = $false,
ValueFromPipelineByPropertyName = $true,
HelpMessage = "Enter the parameters of the function you want to get mock data from. Ex: '-Parameter1 SomeParameter'")]
[ValidateNotNullOrEmpty()]
[string]
$MockFunctionParameters,
[Parameter(
Mandatory = $false,
ValueFromPipelineByPropertyName = $true,
HelpMessage = "Enter the directory you want the mocked data to appear. Default: 'C:\temp'")]
[ValidateNotNullOrEmpty()]
[string]
$MockDataOutputPath = 'C:\temp'
)
$Results = $MockFunctionName $MockFunctionParameters
$Results | Export-Clixml "$MockDataOutputPath\$MockDataFunctionName.xml"
}
您将需要使用Splatting而不是将参数作为字符串传递。 因此,您可以将其称为Get-MockedData -MockFunctionName <name> -MockFunctionParameters @{Parameter1 = "SomeParameter}
然后,使用&
调用$Result
的函数。
$Results = &$MockFunctionName @MockFunctionParameters
Bruce Payette指出, Invoke-Expression
被认为是有害的(在这种情况下,可能会导致注入,因为您传递了任意参数和函数)。
或者,您可以使用DynamicParameters,并实际上使它包含原始函数的参数(这仍然可以像上面那样使用Splatting,但在交互使用时也可以提供更清晰的功能)。
它没有完整的功能,但确实提供了参数的制表符补全功能(尽管有一些问题,例如get-content
不显示-path
但将-pa<tab>
-path
到-path
),尽管它并不总是提供以下功能: ValidationSet
(它在自定义函数上有效,但在New-Item -itemtype
上失败,因此内置命令可能会出现此问题)。 它不需要-MockFunctionParameters
因为可以直接将这些参数( $splat = @{path = "test.xml"}
) Get-MockedData get-content @splat
到函数调用Get-MockedData get-content @splat
。
function Get-MockedData {
[cmdletbinding()]
param(
[Parameter(
Position = 0,
Mandatory = $true,
ValueFromPipelineByPropertyName = $true,
HelpMessage = "Enter the name of the function you want to get mock data from. Ex: Get-GenericCredential")]
[ValidateNotNullOrEmpty()]
[ValidateScript( {Get-Command $_})]
[string]
$MockFunctionName,
[Parameter(
Mandatory = $false,
ValueFromPipelineByPropertyName = $true,
HelpMessage = "Enter the directory you want the mocked data to appear. Default: 'C:\temp'")]
[ValidateNotNullOrEmpty()]
[string]
$MockDataOutputPath = 'C:\temp'
)
DynamicParam {
if ($MockFunctionName) {
$base = get-command $MockFunctionName -ErrorAction SilentlyContinue
}
if ($base) {
$dict = new-object System.Management.Automation.RuntimeDefinedParameterDictionary
$base.Parameters.GetEnumerator() | ForEach-Object {
$val = $_.value
$key = $_.key
if ($key -notin [System.Management.Automation.Internal.CommonParameters].GetProperties().name) {
$param = New-Object System.Management.Automation.RuntimeDefinedParameter($key, $val.parameterType, $val.attributes)
$dict.add($key, $param)
}
}
return $dict
}
}
Begin {
# Get a list of own parameters to exclude later
$self = Get-Command Get-MockedData
$selfParams = $self.parameters.keys | Where-Object {
$_ -notin [System.Management.Automation.Internal.CommonParameters].GetProperties().name -and
-not $self.parameters.$_.isdynamic
}
}
Process {
# Hashtable to hold valid parameters
$splatParams = @{}
# Remove own parameters
$psboundparameters.keys | where-object {$_ -notin $selfParams} | ForEach-Object {
$splatParams.add($_, $psboundparameters[$_])
}
$results = &$MockFunctionName @splatParams
$Results | Export-Clixml "$MockDataOutputPath\$MockDataFunctionName.xml"
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.