PowerShell 5.1 is still the deployment target
The version on the machine matters more than the version on your machine, and it is older than you think.
PowerShell 7 is better in every way I care about. I write in it happily. I do not ship in it, and the reason is simple: it is not on the machines.
Windows PowerShell 5.1 is what is present on a standard Windows install. PowerShell 7 is a separate install, which means a package, a deployment, an approval, and a period where some machines have it and some do not. For a tool whose entire value is that a user can run it right now on a broken machine, that is fatal.
What you actually give up
Less than the discourse suggests. The ternary operator, pipeline chain operators, null coalescing, better parallel handling, and ConvertFrom-Json -AsHashtable. Each of these is a convenience, and every one has a five line workaround in 5.1.
Two things genuinely hurt. Native command error handling in 5.1 is awkward enough that redirecting stderr can make a successful command look failed. And the default file encoding differs across cmdlets in ways that will produce a file another tool cannot read, so you specify encoding explicitly every time.
Neither is a reason to require a runtime the target does not have.
Write for the floor, not the ceiling
The practical rules I follow:
- Declare the minimum version and mean it, then actually test on a clean 5.1 machine rather than on your workstation with seven modules installed.
- No external module dependencies. Every module is an install step, and an install step is a reason the tool does not run at the moment it is needed.
- Be explicit about encoding on anything another program will read.
- Avoid syntax that parses differently across versions. A script that throws a parser error on the target is worse than one that runs slowly.
The general version of this
It applies well beyond PowerShell. The environment you develop in is the best case, and the environment you deploy into is the worst one you have not surveyed. Tooling that assumes the developer's setup fails in exactly the situations where it was most needed, because those situations are correlated with machines that are behind.
Write for the oldest machine that has the problem, not the newest one that does not.