This topic contains 5 replies, has 4 voices, and was last updated by  Brian Cyr 3 years, 6 months ago.

  • Author
  • #21504

    Brian Cyr

    I have a question about calling a function recursively.
    I have a function that has two parameter sets. If the user chooses one of the sets, I want to perform a short operation and then call my routine again but this time using the other parameter set. Like so

    Function DoThis[]
        [CmdletBinding[SupportsShouldProcess=$true, ConfirmImpact='Low']]
        If [$PSCmdlet.ParameterSetName -eq "ByHost"] 
            Foreach[$ThisHost in $HostName]
                $ThisIP = Convert-HostNameToIP[$ThisHost]
                DoThis -IP $ThisIP
        } else {
            If [$PSCmdlet.ShouldProcess[$IP,"Some operation"]] {
                #Do some stuff with this IP address

    If the function is called DoThis -HostName "BlahBlah" -WhatIf then will the recursive call also have the -WhatIf property set? If not, how do I pass it? Can I pass the $PSCmdlet object and will Powershell handle that?

  • #21506

    Tim Pringle

    Personally speaking, I wouldn't use this method at all, think it's over complicating things. If you're providing a cmdlet that provided two forms of possible input, then the cmdlet shouldnt need to call itself for it to operate as required.

    Why not just create an array called $IP if hostnames are provided, and then within a ForEach, get the IP address for each host and add it to the array $IP array? Then when finished, proceed with the #do some stuff part.

  • #21511

    Matt McNabb

    To add to what Tim said, I would question even using the parameter sets. Most native cmdlets with a -ComputerName parameter will accept either a host name or an IP address. Is there any particular reason this can't be done?

    Also, if you are using Powershell 4.0, you can just use Resolve-DnsName instead of using a custom function as you have done. Of course it's understandable if you don't have access to version 4.0 for some reason.

  • #21522

    Brian Cyr

    The example I posted was an overly simplified example and really has nothing to do with what I am trying to accomplish other than that is has recursion in it.

    My question is, if I call a function with -WhatIf, -Confirm or -Verbose and this function is recursive. How do I pass along the fact that these switches were set in the parent call? Do child calls inherit these switches? Do I need to pass $PSCmdlet?

  • #21523

    Daniel Krebs


    I agree with Tim and Matt that there is most likely a simpler way to do this. To answer your questions. You can use the automatic variable $PSBoundParameters, remove the HostName parameter and splat it to your next invocation of DoThis with the IP parameter. This will keep your WhatIf, Confirm and Verbose switches. Verbose is actually kind of recursive depending on where you use the -Verbose switch (at the function or script invocation level).

    Example for $PSBoundParameters:

    function DoThis {
        [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Low')]
        if ($PSCmdlet.ParameterSetName -eq "ByHost") {
            foreach ($ThisHost in $HostName) {
                $ThisIP = Convert-HostNameToIP($ThisHost)
                DoThis -IP $ThisIP @PSBoundParameters
        } else {
            if ($PSCmdlet.ShouldProcess($IP,"Some operation")) {
                "Do some stuff with this IP address $IP"


  • #21657

    Brian Cyr

    Thank you for the information on @PSBoundParameters. That is [u][b]exactly[/b][/u] what I was looking for.

    It's still funny to me how I keep hearing that all variables should be singular and yet I still see some internal variables as plural.

You must be logged in to reply to this topic.