What's the difference Select ID vs Stop-Process ID

Welcome Forums General PowerShell Q&A What's the difference Select ID vs Stop-Process ID

This topic contains 5 replies, has 4 voices, and was last updated by

 
Participant
1 month, 4 weeks ago.

  • Author
    Posts
  • #170170

    Participant
    Topics: 6
    Replies: 10
    Points: 17
    Rank: Member

    I am trying to figure out the why in the following codes. A "why" explanation would be appreciated.

    When I run the following code, select-object displays the piped object ID.

    get-process | where {$_.name -eq 'ytd'} | select ID

    The stop-process ID works if the object ID from the above code is hardwired.

    Stop-Process ####

    If I run the following code, PowerShell returns an error

    get-process | where {$_.name -eq 'ytd'} | Stop-Process ID

    Of course, this following would work and I understood why (Stop-Process is piped the object).

    get-process | where {$_.name -eq 'ytd'} | Stop-Process

    The question is what's the difference between the Stop-Process ID vs Select-Object ID; the object is piped to both cmdlets.

  • #170182
    js

    Participant
    Topics: 25
    Replies: 692
    Points: 1,719
    Helping Hand
    Rank: Community Hero

    What's the error message? Stop-process is probably trying to get the ID from both the pipe and what follows it at the same time.

    • #170668

      Participant
      Topics: 6
      Replies: 10
      Points: 17
      Rank: Member

      Recap the above post:

      get-process | where {$_.name -eq 'ytd'} | select ID # Select output the process ID number
      Stop-Process ID # Use the ID number returned from above, it worked 
      get-process | where {$_.name -eq 'ytd'} | Stop-Process # No ID, it killed the process - ID was not needed
      get-process | where {$_.name -eq 'ytd'} | Stop-Process ID # error (see below); 
      # Trying to understand the difference between line 2 Stop-Process ID and the piped Stop-Process ID

      I understood that ID after Stop-Process was not needed; however I was trying to understand why and how:

      get-process | where {$_.name -eq 'ytd'} | Stop-Process ID

      The following error was returned:

      Stop-Process : Cannot bind parameter 'InputObject'. Cannot convert the "ID" value of type
      "System.String" to type "System.Diagnostics.Process".
      At line:1 char:56
      + get-process | where {$_.name -eq 'ytd'} | Stop-Process ID
      +                                                        ~~
          + CategoryInfo          : InvalidArgument: (:) [Stop-Process], ParameterBindingException
          + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.StopProcess
         Command

      ID string was returned to Select-Object above and Stop-Process ID (integer) was parsed to successfully as well.

      Why when it was piped, Stop-Process looked for System.Diagnostic.Process data type as in the error message.

  • #170680

    Senior Moderator
    Topics: 8
    Replies: 1085
    Points: 3,650
    Helping Hand
    Rank: Community Hero

    well,

    when you use the Stop-Process cmdlet alone, then it requires an input to understand which process to stop(either ID or ProcessName), but when using the same cmdlet in a pipeline(chaining of cmdlets), then the required input is taken from pipeline and should not be passed (Get-Process -Name something | Stop-Process -Id $ID). It will understand what to consume from the pipeline object and proceed. Most of the builtin cmdlets in PowerShell has this capability.

    see more here: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_pipelines?view=powershell-5.1

  • #171844

    Participant
    Topics: 6
    Replies: 10
    Points: 17
    Rank: Member

    Thanks for the link.

    The explanation made it clear. It makes sense if the cmdlet understood the piped object, else (in this case) the ID must be extracted from the object and parse to the next cmdlet.

  • #171949

    Participant
    Topics: 2
    Replies: 497
    Points: 1,229
    Helping Hand
    Rank: Community Hero

    Select-Object will infer that you mean to pass the first provided value to -Property and select the requested properties for you; its -Property parameter is defined as accepting positional input (i.e., not using the explicit parameter name) and as such accepts it when you use Select-Object ID — this is entirely equivalent to Select-Object -Property ID, you're passing it a string value (or array of string values, depending on how you want to work with it) indicating the property or properties you want it to keep.

    Stop-Process's first parameter, however, is -Id — yes, it has the same name as the property you're selecting above, but when you use Stop-Process Id you're not specifying a parameter name, you're passing a value... and Stop-Process doesn't take a string value for its first positional parameter (-Id takes a number, not a string).

    You can see parameter details for any function (including if they can be passed by position, which position they are when multiple parameter values are supplied, whether they can take pipeline input) by using Get-Help -Parameter — to see all the parameters for Stop-Process you can use Get-Help Stop-Process -Parameter *

You must be logged in to reply to this topic.