繁体   English   中英

如何将开关参数传递给另一个 PowerShell 脚本?

[英]How to pass a switch parameter to another PowerShell script?

我有两个 PowerShell 脚本,它们具有开关参数:

编译工具1.ps1:

[CmdletBinding()]
param(
  [switch]$VHDL2008
)

Write-Host "VHDL-2008 is enabled: $VHDL2008"

编译.ps1:

[CmdletBinding()]
param(
  [switch]$VHDL2008
)

if (-not $VHDL2008)
{ compile-tool1.ps1            }
else
{ compile-tool1.ps1 -VHDL2008  }

如何将 switch 参数传递给另一个 PowerShell 脚本,而无需编写大的if..then..elsecase语句?

我不想将compile-tool1.ps1的参数$VHDL2008转换为类型bool ,因为这两个脚本都是前端脚本(由用户使用)。 后者是多个compile-tool*.ps1脚本的高级包装器。

您可以使用冒号语法在开关上指定$true$false

compile-tool1.ps1 -VHDL2008:$true
compile-tool1.ps1 -VHDL2008:$false

所以只需传递实际值:

compile-tool1.ps1 -VHDL2008:$VHDL2008

试试

compile-tool1.ps1 -VHDL2008:$VHDL2008.IsPresent 

根据 power shell 团队的博客(下面的链接),自 V2 以来,有一种称为 splatting 的技术。 基本上,您使用自动变量 @PsBoundParameters 来转发所有参数。 Microsoft Docs 文章(下面的链接)中解释了有关 splatting 的详细信息以及 @ 和 $ 之间的区别。

例子:

父母.ps1

#Begin of parent.ps1     
param(
    [Switch] $MySwitch
    )

 Import-Module .\child.psm1     

Call-Child @psBoundParameters
#End of parent.ps1

孩子.psm1

# Begin of child.psm1
function Call-Child {
    param(
        [switch] $MySwitch
    )

    if ($MySwitch){
        Write-Output "`$MySwitch was specified"
    } else {
        Write-Output "`$MySwitch is missing"
    }
}
#End of child.psm1

现在我们可以在有或没有开关的情况下调用父脚本

PS V:\sof\splatting> .\parent.ps1 
$MySwitch is missing

PS V:\sof\splatting> .\parent.ps1 -MySwitch
$MySwitch was specified

PS V:\sof\splatting> 

更新

在我的原始答案中,我采购了孩子,而不是将其作为模块导入。 似乎将另一个脚本采购到原始脚本中只会使所有子项都可以看到父项的变量,因此这也将起作用:

# Begin of child.ps1
function Call-Child {
    if ($MySwitch){
        Write-Output "`$MySwitch was specified"
    } else {
        Write-Output "`$MySwitch is missing"
    }

}
#End of child.ps1

#Begin of parent.ps1     
param(
    [Switch] $MySwitch
    )

. .\child.ps1    

 Call-Child # Not even specifying @psBoundParameters   
#End of parent.ps1

也许,这不是制作程序的最佳方式,但是,这就是它的工作方式。

关于 Splatting (Microsoft Docs)

如何以及为什么使用 Splatting(传递 [switch] 参数)

另一种解决方案。 如果您使用默认值 $false 声明参数:

[switch] $VHDL2008 = $false

然后以下(没有值的 -VHDL2008 选项)将 $VHDL2008 设置为 $true:

compile-tool1.ps1 -VHDL2008

如果您省略 -VHDL2008 选项,则会强制 $VHDL2008 使用默认的 $false 值:

compile-tool1.ps1

这些示例在从 bat 脚本调用 Powershell 脚本时很有用,因为将 $true/$false bool 从 bat 传递到 Powershell 很棘手,因为 bat 会尝试将 bool 转换为字符串,从而导致错误:

Cannot process argument transformation on parameter 'VHDL2008'. 
Cannot convert value "System.String" to type "System.Management.Automation.SwitchParameter". 
Boolean parameters accept only Boolean values and numbers, such as $True, $False, 1 or 0.

假设您正在迭代开发,很可能在某个时候您将向主脚本添加其他开关和参数,这些开关和参数将传递给下一个被调用的脚本。 使用之前的响应,您必须查找每个调用并在每次添加参数时重写该行。 在这种情况下,您可以通过执行以下操作来避免开销,

.\\compile-tool1.ps1 $($PSBoundParameters.GetEnumerator() | ForEach-Object {"-$($_.Key) $($_.Value)"})

自动变量$PSBoundParameters是一个哈希表,其中包含显式传递给脚本的参数。

请注意, script.ps1 -SomeSwitch等价于script.ps1 -SomeSwitch $truescript.ps1等价于script.ps1 -SomeSwitch $false 因此,包括设置为 false 的开关相当于不包括它。

暂无
暂无

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

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