3 ms·
Writing a robust, idiomatic PowerShell function of any complexity is deceptively challenging, and the background required to do it correctly is almost all uniqu
by mpw222 9y ago
Writing a robust, idiomatic PowerShell function of any complexity is deceptively challenging, and the background required to do it correctly is almost all unique to PowerShell. PS is a weird amalgamation of C#, Bash, Perl, VB and cmd-isms that ends up being incredibly confusing to basically everyone.
Try getting an experienced C# developer to write a PS function that:
- Initializes an IDisposable resource and deterministically disposes of it when the function terminates (successfully, with an error, or due to ctrl+C).
- Honors the caller's $ErrorActionPreference/-ErrorAction.
- Understands that catches won't catch "non-terminating" errors.
- Throws errors without trashing the ErrorRecord so that the caller gets a meaningful stacktrace.
- Copes with the difference between process working directory and PS working directory if a .NET method and a relative path are involved.
- Doesn't blow up on a square bracket because someone didn't realize they needed -LiteralPath.
- Doesn't accidentally write an unintended object to the pipeline.
- Does something reasonable with pipeline input.
- Doesn't get tripped up by type coercion magic - $a = @(); $a -eq $null
- Uses multiple ParameterSets without creating ambiguity problems.
- Doesn't get tripped up by PS silently swallowing exceptions thrown by property getters.
- Uses some appropriate subset of language features and modules available across different versions of the OS and WMF. The OS based limitations are understandable. The hard dependencies that Microsoft's own products have on specific PS versions are not.
- Is not super-slow.
It's not impossible, but it sure is hard (and takes a ton of boilerplate), and there aren't many resources out there to teach you how. It's all quick and dirty "how to do X" recipes for sysadmins that don't care about more than what they need to paste into a console.
To be clear, I actually mostly like PS I'm just trying to express a set of pain points here.
- joeyaiello 9y agoThat list you just provided is actually an AWESOME list of things we should make more accessible/understandable in our documentation. There's a few that would also make great rules for PSScriptAnalzyer[1] (basically our linter; the LiteralPath one in particular would probably be easy to write as a warning). At this point I should also plug our tooling improvements. First, our VS Code Extension[2] is AWESOME, debugging there has massively improved, there's snippet support for boilerplate with best practices, it integrates directly with PSScriptAnalzyer, and even enables some "quick fix" of linter warnings. We've also got something called Plaster[3] that does templating to encourage best practices (think of it like a "Yeoman for PowerShell"). But yeah, as we craft new docs for writing the best "cross-CLR, cross-platform" (aka universal, aka portable) PowerShell modules, I want to make sure we tick all these boxes. Oh, and we believe we addressed the whole "different singleton version on different versions of Windows/WMF" thing by making sure that PowerShell 6[4] is x-copyable, fully side-by-side, and supported downlevel to Windows 7/2008 R2 (though Win7 support is currently busted, we're working through fixing it). If you've got a workload or an application that depends on a new feature of PowerShell, you can include PowerShell 6 app-local, or you can distribute it to machines in an environment through either MSI or a ZIP-based file copy. As for Microsoft products that support specific versions: again, I totally hear you. The best thing you can do is push on those products their respective feedback mechanisms (almost everything is on the Feedback Hub or some product-specific UserVoice now) to support all versions of PowerShell. In the meantime, the side-by-side nature of PowerShell 6 means you can install the latest version without fear that you'll void your support or break existing scripts/workloads. [1] https://github.com/PowerShell/PSScriptAnalyzer https://github.com/PowerShell/PSScriptAnalyzer [2] https://github.com/PowerShell/vscode-powershell https://github.com/PowerShell/vscode-powershell [3] https://github.com/PowerShell/Plaster https://github.com/PowerShell/Plaster [4] https://github.com/PowerShell/PowerShell https://github.com/PowerShell/PowerShell