如何在自定义cmdlet中正确使用-verbose和-debug参数

问题描述 投票:39回答:8

默认情况下,具有[CmdletBinding()]属性的任何命名函数都将接受-debug-verbose(以及其他一些参数)参数,并具有预定义的$debug$verbose变量。我试图弄清楚如何将它们传递给在函数中被调用的其他cmdlet。

假设我有一个这样的cmdlet:

function DoStuff() {
   [CmdletBinding()]

   PROCESS {
      new-item Test -type Directory
   }
}

如果将-debug-verbose传递到我的函数中,我想将该标志传递到new-item cmdlet中。正确的做法是什么?

powershell parameters cmdlets cmdlet
8个回答
32
投票

也许听起来很奇怪,但是对于cmdlet而言,没有任何简单的方法来了解其详细或调试模式。看看相关的问题:

How does a cmdlet know when it really should call WriteVerbose()?

一个不完美,但实际上合理的选择是引入您自己的cmdlet参数(例如$MyVerbose$MyDebug),并在代码中明确使用它们:

function DoStuff {
    [CmdletBinding()]
    param
    (
        # Unfortunately, we cannot use Verbose name with CmdletBinding
        [switch]$MyVerbose
    )

    process {

        if ($MyVerbose) {
            # Do verbose stuff
        }

        # Pass $MyVerbose in the cmdlet explicitly
        New-Item Test -Type Directory -Verbose:$MyVerbose
    }
}

DoStuff -MyVerbose

UPDATE

[当我们只需要一个开关(而不是冗长级别值)时,使用$PSBoundParameters的方法可能比该答案的第一部分(带有附加参数)中提出的方法更好:

function DoStuff {
    [CmdletBinding()]
    param()

    process {
        if ($PSBoundParameters['Verbose']) {
            # Do verbose stuff
        }

        New-Item Test -Type Directory -Verbose:($PSBoundParameters['Verbose'] -eq $true)
    }
}

DoStuff -Verbose

反正一切都不完美。如果有更好的解决方案,那么我真的很想认识他们。


34
投票

$PSBoundParameters不是您想要的。 [CmdletBinding()]属性的使用除了提供Verbose标志外,还允许在脚本中使用$PSCmdlet。实际上,您应该使用相同的Verbose。

通过[CmdletBinding()],您可以通过$PSCmdlet.MyInvocation.BoundParameters访问绑定的参数。这是一个使用CmdletBinding的函数,只需立即输入嵌套提示即可检查函数范围内可用的变量。]​​>

PS D:\> function hi { [CmdletBinding()]param([string] $Salutation) $host.EnterNestedPrompt() }; hi -Salutation Yo -Verbose

PS D:\>>> $PSBoundParameters

____________________________________________________________________________________________________
PS D:\>>> $PSCmdlet.MyInvocation.BoundParameters

Key Value                                                                                                                                                                                                           
--- -----                                                                                                                                                                                                           
Salutation Yo                                                                                                                                                                                                              
Verbose   True                                                                                       

因此,在您的示例中,您需要以下内容:

function DoStuff `
{
    [CmdletBinding()]
    param ()
    process
    {
      new-item Test -type Directory `
        -Verbose:($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent -eq $true)
    }
}

这包括-Verbose,-Verbose:$ false,-Verbose:$ true,以及根本不存在该开关的情况。


26
投票

没有必要。如下面的代码所示,PowerShell已执行此操作。


5
投票

这是我的解决方法:


2
投票

您可以根据绑定的调试或详细参数构建一个新的哈希表,然后将其放到内部命令中。如果您只是指定开关(并且没有传递错误的开关,例如$ debug:$ false),则可以检查是否存在debug或verbose:


2
投票

最好的方法是设置$VerbosePreference。这将为整个脚本启用详细级别。不要忘了在脚本末尾禁用它。


1
投票

您可以在启动脚本时将VerbosePreference设置为全局变量,然后在自定义cmdlet中检查全局变量。


0
投票

我认为这是最简单的方法:

© www.soinside.com 2019 - 2024. All rights reserved.