Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive -Verbose in Powershell

Tags:

powershell

Is there an easy way to make the -Verbose switch "passthrough" to other function calls in Powershell?

I know I can probably search $PSBoundParameters for the flag and do an if statement:

[CmdletBinding()]
Function Invoke-CustomCommandA {
    Write-Verbose "Invoking Custom Command A..."

    if ($PSBoundParameters.ContainsKey("Verbose")) {
        Invoke-CustomCommandB -Verbose
    } else {
        Invoke-CustomCommandB
    }
}

Invoke-CustomCommandA -Verbose

It seems rather messy and redundant to do it this way however... Thoughts?

like image 349
Justin Jahn Avatar asked Dec 05 '13 06:12

Justin Jahn


People also ask

What is the use of recursive in PowerShell?

As stated, “A recursive function is a function that calls, or invokes, itself.” On that note, let's first set up the folder structure necessary for this example. While you can do this with PowerShell, I simply didn't bother. As you can see below, there's a “Test” folder inside my “Documents” folder.

Does shell script support recursive function?

Functions in Bash also support recursion (the function can call itself). For example, F() { echo $1; F hello; sleep 1; } . A recursive function is a function that calls itself: recursive functions must have an exit condition, or they will spawn until the system exhausts a resource and crashes.

How does recursive work?

A recursive function calls itself, the memory for a called function is allocated on top of memory allocated to the calling function and a different copy of local variables is created for each function call.

What does :: mean in PowerShell?

Static member operator :: To find the static properties and methods of an object, use the Static parameter of the Get-Member cmdlet. The member name may be an expression. PowerShell Copy.


3 Answers

One way is to use $PSDefaultParameters at the top of your advanced function:

$PSDefaultParameterValues = @{"*:Verbose"=($VerbosePreference -eq 'Continue')}

Then every command you invoke with a -Verbose parameter will have it set depending on whether or not you used -Verbose when you invoked your advanced function.

If you have just a few commands the do this:

$verbose = [bool]$PSBoundParameters["Verbose"]
Invoke-CustomCommandB -Verbose:$verbose
like image 50
Keith Hill Avatar answered Oct 02 '22 17:10

Keith Hill


I began using KeithHill's $PSDefaultParameterValues technique in some powershell modules. I ran into some pretty surprising behavior which I'm pretty sure resulted from the effect of scope and $PSDefaultParameterValues being a sort-of global variable. I ended up writing a cmdlet called Get-CommonParameters (alias gcp) and using splat parameters to achieve explicit and terse cascading of -Verbose (and the other common parameters). Here is an example of how that looks:

function f1 {
    [CmdletBinding()]
    param()
    process
    {
        $cp = &(gcp)
        f2 @cp
        # ... some other code ...
        f2 @cp
    }
}
function f2 {
    [CmdletBinding()]
    param()
    process
    {
        Write-Verbose 'This gets output to the Verbose stream.'
    }
}
f1 -Verbose

The source for cmdlet Get-CommonParameters (alias gcp) is in this github repository.

like image 41
alx9r Avatar answered Oct 02 '22 16:10

alx9r


How about:

$vb = $PSBoundParameters.ContainsKey('Verbose')
Invoke-CustomCommandB -Verbose:$vb
like image 30
Shay Levy Avatar answered Oct 02 '22 17:10

Shay Levy