The biggest problem with C# and .Net is the Windows platform; very little on Windows can be automated. There is no sane shell. Everything assumes that there's a user clicking the mouse. And since that's the direction MS took, 3rd party devs followed suit. For anyone who has worked with another OS, Windows is fundamentally broken.
Think about it. Setup, Administration or Programming can't use any of the thousands of programs already written for the OS.
Most Microsoft-only developers don't get it. They usually say, "Oh, you should try Powershell". Powershell is, to put it mildly, 'utter crap'. They might have as well asked people to use a C# REPL with the .Net BCL.
I think your opening sentence is simply false; nearly everything on Windows can be automated these days, and usually without much pain. The real problem right now is that the WMI/WSH stacks, and the PowerShell stacks, overlap, but not completely; the right way to automate something requires knowing a lot about the old Windows automation stacks, and the new ones.
Let's take your example. The only reason it's shorter on Unix is that most Unix systems have programs called "zip" and "unzip". That's legitimate, but if we looked at e.g. modifying DNS, tweaking folder permissions, and a lot of other things, the PowerShell and bash/sh ways would be much closer. I'm not going to argue that PowerShell is a great language; I've been pretty public about hating it. But this isn't about whether Windows can be automated.
The real issue is that, for any given task, there's an easy way to do it in either the old COM-based WMI/WSH system, or in the PowerShell system, but not always both. Since we're on the topic of zipfiles anyway: the way I'd actually make a zipfile from a script would be to bust out the ol' "Scripting.FileSystemObject" COM object, which lets you pretend a zipfile is simply a folder, and which is merely a "$fso = New-Object -ComObject Script.FileSystemObject" away in PowerShell. One that bit us at work last week in a more real-world situation is that, while nearly all of Hyper-V is controlled via PowerShell, the network connection sharing settings are only available via COM interfaces, so allowing your Hyper-V machines to talk to the world still requires a trip back to the Windows 2000 administration handbook.
This stinks, and it needs to be fixed. I'll even grant that the situation might be worse than on many Unixes. But it's also totally automatable, and I'm not convinced that it's dramatically worse than other systems I've had to administer.
Until you have to cope with the fact that you have: Powershell cmdlets with their own specific behavior - mostly standardized; COM components loaded from Win32 - major pain in the neck - you basically need a huge brain to really understand all those rules and quirks; AND old school external commands - where all hell breaks loose since on Windows they couldn't standardize even the freaking exit codes (!0 is bad, fools, as Mr. T would say :) ). Yes, Powershell is usable, but it's really hard to write secure, reliable, maintenable scripts with it...
Your zip example actually demonstrates why Powershell is significantly more powerful than Bash (or any other Unix shell). I presume that if asked "How do you zip a file in Bash?" you would reply with something like this:
zip archive.zip folder
The equivalent Powershell code would look like this:
7zip a archive.zip folder
Pretty much exactly the same, since in both cases the shell isn't doing anything other than invoking a standalone executable. So this doesn't really tell us anything at all about the relative merits of Bash and Powershell. A better comparison would be this: how do you zip a folder in Python? Again via Stackoverflow (http://stackoverflow.com/questions/1855095/how-to-create-a-z...):
import os
import zipfile
def zipdir(path, zip):
for root, dirs, files in os.walk(path):
for file in files:
zip.write(os.path.join(root, file))
if __name__ == '__main__':
zip = zipfile.ZipFile('Python.zip', 'w')
zipdir('tmp/', zip)
zip.close()
Compare that to your Powershell example, and I think you'll agree that the .NET API is nicer to use (heh, don't say that very often). But to return to the subject, how do you zip a folder in Bash? YOU CAN'T. Bash can't zip folders. It can't call libraries that can zip folders. It can only invoke programs that can zip folders. And any shell, even the wretched cmd.exe, can do that.
I have plenty of problems with Powershell but it is by far the best effort at a shell that the world has yet seen. I come from a Linux background and when asked what I like about working on Windows, I reply with "well, it's got a nice shell." Usually gets me a weird stare, but if we're really comparing shells to shells (and not shells to a wide variety of standalone utilities) then Powershell blows everything else out of the water.
I actually don't like PowerShell, I don't like the verbosity of it all.. it's easy enough to get most unix tools in Windows (minw) variants... put these into a folder added to your path, and most stuff just works the same, or very similar. I tend to use the command line tools, and piping, or I'll use node.js scripts, which work pretty much the same everywhere I need them...
The only differences are nssm for windows services, and init.d for linux ... haven't had to setup any background/startup services on my mac yet, so not sure what it uses.
I don't get why people hate windows so much as a rule, I really like the Win7 UI (not a fan of 8, but can see how some would be)... Also, warming up to Unity (more than win8)
Agree about PowerShell. It's not just that the scripting language sucks, which as you show it does. But nearly everything about PowerShell is bad. For example:
1) It takes a good 4 or 5 seconds to boot PowerShell. This is unacceptable, a terminal emulator should boot near instantaneously.
2) Cmdlets are really freaking hard to write or use. It's hard for users to enable them, it's hard for users to install them, and it's especially hard for programmers to create them. Unix shells are much easier for all parties involved.
1: Just a note, PS is a shell, not a terminal emulator. And yes, Windows could really use a decent terminal program - the standard console is terrible.
2: The hard-to-enable is a result of Microsoft's pro-security standing. They got a bad rep for allowing scripts to run freely in the past, so they tried to lock it down.
As far as developing and using them, I dunno, it seems vastly better than bash. Sane quoting that helps avoid injection mistakes. Auto-complete built-in throughout the system. Actual types, instead of just passing strings everywhere. And they ship a nice little editor/debugger with it, if you'd like that kind of thing.
No, cmdlets are hard to develop. You have to follow a hard-to-understand API that doesn't ship with the operating system. With bash it is stdin and stdout... that's all you really need to know to write any shell script. With PowerShell you have to write a very particular type of script that compiles to .NET (and again DOES NOT SHIP WITH THE OS); your language choices are limited to about 3. Interoperability is important to something as fundamental as shell scripting and PowerShell is not interoperable.
I lost you on your "Does not ship with the OS" point. What are you referring to?
PowerShell has shipped with the OS since WS 2008 and Vista. We have ALSO made it available to prior versions of the OSes (e.g. down to XP.
I also missed your point about interoperability of shell scripting and PowerShell.
PowerShell can launch any process, pipe data to it and read/parse the data that it generates.
PowerShell can be launched by any process and read/write text.
So when you say "interoperate" that is what I'm thinking of so I think they interoperate well. Are you referring to something else or are you experiencing a problem?
Thanks!
Jeffrey Snover [MSFT]
Distinguished Engineer and Lead Architect for Windows Server and System Center
> I lost you on your "Does not ship with the OS" point. What are you referring to?
The SDK for developing cmdlets. This would be equivalent if on unix you needed an extra download to write to stdout/stderr.
> So when you say "interoperate" that is what I'm thinking of so I think they interoperate well. Are you referring to something else or are you experiencing a problem?
Cmdlets can only be developed by languages created by Microsoft. You cannot write a cmdlet in Python, Perl, or even C.
The app tends to boot fast but you have to wait for .NET to warm up before you can use it. I'm talking about usability time. It's also much faster after you've initially opened the app.
1) What version are you running?
We had a problem with earlier versions that didn't NGEN and had startup delays.
With V2 we made it so you can write cmdlets in PowerShell itself which is pretty simple.
With V3 we added auto-loading of Modules which allowed Xcopy deployments and simplified discovery.
We just released V4 so you might want to give a more recent version a try.
2) What don't you like about the language? Is it just personal preference or are there things you can't do or are too hard to do?
Thanks!
Jeffrey Snover [MSFT]
Distinguished Engineer and Lead Architect for Windows Server and System Center
That is an absolutely fair rock to throw. What we find is that if PowerShell has a cmdlet for what you want to do, it is pretty simple to work with (modulo personal syntax preferences). If there isn't a cmdlet, then you can usually get the job done but you need to roll up your sleeves and do some coding (or searching/downloading).
This is not that different than Unix BUT because so much of Unix is done using ASCII text files, the coding is really manipulating text files which can be done easily by admins. Windows is an API-oriented OS (vs a document-oriented one) which means that the coding looks much more like programming than in Unix.
The solution is to have the cmdlets you need. We are making great progress on that front but the reality is that Unix has about a 30 year head start so it will take us a while. In V2 we had ~240 cmdlets and in V3 we had ~2,400 cmdlets. (Sadly, ZIP/UNZIP are not among them). We added more in V4 and are extending our focus (from IT pros) to devops with features like Desired State Configuration. That is very much of a minimal viable product but I think we got it basically right and there is a lot of energy around this.
I appreciate the criticisms and encourage you do continue making them and don't hold back - we really do read these and use them to make the product better. Politeness is optional but we would really appreciate specificity (like you provided here).
Please let us know other things that we should be adding, doing differently or stop doing.
Thanks!
Jeffrey Snover [MSFT]
Distinguished Engineer and Lead Architect for Windows Server and System Center
That has nothing to do with Windows as an Operating System -- thats just part of the tooling that is included. Feel free to install additional tools into the PATH on Windows and get the same capabilities.
A lack of understanding of how to do something on a very different OS != you can't do it.
I very much dislike PowerShell personally but its incredibly capable in modern versions of windows. We use it with Chef to automate our server configuration/setup.
> as an Operating System -- thats just part of the tooling that is included
An operating system includes the tooling that comes with it. This is what distinguishes Debian from other linux distributions: what tooling comes with it? It matters because it directly determines what you as a user can get done quickly, without needing to go through the trouble of installing additional functionality. (Or, as a developer, what you can do without needing to distribute or include additional functionality.)
Windows is particularly bare in what it comes with: many tasks that I need to accomplish require additional tools. I often field questions of "how to do X on Windows?" that cause me to think, "well, this is a built-in command in Linux… in Windows, you could download X or Y, but they're not scriptable to what you want to do…"
This is what drove me to Linux: The batteries are included. And they're scriptable.
Does it require you to open a browser and download the software?
Does it require you to FTP to a server to grab the file?
Does it require the server to fetch it via network file system and launch the installer UI?
Do you have to add the tool to "PATH" on windows? (unless the installer does it for you... which is variably on Windows platform).
The culture of Windows platform unfortunately dictates you how to use Windows as an OS.
Now let's go to Development Code type of dependencies (we're talking about libraries and stuffs here).
NuGet has reached the "accepted" level of dependency management _recently_ (for a while in the past, it couldn't download the Source Code as well. Maven, RubyGems, and others can) while other platforms have dependency management for years _and_ integrated to developer daily workflow.
What about scripting the build for .NET type of development? I don't know the exact number but I still see people not using MSBuild (or even know what it is) or NAnt.
Most Java IDEs would generate build.xml for your project and would provide you hints that you should be using that instead of "Build Project" (or perhaps the "Build Project" is tied to Ant, by default).
Besides, both MSBuild and NAnt are painful compare to Maven, lots of boilerplate stuff to setup.
What about Continuous Integration and Deployment? Microsoft didn't build one for a while (not sure if they've built one and baked it into TFS) and y'all have to rely on CruiseControl or TeamCity or Bamboo or something else.
I recently interviewed a senior .NET developer who said to me that he deploy his ASP.NET project from VS.NET IDE (like y'know... hitting F5 or something) to the Production server!
Let's take it a little bit further: Docker and Vagrant are useful tools for automation testing. Docker doesn't exist in Windows. Preparing Vagrant for Windows require you to have licenses and probably you have to figure out how to script software installation (you could cheat a little bit by preparing a Windows OS + a base software installed). Compare that to Ubuntu on Vagrant: breezy.
I think the pattern is rather quite obvious: Microsoft/.NET community has always been behind everybody else.
At the end of the day: you cannot automate the process of calling a Sales person in order to get the software, which, in the F/OSS world, such workflow doesn't exist.
You've move the goalposts a bit here, but for the sake of discussion...
On windows we have Chocolatey available to help with application-level package management, granted you need to install it first but I would argue thats not much different than needing to add a PPA or new apt source before apt can install the right app/version you're looking for..
It isn't perfect but its getting better. No UIs launched, all done via console. Handles adding items to the path, handles portable executables, etc.
NuGet is great, apart from a few issues and has been in that state for quite some time. Not sure why we require things to be good for a decade before we're ready to talk kindly about them without the air quotes.
There are a ton of tools for scripting .NET builds but the real trick is that most people don't need to do anything 'special'.
msbuild Solution.sln or msbuild Project.csproj
Your project files can include any number of pre/post build targets to handle any scenario you can imagine. Again, not perfect but manageable. If this isn't to your liking you can use all the build tools for other languages if you like.. Many people like Rake as a general purpose tool and others have done the work of providing msbuild integration there for you.
Your .csproj file is built for you by Visual Studio (or by hand if you wish) and from there you can add much of what you need for your builds. I have worked on several very very large codebases for enterprise projects and there has never been any serious amount of 'boilerplate' to setup for builds.
What about Continuous Integration and Deployment? Microsoft didn't build one for a while (not sure if they've built one and baked it into TFS) and y'all have to rely on CruiseControl or TeamCity or Bamboo or something else.
For CI, you can use TFS if you wish (really, really easy to do but somewhat limited in its ease of customization), or Jenkins, TeamCity, CC, Bamboo, whatever.. Its the same for any language. Pick a CI tool, install it, use it. Hardly a weakness of one platform over another.
As far as deployment, that depends on the type of application you're building. Could be as easy as a git push that deploys to Azure/AppHarbor or it could by a PowerShell script or possibly a ClickOnce deployment. Any one of these can be triggered from the VS IDE.
I recently interviewed a senior .NET developer who said to me that he deploy his ASP.NET project from VS.NET IDE (like y'know... hitting F5 or something) to the Production server!
Certainly this must be the norm then. Capability to deploy from the IDE is great for testing but the same things are available for scripting to put in a real deployment process.
Let's take it a little bit further: Docker and Vagrant are useful tools for automation testing. Docker doesn't exist in Windows. Preparing Vagrant for Windows require you to have licenses and probably you have to figure out how to script software installation (you could cheat a little bit by preparing a Windows OS + a base software installed). Compare that to Ubuntu on Vagrant: breezy.
Yes, containers are great. Windows doesn't have them in the sense that Linux does with LXC. Vagrant can and does work well on Windows. The licensing situation isn't as you think though for most .NET devs - they are likely working with MSDN provided software which provides licenses. As for scripting installs, again - chocolatey. Vagrant + chef is a win on any platform. I do wish it worked with Hyper-V client services properly though.
At the end of the day: you cannot automate the process of calling a Sales person in order to get the software, which, in the F/OSS world, such workflow doesn't exist.
At the end of the day: people believe what they want to believe. Windows as a platform is incredibly capable. Its not perfect and it can't compete on every level but it is getting better constantly.
I work with Windows daily - using .NET, Node.js, Ruby, Python and more. I also work with Linux daily doing the same things. The biggest issues I encounter have more to do with package developers using non-portable code than anything.
I definitely agree with you that Microsoft is listening on the server side. The biggest change that really made me realize this was with the release of Windows Server core.
Also, the release of PowerShell as the glue for automation has really made so many things possible. PowerShell is not perfect but it is definitely making a difference in the Windows ecosystem.
Sometimes it seems that people that are criticizing Windows are still stuck in the Windows 2003 world and pre-Powershell days.
One can basically automate Exchange, SQL Server, IIS etc. using Powershell. Granted, there may be still edge cases, but for the most part it's all there.
This is empirical but I also feel that over the last 5-6 years Microsoft has really started to take the best of linux and open source and start to incorporate it into its ecosystem. There are still scenarios where this is not the case but I do notice the trend.
I echo the other reply, thanks for writing long detailed response. MS does try to improve albeit slow and ugly (but that is for another discussion altogether).
Having said that they are always behind (that seems to be the trend).
IMO the problem with bash piping is that it's just text streams. Which means you end up having to do all sorts of text manipulation tasks if something outputs a complex object. Compare to, say, PowerShell, which pipes objects along. You can treat them as a text representation, or operate on their properties without having to embed a little parser.
I'm not sure what about F#'s piping syntax (it's just reversed function application) blows bash away, though.
FWIW:
F# ships a standard definition for the operator |> as "let (|>) x f = f x".
Hence you can do e.g. "123 |> write" instead of "write 123". In practise this leads to normal chaining of map/reduce and other list manipulations. In F#, this operator also gains attention as F#'s inference is left-to-right, so suppose you have a list of strings "xs". Without piping, you might write:
Again, you are piping functions, not programs. Piping programs is important to shell scripting. This is actually very hard in PowerShell. I've written a few cmdlets; it is hard. And even harder for the user.
Can you provide an example of some task which is easy in a shell script (sh) and difficult in PowerShell? Perhaps something related to piping?
I've written a few .sh scripts here and there and I use PowerShell occasionally; I'm nowhere near an expert in either though, so a concrete example would make it easier to understand your point about PowerShell being more difficult.
Both of those links require a browser plugin that I'm not going to install. From the url's I'm guessing this is about piping functions? I'm not asking about that, I'm asking about piping commands (programs), something any shell scripting language needs to be able to do.
Mono works just well enough to convince people that C#/.NET is an acceptable cross platform solution. By the time they realise it's so buggy and unreliable compared to .NET that they'll have to shell out for Windows licenses, they're stuck with it.
See, for instance, keithwarren's comments in this discussion: he hypes up Mono-based cross-platform support in what's currently the top comment on this submission[1], but when someone who's actually tried Mono replies and talks about the problems they've had with it, he makes it clear that they should shut up, forget about Mono and use Windows[2].
The first time I used Mono in a production environment (part of a payment connector running on a Linux system) was around a decade ago.
Since then I've had daemons running 24/7 doing telecom processing (either routing decisions or call record management), written in F#, running on Mono. We build, debug, etc. on Windows, then deploy the binaries to Linux. It works surprisingly well. These aren't massive systems, and I tend to deplore the handful of core systems (i.e. website) on Windows but all the actual call handling goes on Windows.
The real problem with Mono was the naive GC which for some applications had very degenerate and broken behaviour. AFAIK, the sgen GC has cleared that all up.
Your characterization of the comments are very misleading.
There is also jscript, it's been there for a long time and can be very powerful! It's available also on machines that don't have powershell installed (like windows xp).
I agree. I'm very proficient on any version of Windows but when I started learning web development I was stunned by how hard everything was in Windows. In fact, my immense displeasure with Windows as a development platform is what drove me to consider Linux and Mac. And one I discovered that both of those platforms offer significantly saner development workflows, I've never looked back. Now I use Windows exclusively for Excel and Access. Everything else is done in Linux or Mac.
Think about it. Setup, Administration or Programming can't use any of the thousands of programs already written for the OS.
Most Microsoft-only developers don't get it. They usually say, "Oh, you should try Powershell". Powershell is, to put it mildly, 'utter crap'. They might have as well asked people to use a C# REPL with the .Net BCL.
Edit: I should explain a bit.
How do you zip a folder? via http://stackoverflow.com/questions/1153126/how-to-create-a-z...
You see the problem?