How to properly use the -verbose and -debug parameters in a custom cmdlet

前端 未结 8 669
庸人自扰
庸人自扰 2020-12-13 04:08

By default, any named function that has the [CmdletBinding()] attribute accepts the -debug and -verbose (and a few others) parameters and has the p

相关标签:
8条回答
  • 2020-12-13 04:45

    Here's my solution:

    function DoStuff {
        [CmdletBinding()]
        param ()
    
        BEGIN
        {
            $CMDOUT = @{
                Verbose = If ($PSBoundParameters.Verbose -eq $true) { $true } else { $false };
                Debug = If ($PSBoundParameters.Debug -eq $true) { $true } else { $false }
            }
    
        } # BEGIN ENDS
    
        PROCESS
        {
            New-Item Example -ItemType Directory @CMDOUT
        } # PROCESS ENDS
    
        END
        {
    
        } #END ENDS
    }
    

    What this does different from the other examples is that it will repsect "-Verbose:$false" or "-Debug:$false". It will only set -Verbose/-Debug to $true if you use the following:

    DoStuff -Verbose
    DoStuff -Verbose:$true
    DoStuff -Debug
    DoStuff -Debug:$true
    
    0 讨论(0)
  • 2020-12-13 04:48

    I think this is the easiest way:

    Function Test {
        [CmdletBinding()]
        Param (
            [parameter(Mandatory=$False)]
            [String]$Message
        )
    
        Write-Host "This is INFO message"
    
        if ($PSBoundParameters.debug) {
            Write-Host -fore cyan "This is DEBUG message"
        }
    
        if ($PSBoundParameters.verbose) {
            Write-Host -fore green "This is VERBOSE message"
        }
    
        ""
    }
    Test -Verbose -Debug
    
    0 讨论(0)
  • 2020-12-13 04:49

    $PSBoundParameters isn't what you're looking for. The use of the [CmdletBinding()] attribute allows the usage of $PSCmdlet within your script, in addition to providing a Verbose flag. It is in fact this same Verbose that you're supposed to use.

    Through [CmdletBinding()], you can access the bound parameters through $PSCmdlet.MyInvocation.BoundParameters. Here's a function that uses CmdletBinding and simply enters a nested prompt immediately in order examine the variables available inside the function scope.

    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                                                                                       
    

    So in your example, you would want the following:

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

    This covers -Verbose, -Verbose:$false, -Verbose:$true, and the case where the switch is not present at all.

    0 讨论(0)
  • 2020-12-13 04:50

    You could build a new hash table based on the bound debug or verbose parameters and then splat it to the internal command. If you're just specifying switches (and aren't passing a false switch, like $debug:$false) you can just check for the existence of debug or verbose:

    function DoStuff() { 
       [CmdletBinding()] 
    
       PROCESS { 
            $HT=@{Verbose=$PSBoundParameters.ContainsKey'Verbose');Debug=$PSBoundParameters.ContainsKey('Debug')}
          new-item Test -type Directory @HT
       } 
    } 
    

    If you want to pass the parameter value it's more complicated, but can be done with:

    function DoStuff {  
       [CmdletBinding()]  
       param()
       PROCESS {  
       $v,$d = $null
       if(!$PSBoundParameters.TryGetValue('Verbose',[ref]$v)){$v=$false}
       if(!$PSBoundParameters.TryGetValue('Debug',[ref]$d)){$d=$false}
       $HT=@{Verbose=$v;Debug=$d} 
       new-item Test -type Directory @HT 
       }  
    }  
    
    0 讨论(0)
  • 2020-12-13 04:52

    You can set the VerbosePreference as a global variable on starting your script and then check for the global variable in your custom cmdlet.

    Script:

    $global:VerbosePreference = $VerbosePreference
    Your-CmdLet
    

    Your-CmdLet:

    if ($global:VerbosePreference -eq 'Continue') {
       # verbose code
    }
    

    Checking explicitly for 'Continue' allows the script to be equal to -verbose:$false when you call the CmdLet from a script that doesn't set the global variable (in which case it's $null)

    0 讨论(0)
  • 2020-12-13 04:59

    The best way to do it is by setting the $VerbosePreference. This will enable the verbose level for the entire script. Do not forget to disable it by the end of the script.

    Function test
    {
        [CmdletBinding()]
        param($param1)
    
        if ($psBoundParameters['verbose'])
        {
            $VerbosePreference = "Continue"
            Write-Verbose " Verbose mode is on"
        }
        else
        {
            $VerbosePreference = "SilentlyContinue"
            Write-Verbose " Verbose mode is Off"
        }
    
    
        # <Your code>
    
    }
    
    0 讨论(0)
提交回复
热议问题