繁体   English   中英

如何从变量调用Powershell函数

[英]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"
    }
}

您需要使用调用运算符&间接调用函数。 在函数的第二行中,在$MockFunctionName之前$MockFunctionName '&', $MockFunctionName

  $Results = & $MockFunctionName $MockFunctionParameters

参数是麻烦-有你应该看看泼洒 ,以了解如何传递参数。

最后,您可能想看看Pester如何处理嘲讽

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM