如何使用变量参数列表调用Powershell中的函数

时间:2014-06-03 20:39:36

标签: powershell

我有一个带有八个参数的powershell函数。两个是强制性的,两个是相互排斥的。这给了我24个函数调用的排列。

似乎我应该能够根据参数数据的存在来制作一个字符串,然后执行该字符串来调用该函数,但我没有找到解决方案。

这是XML输入,括号[]中的参数是可选的,|表示/或:

<TextInsert TargetFile="" StartString="" [IncludeStartString="True"] [EndString="" [IncludeEndString="True"]] [SourceFile=""|InsertText=""] [IgnoreCase="True"] />

我曾尝试通过将变量连接到调用中来构建函数调用,如下所示:

Function MakeInsertTextFunctionCallI  {
param (
    [System.Xml.XmlElement]$Params
)
$IgnoreCase   = $Params.IgnoreCase
$StartString  = $Params.StartString
$IncludeStart = $Params.IncludeStartString
$EndString    = $Params.EndString
$IncludeEnd   = $Params.IncludeEndString
$TargetFile   = $Params.TargetFile
$InsertText   = $Params.InsertText
$SourceFile   = $Params.SourceFile

# Section A #############################################################
$CmdStr = "InsertText -File $TargetFile -StartString $StartString"

If($IncludeStart) {
    $CmdStr += " -IncludeStartString"
}

If($SourceFile) {
    $CmdStr += " -SourceFile $SourceFile"
} else {
    $CmdStr += " -InsertText $InsertText"
}

If($EndString) {
    $CmdStr += " -EndString $EndString"
    If($IncludeEnd) {
        $CmdStr += " -IncludeEndString"
    }
}

If($IgnoreCase) {
    $CmdStr += " -IgnoreCase"
}

#    $CmdStr
#    & $CmdStr
Invoke-Expression $CmdStr

但我无法让它发挥作用。我尝试了三种调用函数的变体。一些问题涉及参数中的嵌入式引号。另一个问题是我使用它来编辑标记语言文件,因此有很多嵌入的&lt;&gt;“和这样的符号。导致最后一次尝试出现此错误:Invoke-Expression:'&lt;'运营商留作将来使用。

以下代码部分虽然不优雅且不受支持,但确实有效:

# Section B ############################################################
#Possible Parameters
$cTargetFile =   [Convert]::ToInt32("10000000",2) #128
$cStartString =  [Convert]::ToInt32("01000000",2) #64
$cIncludeStart = [Convert]::ToInt32("00100000",2) #32
$cSourceFile =   [Convert]::ToInt32("00010000",2) #16
$cInsertText =   [Convert]::ToInt32("00001000",2) #8
$cEndString =    [Convert]::ToInt32("00000100",2) #4
$cIncludeEnd =   [Convert]::ToInt32("00000010",2) #2
$cIgnoreCase =   [Convert]::ToInt32("00000001",2) #1

$ParamMask = 0
If($IgnoreCase)   { $ParamMask += $cIgnoreCase }
If($StartString)  { $ParamMask += $cStartString }
If($IncludeStart) { $ParamMask += $cIncludeStart }
If($SourceFile)   { $ParamMask += $cSourceFile }
If($InsertText)   { $ParamMask += $cInsertText }
If($EndString)    { $ParamMask += $cEndString }
If($IncludeEnd)   { $ParamMask += $cIncludeEnd }
If($TargetFile)   { $ParamMask += $cTargetFile }

switch($ParamMask) {
    192 { InsertText -File $TargetFile -StartString $StartString -SourceFile $SourceFile }
    193 { InsertText -File $TargetFile -StartString $StartString -SourceFile $SourceFile -IgnoreCase }
    200 { InsertText -File $TargetFile -StartString $StartString -InsertText $InsertText }
    201 { InsertText -File $TargetFile -StartString $StartString -InsertText $InsertText -IgnoreCase }
.
. <some of the 24 permutations removed for brevity>
.
    246 { InsertText -File $TargetFile -StartString $StartString -IncludeStart -EndString $EndString -IncludeEnd -SourceFile $SourceFile }
    247 { InsertText -File $TargetFile -StartString $StartString -IncludeStart -EndString $EndString -IncludeEnd -SourceFile $SourceFile -IgnoreCase }
    238 { InsertText -File $TargetFile -StartString $StartString -IncludeStart -EndString $EndString -IncludeEnd -InsertText $InsertText }
    239 { InsertText -File $TargetFile -StartString $StartString -IncludeStart -EndString $EndString -IncludeEnd -InsertText $InsertText -IgnoreCase }
    Default { #Then log an invalid parameters error}
}

我说B部分是不可支持的,因为如果有人想要在函数中添加另一个参数,计算位掩码并在switch语句中输入所有新的排列将会非常耗时;而不是仅向A部分添加一个连接。

有没有人有任何简化此代码的提示?或者对A部分的批评可能会改善它的可行性?

1 个答案:

答案 0 :(得分:0)

mjolinor提供了答案。哈希喷溅工程。这是最终的工作代码。

$ParamHash = @{}
If($IgnoreCase)   { $ParamHash.Add("-IgnoreCase",$true) }
If($StartString)  { $ParamHash.Add("-StartString","$StartString") }
If($IncludeStart) { $ParamHash.Add("-IncludeStartString",$true) }
If($SourceFile)   { $ParamHash.Add("-SourceFile","$SourceFile") }
If($InsertText)   { $ParamHash.Add("-InsertText","$InsertText") }
If($EndString)    { $ParamHash.Add("-EndString","$EndString") }
If($IncludeEnd)   { $ParamHash.Add("-IncludeEndString",$true) }
If($TargetFile)   { $ParamHash.Add("-File","$TargetFile") }

InsertText @ParamHash

漂亮,整洁,紧凑,可读。谢谢@mjolinor。