Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Harmonize Get-Process and Stop-Process syntax with Wait-Process to accept both ID and name positionally #6551

Closed
mklement0 opened this issue Apr 3, 2018 · 12 comments
Labels
Issue-Discussion the issue may not have a clear classification yet. The issue may generate an RFC or may be reclassif Resolution-No Activity Issue has had no activity for 6 months or more WG-Cmdlets-Management cmdlets in the Microsoft.PowerShell.Management module

Comments

@mklement0
Copy link
Contributor

Note: Technically, this would be a Bucket 3: Unlikely Grey Area change.

Wait-Process conveniently allows you to target a process by positional argument either by Name or by ID; that is, if a process named foo exists with Id (PID) 1, you can choose either of the following options:

Wait-Process foo  # binds to -Name
Wait-Process 1    # binds to -Id, because 1 can be parsed as [int]

This is convenient; in the unlikely event of an all-digits process name, you can use -Name to disambiguate.

Note: since -Name and -Id are array-valued, the -Id parameter is only bound if all array elements can be parsed as [int].

By contrast, Get-Process and Stop-Process:

  • do not offer the same convenience

  • bind to different parameters by default: Get-Process binds the 1st positional argument to -Name, Stop-Process to -Id.

Harmonizing the parameter syntax among all 3 cmdlets:

  • provides more convenience overall

  • lessens the cognitive load of having to remember which cmdlets defaults to what parameter.

Hypothetically, existing scripts that used something like Get-Process 1234 could break, because with the new syntax the previously -Name-bound 1234 value would now bind to -Id - again, this would only apply to an all-digits name that can be parsed as (and fit into) an [int].

Environment data

Written as of:

PowerShell Core v6.0.2
@mklement0 mklement0 changed the title Harmonize Get-Process and Stop-Process syntax with Wait-Process to accept ID and Harmonize Get-Process and Stop-Process syntax with Wait-Process to accept both ID and name positionally Apr 3, 2018
@BrucePay
Copy link
Collaborator

BrucePay commented Apr 3, 2018

Stop-Process binds to -ID by default because ID identifies a specific process. This is by design to reduce the chance to killing the wrong process - a non-recoverable operation - and should not change. Simply specifying the process name does not guarantee uniqueness. On the other hand, Get-Process binds to -Name because that is most useful. Get-Process -Id is much less common. I suppose we could change Get-Process but I don't see that there is sufficient utility hear to warrant taking a breaking change

@mklement0
Copy link
Contributor Author

mklement0 commented Apr 3, 2018

@BrucePay:

because ID identifies a specific process.

Yes, but sometimes you want to kill all process instances of a given executable or you may happen to know that there's only one.

If someone uses, say, Get-Process bash and sees multiple processes as a a result, it's fair to assume they'll understand that Stop-Process bash will likewise terminate them all.

Personally, I would value the convenience of, say, Stop-Process bash over Stop-Process (Get-Process bash).Id

Yes, the change would be a breaking one, but the risks strike me as low.
The up-side is the double benefit of convenience and consistency.

@BrucePay
Copy link
Collaborator

BrucePay commented Apr 3, 2018

@mklement0 The pattern for stopping multiple processes is:

  1. run Get-Process to see what you are stopping
  2. when you are sure you have the correct processes, pipe Get-Process into Stop-Process to actually stop the processes

As a general rule, while designing PowerShell, we tried to avoid making it too convenient to accidently perform destructive operations. "Convenience and consistency" that make it easier to do the wrong thing are not desirable.

@mklement0
Copy link
Contributor Author

mklement0 commented Apr 3, 2018

@BrucePay:

Yes, that pattern is easier than Stop-Process (Get-Process bash).Id

Here's another pattern, which is the one that keeps tripping me up:

  1. If I need to check first - during experimentation on the command line, I often know that it's fine to just kill by name - I run gps bash to see what bash processes are running.

  2. If I know up front / have determined that all can be killed, I try - and fail to - run spps bash.

Preventing accidental destruction is a good thing to strive for, but it seems to me the better way to handle this is via confirmation prompts / -Force switches, not by restricting syntax and thereby introducing inconsistencies.

(Both features already are a part of Stop-Process, but only for killing another user's process(es), which (a) requires admin privileges and (b) is currently not enforced on Unix-like platforms).

Also note that the the current restriction offers little protection:

If I try to use Stop-Process <name> and I get an error message and then remember to use -Name / discover -Name via Stop-Process -?, I will runStop-Process -Name <name>, resulting in the feared destruction.


As an aside: the error message you get for Stop-Process <name> is unhelpful, which is another byproduct of the syntax restriction:

Stop-Process : Cannot bind parameter 'InputObject'. Cannot convert the "foo" value of type
"System.String" to type "System.Diagnostics.Process"

@BrucePay
Copy link
Collaborator

BrucePay commented Apr 3, 2018

I will run Stop-Process -Name <name>, resulting in the feared destruction

After a 3-step process (including looking up the command syntax), one hopes one is paying attention to what one is doing.

In summary, providing friction along destructive paths doesn't guarantee that you won't do something unwise, but it gives you more opportunities to think about what you are doing.

@mklement0
Copy link
Contributor Author

I fully agree: sowing confusion with inconsistency and unhelpful error messages, and generally making the task at hand as difficult as possible even to those who know what they're doing is indeed the best way to educate and guide users toward not harming themselves.

Satire aside, is this not a fair summary of the current behavior?

@iSazonov iSazonov added Issue-Discussion the issue may not have a clear classification yet. The issue may generate an RFC or may be reclassif WG-Cmdlets-Management cmdlets in the Microsoft.PowerShell.Management module labels Apr 5, 2018
@lzybkr
Copy link
Member

lzybkr commented Apr 5, 2018

See #2722 for a related discussion.

@mklement0
Copy link
Contributor Author

Thanks, @lzybkr.
I see that you've since abandoned the idea of positional use of PIDs there, and a helpful error message is definitely the next best thing in that case.

Note that Wait-Process, which does support Wait-Process <pid>, decides whether argument should bind to -ID purely formally, based on the parameter declarations (no fallback logic based on whether something that is found not to exist as a name exists as a PID) - if it can be parsed as an [int] (array), it binds to -ID, otherwise to -Name.

This behavior makes sense to me (it is easily explained and easy to remember), and while it is obviously less dangerous in Wait-Process than in Stop-Process, I think worrying about all-digit executable filenames is too exotic a scenario to forgo that convenience, especially since you can always disambiguate with -Id vs. -Name.


Returning to (also) defaulting to -Name with Stop-Process:

Here's the very first example from Get-Help Stop-Process:


Example 1: Stop all instances of a process

PS C:\> Stop-Process -Name "notepad"

This command stops all instances of the Notepad process on the computer.
Each instance of Notepad runs in its own process.
It uses the Name parameter to specify the processes, all of which have the same name.
If you were to use the Id parameter to stop the same processes, you would have to list the process IDs of each instance of Notepad.


This tells me two things:

  • The behavior of Stop-Process -Name is well-documented and clearly indicates that all matching processes will be stopped.

  • Using Stop-Process -Name is not an exotic use case.

So, if Get-Process Notepad is the same as Get-Process -Name Notepad, then it is reasonable to expect that Stop-Process Notepad is the same as Stop-Process -Name Notepad.

This not being the case amounts to nothing but a puzzling inconvenience; it is not educational, and not recognizable as a safety measure.

In fact, until @BrucePay framed it as a safety feature, that had never even crossed my mind - despite my knowing of the implications (potentially killing multiple processes).

Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

1 similar comment
Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

@microsoft-github-policy-service microsoft-github-policy-service bot added Resolution-No Activity Issue has had no activity for 6 months or more labels Nov 16, 2023
Copy link
Contributor

This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

Copy link
Contributor

This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Discussion the issue may not have a clear classification yet. The issue may generate an RFC or may be reclassif Resolution-No Activity Issue has had no activity for 6 months or more WG-Cmdlets-Management cmdlets in the Microsoft.PowerShell.Management module
Projects
None yet
Development

No branches or pull requests

4 participants