Behavior of System Altering Cmdlets

Good morning everyone!

I have a quick question around the behavior of system altering Cmdlets. I see in Powershell that Cmdlets with verbs such as start, stop, set, new, etc., generally do not return an output and the implementation of the PassThru parameter is used to display a resulting object if desired. When I am making my own Cmdlets, should I also follow this pattern as a best practice? Is there official documentation on both the use of PassThru as well as the behavior to not return output by default on system altering Cmdlets?

One of the main reason for using such verbs is for better predictability of cmdlets and normally they don’t show output by default. But there is no such rule do it in that way. But to preserve the same level of predictability, I recommend to go with -PassThru for similar cmdlets you create.

You can refer below link for the community best practices

I would say that output should be returned if output is expected.

Get-ChildItem expects child items to be returned. That is the only thing it expects, so output is desired.

Stop-Service expects a service to be stopped, and not necessarily alerting a user that a service has been stopped. If you want to know, you would see for yourself with

Stop-Service 'Foo' ; (Get-Service 'Foo').status

or similar.

In short, never try to predict what someone wants with your cmdlets. Make them do what they are designed to do, and nothing more. The same rules apply for hard-coding a -Filter List, for example. Leave optional formatting up to the user. Same goes for output.

While we’re on the topic of best practices with system-altering cmdlets, I’d also encourage you to ensure that you implement ShouldProcess support for your functions: https://vexx32.github.io/2018/11/22/Implementing-ShouldProcess/

That’ll help users make sure they’re doing what they want to be doing and not accidentally breaking anything when they use your custom commands.

I appreciate all of the feedback. Our team absolutely implements shouldProcess for System altering Cmdlets. I wish more people did this.

Nathaniel, I understand where you are coming from, but I’m more so trying to understand why this is the default behavior of so many built-in Cmdlets. I cant figure out if you are pro-PassThru or anti-PassThru.

Some of the types of cmdlets in question are: Enable-SomeMachine, Disable-SomeMachine, Stop-SomeTask and Start-SomeTask. These aren’t the actual Cmdlet names but they are close enough to give you the idea of what actions they are performing. I made these functions return no output and implemented the PassThru parameter to force results (the same results given if the Get verb of the same noun Cmdlets were executed). I am in a situation where that decision is being heavily challenged and I’m forced to defend my practices, Hence why I asked for any documentation on the matter. Unfortunately, I don’t know if I have enough proof to justify how I coded these functions.

The only guidelines I was able to find on the topic were here: https://docs.microsoft.com/en-us/powershell/developer/cmdlet/strongly-encouraged-development-guidelines#parameter-design-guidelines-sd03

It tells me under what condition to use PassThru, but doesn’t tell me anything further about the “sinks” that it is referring to.

Agreed, WhatIf and confirmImpact are mandatory in my environment.

I made a comment yesterday but it got put in a moderator review state :frowning: