简体   繁体   English

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

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

I have two PowerShell scripts, which have switch parameters:我有两个 PowerShell 脚本,它们具有开关参数:

compile-tool1.ps1:编译工具1.ps1:

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

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

compile.ps1:编译.ps1:

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

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

How can I pass a switch parameter to another PowerShell script, without writing big if..then..else or case statements?如何将 switch 参数传递给另一个 PowerShell 脚本,而无需编写大的if..then..elsecase语句?

I don't want to convert the parameter $VHDL2008 of compile-tool1.ps1 to type bool , because, both scripts are front-end scripts (used by users).我不想将compile-tool1.ps1的参数$VHDL2008转换为类型bool ,因为这两个脚本都是前端脚本(由用户使用)。 The latter one is a high-level wrapper for multiple compile-tool*.ps1 scripts.后者是多个compile-tool*.ps1脚本的高级包装器。

You can specify $true or $false on a switch using the colon-syntax :您可以使用冒号语法在开关上指定$true$false

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

So just pass the actual value:所以只需传递实际值:

compile-tool1.ps1 -VHDL2008:$VHDL2008

试试

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

According to a power shell team's blog (link below,) since V2 there is a technique called splatting.根据 power shell 团队的博客(下面的链接),自 V2 以来,有一种称为 splatting 的技术。 Basically, you use the automatic variable @PsBoundParameters to forward all the parameters.基本上,您使用自动变量 @PsBoundParameters 来转发所有参数。 Details about splatting and the difference between @ and $ are explained in the Microsoft Docs article (link below.) Microsoft Docs 文章(下面的链接)中解释了有关 splatting 的详细信息以及 @ 和 $ 之间的区别。

Example:例子:

parent.ps1父母.ps1

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

 Import-Module .\child.psm1     

Call-Child @psBoundParameters
#End of parent.ps1

child.psm1孩子.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

Now we can call the parent script with or without the switch现在我们可以在有或没有开关的情况下调用父脚本

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

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

PS V:\sof\splatting> 

Update更新

In my original answer, I sourced the children instead of importing it as a module.在我的原始答案中,我采购了孩子,而不是将其作为模块导入。 It appears sourcing another script into the original just makes the parent's variables visible to all children so this will also work:似乎将另一个脚本采购到原始脚本中只会使所有子项都可以看到父项的变量,因此这也将起作用:

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

}
#End of child.ps1

with

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

. .\child.ps1    

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

Maybe, this is not the best way to make a program, nevertheless, this is the way it works.也许,这不是制作程序的最佳方式,但是,这就是它的工作方式。

About Splatting(Microsoft Docs) 关于 Splatting (Microsoft Docs)

How and Why to Use Splatting (passing [switch] parameters) 如何以及为什么使用 Splatting(传递 [switch] 参数)

Another solution.另一种解决方案。 If you declare your parameter with a default value of $false:如果您使用默认值 $false 声明参数:

[switch] $VHDL2008 = $false

Then the following (the -VHDL2008 option with no value) will set $VHDL2008 to $true:然后以下(没有值的 -VHDL2008 选项)将 $VHDL2008 设置为 $true:

compile-tool1.ps1 -VHDL2008

If instead you omit the -VHDL2008 option, then this forces $VHDL2008 to use the default $false value:如果您省略 -VHDL2008 选项,则会强制 $VHDL2008 使用默认的 $false 值:

compile-tool1.ps1

These examples are useful when calling a Powershell script from a bat script, as it is tricky to pass a $true/$false bool from bat to Powershell, because the bat will try to convert the bool to a string, resulting in the error:这些示例在从 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.

Assuming you were iterating on development, it is highly likely that at some point you are going to add other switches and parameters to your main script that are going to be passed down to the next called script.假设您正在迭代开发,很可能在某个时候您将向主脚本添加其他开关和参数,这些开关和参数将传递给下一个被调用的脚本。 Using the previous responses, you would have to go find each call and rewrite the line each time you add a parameter.使用之前的响应,您必须查找每个调用并在每次添加参数时重写该行。 In such case, you can avoid the overhead by doing the following,在这种情况下,您可以通过执行以下操作来避免开销,

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

The automatic variable $PSBoundParameters is a hashtable containing the parameters explicitly passed to the script.自动变量$PSBoundParameters是一个哈希表,其中包含显式传递给脚本的参数。

Please note that script.ps1 -SomeSwitch is equivalent to script.ps1 -SomeSwitch $true and script.ps1 is equivalent to script.ps1 -SomeSwitch $false .请注意, script.ps1 -SomeSwitch等价于script.ps1 -SomeSwitch $truescript.ps1等价于script.ps1 -SomeSwitch $false Hence, including the switch set to false is equivalent to not including it.因此,包括设置为 false 的开关相当于不包括它。

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

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