So a few weeks ago I decide to learn some powershell in order to set up a backup routine for some mission critical systems. One would expect that Microsoft would have put something together that was useful to *nix heads, in fact all they did was succeed in frustrating me.
Why is this? Well here in a nutshell are my complaints:
- Powershell uses pipes are used for intra process communication. They move objects around. That’s all well and good, but pipes are historically used by shells for inter process communication.
- Redirection locks files so that you cannot read them as they are being written. Terrific, so I cannot monitor powershell process that are launched in the background.
- Redirection of standard error mangles the output. Why is it that such a good thing?
Here
1# ruby -e "STDERR.puts %Q[I AM AN ERROR]" 2> file
2# cat file
ruby.exe : I AM AN ERROR
At line:1 char:5
+ ruby <<<< -e "STDERR.puts %Q[I AM AN ERROR]" 2> file
So what the hell is going on here? But that’s not the end of it:
- I cannot (easily) launch process in the background, so forget launching something that writes to a log, then tailing the log. This really hinders whating the progress of scheduled tasks. As to shell transcripts; yeah I tried that. Big failure.
- This last one I think really put me over the edge. If I use Mark Russinovich’s
psexec.exeto launch a terminal session, I get nothing, zip.
C:\>psexec \\appserver cmd.exe
PsExec v1.94 – Execute processes remotely
Copyright (C) 2001-2008 Mark Russinovich
Sysinternals – www.sysinternals.com
Microsoft Windows [Version 5.2.3790]
(C) Copyright 1985-2003 Microsoft Corp.
C:\WINDOWS\system32>powershell -command "echo hello"
*nothing*
Yes, where I typed the word “*nothing*” is where nothing is returned. It just hangs there. Some shell! Obviously powershell does not want to play well with others. I’ll be this is a feature!
- Shell transcripts do not capture standout output of child process. I didn’t bother trying to work around this. By this time I decided to redo everything in perl or ruby if I ever have the chance.
Lets look at the powershell answer to *nix "find"
1# get-childitem C:\windows\system32 | where {$_.extension -eq ".log"}
Directory: Microsoft.PowerShell.Core\FileSystem::C:\windows\system32
Mode LastWriteTime Length Name
—- ————- —— —-
-a— 8/10/2009 12:35 PM 90 spupdwxp.log
-a— 4/16/2009 2:32 PM 211792 TZLog.log
Good luck trying to pipe that into pkzip or 7zip as a list of input filenames! As to the commandlets to format this stuff, I don’t want to do extra work to coerce my output into a simple format. (POSIX calls them builtins, but why not come up with a trademarked term. What a great idea!)
At this point I rest my case. Powershell exists only as a platform to prevent stringing programs together, which is contrary to the essential purpose of a shell. I am sure the party line response is to re-write everything in dotNet. Well sure, but the point of a shell is to allow you to quickly get work done, not to force you to re-write everything. Or maybe Microsoft doesn’t see it quite that way?
Powershell is a terrific example of "embrace and extend" and then break it as cleverly as possible!
