tl;dr Yes it's worth learning PS.
I think we all have some reasons why we decided to do Batch scripting. For some of us just historical reasons like because we grew up with Batch, we are used to write Batch scripts, we are more experienced with Batch than with other scripting languages, we know how to handle obstacles like early variable expansion and other pitfalls ... Batch still has its raison d'être e.g. for simple automation tasks where quite some specialized tools exist (mainly thinking of file system work like ROBOCOPY, ICACLS and friends). Or even just because it's fun trying to get beyond the obvious limits of this language. IMO Batch is still a good choice for pragmatic people who just want to get the task done (preferably unattended) and who don't care much about visual and audible effects. It's been developed for a simple textual interface with originally only allowing a single keystroke for user input (SET /P is an extension that came with NT first). Even things that alredy existed once, like the CHOICE tool, were removed in-between times e.g on XP. That emphasizes what Microsoft thought about the aim of Batch scripting.
Serious arguments against Batch (IMHO):
- Batch is one of the most limited languages ever. Its origin is literally just a batch/list of single command lines. It never really evolved to loose this characteristic. This makes that Batch is not a mature scripting language. Thasks for which no CLI tool is available are often just not to be done. There's no possibility to directly access .NET classes or the Win32 API (or even 3rd party libraries).
- Batch is one of the most difficult languages. This is often underestimated because you may successfully resolve supposedly difficult tasks very quickly, at least if you found a CLI tool dedicated to do the task. But: The definition and use of variables may have side effects. The order of instructions in a command line may have side effects. Using or ommitting spaces in a command line may have side effects. Apart from UTF-8 (to only some extend) there is no Unicode support; instead the CMD typically interprets the script code in another charset than the editors where it was written, which may have side effects. Variables are environment variables that are directly passed on to child processes. All of these peculiarities (which would be beyond the scope to describe in more detail here and which often do not follow any specific rules) have to be known and kept in mind when writing batch code, which makes it almost impossible to write scripts without bugs.
- The behavior of command lines may differ depending on whether they are executed in a Batch script or in a CMD prompt.
- Math is a nightmare. Basic arithmetic and bitwise operations are supported. That's it. Not even floating point numbers, only 32-Bit signed integers. That's why 2 / 3 = 0.
- Many data types, such as arrays and datetime types that are intrinsic in other languages are just not there.
- Batch doesn't support the asynchronous execution of parallel threads/jobs.
- Error handling is difficult. You need to rely on the errorlevel being set properly by commands/tools and you have to check the errorlevel after every command, at least in theory. There's no such things like exceptions or exception handling.
- Batch allows to use GOTO to jump to labels. That's for compatibility reasons and because it lacks certain loop types (like WHILE). This tempts to write unreadable and unmaintainable spaghetti code (although subroutines are supported since NT was introduced).
- The limitations of the language lead to exploits of every bug and of all kind of undefined behavior. That's a serious form of "Hyrum's Law" because people (including me) have been deliberately done investigations to find usable exploits. However, such things shouldn't ever be a base for code that you want users to rely on.
- The fact that all kind of bugs are already intentionally exploited prevents Microsoft from fixing them as this would instantly break too many scripts worldwide. (Refer to the console/terminal core team
https://github.com/microsoft/terminal/b ... ksa.md#cmd These statements can be extended to the whole toolset typically used in a Batch script.) Thus, Batch keeps being an error prone language with umpteen bugs that are often difficult to recognize, especially if they occur only under certain circumstances.
In brief, a few of the arguments in favor of PowerShell (without any claim to completeness):
- Here, too, there are ready-made CmdLets for special tasks to prevent you from constantly reinventing the wheel. But beyond that, everything that is possible with .NET is also possible in PowerShell. This includes access to the platform API if required. In other words, you don't necessarily need compiled tools for certain tasks. Everything can be done in the script code.
- Threading, in the form of asynchronous jobs, is supported.
- Unicode is supported. (BTW: The developments in PowerShell, Windows Terminal and even Notepad indicate that we can probably expect UTF-8 as a quasi-standard for text-based interfaces on Windows in the medium term.)
- PowerShell is under active development. PowerShell Core is an open source project and is available not only for Windows, but also for Linux distros and macOS. Scripts can therefore also be used across platforms if they don't invoke the platform API.
However, I also have some caveats regarding PowerShell:
- Just like Batch, the typical PS syntax isn't comparable with any other language. It may include a few elements of C-like languages. However, experiences in Batch or Linux shell scripting are only little helpful.
- PS's pipe syntax encourages writing excessively long lines of code. Some people seem to find it fascinating to write everything in just one line. Similar to the overuse of GOTO in Batch, this has the downside of losing readability.
- By far not everything is already wrapped into CmdLets. Therefore, it is beneficial to be familiar with .Net or to gain experience with it. If you want to do so, C#.Net should be preferred since custom classes need to be written in C# code anyway.
- As soon as you need to go beyond predefined CmdLets, you also have to go beyond the typical PS syntax. E.g. if you need to call methods of .Net classes. At a closer look, PS scripting is often not as clean as it should be expected.
- It's annoying that Windows PowerShell (v5.1) still requires scripts to get invoked from the context menu. This seems to be gone with PowerShell Core installed (at least on my Win 11). However, Windows still ships with only 5.1.
- PS takes longer to start up because it has to load all of its dependencies first.
Steffen