Yes, PowerShell. And it may actually arrive at Linux/Unix soon, due to CoreCLR. The specification is already open, but until now not much progress has been made towards bringing it uncrippled to Linux/Unix
PowerShell is extremely consistent. Examples: All commands are strictly on the verb-noun form where there are only 40 or so "approved" verbs. Noun represent the topic, so if you are working with ACLs, the commands are Get-Acl, Set-Acl, and if you are working with network network adapters, the commands are Disable-NetAdapter, Enable-NetAdapter, Get-NetAdapter, Rename-NetAdapter, Restart-NetAdapter, Set-NetAdapter. All (PowerShell) commands require the parameters in the same way (no - and -- confusion) as it is actually the shell that does the parameter parsing.
The grammar is "modern" so it has no surprises for anyone used to context-free grammars (like C, Python, Java, ...).
PowerShell is certainly flexible as it comes with the ability to invoke anything that has an exposed .NET API, or even has a WBEN/CIM standard interface (like some network switches etc).
I urge anyone at all with any interest in PowerShell to give it a shot. Spoiler: it's not possible without an epic level of hackery; but along the way, you will uncover that PS uses the same parameter to mean very different things for different commands, that the 'everything is an object' conceit doesn't work when the object you want doesn't exist, that PS is chock full of hacky, revolting cruft already despite its youth, hacky revolting cruft that makes oh-my-zsh look like /bin/rc, that most windows commands will fill your screen with banner(8) style output even on success, and that no two windows commands are alike.
Given which decade it was developed in, PowerShell represents the most absolute and fundamental failure of software I've had the pleasure of encountering in the last five years; and I've seen Windows 8.0. Anyone who thinks PowerShell is at all any good has, axiomatically, never seen any other shell besides cmd.exe before. You may think I'm exaggerating. Please, try the example above, then report back here with a list of what you had to do.
$hosts = 'host1','host2','host3'
$source = '\\host0\c$\source'
$dest = 'c:\dest'
$executable = 'C:\Program Files (x86)\Notepad++\notepad++.exe'
Invoke-Command -Computer $hosts -ScriptBlock {
Get-Process | Where-Object Path -eq $using:executable | Stop-Process -Force
Copy-Item -Path $using:source -Destination $using:dest
}
Explanation:Line 1-4: Set up variables to make the script more explanatory. Line 1 defines an array (the "," operator)
Line 6: Invoke-Command takes an array of (remote) hosts (the -Computer parameter) to execute the script block (the -ScriptBlock parameter).
Lines 7-9: The script to execute at each host simultaneously (the Invoke-Command executes the scripts in parallel at each host)
Line 7: Get the process list (Get-Process), pipe through the filter (Where-Object) which selects only the process(es) executing the desired executable, pipe those processes to the Stop-Process cmdlet which will forcably stop the process.
Line 8: Copy files from the desired source at an UNC path to the local machine at the destination
Now, the above script was the canonical way, using the long form. For casual scription, I could have written just this:
$hosts = 'host1','host2','host3'
$executable = 'C:\Program Files (x86)\Notepad++\notepad++.exe'
icm $hosts { ps | ? Path -eq $using:executable | kill -f; cp \\host0\c$\source c:\dest }Your solution finds the process to kill only if the executable path is at a known location.
How would you do this if you only know what the process name will be -- e.g., what if the executable path is on D:\stuff\gui.exe on host1 and E:\secretstuff\gui.exe on host2, if gui.exe always runs as a process named "Updatable GUI Thing"?
https://rkeithhill.wordpress.com/2009/05/02/powershell-v2-re...
and if that's not hair-raisingly terrifying enough (note the super-intuitive 'set-item wsman://...' call), you'll quickly find that when you start a program (which you left off) using a script remotely, it doesn't show up anywhere on-screen, despite being authenticated as the logged-in user, but it does show up in the process list. Guess why THAT is.
There are some pretty parts to PS; but they fall apart, at the touch, instantly, like fairy buildings made of dew.
Example needed.
The claim is surprising, given that there exists a PowerShell Command Line Standard which includes a list of parameter names and their semantics: https://technet.microsoft.com/en-us/library/ee156811.aspx#EM...
Really. That feels like quite an uncharitable statement. The only reason someone could think something that you don't like is good because they just don't know any better?
[it does generate annoyingly long error messages!]
$ErrorView = "CategoryView"
(unlike bash, whitespace is not significant)As for learning PowerShell, if you lean towards online training, Microsoft Virtual Acedemy has a really good series of courses, even featuring Jeffrey Snover - who is surprisingly good at explaining stuff.
This is a good starting point:
https://www.microsoftvirtualacademy.com/en-US/training-cours...
I usually prefer books/articles etc where I can set my own pace, but those online courses are really that good.
Otherwise links: * https://technet.microsoft.com/en-us/library/cc281945(v=sql.1... * http://learn-powershell.net/
And let's not forget the very friendly community at http://powershell.org/ with articles such as this one: http://powershell.org/wp/2015/07/31/introduction-to-powershe...
The only problem with PowerShell is that you need to write C# (or any other .NET language of course) if you want to create a real cmdlet (if I remember the name correctly). Other than that it's a quite nice shell and a sane procedural scripting language (again, with access to most of .NET).
The other, general problem with cmdlines/shells under Windows is the fact that they all work very differently than terminals that worked with type-writers 40 years ago. Which is what most console apps expect, for one reason or another, under Linux.
What you say was true for PowerShell 1.0. Since 2.0 you have been able to create cmdlets and modules through scripting. An "advanced function" with [CmdletBinding] attribute is a full-featured cmdlet.
Now at version 5.0, PowerShell even has native syntax for creating classes and enums.
> The other, general problem with cmdlines/shells under Windows is the fact that they all work very differently than terminals that worked with type-writers 40 years ago
Not sure I'm following. The straight PowerShell engine is the most basic (typewriter-like) shell. But if you think in terms of support for terminal control characters - like VT220 - you'd be right. However, that is per specification not part of PowerShell but rather part of the console/shell process hosting the engine. The engine does indeed feature a number of hooks to make rich interaction possible. That is why the same engine can be used in the (admittedly) rather basic console "command prompt" of Windows pre-10 as well as with the ISE and Windows 10's not wuite so embarrassing "command prompt".
Ok, I said I used it many years ago :) Thanks, it's good to know.
About the console/terminal emulation: PowerShell has way saner architecture in this regard. I wasn't clear enough, what I wanted to say is that on Linux we have terminal emulators which try their best to emulate (hence the name) physical hardware from ages ago. I was both impressed and seriously disturbed when I read this: http://www.linusakesson.net/programming/tty/ In short:
> In present time, we find ourselves in a world where physical teletypes and video terminals are practically extinct. Unless you visit a museum or a hardware enthusiast, all the TTYs you're likely to see will be emulated video terminals — software simulations of the real thing. But as we shall see, the legacy from the old cast-iron beasts is still lurking beneath the surface.
PowerShell simply ignores all the legacy cruft and doesn't even try to be compatible with 1940-era hardware. Which is, in my opinion, better and a sound technical decision, which resulted in much better architecture. The problem is that most Linux cmd-line apps expect to work under terminal emulators, not inside a modern environment PS provides.
PowerShell's commands ("cmdlets") are .NET classes within PowerShell, not arbitrary executables as in Unix shells. PowerShell's "object pipeline" is function chaining like in Ruby, not using OS-level pipelines as in Unix shells.
PowerShell is really just a .NET CLI, analogous to the Ruby's irb or Python's CLI, but dressed up to look like a Unix shell.