What is Parameter Position 0 ?

What is parameter position 0 ?

Explained nowhere that I could find.

To define a positional parameter, add the Position keyword in the Parameter attribute declaration, and then specify a position. In the following sample, the UserName parameter is declared as a positional parameter with position 0. This means that the first argument of the call will be automatically bound to this parameter.

https://msdn.microsoft.com/en-us/library/dd878252(v=vs.85).aspx?f=255&MSPPError=-2147217396

I appreciate the point to MSDN, but what does that language mean to a home user who speaks only English ?

what are you trying to achieve?
can you post your script?

I am just a home user trying to understand what Position 0 means.

“This means that the first argument of the call will be automatically bound to this parameter.”

The above sentence in quotes - that makes absolutely no sense to me. It explains nothing. It is techno-gibberish. I speak only English.

Actually, I am using Don’s book and in it, Position 1 is explained as defining a Positional parameter, but there is no explanation of Position 0.

I am just looking for a basic explanation of what is “Position 0” in terms of parameters within the context of Position 1 = a Positional parameter.

Is Position 0 the first positional parameter or a mandatory positional parameter ?

8^}

what does that language mean to a home user who speaks only English ?

Lev, pointed you the authoritative source and points.
I know TL;DR is pervasive, but the most direct answer to your question is in the text at the beginning of the text, the first paragraph after the C# code block.

a positional parameter with position 0. This means that the first argument of the call will be automatically bound to this parameter.

Parameters are by default 0 based like arrays / collections. Meaning when looking at a list of things. 0 is 1, 1 is 2 and so on.
So, you choose what parameter you want to be the start parameter and the is set as 0.

This 0 thing is not unique to PoSH, this is literally everywhere. Think medical disease break and control. They always use the term patient 0, not patient 1.

    $MyArrary = 'position01','position02','position03'
    'MyArray count'
    $MyArrary.Count
    'show the array names by position / index...'
    $MyArrary[0]
    $MyArrary[1]
    $MyArrary[2]

    MyArray count
    3

    show the array names by position / index...
    position01
    position02
    position03

So, you can have many parameters you’d like to use, but you either accept the default list position, or number the parameters position.

So, this sort of thing (vs the C# version)…

    # Position

    # If a function is called with parameters and the parameter isn't assigned by 
    # name, its done by position, and the Position parameter attributes value indicates 
    # which value is assigned to which parameter. This is 0 based assignment.

    Function Get-NameAndAge 
    {
        Param
        (
            [parameter(Position=0)]
            [string]$Name,

            [parameter(Position=1)]
            [int]$age
        )

        "Name: $name Age: $age"
    }

    #can be called the normal way,
    Get-NameAndAge -Name Justin -age 30

    #or, because we've defined position values we can call it without named parameters
    Get-NameAndAge Justin 30

OK, in the Help files, some parameters are listed as either Position 0 or Position 1. I am just trying to find out the difference between a Position 0 and a Position 1 parameter.

In Don’s book, it is explained that Position 1 parameters are Positional parameters, but no explanation is given for Position 0 parameters.

All I am looking for is a basic explanation as to what is a Position 0 parameter.

Simply put, it’s all about what gets used first, second, third… etc., if you don’t specify the name.

In the above example, this would be wrong (because you are not using the name)…

Get-NameAndAge 30 Justin

… because position 0 is looking for a string and position 1 is cast as a number only as settings / assignments.

So, the above would error because of what is in the defined position.

    Get-NameAndAge 30 Justin
    Get-NameAndAge : Cannot process argument transformation on parameter 'age'. Cannot convert value "Justin" to type "System.Int32". Error: "Input string was 
    not in a correct format."
    At line:1 char:23
    +     Get-NameAndAge 30 Justin
    +                       ~~~~~~
        + CategoryInfo          : InvalidData: (:) [Get-NameAndAge], ParameterBindingArgumentTransformationException
        + FullyQualifiedErrorId : ParameterArgumentTransformationError,Get-NameAndAge

So that still does not explain (perhaps you are explaining it but I am not seeing it), why for example, in the Microsoft Help File for

Get-EventLog

parameter

-LogName is defined as a Position 0 parameter

and

-InstanceId is defined as a Position 1 parameter

I am just looking for an explanation as to the difference between a Position 0 and Position 1 parameter in the Microsoft Help Files.

And also, in Don’s book, a Position 1 parameter is defined as a Positional parameter but there is no definition provided for a Position 0 parameter (which is obviously also a Positional parameter).

I asked earlier in this thread “Is Position 0 the first Positional Parameter ?”

What is your background in computers? What is your purpose for learning PowerShell?

You say you only speak “English” and everything else is “techno-gibberish”. Without a solid foundation in Windows administration, or even as a power user, it’s going to be very difficult to pick up some very basic things in PowerShell.

Your confusion around positional parameters for Get-EventLog is a perfect example of that.

The position 0 vs position 1 has been very clearly defined here, but let’s breakdown get-eventlog.

After you type “get-eventlog” you can’t put in any parameters until you tell it which logname you want to lookup. Hence -logname being parameter 0. After that you can choose any of the named parameters i.e source, computername or you can choose the other positional parameter instance ID. Instance ID has 1 because you have to specify the logname first, then you can specify the instance id and after that you can give named parameters to get more specific information.

Jon

My background and purpose are none of your business. And your condescending personal judgment is not welcome. I know people that have PhDs from Carnegie-Mellon that struggle to understand Microsoft’s half-witted, poorly written documentation. I happen to have attended the University of Chicago myself. So don’t ever think you can talk down to me. What makes you think you have that right ?

You should try and not take things so personal.

Have a great Monday and I hope you have continued success in learning PowerShell.

Like a lot of computer stuff, PowerShell actually starts numbering at zero. So parameter 1 is actually second on the list. There are a few places where the shell “translates” that, so you’ll sometimes see “position 1” as the first one. It’s a wee bit inconsistent, but computers are sometimes.

It’s been more or less covered, but in hopes I can try to be a little more clear here:

In many programming languages, arrays start at index 0. This means that the first item in a collection of items is numbered 0. The second is numbered 1, the third is 2, and so on.

In PowerShell, arrays are also very prevalent, and you can access their index like this:

PS C:> $array = 1, 2, 3, 4, 5
PS C:> $array[0]
1

The “0th” item is very often the first item, and that is the standard assumption. This applies to parameters that you set a position for as well:

PS C:\> function Example {
    param(
        [Parameter(Position = 0)]
        $Param1,
        [Parameter(Position = 1)]
        $Param2
    )
    Write-Output "Param 1: $Param1 -- Param 2: $Param2"
}
PS C:\> Example one two
Param 1: one -- Param 2: two

This is only important when you’re calling a function without specifying the parameter names. For a more commonplace example, let’s use Get-ChildItem:

PS C:\> Get-ChildItem C:\Users

Because I didn’t specify which parameter to send the ‘C:\Users’ path to, PowerShell automatically determines which parameter to give it to by checking how many values I’ve given it, and automatically giving them to the first available parameters in order. In this case, the first one is the -Path parameter, so my path gets stored in that parameter and the function is executed. You can explicitly tell PS which parameters to send items to by specifying their name(s):

PS C:\> Get-ChildItem -Path C:\Users -Force -Recurse -Include "*bob*"

In this case, the set positions are irrelevant.

It’s generally recommended when making your own functions to set position numbers for your parameters. That way, you can skip having to always specify the parameter name when calling the function, if you want. And just like arrays, parameter numbers start counting from 0.

It's generally recommended when making your own functions to set position numbers for your parameters. That way, you can skip having to always specify the parameter name when calling the function, if you want. And just like arrays, parameter numbers start counting from 0.

I’ll disagree with that bit :). Using parameter names makes the command easier to read, parse, and maintain for human beings in the long-term. The general recommendation is to always used named parameters, not positional values. And, bear in mind that even if you don’t explicitly define positional indexes, PowerShell still implicitly assigns them based on the order in which the parameters are defined within your script or function.

PowerShell’s own native cmdlets don’t set position numbers for every parameter, so doing so is definitely not a recommendation. You would typically define parameter positions only for parameters where you want to create a shortened console syntax, like “ren file1.txt file2.txt”. In a script, parameters should always be explicitly listed out by name, as a better practice, even when the command can accept positional values.

I’ve seen more people bang their heads against a brick wall troubleshooting a command because they’ve gotten the value sequence wrong, and using named parameters eliminates that as a point of failure.

Lockdown, in the event that none of the foregoing has been helpful:

"This means that the first argument of the call will be automatically bound to this parameter."

Take a command like Import-Module. I’ll make references to the doc page at Import-Module (Microsoft.PowerShell.Core) - PowerShell | Microsoft Learn.

If you scroll about halfway down to the -Name parameter (I can’t link directly to that point on the page, sorry), you’ll see that it’s defined as position zero. That means I could run:

Import-Module MyModule

That is exactly the same as:

Import-Module -Name MyModule

The positions means that the first value (“MyModule”) will be “bound,” or “attached,” to the -Name parameter, even if you didn’t type the actual “-Name” parameter name. This gets a little hard to read once you start using multiple parameters. For example:

Add-Member -MemberType NoteProperty -Name Whatever -Value Something

It’s not too hard to follow that command, because I used parameter names. However:

Add-Member NoteProperty Whatever Something

Is a little harder to follow. You’d have to look up the command syntax to figure out which parameters were “attached” to positions zero, one, and two.

LMK if that’s not a little clearer.

Oh, I completely agree, Don. You’re applying a recommendation I made for writing functions to using functions instead, however.

When making use of functions and writing scripts, yes, 100% always opt for the more verbose option, it saves you an enormous amount of headaches.

However, when writing your own functions, I’d still recommend defining a parameter order for your function so that it can still potentially be used for quick, off-the-cuff sorts of things in the command line interface itself. Nobody wants to type out a half-page just to test something, when a brief word or two will do.

Just a good habit to get into, part of properly defining one’s parameters, in my opinion!

See this article to determine if it provide more clarity.

https://blogs.msmvps.com/richardsiddaway/2018/04/02/positional-parameters-2

I agree with your sentiment

Just a good habit to get into, part of properly defining one's parameters, in my opinion!

but not with the implied conclusion that positions have to be defined

using 1 or 2 positional parameters at the command line can be a great time saver. trying to do everything with positional parameters will cost you a lot of troubleshooting in the end.

As has been stated most cmdlets don’t have positions explicitly defined all of their parameters - just the key ones.

I tend not to bother with positions as I’m writing functions to be used in other functions or scripts. I also tend to avoid them at the command line as I find that the small amount of time I save by using positions is soon lost when I get the order wrong