如何从变量

时间:2018-04-04 18:28:24

标签: xml function powershell

我想创建一个函数来调用带参数的函数并输出被调用函数的结果。

工作代码:

$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"
}

2 个答案:

答案 0 :(得分:0)

您将需要使用Splatting而不是将参数作为字符串传递。因此,您将其称为$Result

然后使用&$Results = &$MockFunctionName @MockFunctionParameters 中调用该函数。

Invoke-Expression

Bruce Payette指出get-content被认为是有害的(在这种情况下可能导致注射,因为你传递了任意参数和函数)。

或者,您可以使用DynamicParameters,实际上它包含原始函数中的参数(如上所述仍可使用splatting,但在交互使用时也允许更清晰的功能)。

它没有完整的功能,但确实为参数提供了标签完成功能(它有一些问题,例如-path没有显示-pa<tab>,而是-path完成ValidationSet虽然它不会总是提供New-Item -itemtype的标签完成(它适用于自定义函数但在-MockFunctionParameters上失败,因此它可能是内置命令的问题)。它不需要$splat = @{path = "test.xml"},因为这些参数可以直接打印到函数调用Get-MockedData get-content @splat中。{/ p>

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"
    }
}

答案 1 :(得分:0)

您需要使用调用运算符&来间接调用函数。在函数的倒数第二行放置'&amp;'在$MockFunctionName之前,如

  $Results = & $MockFunctionName $MockFunctionParameters

参数比较棘手 - 你应该看一下splatting来看看如何传递参数。

最后,您可能希望了解Pester处理mocking的方式。