But in practice, I find it both cumbersome and very, very slow.
For example:
marcel@vger[Downloads]time pwsh -c 'ls' >/dev/null
real 0m0.824s
user 0m0.636s
sys 0m0.213s
marcel@vger[Downloads]time sh -c 'ls' >/dev/null
real 0m0.011s
user 0m0.003s
sys 0m0.005s
marcel@vger[Downloads]
That's around a factor 80. Hmm. OK, startup costs, JITs hard time, yadda yadda.
But it's not just that. For example I found a simple
On top of this, writing PowerShell feels like programming rather than scripting. I know that's sort of ambiguous, but PowerShell is astonishingly verbose compared to bash, or sed/awk, or Perl. PowerShell may be a better programming language than bash, but the times I wrote some, it took me a lot longer (maybe mostly because of my own familiarity with bash) and the resulting scripts were bigger (which I think is unavoidable).
I just don't find PowerShell fills a niche I need to fill, even though it seems to be really powerful and designed by smart people. I guess if I worked on Windows it would fill a niche since it has hooks into the system that are harder to reach in other non-MS languages.
Just typing "notepad" is enough to launch it. The problems with powershell and executables only really come in to play when argument passing, where some escaping is necessary.
You can download and install PowerShell Core 6 completely side-by-side with Windows PowerShell 3.0. We even have a portable ZIP you can drop down wherever: https://github.com/powershell/powershell/releases
The only reason to use iex is if the thing you're trying to execute is not directly the name of the process. So you need & for `&'notepad'` and `&$string_variable` but not `notepad`
That's not quite correct (and neither is that StackOverflow answer).
If you want to execute the EXE stored in a variable or whatnot, then yes, you need `&`, which I think is borrowed from Perl. But otherwise, the rules in PowerShell are the same as a Unix shell: if it's in the PATH, just type the command name (with or without the .exe); otherwise, use the full path.
>That's not quite correct (and neither is that StackOverflow answer).
The SO answer isn't wrong. The EXE there has a space in the path. The answer uses a string literal for it and thus needs &. It could of course escape the spaces with ` instead; then it wouldn't need a string literal and thus not need &.
My biggest complaint with PowerShell is that it's unnecessarily inscrutable -- filled with Bash-like and Perl-like syntax and semantics without the legacy to justify it. I wish writing in PowerShell was as easy as writing C# but instead it's almost as bad as writing Bash scripts.
It's not good for programming or scripting. There are so many good ideas in PowerShell but it's wrapped in a weird body.
I love it for both programming and scripting. It's probably not the best option a lot of the time, but I still find myself going back to write things in PowerShell. I don't find myself running into any of the issues you bring up in my experiences. Everyone has something specific they prefer, though. I find coming back to and reading foreign PowerShell to be quite natural, and rarely taxing if formatted well.
I can't pinpoint what I like so much about it either... It just draws me in well. It does devolve in readability when trying to squeeze out every drop of speed, though.
IPC is what I find to be the most challenging for me in PoSH, but I'm not sure if that's due to incompetence.
As a Syasdmin, Powershell is a scripting dream: it has tab completion for the commands and the switches. I don't feel like I have to guess or look at man pages to figure out why there's a -s and an -S. The help pages are usually written for human consumption by comparison. Saying that it is 'unnecessarily inscrutable' is quite hilarious - have you seen some Linux commands & the lack of output they give? Powershell, if anything, ins extremely verbose & is clear in when something goes wrong.
At least, it doesn't insult you like Ansible tooling with the
^
YOU MADE A MISTAKE HERE BUT WE CAN'T BE CLEAR WHAT IT IS
I realise this is a bit of a cop out, but it's fairly easy to mix and match PowerShell and C# code, even without needing to precompile C# code, by using Add-Type.
It's worth noting that all code in .NET is enclosed within a type (at a fundamental level .NET code is either contained within a value type or reference type, but knowing those names isn't important when you're starting out), so this doesn't limit you to creating/importing data types, you can use it to write inline C# functions too.
It's also interesting to note that the .NET Framework comes with its own .NET compiler, so you don't need to install any dev tools on Windows to code in C#, it's possible to do so with the tools that are available out of the box.
If you want to try out referencing C# code using Add-Type, the following article is a good introduction:
We thought about that but the reality is that it does not work well for interactive experiences.
When you look at how admins get their job done, it starts in the interactive shell and then when the do things frequently, they put it into a simple script and when then need it to be more formal, they invest in making it production quality.
That is the flow that PowerShell was designed to support.
I can easily program in C#, Java, C, C++, Swift, Python, etc, etc. There are subtle differences, sure, but generally the differences are minor. If they have difference in one area, they have plenty of similarities in others.
If these are flavors of ice cream, they're all pretty similar and taste good. Where is Powershell in this? It's certainly not vanilla or chocolate... it's more like pepperoni. It's like C# and Perl had a really ugly baby. Even simple things like using -eq and -ne for comparisons seems 40 years out of date.
Syntax is supposed to be composible and intuitive. One shouldn’t have to keep looking docs to find out how to do X. PowerShell has pretty bad, unimaginative and non-intuitive syntax. I was actually chosen many times to keep scripting in old dos syntax because that was more intuitive. Go look in to stackoverflow and forums where people struggle every day on how to do simple things.
Powershell has short aliases (and you can define your own too) for the most frequently used commands, and I find the process of reformatting text output between commands to get them to pipe to each other and not choke on formatting differences more cumbersome and time consuming than any extra verbiage added by powershell.
But this can cause other problems. An example would be the way that Powershell for a long time aliased the Invoke-WebRequest cmdlet to both 'curl' and 'wget'. This was supposed to be a convenience feature, but it broke all sorts of scripts that were written to use "real" curl or wget because Invoke-WebRequest didn't accept curl or wget option parameters (oops).
They've fixed this in recent versions by shipping actual curl binaries, but it's a useful illustration of how just aliasing popular shell commands to their Powershell alternatives isn't necessarily helpful.
invoke-webrequest has a "native" short alias too: iwr. I like these native aliases because they use a consistent pattern of abbreviations for verbs and nouns, e.g., the same "i" for invoke is used in icm = invoke-command, iex = invoke-expression, ihy = invoke-history, etc.; then if you look at the nouns in one of those others (since invoke-webrequest is the only "webrequest" cmdlet), they're also consistent, e.g., gcm = get-command, shcm = show-command, trcm = trace-command.
I concur. For me personally, PowerShell's dependency on the .Net Framework just makes me write what I need in C# and then deploy to clients using GP. In my environment the client computers don't have a consistent .Net version which follows that they don't have a consistent PS version installed either. For a recent data collection program it was faster and easier to write it in C# and target .Net V2 then to fiddle with PS, and its execution policy https://stackoverflow.com/questions/4037939/powershell-says-...
What kind of C# are you writing, is it a compiled exe you're distributing or is there some way to run C# script on windows?
I've done almost nothing with PowerShell due to the brutal syntax, would love to use a nice language like C# or Python for the control structure (logic, looping, etc) and then just calling out to PowerShell when needing to execute a function. Seems like that should be a possibility, although passing data through may be problematic.
You don't need to 'shell' out to call PoSh. You can host it yourself, see https://msdn.microsoft.com/en-us/library/dn569260(v=vs.85).a... Passing data is quite easy, both ways, is just C# objects.
This can be convenient when faced with one of those 'Powershell only API' features.
It's a compiled binary (PE). I've read through numerous books on PowerShell and I don't see its value in comparison to using any other .Net language. All namespaces in PowerShell are available in C#/VB/blah so why deal with the annoyance of ensuring that the client has not only the required version of .Net Framework/Core installed, but also the PowerShell interpreter version too? Perhaps it's because PowerShell doesn't require a compiled binary so it can be modified and run without an extra step, and it allows for easy add-ins with the cmdlet interface.
That whatever space powershell fills on windows
its not a niche .. not a niche at all
I agree with you, powershell is powerful and I guess benefit from being new .. it has amazing uniformity and amazing discover-ability
Anyway, I was saying, powershell fills automation on windows, it is THE automation tool on windows and has been for a while, there is hundreds of commands that you can you to manage and deploy and update almost anything important on windows
This is not a niche, not a niche at all .. it is as far from niche as i can think of
And now that it is being ported to other systems, it had the potential to be THE automation tool for many organization that have mixed environments
So you see, when it was primarily windows, it was not a nice, again because automation on windows is not a niche .. now imagine it beyond even windows
Powershell is about automation, not scripting, and not just the command line ... it is really about automation
Instead of following steps, you automated with one script ..or possibly a small GUI app
I think you and I merely disagree on the meaning of "niche" in this context, rather than on facts about usage of PowerShell.
I was simply saying that PowerShell doesn't serve a unique purpose in my environment that isn't better served by other languages or shells. "Niche" was short-hand for, "This language is particularly well-suited for this task or set of tasks", and I wasn't (intentionally) saying anything about its popularity.
All programming languages have a niche where they are strong. It is not a way of saying, "This language is obscure or not used a lot." It's a way of saying, "For the things I do, I can rule it out, because I don't need to do the things this language does better than others." From what I can tell, scripting (or, "automating", if you prefer that term) Windows is PowerShell's niche. I don't need to script Windows, so I don't need PowerShell.
In short: Saying PowerShell doesn't fill a niche I need to fill is not an insult to PowerShell or a statement about how popular it is. It's merely saying I don't find it suits my needs in my environment (which contains no Windows servers).
Programming is automation though. Scripting is a (loosely defined) form of programming. I'm really not sure what the distinction is. You could just as easily say bash "is really about automation", because it would also be true. Water is wet, etc.
PowerShell is useful on Windows because it does something that could not be done easily or at all before, that being automation without using GUI's. It does this by providing hooks into the Windows infrastructure to change settings and perform tasks without fragile registry edits and GUI manipulation. But UNIX systems have no need for this by virtue of it's command-line first design. If MS was still using DOS and ini files the situation would be similar.
So what does PowerShell really offer in UNIX land? Configuring and automating nix systems is drastically different than doing the same on Windows systems, so having a common scripting language probably does not help much.
I guess a better question would be what does PowerShell offer in the way of "automation" that is so much superior to bash and *nix command line programs.
PowerShell was designed to provide a very wide dynamic range of capabilities from interactive actions to simple ad hoc scripts to more formal programming. The goal was to have a single tool that admins and programmers could share to create and manage systems where they could pick how formal they needed to be to solve the problem at hand and can simply modify (vs replace) it as the solution need to be by more people or more production scenarios.
Powershell 6 halved my start times from 1.5s to 720ms.
However some things will always be slower, aince powershell does more for you than bash does. Compare productivity from not scraping to consider the tradeoffs.
I have tried PowerShell multiple times and hated it every time. They either should have gone with a language like bash or gone straight to C# as scripting language. Powershell is that weird in between that does nothing well.
Agreed. I tried automating an installation of some software in powershell. I kept getting different errors on different windows machines depending on what version of Windows they were on and what features they had installed. Ended up rewriting the whole thing in C#. Runs everywhere I need it to and zero issues.
Our filesystem provider could definitely use some performance work, and we're discussing redoing it at some point in the next minor version release or two.
Personally, for quick interactive stuff, I just `ls` when I'm sitting on a non-Windows machine. My finger muscle memory just does `ls -al` and `rm -rfv` when I'm sitting on a Linux box.
But if I need to do some heavy sorting/filtering, I'd much rather save the minutes wrestling grep/awk/sed/xargs than save the minutes on execution (or the hours on having just done some operation based on some grep/awk/sed/xargs work that I didn't properly test).
I am more of a windows guy and I have been trying to automate more things with powershell in the last month and I must say that compared to its equivalent in linux it is an absolute dog's breakfast.
A few examples of the absurd things I found along the way:
It is impossible to update windows remotely with powershell. The only API to windows update is apparently a COM interface that refuses to be called remotely. I found a hack on a forum where I have to create a scheduled task that runs as a local admin user and trigger that task remotely. This is farcical.
The equivalent of ssh is something called powershell remoting. Of course opening that interface is a significant security risk that need to be monitored. However windows events records all failed authentication attempts on powershell remoting as a local connection and therefore does not expose the IP of the attacker. So much for monitoring.
Very few basic functions have been implemented in powershell, half of my powershell script is actually made of traditional batch commands, with all sort of random behaviors (like nslookup makes the script fail), inconsistent API, etc. It feels like using Windows 10 where we are stuck with half of our settings in an old control panel and the other half in a new one, feels sort of half baked. In addition some powershell commands managed to be inferior to their batch equivalent. Setting a registry key is a prime example (and god knows it is a common task), it takes several commands in powershell for something that is done in one command with reg.exe.
Of course there is no way to run a ps1 with admin privileges directly from the windows shell [1]
>In addition some powershell commands managed to be inferior to their batch equivalent. Setting a registry key is a prime example. ... it takes several commands in powershell for something that is done in one command with reg.exe.
The massive paradigm shift that is powershell (ie object based instead of text based) gives it enough space to exist alongside bash. It will not replace bash, and at least on other platforms I highly doubt it's supposed to, as powershell is so heavily Windows focused
Which is very unfortunate in my opinion. Powershell does the UNIX philosophy better than the equivalent traditional toolset by a wide margin.
Bourne shell is a clumsy, ugly, footgun-laden automation language and the toolset uses text formatting and parsing in its piping io. The whole thing could really stand to be rethought.
The convention was chosen back when both CPU and memory were also many orders of magnitude less. Also chosen back when many principles of good software design were still in their infancy. Decisions made 40 years ago were based on entirely different constraints and with a lot less history.
Nearly everything taught to you by Unix is wrong. The textual format convention is wrong because text needs to be parsed and unparsed, which is slow and error-prone. Moving objects with clearly defined APIs between programs is more performant and robust. To move objects between machines, use a binary format like Cap'n Proto, which requires no parsing. The only thing text gives you is viewability/editability with vi or nano; with a well-defined, open binary format, tools can be easily written to view and manipulate the raw data streams.
Unix's I/O model is broken because it has no intrinsic support for asynchronous I/O. The POSIX aio API sucks, nobody uses it, and it doesn't allow the single syscall check-for-data-and-kickoff-overlapped-I/O-if-not-found that's practically an idiom in Windows (at least not under Linux, where it's implemented in user space via helper processes).
The standard multiprocessing primitives in Unix are broken. fork() starts a new process with the same memory image, possessing the same system resources as the old -- convenient in 1979 but highly dangerous in the presence of threads. The correct approach would be to specify a new image to load and run, as in posix_spawn or Windows CreateProcess.
The claim was that text based tools are slower, right now that is clearly not the case. Of course a comparison between the current implementation of powershell and unix tools is not quite fair, they only had twelve years after all and unix had ~fourty. I would give them annother three decades to catch up.
Compiled code generally runs faster than plain-text interpreted code, even with no compiler optimizations. How about those tools? The whole point was that text parsing is an additional overhead that will make things slower. It's trivially true.
How does powershell pass objects from one process to another? Presumably there's a serialization/deserialization step involved? This could easily be slower than copying test around.
There doesn't have to be. It could just pass references to memory addresses of the object, or even just a copy of the raw binary data. If both the passer and the receiver understand the class of the object, then there is no serialization/deserialization necessary.
> It could just pass references to memory addresses of the object
How? They're different processes running in different threads. If it's raw binary data then it has to at least be copied, which will often be a lot less efficient than just copying text. You can't just memcpy complex .net objects though.
There's nothing stopping unix programs from piping raw binary data, it's just not generally done because it's usually a bad idea.
I don't think powershell is slow because of the everything-as-object philosophy. I think performance just isn't a massive objective because (possible chicken and egg) it's not that prevalent. It could very well be that object passing could be faster than the serialize-unserialize overhead, but powershell is poorly implemented
Not to mention that many speed tests I've seen of PowerShell involve lots of producing text and/or parsing text (including interoperating with existing Unix-like commands). Very few speed comparisons I've seen take advantage of the object capabilities of PowerShell.
It just so happens that over 44 years people have learned how to write excellent performing code for this environment. And Bash is very old at this point, so very care-taken.
I mean, I agree with most of the above-poster's complains about *nix. I think it's terrible. But it has the huge advantage of being there, of being reliably what it is, of having a rather well understood set of facilities, and having an immense history of use.
Because of IBM and Microsoft's misteps in the 80s and early 90s -- with OS/2 and NT respectively -- we don't have a dominant workstation or server operating system that isn't Unix. Sad, but pragmatic fact.
With binary you need to worry about versioning, you need to worry about API support, you cant as easily verify the contents of what you're passing around - in general the industry has moved away from binary everything towards text based file formats (containerized like OOXML, or ODF), text based signalling (SIP, and XMPP) - I can go on.
While I think binary blobs have a place, I dont think they're a panacea to solve problems - I consider them an anti-pattern because they make the humans trying to troubleshoot when things go wrong much harder.
If the text format was chosen responsibly most unix utilities could output data in a machine readable TSV mode with a standardized header and escaping format, not the mess we have now.
powershell also kind of has an awful UX, and a serious discoverability problem. I know powershell can do literally anything I want, but god help me find out what it's called
Not to mention the way it reports errors to the user is incredibly verbose. However, it seems very par for the course for a strong Microsoft tool. If you are able to get in the correct headspace, it's magical. I'm just sad I have to sell my soul to the cult to use it
> "powershell also kind of has an awful UX, and a serious discoverability problem."
There are points of criticism I could level at PowerShell, but discoverability is not one of them.
If you want to explore PowerShell without using any formal tutorials, I'd recommend five commands:
* Get-Verb
* Get-Alias
* Get-Help
* Get-Module
* Get-Command
Get-Verb is useful as it gives you clues about the PowerShell naming convention. Aside from aliases, the vast majority of the commands in PowerShell start with one of the verbs listed by Get-Verb. You can use tab completion to cycle through all currently available commands, e.g. type "Get" (without quotes) then keep pressing the tab key to see the available commands (that are currently loaded).
Get-Alias shows you the command aliases that have been setup for use in your PowerShell session. The reason I recommend it here is twofold:
1. The aliases provided by default are assigned to the most commonly used commands, so Get-Alias can give you a shortlist of commands that are good to explore first.
2. If you have prior experience with the Windows command line or the Linux terminal, Get-Alias will give you clues about what different commands do. For example, dir and ls are both aliases for Get-ChildItem.
Get-Help gives you access to command documentation. One hint I'd give about help in PowerShell is if you need to update the PowerShell help available on your machine, run Update-Help from an elevated command prompt (e.g. on Windows, run PowerShell as an administrator before running Update-Help). If you haven't got local admin permissions, Get-Help is still useful, and will point you in the direction of relevant online documentation if it can't find the help documentation locally.
Get-Module lists the commands by the module they're found in. By default it only shows the modules that are currently loaded, but with Get-Module -ListAvailable you can see all the modules you can choose from. In later versions of PowerShell running a command automatically loads the module it's in (in earlier versions you have to use Load-Module beforehand if the module wasn't already loaded). Note that the -ListAvailable option could've been discovered using Get-Help (e.g. Get-Help Get-Module).
Get-Command allows you to explore the metadata about a command. You're better off reading up on what it can do (Get-Help Get-Command would be a decent start), but to give you one example of why you might find it useful when starting out is that it lets you explore the parameter sets associated with a command. Parameter sets are ways of allowing different groups of parameters to be used with a single command. For example, if you're testing the network connection of computers on a work network, you may choose to reference the computer by IP address, or you may reference the computer by computer name. In this case, parameter sets are a way of making one of those parameters mandatory. Note that commands have a default parameter set, and if you try running a command with mandatory parameters in the default parameter set without passing them in, it will request the minimum information the command requires to function. With all that said, I'd leave Get-Command alone until you're more familiar with the basic operations in PowerShell.
As a final piece of advice, if you're on Windows I would recommend using PowerShell ISE when you start out. It might not look as pretty as VS Code (which also has decent PowerShell support), but it's good at exposing what you need to write effective PowerShell scripts. I use it regularly at work, even for simple tasks that the standalone PowerShell command line would work for. Also worth noting that it ships with Windows, simply search for PowerShell ISE using the Windows menu search.
More subtle discoverability point; Go log onto your production box and use get-whatever the hell you want. There is nothing you can do wrong if you stick to get- while learning. That really encourages users to open the console and have a go.
Nope. Show me the script that gets a list of mounted filesytems for locally attached disks and flags any that are larger than 20G and are more than 90% full.
Since it is cross platform it will run the same on linux/bsd/os x and windows, right?
I haven't used the Windows Subsystem for Linux much, but shouldn't it be possible to have a bash script that runs on all of them? (though it might take some testing against the environment, for things like osx's /Volumes etc.)
I use WSL daily, and yes you can see your entire C:\ drive in WSL under /mnt/c/, and all the common directory commands work, so running a bash script is 'cross-platform' in that way.
That's sort of cheating though. In that instance, Bash isn't really being cross platform, so much as Windows bent over backwards to re-implement lots of Linux underneath Bash, so Bash could treat Linux and Linux (on Windows) identically.
Or to restate that: If Linux apps get to claim they are 'cross-platform' because of WSL, then Windows apps get to claim they are 'cross-platform' because you could run them in WINE.
I used HP-UX for a while; it was good. In fact I first wrote this Unix utility [1] (and later an IBM developerWorks article about it) on an HP-UX system, for a big manufacturing client. HP-UX was pretty stable and had a good patch management system. Had some good tools from HP on top of the OS, such as GlancePlus, Ignite-UX, Process Resource Manager, etc., and another high-end one called MC ServiceGuard.
HP-UX is still alive until 2025 apparently. I used on my workstation for a while (an HP Visualize C3000) in the 90s -- it was my first 64-bit workstation. It's not great.
Interesting. Haven't used it for a while. I miss that OS. Last used it some years ago, so things have moved on since then. For the time, I found it good, though. And HP had pretty good quality in those days - in both hardware and software (the stuff I used, anyway).
Also, I only used it on HP business servers - the PA-RISC series, not on their workstations. Don't know, but there could be some differences in the HP-UX versions between the servers and workstations, the latter which, IIRC, were based on the acquisition of Apollo (but don't know much about that).
My rule of thumb is that if a bash script is > 10-20 lines or needs a function, then I rewrite it in Python. It's simply way more readable.
The main downside to using Python is that if you're running on a minimal system, in a container, or on Windows, Python is a large install.
But I don't see how porting Powershell to _nix solves that issue. _nix systems are more common in most web-centric companies nowadays. If you're a company that uses both you're better off installing Python on your Windows boxes IMO since they probably have bigger disks anyways to handle the large OS.
> "But I don't see how porting Powershell to _nix solves that issue."
I'd say the main reason to install PowerShell on Linux is if you want to use the tools for managing Azure. Aside from that, there are other scripting languages that are have a more mature library ecosystems on Linux.
I've migrated some of bash scripts I use, so the same script can be used for Windows and Linux.
Bash ports on Windows can be messy especially if it involves non-Latin codepages, especially when it involves language like Japanese, which frontend is still not migrated fully into UTF-8. (Also WSL handles it more gracefully.)
I am program in C# a lot, so extensibility via CmdLet is also interesting. (Although, I haven't explored this much, yet...)
You should : even if I consider Powershell pretty alien as a language (coming from an old time Windows dev), Cmdlet is vastly superior to other various argument parsing tooling (optparse, argparse, argv, etc.) I've used in the past.
> "Cmdlet is vastly superior to other various argument parsing tooling (optparse, argparse, argv, etc.) I've used in the past."
I can't comment on the other options you listed, but I would agree that PowerShell has good features for parsing arguments (if you use advanced cmdlets, which only require one extra line to enable on basic cmdlet code, for [CmdletBinding()] ). Aside from built-in attributes for enabling common argument checks (like checking for nulls), you can completely customise parameter validation using ValidateScript, which allows you to set up a script that must evaluate as true in order for an argument to be valid. I'd be interested to find out if any Unix command line scripting language offers something similar.
No, absolutely, there are many cases where semicolon is a bad replacement and a more suitable arrangement found. I'm just speaking to a lot of the "quick one line scripts" that aren't dangerous, such at the parent suggested. Things like `npm install && npm prune` are fine as `npm install; npm prune`. It may "waste" cycles in the rare case of a failed install, but it isn't dangerous.
I agree though, a good short-circuiting Boolean operator would be nice.
It's not the same at all. `&&` only continues the chain if the previous command exited successfully (i.e. exit code is 0) whereas `;` always continues.
So long as Microsoft continues to operate its Linux patent racket I won't be letting PowerShell or .Net Core anywhere near my Linux boxen. People, wake-up. It is NOT OK to let Microsoft become another Linux player without holding it to account for its current and past anti-open source practices.
I'm a bash guy. I'd heard of Powershell and thought it was interesting that Windows finally had something like bash. But back then I didn't use Windows. More recently I had the need to do some scripting for Windows so naturally I looked at Powershell and was excited thinking it would "just like home". It was awful. More like writing Java code than scripting. Except weirdly heterogeneous and ad hoc. I also had to use weird hacks to stop it corrupting every text file with BOM crap.
I can't help but thinking the praise Powershell got is just because Windows people have suddenly realised there's more to life than point and click. Well no shit, guys. This is why we've been using Linux this whole time.
PowerShell is kind of bizarre. I totally get why is has taken off with Windows sysadmins, compared to the previous built-in alternatives it is amazing.
I think a lot of the bizarreness comes from trying to be multiple things, an interactive shell and systems automation language. It is case-insensitive, with seemingly no consensus on what case to use for things. Kinda makes sense for a shell environment with a case-insensitive file system, but very odd when writing automation. It can be written to look like any modern C-like language; set variables, pass variables to functions, etc. But idiomatic PowerShell seems to be (at least in some circles) piping one function to the next in very long chains. Again, that makes sense in a shell, but becomes somewhat unreadable in an application.
Most of what I've seen PowerShell used for is automation, from small 1000 line scripts to seriously large applications with libraries and databases. And I can't help but think that Python would have been so much nicer, if only it was built-in to Windows. Python has libraries for working with the Win32 API and COM objects, there is even IronPython which runs on the CRL and can integrate with .NET.
I don't think anyone was asking for an interactive shell and a serious programming language to be combined, and it would have been nice if they were separate. Instead they have an awful terminal console, an oddly verbose shell language, and a slow case-insensitive programming language.
> "It is case-insensitive, with seemingly no consensus on what case to use for things."
There are naming conventions in PowerShell, but you don't need to know about them when you start out. For example, it's common practice to use camel case for variable names, such as $myVariableName.
> "But idiomatic PowerShell seems to be (at least in some circles) piping one function to the next in very long chains."
For the code I've seen and written, it's rare to see pipes longer than 4 commands long. If you get any longer than that, it's easy to store the output object in a variable and continue to work with this variable as a shorthand.
Regarding case-insensitivity, I'm not referring to user picked names, I'm referring to the whole language.
Is it ForEach, Foreach, foreach, or ForEach-Object? Official documentation[1][2][3][4][5] has all four variations. Same for True/False, While, Write-Output, etc. Everything is case-insensitive and the docs can't decide which to use. Again, it kind of makes sense for a shell language when your users are used to case-insensitivity, but I much prefer stricter consistency in programming languages.
ForEach is an unusual statement. Depending on the context in which it's used, sometimes it's an alias of ForEach-Object, but sometimes it is not. The following article has more details on this, but one thing that I'd like to highlight now is that one way that ForEach and ForEach-Object can differ from each other is in memory use, as ForEach will load all objects that it's iterating over into memory first before starting the loop, whereas ForEach-Object will not. As suggested before, more details can be found here:
Going back to the naming conventions, the conventional way to write ForEach is in PascalCase. The variations slip into code as it's also an alias, and aliases tend to be in all lower case, and also because naming convention guidelines are just suggestions, not something that is strongly enforced (Foreach does seem to be commonly used, even if it's not necessarily in the standard styles).
Generally speaking, PowerShell coding style is similar to .NET coding style. You can read a discussion about it here:
By the way, I respect your right to use whatever language you like best, I'm just clarifying that whilst PowerShell may not have it's "PEP-8" or gofmt, there are still conventions that PowerShell coders follow.
> Instead they have an awful terminal console, an oddly verbose shell language, and a slow case-insensitive programming language.
The terminal is absolutely horrible. If you are going to use powershell, try ConEmu. I also agree with you on the language drawbacks, but it's object-oriented nature makes up for it in my opinion. Whereas on linux/unix you are generally passing and processing text to and fro, the ability to deal with objects can make things a bit easier and more robust.
But considering that the windows world had to live with cmd/ms-dos forever, anything else seems like a god send.
TL;DR: Yes, I see there is potential. But as always, MS botched it.
Edit:
As an example where they did object-based scripting better, I'd look to F#, which also is a vastly better language. But it doesn't have good on-the-fly capabilities (you have to set up a project each time and need VS), and it doesn't come built in.
<rant>
> [...] the ability to deal with objects can make things a bit easier and more robust.
There are drawbacks to that too, though. As a heavily object-based scripting language, PS would depend even more on tooling than scripting languages do anyway. But that in turn means that the tooling we get just isn't good enough. Windows is notorious for its bad CLI windows, which hasn't changed much even with Win10. Discovering objects in PS is a usability nightmare. The little tab completion there is might be fine for one-off commands, but for anything interesting, it'll fall flat on its face.
If you have heavily state-dependent task, ISE contains more friction than value. Until today, I haven't found a simple and fast way to wipe the shell window clean, for example. If you still have things like sockets lying around (which means you'll have to restart the process for a clean state, it seems you're SOL).
Which brings me to
> If you are going to use powershell, try ConEmu.
I'd love to. I can't. In many business environments where you're not in control, "just installing independent tool X" is not an option. Yes, organizational BS is a separate problem, but you're not getting anything done fighting it. And honestly: It's about effing time MS distributes actually usable tools with their OS. I really don't get why that's the particular thing they fail so gloriously at.
The same problem extends to all sort of things. For example: Why the hell aren't the Sysinternals tools built-in already? It's been what? A decade? And there still is no decent Task manager in Windows? Gimme a break!
Criminy, the Mac tarball expands to over a hundred megabytes, with at least two hundred DLLs and dylibs. If I already have .NET Core installed, is running dotnet pwsh.dll basically the same as running pwsh?
If PowerShell is bad because its too much like a programming language thats fine with me. I like being able to hop onto any windows computer and make things happen. I can scrape websites, consume web apis, host webservers, and more all in beautiful one liners. Also text to speech and wscriptshell are fun for messing with your friends computers.
Personal opinion: I tend to find that the times when I end up using advanced Powershell features, I should have been writing code; and times when I don't I could easily have used a batch file.
It's too bad that the focus wasn't put on creating an amazing .net interpreter for the commandline.
Oh goodie, a PowerShell thread on HN. I'm excited to see how many variations of "I hate PowerShell because I've never bothered to spend time learning how to use it, so I don't, and it's also not X, which I use and like" will show up.
As someone thats never been very good at programming in full languages I find that PowerShell is very easy to learn and quite intuitive once you know the basics. I have used it for a huge amount of things that are quite varied. I dont think I've ever had a thought of something I wanted to accomplish and wasnt able to do it (eventually in PowerShell)
PowerShell is fundamentally flawed system. The object oriented language does not belong to shell. It’s simply too verbose and awkward for repeated fast interactive use. When tons of commands starts with get-*, that’s 4 extra keystrokes before even you begin to specify actual command. I know there are shortcuts but still that’s workaround this bad foundation.
A general purpose programming language where you write statement and it stays there and gets executed million times is very different model than shell language where you write statement, throw it away and move on with next. Combining both is creating Frankenstein that’s good at neither. It’s just quite funny that PowerShell syntax doesn’t allow == but does need curlies. Who in the world would have thought of that?
Also the view that everything in shell should output structured data is plain wrong. Shell should output human readable formats. always. It’s tool’s job to do proper parsing and deal with related complexity. The convenience should always be afforded to humans, not tools. Even if one changes all built-in commands to comply this, vast majority of programs won’t.
So lot of above leads to Frankenstein-ish design that looks like awkward hodge pudge of bandaids. While cross platform is good, MSFT needs to start brand new effort, leave PowerShell behind and take command line to next generation with right first principles.
For those who don't like PowerShell's syntax and choices, I highly recommend looking at http://xon.sh/tutorial.html - it's a marriage of Python and a shell done right, and it's cross platform.
120 comments
[ 2.9 ms ] story [ 222 ms ] threadBut in practice, I find it both cumbersome and very, very slow.
For example:
That's around a factor 80. Hmm. OK, startup costs, JITs hard time, yadda yadda.But it's not just that. For example I found a simple
to be more around 50x slower than the equivalent And so on.I just don't find PowerShell fills a niche I need to fill, even though it seems to be really powerful and designed by smart people. I guess if I worked on Windows it would fill a niche since it has hooks into the system that are harder to reach in other non-MS languages.
& notepad.exe
Which isn't complicated I agree but annoyed me.
Just typing "notepad" is enough to launch it. The problems with powershell and executables only really come in to play when argument passing, where some escaping is necessary.
If you want to execute the EXE stored in a variable or whatnot, then yes, you need `&`, which I think is borrowed from Perl. But otherwise, the rules in PowerShell are the same as a Unix shell: if it's in the PATH, just type the command name (with or without the .exe); otherwise, use the full path.
The SO answer isn't wrong. The EXE there has a space in the path. The answer uses a string literal for it and thus needs &. It could of course escape the spaces with ` instead; then it wouldn't need a string literal and thus not need &.
It's not good for programming or scripting. There are so many good ideas in PowerShell but it's wrapped in a weird body.
I can't pinpoint what I like so much about it either... It just draws me in well. It does devolve in readability when trying to squeeze out every drop of speed, though.
IPC is what I find to be the most challenging for me in PoSH, but I'm not sure if that's due to incompetence.
At least, it doesn't insult you like Ansible tooling with the ^ YOU MADE A MISTAKE HERE BUT WE CAN'T BE CLEAR WHAT IT IS
It's such a shame powershell didn't come 2 years later, I feel like they'd have had no choice but to use C# instead of inventing a new language.
It's worth noting that all code in .NET is enclosed within a type (at a fundamental level .NET code is either contained within a value type or reference type, but knowing those names isn't important when you're starting out), so this doesn't limit you to creating/importing data types, you can use it to write inline C# functions too.
It's also interesting to note that the .NET Framework comes with its own .NET compiler, so you don't need to install any dev tools on Windows to code in C#, it's possible to do so with the tools that are available out of the box.
If you want to try out referencing C# code using Add-Type, the following article is a good introduction:
https://blogs.technet.microsoft.com/stefan_gossner/2010/05/0...
When you look at how admins get their job done, it starts in the interactive shell and then when the do things frequently, they put it into a simple script and when then need it to be more formal, they invest in making it production quality.
That is the flow that PowerShell was designed to support.
Jeffrey Snover [MSFT]
Jeffrey Snover [MSFT]
If these are flavors of ice cream, they're all pretty similar and taste good. Where is Powershell in this? It's certainly not vanilla or chocolate... it's more like pepperoni. It's like C# and Perl had a really ugly baby. Even simple things like using -eq and -ne for comparisons seems 40 years out of date.
They've fixed this in recent versions by shipping actual curl binaries, but it's a useful illustration of how just aliasing popular shell commands to their Powershell alternatives isn't necessarily helpful.
I've done almost nothing with PowerShell due to the brutal syntax, would love to use a nice language like C# or Python for the control structure (logic, looping, etc) and then just calling out to PowerShell when needing to execute a function. Seems like that should be a possibility, although passing data through may be problematic.
That whatever space powershell fills on windows its not a niche .. not a niche at all
I agree with you, powershell is powerful and I guess benefit from being new .. it has amazing uniformity and amazing discover-ability
Anyway, I was saying, powershell fills automation on windows, it is THE automation tool on windows and has been for a while, there is hundreds of commands that you can you to manage and deploy and update almost anything important on windows
This is not a niche, not a niche at all .. it is as far from niche as i can think of
And now that it is being ported to other systems, it had the potential to be THE automation tool for many organization that have mixed environments
So you see, when it was primarily windows, it was not a nice, again because automation on windows is not a niche .. now imagine it beyond even windows
Powershell is about automation, not scripting, and not just the command line ... it is really about automation
Instead of following steps, you automated with one script ..or possibly a small GUI app
I was simply saying that PowerShell doesn't serve a unique purpose in my environment that isn't better served by other languages or shells. "Niche" was short-hand for, "This language is particularly well-suited for this task or set of tasks", and I wasn't (intentionally) saying anything about its popularity.
All programming languages have a niche where they are strong. It is not a way of saying, "This language is obscure or not used a lot." It's a way of saying, "For the things I do, I can rule it out, because I don't need to do the things this language does better than others." From what I can tell, scripting (or, "automating", if you prefer that term) Windows is PowerShell's niche. I don't need to script Windows, so I don't need PowerShell.
In short: Saying PowerShell doesn't fill a niche I need to fill is not an insult to PowerShell or a statement about how popular it is. It's merely saying I don't find it suits my needs in my environment (which contains no Windows servers).
That's where powershell failed abysmally.
PowerShell is useful on Windows because it does something that could not be done easily or at all before, that being automation without using GUI's. It does this by providing hooks into the Windows infrastructure to change settings and perform tasks without fragile registry edits and GUI manipulation. But UNIX systems have no need for this by virtue of it's command-line first design. If MS was still using DOS and ini files the situation would be similar.
So what does PowerShell really offer in UNIX land? Configuring and automating nix systems is drastically different than doing the same on Windows systems, so having a common scripting language probably does not help much.
I guess a better question would be what does PowerShell offer in the way of "automation" that is so much superior to bash and *nix command line programs.
1- it runs on both unix and windows .. and hopefully more in the future
2- uniformity, all command have the same form, verb-noun
3- discover-ability, you dont need google to find the cmdlet, you can glob search the help system
4- support, there are cmdlets for many systems that bash will never, ever, ever, ever approach or support
5- GUI, you can create a GUI in powershell
More than that, it has the entire CLR at its disposal, including the C FFI.
Jeffrey Snover [MSFT]
However some things will always be slower, aince powershell does more for you than bash does. Compare productivity from not scraping to consider the tradeoffs.
I know a lot of people love Powershell though.
Personally, for quick interactive stuff, I just `ls` when I'm sitting on a non-Windows machine. My finger muscle memory just does `ls -al` and `rm -rfv` when I'm sitting on a Linux box.
But if I need to do some heavy sorting/filtering, I'd much rather save the minutes wrestling grep/awk/sed/xargs than save the minutes on execution (or the hours on having just done some operation based on some grep/awk/sed/xargs work that I didn't properly test).
A few examples of the absurd things I found along the way:
It is impossible to update windows remotely with powershell. The only API to windows update is apparently a COM interface that refuses to be called remotely. I found a hack on a forum where I have to create a scheduled task that runs as a local admin user and trigger that task remotely. This is farcical.
The equivalent of ssh is something called powershell remoting. Of course opening that interface is a significant security risk that need to be monitored. However windows events records all failed authentication attempts on powershell remoting as a local connection and therefore does not expose the IP of the attacker. So much for monitoring.
Very few basic functions have been implemented in powershell, half of my powershell script is actually made of traditional batch commands, with all sort of random behaviors (like nslookup makes the script fail), inconsistent API, etc. It feels like using Windows 10 where we are stuck with half of our settings in an old control panel and the other half in a new one, feels sort of half baked. In addition some powershell commands managed to be inferior to their batch equivalent. Setting a registry key is a prime example (and god knows it is a common task), it takes several commands in powershell for something that is done in one command with reg.exe.
Of course there is no way to run a ps1 with admin privileges directly from the windows shell [1]
etc.
[1] winaero has a hack to do that: https://winaero.com/blog/run-as-administrator-context-menu-f... But come on Microsoft, don't you use your own product?
>nslookup
>In addition some powershell commands managed to be inferior to their batch equivalent. Setting a registry key is a prime example. ... it takes several commands in powershell for something that is done in one command with reg.exe.On the registry, your command will fail if HKLM:\path\to\key doesn't exist whereas reg.exe would create the key automatically
It does not "crash" a powershell script for any meaningful definition of "crash".
Bash.
Bourne shell is a clumsy, ugly, footgun-laden automation language and the toolset uses text formatting and parsing in its piping io. The whole thing could really stand to be rethought.
How so? Remember that the "text" convention was not chosen haphazardly, but rather very consciously.
Nearly everything taught to you by Unix is wrong. The textual format convention is wrong because text needs to be parsed and unparsed, which is slow and error-prone. Moving objects with clearly defined APIs between programs is more performant and robust. To move objects between machines, use a binary format like Cap'n Proto, which requires no parsing. The only thing text gives you is viewability/editability with vi or nano; with a well-defined, open binary format, tools can be easily written to view and manipulate the raw data streams.
Unix's I/O model is broken because it has no intrinsic support for asynchronous I/O. The POSIX aio API sucks, nobody uses it, and it doesn't allow the single syscall check-for-data-and-kickoff-overlapped-I/O-if-not-found that's practically an idiom in Windows (at least not under Linux, where it's implemented in user space via helper processes).
The standard multiprocessing primitives in Unix are broken. fork() starts a new process with the same memory image, possessing the same system resources as the old -- convenient in 1979 but highly dangerous in the presence of threads. The correct approach would be to specify a new image to load and run, as in posix_spawn or Windows CreateProcess.
In short, fuck Unix and fuck the Unix Philosophy.
And yet in all my tests Unix was at least an order of magnitude faster than PowerShell.
Considering the data doesn't back you, I'd watch my proclamations.
How? They're different processes running in different threads. If it's raw binary data then it has to at least be copied, which will often be a lot less efficient than just copying text. You can't just memcpy complex .net objects though.
There's nothing stopping unix programs from piping raw binary data, it's just not generally done because it's usually a bad idea.
I mean, I agree with most of the above-poster's complains about *nix. I think it's terrible. But it has the huge advantage of being there, of being reliably what it is, of having a rather well understood set of facilities, and having an immense history of use.
Because of IBM and Microsoft's misteps in the 80s and early 90s -- with OS/2 and NT respectively -- we don't have a dominant workstation or server operating system that isn't Unix. Sad, but pragmatic fact.
With binary you need to worry about versioning, you need to worry about API support, you cant as easily verify the contents of what you're passing around - in general the industry has moved away from binary everything towards text based file formats (containerized like OOXML, or ODF), text based signalling (SIP, and XMPP) - I can go on.
While I think binary blobs have a place, I dont think they're a panacea to solve problems - I consider them an anti-pattern because they make the humans trying to troubleshoot when things go wrong much harder.
Not to mention the way it reports errors to the user is incredibly verbose. However, it seems very par for the course for a strong Microsoft tool. If you are able to get in the correct headspace, it's magical. I'm just sad I have to sell my soul to the cult to use it
I find this an odd assertion since powershell lets you tab-complete cmdlets and argument options and has Get-Member.
There are points of criticism I could level at PowerShell, but discoverability is not one of them.
If you want to explore PowerShell without using any formal tutorials, I'd recommend five commands:
* Get-Verb
* Get-Alias
* Get-Help
* Get-Module
* Get-Command
Get-Verb is useful as it gives you clues about the PowerShell naming convention. Aside from aliases, the vast majority of the commands in PowerShell start with one of the verbs listed by Get-Verb. You can use tab completion to cycle through all currently available commands, e.g. type "Get" (without quotes) then keep pressing the tab key to see the available commands (that are currently loaded).
Get-Alias shows you the command aliases that have been setup for use in your PowerShell session. The reason I recommend it here is twofold:
1. The aliases provided by default are assigned to the most commonly used commands, so Get-Alias can give you a shortlist of commands that are good to explore first.
2. If you have prior experience with the Windows command line or the Linux terminal, Get-Alias will give you clues about what different commands do. For example, dir and ls are both aliases for Get-ChildItem.
Get-Help gives you access to command documentation. One hint I'd give about help in PowerShell is if you need to update the PowerShell help available on your machine, run Update-Help from an elevated command prompt (e.g. on Windows, run PowerShell as an administrator before running Update-Help). If you haven't got local admin permissions, Get-Help is still useful, and will point you in the direction of relevant online documentation if it can't find the help documentation locally.
Get-Module lists the commands by the module they're found in. By default it only shows the modules that are currently loaded, but with Get-Module -ListAvailable you can see all the modules you can choose from. In later versions of PowerShell running a command automatically loads the module it's in (in earlier versions you have to use Load-Module beforehand if the module wasn't already loaded). Note that the -ListAvailable option could've been discovered using Get-Help (e.g. Get-Help Get-Module).
Get-Command allows you to explore the metadata about a command. You're better off reading up on what it can do (Get-Help Get-Command would be a decent start), but to give you one example of why you might find it useful when starting out is that it lets you explore the parameter sets associated with a command. Parameter sets are ways of allowing different groups of parameters to be used with a single command. For example, if you're testing the network connection of computers on a work network, you may choose to reference the computer by IP address, or you may reference the computer by computer name. In this case, parameter sets are a way of making one of those parameters mandatory. Note that commands have a default parameter set, and if you try running a command with mandatory parameters in the default parameter set without passing them in, it will request the minimum information the command requires to function. With all that said, I'd leave Get-Command alone until you're more familiar with the basic operations in PowerShell.
As a final piece of advice, if you're on Windows I would recommend using PowerShell ISE when you start out. It might not look as pretty as VS Code (which also has decent PowerShell support), but it's good at exposing what you need to write effective PowerShell scripts. I use it regularly at work, even for simple tasks that the standalone PowerShell command line would work for. Also worth noting that it ships with Windows, simply search for PowerShell ISE using the Windows menu search.
> bash
Nope. Show me the script that gets a list of mounted filesytems for locally attached disks and flags any that are larger than 20G and are more than 90% full.
Since it is cross platform it will run the same on linux/bsd/os x and windows, right?
That's sort of cheating though. In that instance, Bash isn't really being cross platform, so much as Windows bent over backwards to re-implement lots of Linux underneath Bash, so Bash could treat Linux and Linux (on Windows) identically.
Or to restate that: If Linux apps get to claim they are 'cross-platform' because of WSL, then Windows apps get to claim they are 'cross-platform' because you could run them in WINE.
https://en.wikipedia.org/wiki/HP-UX
I used HP-UX for a while; it was good. In fact I first wrote this Unix utility [1] (and later an IBM developerWorks article about it) on an HP-UX system, for a big manufacturing client. HP-UX was pretty stable and had a good patch management system. Had some good tools from HP on top of the OS, such as GlancePlus, Ignite-UX, Process Resource Manager, etc., and another high-end one called MC ServiceGuard.
https://en.wikipedia.org/wiki/Ultrix
https://en.wikipedia.org/wiki/Tru64_UNIX
Edit: Sorry, forgot to add the link I quoted above. Done now:
[1] https://jugad2.blogspot.in/2014/09/my-ibm-developerworks-art...
It's a tutorial on the topic: Developing a Linux command-line utility (in C).
Also, I only used it on HP business servers - the PA-RISC series, not on their workstations. Don't know, but there could be some differences in the HP-UX versions between the servers and workstations, the latter which, IIRC, were based on the acquisition of Apollo (but don't know much about that).
I still build a cross-compiler toolchain for HP-UX PA-RISC 2.0 long-mode (64-bit address mode).
My rule of thumb is that if a bash script is > 10-20 lines or needs a function, then I rewrite it in Python. It's simply way more readable.
The main downside to using Python is that if you're running on a minimal system, in a container, or on Windows, Python is a large install.
But I don't see how porting Powershell to _nix solves that issue. _nix systems are more common in most web-centric companies nowadays. If you're a company that uses both you're better off installing Python on your Windows boxes IMO since they probably have bigger disks anyways to handle the large OS.
I'd say the main reason to install PowerShell on Linux is if you want to use the tools for managing Azure. Aside from that, there are other scripting languages that are have a more mature library ecosystems on Linux.
Bash ports on Windows can be messy especially if it involves non-Latin codepages, especially when it involves language like Japanese, which frontend is still not migrated fully into UTF-8. (Also WSL handles it more gracefully.)
I am program in C# a lot, so extensibility via CmdLet is also interesting. (Although, I haven't explored this much, yet...)
I can't comment on the other options you listed, but I would agree that PowerShell has good features for parsing arguments (if you use advanced cmdlets, which only require one extra line to enable on basic cmdlet code, for [CmdletBinding()] ). Aside from built-in attributes for enabling common argument checks (like checking for nulls), you can completely customise parameter validation using ValidateScript, which allows you to set up a script that must evaluate as true in order for an argument to be valid. I'd be interested to find out if any Unix command line scripting language offers something similar.
git add --all && git commend
(commend being an alias for "commit --amend --no-edit")
or
npm install && npm prune && npm run watch
This is the main reason I use git-bash as my primary terminal whenever I'm working on Windows.
There are some community tools to fake it a little better (Get-ExitBoolean).
Also, a big GitHub issue tracking it: https://github.com/PowerShell/PowerShell/issues/3241
I would say it's a little more than semantics. Consider
vs the semi-colon equivalent.I agree though, a good short-circuiting Boolean operator would be nice.
You're welcome.
I can't help but thinking the praise Powershell got is just because Windows people have suddenly realised there's more to life than point and click. Well no shit, guys. This is why we've been using Linux this whole time.
I think a lot of the bizarreness comes from trying to be multiple things, an interactive shell and systems automation language. It is case-insensitive, with seemingly no consensus on what case to use for things. Kinda makes sense for a shell environment with a case-insensitive file system, but very odd when writing automation. It can be written to look like any modern C-like language; set variables, pass variables to functions, etc. But idiomatic PowerShell seems to be (at least in some circles) piping one function to the next in very long chains. Again, that makes sense in a shell, but becomes somewhat unreadable in an application.
Most of what I've seen PowerShell used for is automation, from small 1000 line scripts to seriously large applications with libraries and databases. And I can't help but think that Python would have been so much nicer, if only it was built-in to Windows. Python has libraries for working with the Win32 API and COM objects, there is even IronPython which runs on the CRL and can integrate with .NET.
I don't think anyone was asking for an interactive shell and a serious programming language to be combined, and it would have been nice if they were separate. Instead they have an awful terminal console, an oddly verbose shell language, and a slow case-insensitive programming language.
There are naming conventions in PowerShell, but you don't need to know about them when you start out. For example, it's common practice to use camel case for variable names, such as $myVariableName.
> "But idiomatic PowerShell seems to be (at least in some circles) piping one function to the next in very long chains."
For the code I've seen and written, it's rare to see pipes longer than 4 commands long. If you get any longer than that, it's easy to store the output object in a variable and continue to work with this variable as a shorthand.
Is it ForEach, Foreach, foreach, or ForEach-Object? Official documentation[1][2][3][4][5] has all four variations. Same for True/False, While, Write-Output, etc. Everything is case-insensitive and the docs can't decide which to use. Again, it kind of makes sense for a shell language when your users are used to case-insensitivity, but I much prefer stricter consistency in programming languages.
[1] https://docs.microsoft.com/en-us/powershell/module/microsoft...
[2] https://docs.microsoft.com/en-us/powershell/module/psworkflo...
[3] https://docs.microsoft.com/en-us/previous-versions/windows/i...
[4] https://technet.microsoft.com/en-us/library/hh551144.aspx
[5] https://docs.microsoft.com/en-us/powershell/module/microsoft...
https://blogs.technet.microsoft.com/heyscriptingguy/2014/07/...
Going back to the naming conventions, the conventional way to write ForEach is in PascalCase. The variations slip into code as it's also an alias, and aliases tend to be in all lower case, and also because naming convention guidelines are just suggestions, not something that is strongly enforced (Foreach does seem to be commonly used, even if it's not necessarily in the standard styles).
Generally speaking, PowerShell coding style is similar to .NET coding style. You can read a discussion about it here:
https://github.com/PoshCode/PowerShellPracticeAndStyle/issue...
By the way, I respect your right to use whatever language you like best, I'm just clarifying that whilst PowerShell may not have it's "PEP-8" or gofmt, there are still conventions that PowerShell coders follow.
The terminal is absolutely horrible. If you are going to use powershell, try ConEmu. I also agree with you on the language drawbacks, but it's object-oriented nature makes up for it in my opinion. Whereas on linux/unix you are generally passing and processing text to and fro, the ability to deal with objects can make things a bit easier and more robust.
But considering that the windows world had to live with cmd/ms-dos forever, anything else seems like a god send.
Edit:
As an example where they did object-based scripting better, I'd look to F#, which also is a vastly better language. But it doesn't have good on-the-fly capabilities (you have to set up a project each time and need VS), and it doesn't come built in.
<rant>
> [...] the ability to deal with objects can make things a bit easier and more robust.
There are drawbacks to that too, though. As a heavily object-based scripting language, PS would depend even more on tooling than scripting languages do anyway. But that in turn means that the tooling we get just isn't good enough. Windows is notorious for its bad CLI windows, which hasn't changed much even with Win10. Discovering objects in PS is a usability nightmare. The little tab completion there is might be fine for one-off commands, but for anything interesting, it'll fall flat on its face.
If you have heavily state-dependent task, ISE contains more friction than value. Until today, I haven't found a simple and fast way to wipe the shell window clean, for example. If you still have things like sockets lying around (which means you'll have to restart the process for a clean state, it seems you're SOL).
Which brings me to
> If you are going to use powershell, try ConEmu.
I'd love to. I can't. In many business environments where you're not in control, "just installing independent tool X" is not an option. Yes, organizational BS is a separate problem, but you're not getting anything done fighting it. And honestly: It's about effing time MS distributes actually usable tools with their OS. I really don't get why that's the particular thing they fail so gloriously at.
The same problem extends to all sort of things. For example: Why the hell aren't the Sysinternals tools built-in already? It's been what? A decade? And there still is no decent Task manager in Windows? Gimme a break!
</rant>
Edit: Added a quote for clarity
It's too bad that the focus wasn't put on creating an amazing .net interpreter for the commandline.
Please don't link to articles from The New Stack. Their articles are often nothing more than warmed over press releases...
A general purpose programming language where you write statement and it stays there and gets executed million times is very different model than shell language where you write statement, throw it away and move on with next. Combining both is creating Frankenstein that’s good at neither. It’s just quite funny that PowerShell syntax doesn’t allow == but does need curlies. Who in the world would have thought of that?
Also the view that everything in shell should output structured data is plain wrong. Shell should output human readable formats. always. It’s tool’s job to do proper parsing and deal with related complexity. The convenience should always be afforded to humans, not tools. Even if one changes all built-in commands to comply this, vast majority of programs won’t.
So lot of above leads to Frankenstein-ish design that looks like awkward hodge pudge of bandaids. While cross platform is good, MSFT needs to start brand new effort, leave PowerShell behind and take command line to next generation with right first principles.