通过包含函数名的变量间接调用函数

时间:2017-03-27 16:32:58

标签: powershell parameter-passing indirection

我将XML节点导入变量XmlInstallNode,然后动态构建我想要调用的函数。

如果我直接通过名称调用函数,那么一切都很好,但是如果使用$ functionName在invoke命令中调用它,那么参数-App - 在它应该是System.Xml时转换为字符串。 XmlLinkedNode。我已经尝试使用Invoke-Expressions和Invoke-Command对它进行转换并使用不同的方法但没有成功...

我收到此错误,这有点道理: 无法在参数' App'上处理参数转换。无法转换" $ app" type" System.String"的值输入" System.Xml.XmlElement"

function global:XtrInstall{
try
{
    $error=$false
    XtrLog -Level INFO -FunctionName $MyInvocation.MyCommand -Msg "Installing Apps..."

    XtrLog -Level DEBUG -FunctionName $MyInvocation.MyCommand -Msg "Getting available Apps from config file."
    $XmlInstallNode=XtrGet-XmlInstall

    if($XmlInstallNode.Apps)
    {        
        foreach($app in $XmlInstallNode.apps.app)
        {
            $functionName = "$("XtrInstall-")$($app.Name)"
            XtrLog -Level DEBUG -FunctionName $MyInvocation.MyCommand -Msg "$("Building function name: ")$($functionName)"

            if (Get-Command $functionName -errorAction SilentlyContinue)
            {
                XtrLog -Level DEBUG -FunctionName $MyInvocation.MyCommand -Msg "$("Invoking App Install function ")$($functionName)"
                $command = "$($functionName)$(" -App")"
                $error = Invoke-Command -ScriptBlock { Invoke-Expression -Command $command} -ArgumentList $app                    
            }
            else
            {
                XtrLog -Level FATAL -FunctionName $MyInvocation.MyCommand -Msg "$("App Install Function " )$($functionName)$(" not found. See App name (e.g.'XtrInstall-Aplication')")"
                return $true
            }
        }
    }
    else
    {
        XtrLog -Level WARN -FunctionName $MyInvocation.MyCommand -Msg "No Apps detected in Config file."
        $error=$true
    }
}
catch
{
    XtrLog -Level FATAL -FunctionName $MyInvocation.MyCommand -Msg $_.Exception.Message
    $error=$true
}
return $error
}

我打电话的功能是:

    function global:XtrInstall-Filesite()
    {
    Param(
        [Parameter(Mandatory=$true)]
        [Xml.XmlElement]$App
    )
        //DO STUFF
    }

如何按原样传递参数?

1 个答案:

答案 0 :(得分:1)

无需在字符串中构建(部分)命令并使用Invoke-Expression,甚至Invoke-Command

请尝试以下方法:

$error = & $functionName -App $app                    
  • &,PowerShell的call operator,可用于调用 name 存储在变量中的任何命令。
    • (由于包含空格或其他具有特殊含义的字符,您还需要它来调用具有必须引用的路径的外部实用程序;例如,
      & 'c:\path\to\some folder\some.exe')。