Powershell on Linux

A few days ago Microsoft has announced Powershell on Linux. You can get it from Powershell’s Github. This is a big announcement and perfectly complies with “Microsoft loves Linux” philosophy.

The installation (here, for Ubuntu 14.04) is pretty straightforward:

$ wget https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.9/powershell_6.0.0-alpha.9-1ubuntu1.14.04.1_amd64.deb
$ sudo apt-get install libunwind8 libicu52
$ sudo dpkg -i powershell_6.0.0-alpha.9-1ubuntu1.14.04.1_amd64.deb

So now, I can do this:

> c:\windows\system32\bash
$ whereis powershell
powershell: /usr/bin/powershell
$ powershell
PS> write-host "hello world!"
hello world!

Yay, look at that: Powershell on Bash on Windows :)

Of course, the important thing here is that the same works on a real Linux.

What works?

Note: This is PowerShell v6.0.0-alpha.9, so you can expect “Alpha-quality” and “things won’t work”.

Let’s take a look at available preinstalled modules:

PS> Get-Module -ListAvailable

    Directory: /opt/microsoft/powershell/6.0.0-alpha.9/Modules

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest    Microsoft.PowerShell.Archive        {Compress-Archive, Expand-Archive}
Manifest    Microsoft.PowerShell.Host           {Start-Transcript, Stop-Transcript}
Manifest    Microsoft.PowerShell.Management     {Add-Content, Clear-Content, Clear-ItemProperty, Join-Path...}
Manifest    Microsoft.PowerShell.Security       {Get-Credential, Get-ExecutionPolicy, Set-ExecutionPolicy, ConvertFrom-SecureString...}
Manifest    Microsoft.PowerShell.Utility        {Format-List, Format-Custom, Format-Table, Format-Wide...}
Binary    PackageManagement                   {Find-Package, Get-Package, Get-PackageProvider, Get-PackageSource...}
Script     3.3.9      Pester                              {Describe, Context, It, Should...}
Script    PowerShellGet                       {Install-Module, Find-Module, Save-Module, Update-Module...}
Script     0.0        PSDesiredStateConfiguration         {IsHiddenResource, StrongConnect, Write-MetaConfigFile, Get-InnerMostErrorRecord...}
Script     1.2        PSReadLine                          {Get-PSReadlineKeyHandler, Set-PSReadlineKeyHandler, Remove-PSReadlineKeyHandler, Get-PSReadlineO...

Note that PowerShellGet is available, so you should be able to install modules from Powershell Gallery:

PS> Install-Module PathUtils

But this seem to be broken for now:

    PackageManagement\Install-Package : Could not compare "6.0.0-alpha" to "5.0". Error:
    "Cannot convert value "5.0" to type "System.Management.Automation.SemanticVersion". Error:
    "Cannot process argument because the value of argument "version" is not valid. Change the value of the "version" argument and run the operation again.

There already is a fix for this particular problem. If you want to use that patch:

$ sudo cp /opt/microsoft/powershell/6.0.0-alpha.9/Modules/PowerShellGet/PSModule.psm1 /opt/microsoft/powershell/6.0.0-alpha.9/Modules/PowerShellGet/PSModule.psm1.bak
$ sudo wget https://raw.githubusercontent.com/bmanikm/PowerShell/97eb76cf9841faf1754028842ee5a1eb11516538/src/Modules/Shared/PowerShellGet/PSModule.psm1 -O /opt/microsoft/powershell/6.0.0-alpha.9/Modules/PowerShellGet/PSModule.psm1

And voila, Install-Module works.

Watch out: Unix is case-sensitive! Although Powershell is not, you have to use the right casing of module names. So Import-Module PathUtils will work, whereas Import-Module pathutils will fail. Also, the name of the psd1 file has to match exactly the name of the module (this is important for module maintainers).

Open source everything

As excited as I am with running PowerShell scripts on Linux, I think that the most important thing here is the open sourcing of PowerShell. If Microsoft didn’t prepare a version that runs on Linux, some other geek would probably do it (sooner or later). But the fact that I can now look into PS source code and see, how they do things, then tinker around and send a pull request is really amazing. I’ve been using Asp.Net Core for some time now and the possibility to just look at the source code proven invaluable a cuple of times.

It’s worth mentioning that there already exists an open source effort to reimplement Powershell: Pash. I wonder what will become of it now.


Taking aside the excitement of “because I can”, what are real benefits of using PowerShell on Linux, when you have Bash available at your disposal?

Build scripts

Up until now, cross platform .Net projects, like Dotnet CLI itself, used separate build scripts for Linux and Windows. Now, it will be possible to write one PowerShell script to rule them all. I personally have tons of build/deploy/other DevOps scripts written in PowerShell (and DSC). I would rather gladly test them on Linux and work around the rough edges than rewrite all that stuff in Bash (and maintain two separate versions).

If you think of dockerizing your services, the possibility to use the same scripts on Linux and Windows should make the transition much smoother.

Managing the cloud

If you are managing multiple Linux and Windows machines, you will be able to use the same shell and scripts for all of them. Also, as MS announcement says:

We will be extending the PowerShell Remoting Protocol (MS-PSRP) to use OpenSSH as a native transport. Users will have the option to use SSH or WINRM as a transport.

So, you will be able to do something like:

PS> Invoke-Command -ComputerName MyLinux { wtite-host "this is me executing remotely" }

And that will work over SSH, without the struggle of setting up WINRM.

What’s next

As of today, there are 322 issues, so Powershell 6 has some way to go before it’s “production ready”. But I’m not waiting until then - I’m starting to make my scripts and modules “cross-platform” with PowerShell 6 right now.