none
Where-Object's InputObject parameter, is there an example of using it?

    Question

  • Can anyone provide an example of using Where-Object's -InputObject parameter?
    Especially confusing to me is how to use Where-Object's -InputObject and the -FilterScript parameter together.

    Friday, September 28, 2012 9:13 PM

All replies

  • Can anyone provide an example of using Where-Object's -InputObject parameter?
    Especially confusing to me is how to use Where-Object's -InputObject and the -FilterScript parameter together.

    A good question. Have a look here: http://connect.microsoft.com/PowerShell/feedback/details/716546/where-object-select-object-inputobject-parameter-does-not-work-as-expected


    Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

    • Proposed as answer by Bigteddy Saturday, September 29, 2012 7:44 AM
    Friday, September 28, 2012 9:41 PM
  • Thanks for the link.  It sure sounds like some people are being stubborn and that Microsoft is not
    going to modify the implementation to make it more useful.
     
    Friday, September 28, 2012 10:05 PM
  • $a = 5
    ? -inputobject $a {$_ -lt 10}

    Now, some might say, "Why would you do that?" Well, would this make more sense?

    $a = 5
    $a | ? {$_ -lt 10}

    If you think that doesn't make sense, try Sort-Object -InputObject:

    $a = 10..1
    sort -inputobject $a

    Why would anyone do that with Sort?

     

    I think the problem is that some cmdlets have more specific uses than other cmdlets. For example, Sort-Object really only makes sense with collections (at least for me). Get-Member on the other hand, is equally useful with all kinds of objects. Cmdlets like Where, Select, and ForEach falls somewhere in the middle of that spectrum.

     

    Let me take Select-Object as an example because it has two distinct uses.

    Get-Process |
        Select -First 5 |
        Select Name, ID

    The first Select partitions a collection by getting the first 5 items. The second Select creates a new object from the specified properties. That "makes sense." But what if we want to create a new object from the properties of an array?

    PS C:\> $a = Get-Process
    PS C:\> Select-Object -InputObject $a Length, Rank

             Length           Rank
             ------           ----
                 67              1

    Does it make sense for anyone to do that? Shouldn't it automatically unroll $a and know that I want to make new objects from the process objects? Some might say yes, others might say no.

     

    Now if we do this:

    PS C:\> $a = Get-Process
    PS C:\> Select-Object -InputObject $a -First 5

    The fact that the result from these two lines have more than 5 processes is probably very uncomfortable to many people. This example probably makes less sense than the one before it. I know that's how I feel about it.

     

    Cmdlets like Get-Member is clearly useful for all types of objects. Cmdlets like Sort-Object is clearly only useful for collections. Cmdlets like ForEach, Select, and Where are kind of in the middle of that spectrum, and I think that's what is causing the discomfort.

     

    So, as for the question, here's my response again:

    $a = 5
    ? -inputobject $a {$_ -lt 10}

    Should that make sense? Should all possible ways of calling Where-Object "make sense?" Who should decide what makes sense and what doesn't? I have no idea where to even begin looking for the answer to those questions, but as for the example of using where with -inputobject and -filterscript, well, there you go.

    Saturday, September 29, 2012 4:48 AM
  • I still find no use for outcomes like
     
    C:> ? -inputobject 5,11 {$_ -lt 10}
    5
    11
    C:> 5,11 | ? {$_ -lt 10}
    5
     
    When the documentation clearly states
    -InputObject <psobject>
    Specifies the objects to be filtered. You can also pipe the objects to Where-Object.
     
    I'm finding it very hard to be convinced that this is not a bug.
     
     
    Saturday, September 29, 2012 6:27 PM
  • Select-String has a similar problem.  If you pass an array of strings to -InputObject, it will treat the array as one long string.  If, however, you pipe an array of strings to Select-String, it processes them one at a time.

    This essentially makes the -InputObject parameter for Select-String practically useless.


    Grant Ward, a.k.a. Bigteddy

    Saturday, September 29, 2012 6:40 PM
  • I still find no use for outcomes like
    C:> ? -inputobject 5,11 {$_ -lt 10}
    5
    11
    C:> 5,11 | ? {$_ -lt 10}
    5
    When the documentation clearly states
    -InputObject <psobject>
    Specifies the objects to be filtered. You can also pipe the objects to Where-Object.
    I'm finding it very hard to be convinced that this is not a bug.

    I don't find that useful either, just like I don't find Sort-Object -InputObject $a to be useful. If there is a bug somewhere, then I think it's in the Help File, not in the cmdlet. If the PowerShell cmdlets treated -InputObject inconsistently, then I would agree with you and say that Where-Object has a bug. But since that is not the case, I would have to say that the bug is in the Help File. I think the description of Where-Object's -InputObject parameter should have been written more like this:

    -InputObject <psobject>
        Specifies the objects to be sorted.
           
        When you use the InputObject parameter to submit a collection of items, Sort-Object receives one object that represents the collection. Because one object cannot be sorted, Sort-Object returns the entire collection unchanged.

    Sunday, September 30, 2012 12:28 AM
  • And that, as an intentional design, would border on the insane, IMO.
    (even overlooking the fact that you probably have Sort-Object and Where-Object mixed up).
     
    On 9/29/2012 7:28 PM, imfrancisd wrote:
    > ...I think the description of Where-Object's -InputObject parameter should have been
    > written more like this:
    >
    > -InputObject <psobject>
    > Specifies the objects to be sorted.
    >
    > When you use the InputObject parameter to submit a collection of items, Sort-Object receives one
    > object that represents the collection. Because one object cannot be sorted, Sort-Object returns the
    > entire collection unchanged.
    >
     
     
    Sunday, September 30, 2012 12:51 AM
  • I don't have it mixed up. I'm just using it as an example.
    Sunday, September 30, 2012 1:01 AM
  • But....you wrote:
    "
    I think the description of Where-Object's -InputObject parameter should have been written more like
    this:
    -InputObject <psobject>
        Specifies the objects to be sorted.
    "
    Why would Where-Object describe -InputObject as "the objects to be sorted." ?
     
    On 9/29/2012 8:01 PM, imfrancisd wrote:
    > I don't have it mixed up. I'm just using it as an example.
     
     
    Sunday, September 30, 2012 1:15 AM
  • I meant the wording of the text, not the text itself. Sorry.

    Maybe they should write about_InputObject.

    Sunday, September 30, 2012 1:28 AM
  • Oh!

    I took that from Get-Help Sort-Object. Those are not my words. I just wanted to show that other parts of the help explained how InputObject works in different ways. When Where-Object's help states:

    "Specifies the objects to be filtered. You can also pipe the objects to Where-Object."

    the help file makes it seem like piping to Where-Object is optional, when it is not. The help in Sort-Object doesn't make that mistake.

    Sunday, September 30, 2012 1:54 AM
  • I'll take a look at Sort-Object next.
     
    Sunday, September 30, 2012 3:36 PM
  • I'll take a look at Sort-Object next.

    It looks equally useless.  From the help:

    -InputObject<PSObject>

    Specifies the objects to be sorted.

    When you use the InputObject parameter to submit a collection of items, Sort-Object receives one object that represents the collection. Because one object cannot be sorted, Sort-Object returns the entire collection unchanged.

    To sort objects, pipe them to Sort-Object.


    Grant Ward, a.k.a. Bigteddy

    Sunday, September 30, 2012 3:42 PM
  • Then, for Sort-Object, why is that not a bug that needs to be fixed?
    Or, in other words, why hasn't that bug been fixed?
     
    Outside of this forum, I'm trying to reach out to a wider group of PowerShell experts (including
    some of them who used to post here, until Microsoft converted this forum into a "social" experience
    - away from the basic NNTP newsgroup it used to be).  Even Microsoft's Jeffrey Snover and Bruce
    Payette are missing here, and they used to post regularly when we were using the NNTP format.
     
    Sunday, September 30, 2012 5:23 PM
  • Hi,

    Pipeline is used commonly than -inputobject for me, so what I understand is that Microsoft maybe leave this as a bug, but we do have other simple way to achieve.

    Regards,

    Yan Li

    TechNet Subscriber Support

    If you are TechNet Subscription user and have any feedback on our support quality, please send your feedback here.


    Yan Li

    TechNet Community Support

    Monday, October 01, 2012 3:06 AM
  • ... and, some common bugs are left unfixed to avoid the possibility of breaking code.

    Grant posted this: "Select-String has a similar problem.  If you pass an array of strings to -InputObject, it will treat the array as one long string.  If, however, you pipe an array of strings to Select-String, it processes them one at a time."

    So, if someone was using select string with -InputObject for the very purpose of treating an array or collection of strings as a single string, an applied "fix" would break that person's code.


    Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

    Monday, October 01, 2012 4:14 PM
  • ... and, some common bugs are left unfixed to avoid the possibility of breaking code.

    Grant posted this: "Select-String has a similar problem.  If you pass an array of strings to -InputObject, it will treat the array as one long string.  If, however, you pipe an array of strings to Select-String, it processes them one at a time."

    So, if someone was using select string with -InputObject for the very purpose of treating an array or collection of strings as a single string, an applied "fix" would break that person's code.


    Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

    A good point.  But who would actually use it this way?  It makes it useless.  I think what I (and possibly Larry too) am getting at is that it seems intuitive that -InputObject should behave exactly the same way as piping to it by value.  The fact is that with a number of cmdlets, using -InputObject has different effects to simply piping to it.  This is inconsistent behaviour, by any measure.

    I say it could be called a bug, or at the very least, a "feature deficiency".


    Grant Ward, a.k.a. Bigteddy

    Monday, October 01, 2012 4:35 PM
  • Does anyone have a list of all cmdlets that accept -InputObject as a parameter in V3?
     
    Here is how I find them in V2:
     
    $((Get-Command -type cmdlet) | %{$_.Definition}) | select-string '-InputObject' -simplematch |
    Select Line | fl *
     
    And count them
     
    $((Get-Command -type cmdlet) | %{$_.Definition}) | select-string '-InputObject' -simplematch |
    Select Line | fl * | measure
     
    I get 58 in V2.
     
    Monday, October 01, 2012 4:43 PM
  • I have gotten Jeffrey Snover's attention on this.  Maybe he will get interested in either fixing it
    or getting us an explanation we have not yet thought of.
     
    The current online help for Sort-Object at
     
    says
     
    @'
    -InputObject<PSObject>
    Specifies the objects to be sorted.
    When you use the InputObject parameter to submit a collection of items, Sort-Object receives one
    object that represents the collection. Because one object cannot be sorted, Sort-Object returns the
    entire collection unchanged.
    To sort objects, pipe them to Sort-Object.
    '@
     
    So, to me, that is saying that -InputObject used by Sort-Object is useless.  Makes one wonder why
    they included it at all in Sort-Object's parameter set.
     
    BTW, I have knowingly expanded the discussion to Select-String in spite of this thread's subject
    that mentions only Where-Object.  I will probably start a new thread soon about -InputObject in
    general.
      - LarryW
     On 10/1/2012 11:35 AM, Bigteddy wrote:
     > ...
    > I say it could be called a bug, or at the very least, a "feature deficiency".
    >
     
    Monday, October 01, 2012 5:15 PM
  • With the bugs surrounding using -InputObject (at least for Where-Object and Sort-Object), I don't
    doubt that coders have to avoid using it.
     
    On 9/30/2012 10:06 PM, Yan Li_ wrote:
    > Pipeline is used commonly than -inputobject for me, so what I understand is that Microsoft maybe
    > leave this as a bug, but we do have other simple way to achieve.
    >
     
     
    Monday, October 01, 2012 5:27 PM
  • ... and, some common bugs are left unfixed to avoid the possibility of breaking code.

    Grant posted this: "Select-String has a similar problem.  If you pass an array of strings to -InputObject, it will treat the array as one long string.  If, however, you pipe an array of strings to Select-String, it processes them one at a time."

    So, if someone was using select string with -InputObject for the very purpose of treating an array or collection of strings as a single string, an applied "fix" would break that person's code.


    Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

    A good point.  But who would actually use it this way?  It makes it useless.  I think what I (and possibly Larry too) am getting at is that it seems intuitive that -InputObject should behave exactly the same way as piping to it by value.  The fact is that with a number of cmdlets, using -InputObject has different effects to simply piping to it.  This is inconsistent behaviour, by any measure.

    I say it could be called a bug, or at the very least, a "feature deficiency".


    Grant Ward, a.k.a. Bigteddy


    Oh, I agree completely that, unless the help text documents it otherwise, it is counterintuitive for these objects to treat their InputObject parameters in a manner substantially different from pipelined input. I was only suggesting one reason why they *might* tend to leave things as they are.

    Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

    Monday, October 01, 2012 6:24 PM
  • I suspect that perhaps the cmdlets sharing the -inputobject parameter also share the code for processing the parameter, and that perhaps it makes sense in at least one of the cases.

    I also suspect that the lack of examples showing the use of the -inputobject parameter is an indication that it was never considered significant, and included just for the sake of completeness, or to satisfy those that do not like using pipelines.

    Worse, though, it also may indicate a weakness in their approach to testing. If they had actually run some examples to use in the help, the surprising behaviour might have caused them to re-visit that code.


    Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

    Monday, October 01, 2012 6:36 PM
  • hey, here's one where -InputObject seems to supply a collection of objects rather than a single one: write-output:

    PS C:\> $A = get-service
    PS C:\> $(write-output -inputobject $A).length
    111
    PS C:\> write-output -inputobject $A
    Status   Name               DisplayName
    ------   ----               -----------
    Stopped  AdobeFlashPlaye... Adobe Flash Player Update Service
    Stopped  Alerter            Alerter
    Stopped  ALG                Application Layer Gateway Service
    <snip>


    Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

    Monday, October 01, 2012 6:38 PM
  • I don't see a difference.
     
    Even in
    Sort-Object -inputobject $(15..1)
    the -inputobject seems to supply a collection of objects.
      - LarryW
     
    On 10/1/2012 1:38 PM, Al Dunbar wrote:
    > hey, here's one where -InputObject seems to supply a collection of objects rather than a single
    > one: write-output:
    > PS C:\>  $A = get-service
    > PS C:\>  $(write-output -inputobject $A).length
    > 111
    > PS C:\>  write-output -inputobject $A
    > Status   Name               DisplayName
    > ------   ----               -----------
    > Stopped  AdobeFlashPlaye... Adobe Flash Player Update Service
    > Stopped  Alerter            Alerter
    > Stopped  ALG                Application Layer Gateway Service
    > <snip>
    >
     
    Monday, October 01, 2012 7:21 PM
  • I was just quoting the help on Sort-Object.  I didn't actually try it out.  Perhaps the help is incorrect / misleading?

    Grant Ward, a.k.a. Bigteddy

    Monday, October 01, 2012 7:50 PM
  • Perhaps.  I'm sensing a need for more testing across the board for all cmdlets that take a
    -InputObject parameter.  Also, I'm waiting for additional advice from Jeffrey Snover.
     On 10/1/2012 2:50 PM, Bigteddy wrote:
    > I was just quoting the help on Sort-Object. I didn't actually try it out. Perhaps the help is
    > incorrect / misleading?
     
    Monday, October 01, 2012 8:01 PM
  • @Bigteddy

    It wasn't lying.

    PS C:\> $a = 2, 1, 3
    PS C:\> $a | sort | %{" * $_ * "}  # piping to sort
     * 1 *
     * 2 *
     * 3 *
    PS C:\> sort -in $a | %{" * $_ *"} # not piping to sort
     * 2 1 3 *

    @Al Dunbar

    Write-Output's InputObject parameter is PSObject[]. The unintuitive cmdlets seem to have their InputObject parameter of type PSObject.

    Monday, October 01, 2012 9:19 PM
  • The text in
    is starting to sink in (albeit slowly).
     
    Apparently how -InputObject is consumed is up to the implementation of the Cmdlet (aka Advanced
    Function).
     
    I still don't have a comfortable understanding of the concept of -InputObject
     
     
    Monday, October 01, 2012 9:26 PM
  • Here's what I think now.  -InputObject exists to give the implementation of a PowerShell Advanced
    Function or cmdlet a regular name to explicitly access items from the pipeline (the name $InputObject).
     
    The code that calls such an Advanced Function should never set an explicit value to -InputObject
     
    Any documentation of -InputObject should say to not use it explicitly on the call to the Advanced
    Function or cmdlet.
      - LarryW
     On 10/1/2012 4:26 PM, Larry Weiss wrote:
    > The text in
    > is starting to sink in (albeit slowly).
    > Apparently how -InputObject is consumed is up to the implementation of the Cmdlet (aka Advanced
    > Function).
    > I still don't have a comfortable understanding of the concept of -InputObject
     >
     
     
    Monday, October 01, 2012 10:13 PM
  • Just when I think I understand -InputObject, I run across examples like below
    tee -inputobject $(gps p*) -variable P
    that seem like a reasonable use of giving it a value on the call to a cmdlet.
     
     
    Tuesday, October 02, 2012 12:13 PM
  • Consider -InputObject like -Force:  It has different behaviours, depending on the cmdlet being used.  It seems to me that the designers were more concerned with having a limited set of parameter names, and using these as best they could, depending on the cmdlet's needs.

    This does lead to confusion, because one would naturally expect parameter names with the same name to do the same thing.  But they don't, and, like I say, this is not unique to -InputObject.


    Grant Ward, a.k.a. Bigteddy

    Tuesday, October 02, 2012 12:21 PM
  • Thanks.  That perspective is the one I started out with, but then I tried a more universal one, and
    am getting more confused trying to force one meaning to fit all uses of -InputObject
     
    That article
    that shows you how to implement -InputObject in your own "Advanced Functions" written in
    PowerShell, does show you how to do it in several ways.
     
     
    Tuesday, October 02, 2012 12:27 PM
  • Thanks.  That perspective is the one I started out with, but then I tried a more universal one, and
    am getting more confused trying to force one meaning to fit all uses of -InputObject
    That article
    that shows you how to implement -InputObject in your own "Advanced Functions" written in
    PowerShell, does show you how to do it in several ways.

    LOL, Larry. I can somehow picture you working with Einstein and others in trying to develop the unified theory of everything that has eluded science for so long. It could be that it is just out of our reach, too complicated for us to understand, or perhaps there is no such thing. But, of course, that does not mean there is no value in looking for it.

    But the difference here is that "Everything" exists on its own in nature, while Powershell is a creation of man. Yes, it has a high degree of consistency. But it is not perfectly consistent.


    Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

    Tuesday, October 02, 2012 5:23 PM
  • Is this not consistent?

    Pipe = send multiple objects to cmdlet
    InputObject = send 1 object to cmdlet

    Yes, the difference is sometimes difficult to see, but it's there.

    PS C:\> $a = 2, 'a', 1.1

    PS C:\> $a | ForEach-Object {"* $_ *"}
    * 2 *
    * a *
    * 1.1 *

    PS C:\> ForEach-Object -InputObject $a {"* $_ *"}
    * 2 a 1.1 *

     

    PS C:\> $a | Where-Object {$true} | %{"* $_ *"}
    * 2 *
    * a *
    * 1.1 *

    PS C:\> Where-Object -InputObject $a {$true} | %{"* $_ *"}
    * 2 a 1.1 *

     

    PS C:\> $a | Select-Object | %{"* $_ *"}
    * 2 *
    * a *
    * 1.1 *

    PS C:\> Select-Object -InputObject $a | %{"* $_ *"}
    * 2 a 1.1 *

     

    PS C:\> $a | Tee-Object -Variable p | %{"* $_ *"}
    * 2 *
    * a *
    * 1.1 *

    PS C:\> Tee-Object -InputObject $a -Variable p | %{"* $_ *"}
    * 2 a 1.1 *

     

    PS C:\> $a | Get-Member -Name ToString


       TypeName: System.Int32
        ...

       TypeName: System.String
        ...

       TypeName: System.Double
        ...


    PS C:\> Get-Member -InputObject $a -Name ToString


       TypeName: System.Object[]
        ...

     

     

    PS C:\> $a = 1, 2
    PS C:\> $b = $a, $a
    PS C:\> $c = $b, $b, $b

    PS C:\> $c | Write-Output | %{"* $_ *"}
    * 1 *
    * 2 *
    * 1 *
    * 2 *
    * 1 *
    * 2 *
    * 1 *
    * 2 *
    * 1 *
    * 2 *
    * 1 *
    * 2 *

    PS C:\> Write-Output -InputObject $c | %{"* $_ *"}
    * 1 2 *
    * 1 2 *
    * 1 2 *
    * 1 2 *
    * 1 2 *
    * 1 2 *

    Tuesday, October 02, 2012 9:40 PM
  • I can at least ask that it be adequately (if not perfectly) documented.
      - LarryW
     
    On 10/2/2012 12:23 PM, Al Dunbar wrote:
     > ...
    > But the difference here is that "Everything" exists on its own in nature, while Powershell is a
    > creation of man. Yes, it has a high degree of consistency. But it is not perfectly consistent.
    >
     
    Wednesday, October 03, 2012 1:19 PM
  • Yes, but if that one object is a collection, then in some cases, when confronted with a collection,
    PowerShell "unrolls" that collection into multiple objects automatically.
     
    See:
     
     
      - LarryW
     
    On 10/2/2012 4:40 PM, imfrancisd wrote:
    > Is this not consistent?
    >
    > Pipe = send multiple objects to cmdlet
    > InputObject = send 1 object to cmdlet
    >
     > ...
     >
     
    Wednesday, October 03, 2012 2:13 PM
  • Yes, but if that one object is a collection, then in some cases, when confronted with a collection,
    PowerShell "unrolls" that collection into multiple objects automatically.
    See:
      - LarryW
    On 10/2/2012 4:40 PM, imfrancisd wrote:
    > Is this not consistent?
    >
    > Pipe = send multiple objects to cmdlet
    > InputObject = send 1 object to cmdlet
    >
     > ...
     >

    If so, then, it would appear that what we are looking at here exists outside of the set of those cases where unrolling is done.

    Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

    Wednesday, October 03, 2012 7:49 PM
  • Exactly!  What I would propose is to make Sort-Object and Where-Object start unrolling -InputObject
    when necessary to get "sane" behavior (aka "useful" behavior).
      - LarryW
     
    On 10/3/2012 2:49 PM, Al Dunbar wrote:
    > If so, then, it would appear that what we are looking at here exists outside of the set of those
    > cases where unrolling is done.
     
    Wednesday, October 03, 2012 8:51 PM
  • Yeah, I agree that it is counterintuitive for the where and sort objects to be unable to accept through the -InputObject parameter a collection to be sorted or filtered. Since it is said that this and other common parameters may have slightly different implmentations in different cmdlets, it seems odd that these two cmdlets are stuck with a do-nothing capability.


    Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

    Wednesday, October 03, 2012 10:03 PM
  • Well said!
     
    Now if only Jeffrey Snover can be convinced.
      - LarryW
     
    On 10/3/2012 5:03 PM, Al Dunbar wrote:
    > Yeah, I agree that it is counterintuitive for the where and sort objects to be unable to accept
    > through the -InputObject parameter a collection to be sorted or filtered. Since it is said that
    > this and other common parameters may have slightly different implementations in different cmdlets,
    > it seems odd that these two cmdlets are stuck with a do-nothing capability.
    >
     
    Wednesday, October 03, 2012 10:15 PM
  • I've "hit the wall" on trying to get some additional dialog on this topic outside this forum.
     
    My understanding now is that since Microsoft did a faulty implementation in earlier releases of
    PowerShell of not properly exploiting the -InputObject parameter for cmdlets like Select-Object,
    Sort-Object and Which-Object that they now have no plans to fix it, and will simply change the
    documentation to say that using the -InputObject parameter with these cmdlets has no effect.
     
    In other words, just don't use it.
     
    Here's how the online help for Sort-Object describes it at
     
    <#
    -InputObject <PSObject>
    Specifies the objects to be sorted.
    When you use the InputObject parameter to submit a collection of items, Sort-Object receives one
    object that represents the collection. Because one object cannot be sorted, Sort-Object returns the
    entire collection unchanged.
    To sort objects, pipe them to Sort-Object.
    #>
     
     
    Friday, October 05, 2012 3:12 PM
  • The reason they do not plan to fix it is not that they executed a faulty implementation. If that were a valid reason they would never fix anything, would they. ;-)

    I rather think there may be other reasons, which could include:

      • avoiding the possibility of breaking existing scripting code.
      • there might be a risk in modifying code that is shared with other functions that currently are working properly.
      • there might not be too many situations (or any?) where using the parameter is more efficient or intuitive than piping the value to the cmdlet.
      • there have been few complaints on this (maybe just yours), and yours is mainly an appeal for consistency rather than to fix something whose broken state is causing significant problems.
      • the shareholders do not see the fix of a minor component as having a sufficient return to invest in it.


    Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

    Friday, October 05, 2012 4:41 PM
  • As an aside, you mention a number of cmdlets including "Which-Object", and I cannot find *any* documentation on that one...

    Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

    Friday, October 05, 2012 4:42 PM
  • Rats! I'm always doing that sort of thing.
     
    On 10/5/2012 11:42 AM, Al Dunbar wrote:
    > As an aside, you mention a number of cmdlets including "Which-Object", and I cannot find *any*
    > documentation on that one...
    >
     
     
    Friday, October 05, 2012 4:53 PM
  • Actually, in this case I'm wanting inconsistency when it makes sense to be inconsistent.
      - LarryW
     
    On 10/5/2012 11:41 AM, Al Dunbar wrote:
    >       * ... yours is mainly an appeal
    >         for consistency rather than to fix something whose broken state is causing significant
    >         problems.
     >
     
    Friday, October 05, 2012 4:55 PM
  • I'm hardly the first to want this fixed.  For example, see this post from a long-time PowerShell
    expert:
     
      - LarryW
     On 10/5/2012 11:41 AM, Al Dunbar wrote:
    >
    >       * there have been few complaints on this (maybe just yours), ...
     >
     
     
    Friday, October 05, 2012 4:58 PM
  • Actually, in this case I'm wanting inconsistency when it makes sense to be inconsistent.
      - LarryW
    On 10/5/2012 11:41 AM, Al Dunbar wrote:
    >       * ... yours is mainly an appeal
    >         for consistency rather than to fix something whose broken state is causing significant
    >         problems.
     >

    I agree.  However, I think it is wrong to have a common name for a parameter, like -Force, which means different things to different cmdlets.  Check the help on any number of cmdlets on the -Force parameter, and you'll see what I mean.

    IMO, the parameters should be more function-specific, as opposed to having the same names.  Like -ForceOverwrite, or -ForceCreateNew.  But as it is, we have to peruse the help to be absolutely sure what the -Force parameter does for the particular cmdlet in question.  Seems like double work to me.


    Grant Ward, a.k.a. Bigteddy

    Friday, October 05, 2012 5:47 PM
  • Cmdlet parameter aliases exist.  This shows the current ones:
     
    gcm -type Cmdlet| %{$_.name;($_.parameters | % {$_.values|ft Name,Aliases})}
      -LarryW
     
    On 10/5/2012 12:47 PM, Bigteddy wrote:
    > I agree. However, I think it is wrong to have a common name for a parameter, like -Force, which
    > means different things to different cmdlets. Check the help on any number of cmdlets on the -Force
    > parameter, and you'll see what I mean.
    >
    > IMO, the parameters should be more function-specific, as opposed to having the same names. Like
    > -ForceOverwrite, or -ForceCreateNew. But as it is, we have to peruse the help to be absolutely sure
    > what the -Force parameter does for the particular cmdlet in question. Seems like double work to me.
    >
     
    Friday, October 05, 2012 6:07 PM
  • Cmdlet parameter aliases exist.  This shows the current ones:
    gcm -type Cmdlet| %{$_.name;($_.parameters | % {$_.values|ft Name,Aliases})}
      -LarryW

    Yes, Larry, but I don't see what that's got to do with what I said.  I think you're just having fun with PS.  We are all aware of the alias "cn", and that about the only one I use, because I have a bad memory, and I have tab completion.

    Grant Ward, a.k.a. Bigteddy

    Friday, October 05, 2012 6:28 PM
  • I was hoping that we could create additional parameter aliases for a cmdlet.
      - LarryW
     On 10/5/2012 1:28 PM, Bigteddy wrote:
    > Yes, Larry, but I don't see what that's got to do with what I said. I think you're just having fun
    > with PS. We are all aware of the alias "cn", and that about the only one I use, because I have a
    > bad memory, and I have tab completion.
    >
     
    Friday, October 05, 2012 6:42 PM
  • It turns out you can add parameter aliases to existing cmdlets, with a lot of effort.  See
     
     
      - LarryW
     
    On 10/5/2012 1:42 PM, Larry Weiss wrote:
    > I was hoping that we could create additional parameter aliases for a cmdlet.
     
     
    Friday, October 05, 2012 6:48 PM
  • It turns out you can add parameter aliases to existing cmdlets, with a lot of effort.  See
      - LarryW
    On 10/5/2012 1:42 PM, Larry Weiss wrote:
    > I was hoping that we could create additional parameter aliases for a cmdlet.

    Just more to remember.  The thing I love about Powershell is its discoverability.  Especially with V3, with it's intellisense, it's a breeze to write scripts using full parameter names.

    Makes them more readable too.  I have functions declared in my profile that I never use, simply because it's so simple to do stuff on the command line, and I forget they're there.  As I say, I have a bad memory, and that's why I never got into VBS.  Powershell writes itself!


    Grant Ward, a.k.a. Bigteddy

    Friday, October 05, 2012 6:59 PM
  • You asked for -ForceOverwrite or -ForceCreateNew parameters in the context of appropriate cmdlets.
    You can have those names if you want them badly enough as aliases for -Force (but of course they
    won't be portable to all PowerShell hosts without your proxies).
     
    I think we have ridden this horse far enough, as I think we both think that this extreme level of
    customization (custom parameter aliases via proxies) is not productive.
     
    We are stuck with generic -Force just like we are stuck with the ineffective -InputObject parameter
    for Sort-Object since PowerShell has congealed into the state it is in and won't be changing either
    of those things.
      - LarryW
     On 10/5/2012 1:59 PM, Bigteddy wrote:
    > Just more to remember. ...The thing I love about Powershell is its discoverability. Especially with
    > V3, with it's intellisense, it's a breeze to write scripts using full parameter names.
    >
    > Makes them more readable too. I have functions declared in my profile that I never use, simply
    > because it's so simple to do stuff on the command line, and I forget they're there. As I say, I
    > have a bad memory, and that's why I never got into VBS. Powershell writes itself!
    >
     
     
    Friday, October 05, 2012 7:49 PM
  • You asked for -ForceOverwrite or -ForceCreateNew parameters in the context of appropriate cmdlets.
    You can have those names if you want them badly enough as aliases for -Force (but of course they
    won't be portable to all PowerShell hosts without your proxies).
    I think we have ridden this horse far enough, as I think we both think that this extreme level of
    customization (custom parameter aliases via proxies) is not productive.
    We are stuck with generic -Force just like we are stuck with the ineffective -InputObject parameter
    for Sort-Object since PowerShell has congealed into the state it is in and won't be changing either
    of those things.
      - LarryW
     On 10/5/2012 1:59 PM, Bigteddy wrote:
    > Just more to remember. ...The thing I love about Powershell is its discoverability. Especially with
    > V3, with it's intellisense, it's a breeze to write scripts using full parameter names.
    >
    > Makes them more readable too. I have functions declared in my profile that I never use, simply
    > because it's so simple to do stuff on the command line, and I forget they're there. As I say, I
    > have a bad memory, and that's why I never got into VBS. Powershell writes itself!
    >

    I believe it was a conscious design decision (Ref: "PowerShell In Action" - Bruce Payette) to avoid having millions of different, cmdlet-specific parameter names to contend with. Whether it is -force, -ForceCreateNew, or something else, you still need to use the right one and know what it does. And I don't think any convention would make that universally intuitive.

    Al Dunbar -- remember to 'mark or propose as answer' or 'vote as helpful' as appropriate.

    Friday, October 05, 2012 8:52 PM
  • I think the main idea is readability.  If the parameter's name actually described what it does, the
    code would be more easily read with the proper interpretation because of the specificity of the
    name.  A name like -Force just means to me "ignore safeguards".  And what that exactly means is
    context specific.
     
    Ironically, the way that parameter names are parsed, as long as the more specifically named
    parameter name begins with "Force", then -Force would probably always be sufficient to represent
    names like -ForceCreateNew
     
    There are a few provided parameter aliases that provide more specific name alternatives.
    For example:
     
    Debug-Process
    Id                                      {PID, ProcessId}
     
    Export-FormatData
    Path                                    {FilePath}
     
    Get-Date
    Date                                    {LastWriteTime}
      - Larry
     On 10/5/2012 3:52 PM, Al Dunbar wrote:
    > I believe it was a conscious design decision (Ref: "PowerShell In Action" - Bruce Payette) to avoid
    > having millions of different, cmdlet-specific parameter names to contend with. Whether it is
    > -force, -ForceCreateNew, or something else, you still need to use the right one and know what it
    > does. And I don't think any convention would make that universally intuitive.
    >
     
    Friday, October 05, 2012 9:51 PM
  • <disclaimer>I didn't read the whole, thread, only the first few ... dozen ... posts</disclaimer>

    Since I've been quite effectively pinged, let me offer my (updated) 2c on the topic:

    I wrote "what's the desired behavior of InputObject" over 5 years ago, when PowerShell v1 was young.  I wrote it in defense of my (rather unorthodox, it turns out) view that cmdlets should always work both in the pipeline and stand-alone. There's no reason that cmdlets have to be one or the other -- especially when this causes some apparently legitimate uses to do nothing and not work at all.

    My opinion is stated clearly in writing Cmdlets for the PowerShell pipeline where I noted that even back then people were claiming that the way InputObject works in Select-Object and Where-Object was "inherent" and "unavoidable." It's not, and I gave two possible alternatives there.  I could give a couple more now.  At the very least, these Cmdlets should throw an exception when you try to do something like these commands, because they are obviously nonsense, and it's trivial to do so:


    Where-Object -Input $DoesNotMatter { $_.Name -like "Thing*" }

    Select-Object -Input $WhyAreYouDoingThis -Last 5

    Let me clear up a misconception however (although I think others have stated this, I just want to reinforce it):

    InputObject is very much like Force. It's a manually written parameter. The cmdlet author chooses that name and has to program it's behavior.  It's a commonly chosen name with some implied meaning -- it's usually chosen as the parameter name (or as an alias for the parameter name) when you have a parameter which takes input by value from the pipeline. 

    In order to write a cmdlet which takes input from the pipeline, you must have a parameter that accepts the pipeline input. That's the only reason cmdlets like Where-Object have an InputObject parameter -- they can't not have it.  It's hard (as you can see in my post) to write a cmdlet that works effectively using the same parameter in both pipeline and direct invocation. But it's not impossible, and it's the right way to do it.

    Note: just because you write a parameter that takes an array doesn't mean it can't also treat an array as a single input. As Bruce Payette wrote in PowerShell in Action: "If you want to pass an array as a single value, you need to do it yourself and write it in parentheses with the unary comma operator, as discussed in chapter 3." (pg 351)

    Having said all that -- it's hard to imagine changing core cmdlets where it would break existing scripts at this point, unless they changed the syntax enough to break compatibility completely, and probably not even then.  However, it would make sense to me to at least make them throw exceptions when you invoke them in ways that can't actually do anything useful.

    More importantly, we need to encourage other developers to write cmdlets that always work, instead of taking the easy way out.

    Wednesday, October 10, 2012 3:46 AM
  • Thanks, Joel.  The perspective of a long time PowerShell expert like yourself is appreciated.
     
    Wednesday, October 10, 2012 11:31 AM
  • It is probably time for a followup article
     
    "The routine and the unexpected behaviors of InputObject in PowerShell V3.0"
     On 10/9/2012 10:46 PM, Joel -Jaykul- Bennett [MVP] wrote:
    > I wrote "what's the desired behavior of InputObject" over 5 years ago, ...
     >
     
    Wednesday, October 10, 2012 12:12 PM