Powershell:检查、使用和传递参数?

标签 powershell

我有一个脚本(我们称之为 caller.ps1),它调用另一个脚本 callee.ps1。在 caller.ps1 中,我想检查一些参数并将它们与其他一些参数一起传递给 callee.ps1

caller:

param (
[Parameter(Mandatory, ParameterSetName="ByA")][string]$a, // passthru
[Parameter(Mandatory, ParameterSetName="ByB")][string]$b, // passthru
// some more passthru parameters
[Parameter()][switch]$inspect,  // inspect, then pass on
[Parameter()][switch]$consume   // consume, do not pass on
)
callee:

param (
[Parameter(Mandatory, ParameterSetName="ByA")][string]$a,
[Parameter(Mandatory, ParameterSetName="ByB")][string]$b,
// some more parameters
[Parameter()][switch]$inspect
)

这里的最佳实践是什么?我已经尝试过 @args 但它看起来是空的。我想那是因为所有参数都绑定(bind)到名称?

由于我有两个参数集“ByA”和“ByB”,以及一堆开关参数,因此检查每个参数集并为被调用者编写一个新的参数列表会非常笨重。有没有一种优雅的方法来做到这一点?谢谢。

最佳答案

automatic variable $PSBoundParameters在这种情况下非常有用,只要被调用者的参数名称具有相同的名称或具有 aliases ,它就允许您将相同的参数传递到下一个脚本 block 。与调用者的匹配。

使用2个脚本 block 进行演示,但逻辑与2个.ps1文件完全相同。

$caller = {
    param (
        [Parameter(Mandatory, ParameterSetName="ByA")]
        [string] $a,

        [Parameter(Mandatory, ParameterSetName="ByB")]
        [string] $b,

        [Parameter()]
        [switch] $inspect,

        [Parameter()]
        [switch] $consume
    )

    # remove the bound parameter before calling the next script
    $null = $PSBoundParameters.Remove('consume')
    # do whatever you need here with `$consume` then
    # call the next script using the bounded parameters
    & $callee @PSBoundParameters
}

$callee = {
    param (
        [Parameter(Mandatory, ParameterSetName="ByA")]
        [string] $a,

        [Parameter(Mandatory, ParameterSetName="ByB")]
        [string] $b,

        [Parameter()]
        [switch] $inspect
    )

    $PSBoundParameters
}

& $caller -a 'hey there' -inspect -consume

至于为什么$args不起作用,正如文档所述, $args 仅适用于未声明的参数,并且您的脚本正在使用 param block (声明的参数),并且不允许未声明的参数,因为这些是advanced scriptblocks / functions从某种意义上说,由于 Parameter attribute declarations .

一个简单的例子来直观地说明这意味着什么:

在此示例中,脚本 block 仅具有 2 个声明的参数和 3 个正在传递的参数,1 和 2 绑定(bind)到声明的参数,3 作为未声明的参数传递,因此绑定(bind)到 $args :

# works fine, outputs 3
& {param($paramA, $paramB) $args } -paramA 1 -paramB 2 3

现在,如果我们尝试对高级脚本 block 执行相同的操作,我们将看到错误,因为它们不允许未声明的参数:

# Fails: A positional parameter cannot be found that accepts argument '3'.
& {[CmdletBinding()]param($paramA, $paramB) $args } -paramA 1 -paramB 2 3

关于Powershell:检查、使用和传递参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74710805/

相关文章:

powershell - Azure PowerShell Set-AzureRmSqlDatabase 挂起/非常慢

powershell - Windows 使用 powershell 安排任务创建问题

windows - Powershell 为局部变量设置环境变量

使用 xPath .SelectSingleNode 的 Powershell 脚本无法从 web.config 文件 xmlns 中提取值

powershell - 使用Powershell编辑多个XML文件

azure - 导出所有 Azure AD 组及其成员 (PowerShell)

powershell - 将 powershell 控制台窗口移动到屏幕左侧的最佳方法是什么?

powershell - PowerShell Copy-Item 中的排除列表似乎不起作用

database - 如何使用PowerShell批量调用Update-Database

由于 Filesystemwatcher,Powershell 挂起