powershellfunctionargumentsargc

Get argc value in a function inside $PROFILE script file


I have created the following function in my $PROFILE script file :

function host($name, $server, $type) {
    $FUNCNAME = $MyInvocation.MyCommand.Name
    $argc = $args.Count
    if ( $argc -eq 0 ) {
        "=> Usage : $FUNCNAME `$name [`$server] [`$type=A]"
    } elseif ( $argc -eq 1 ) {
        $fqdn = $name -Replace('https?://|s?ftps?://','') -Replace('/.*$','')
        (Resolve-DnsName $fqdn)[0].Name
        (Resolve-DnsName $fqdn).IP4Address
    } elseif ( $argc -eq 2 ) {
        $fqdn = $name -Replace('https?://|s?ftps?://','') -Replace('/.*$','')
        (Resolve-DnsName -name $fqdn -server $server)[0].Name
        (Resolve-DnsName -name $fqdn -server $server).IP4Address
    } elseif ( $argc -eq 3 ) {
        $fqdn = $name -Replace('https?://|s?ftps?://','') -Replace('/.*$','')
        if ( $type -eq "-4" ) {
            $type = "A"
        } elseif ( $type -eq "-6" ) {
            $type = "AAAA"
        } else {
            $type = "A_AAAA"
        }
        (Resolve-DnsName -type $type -name $fqdn -server $server)[0].Name
        (Resolve-DnsName -type $type -name $fqdn -server $server).IP4Address
    } else {
        Write-Warning "=> Not supported for the moment."
    }
}

I tried to fetch the value of argc C equivalent.

So I tried $args.Count but it always return 0 from inside my function.

Can you help me ?


Solution

  • As @js2010 said, $args exists only if there is no parameters in the function.

    But it's a easy fix: you can simply replace $argc = $args.Count with $argc = $PSBoundParameters.Count

    Plus this lets you access named parameters directly, making code easier to write and read:

    # Evaluate using a Approved Verbs name
    function Get-ResolveDnsName {
        # an alias for easier use in terminal.  
        # I do not suggest to use it in scripts.  
        [Alias('Host')]
        [CmdletBinding(
            # this forces the position of the parameters when not using names
            PositionalBinding = $true, 
            DefaultParameterSetName = 'ZeroParameters'
        )]
        param (
            # By using a default a ParameterSet with NO parameters,
            # we make possible to call the function without parameters while
            # have the $Name being mandatory otherwise
            [Parameter(Position = 1, Mandatory = $true, ParameterSetName = 'Minimum')]
            [string]$Name,
            [Parameter(Position = 2, ParameterSetName = 'Minimum')]
            [string]$Server,
            [Parameter(Position = 3, ParameterSetName = 'Minimum')]
            # let's add some validation given we have a limited set of correct values.  
            [ValidateSet('4', 'A', '6', 'AAAA', 'A_AAAA')]
            [string]$Type
        )
        
    
        # if no parameter is passed, call self-help and quit the function
        if (-not $PSBoundParameters.Count) { 
            Get-Help $MyInvocation.MyCommand.Name 
            break
        }
    
        # Let's start making a SPLATtable hastable for the Resolve-DnsName parameters
        $Splat = @{
            # You always have the $Name so let's add it
            Name = $Name -Replace ('https?://|s?ftps?://', '') -Replace ('/.*$', '')
        }
    
    
        # let's add the other parameters as necessary
        if ($PSBoundParameters.ContainsKey('Server')) { $Splat['Server'] = $Server }
    
        if ($PSBoundParameters.ContainsKey('Type')) {
            $Splat['type'] = switch ($Type) {
                # -iin forces case Insensitivity  
                { $_ -iin '4', 'A' } { 'A' }
                { $_ -iin '6', 'AAAA' } { 'AAAA' }
                default { 'A_AAAA' }
            }
        }
        
        # SPLAT!
        Resolve-DnsName @Splat
    }