Resursion

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']]
    [OutputType[[String[]]]]
    Param[
        [Parameter[Mandatory=$True,ParameterSetName="ByIP"]][String[]]$IP,
        [Parameter[Mandatory=$True,ParameterSetName="ByHost"]][String[]]$HostName
        ]
    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?

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.

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.

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?

Brian,

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')]
    [OutputType([String[]])]
    
    Param(

        [Parameter(Mandatory=$True,ParameterSetName="ByIP")]
        [String[]]
        $IP,

        [Parameter(Mandatory=$True,ParameterSetName="ByHost")]
        [String[]]
        $HostName
    )
    
    if ($PSCmdlet.ParameterSetName -eq "ByHost") {

        foreach ($ThisHost in $HostName) {

            $ThisIP = Convert-HostNameToIP($ThisHost)

            $PSBoundParameters.Remove('HostName')

            DoThis -IP $ThisIP @PSBoundParameters
        }
    } else {
 
        if ($PSCmdlet.ShouldProcess($IP,"Some operation")) {
            "Do some stuff with this IP address $IP"
        }
    }
}

Best,
Daniel

Daniel,
Thank you for the information on @PSBoundParameters. That is exactly 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.