This is an article realized for StarWind blog and focused on how use PowerShell (Core) on Linux system. See also the original post.
PowerShell is a command line (CLI) scripting language developed by Microsoft to simplify automation and configuration management, consisting of a command-line shell and associated scripting language.
It’s a (huge) evolution (or better a revolution) from the original DOS batch language (still supported in latest Windows OS with the cmd.exe command), and it’s really better compared to the different previous attempts to replace the batch language (like Windows Script Host).
https://www.starwindsoftware.com/blog/using-powershell-on-linux
PowerShell Introduction
PowerShell is a command line (CLI) scripting language developed by Microsoft to simplify automation and configuration management, consisting of a command-line shell and associated scripting language.
It’s a (huge) evolution (or better a revolution) from the original DOS batch language (still supported in latest Windows OS with the cmd.exe command), and it’s really better compared to the different previous attempts to replace the batch language (like Windows Script Host).
Windows PowerShell (actually at version 5.1) is the edition of PowerShell built on top of .NET Framework (sometimes referred to as “FullCLR”). Because of its dependency on the .NET Framework, Windows PowerShell is only available on Windows (hence the name). The released versions of Windows PowerShell include 1.0, 2.0, 3.0, 4.0, 5.0, and 5.1. Windows PowerShell is launched as powershell.exe.
PowerShell initially was a Windows component only, known as Windows PowerShell, but recently it was made open-source and cross-platform on 18 August 2016 with the introduction of PowerShell Core.
PowerShell Core uses .NET Core 2.0 as its runtime (sometimes simplified to “CoreCLR”), that enables PowerShell Core to work on multiple platforms, thanks to the cross-platform nature of .NET Core.
PowerShell Core also exposes the API set offered by .NET Core 2.0 to be used in PowerShell cmdlets and scripts. Windows PowerShell used the .NET Framework runtime to host the PowerShell engine.
PowerShell it’s cross-platform and this means that now you can run it, of course, on Windows, but also on several different Linux distributions, on MacOSX 10.12 and also on ARM platform!
The list of supported Linux distributions is quite good: Ubuntu 14.04, Ubuntu 16.04, Ubuntu 17.04, Debian 8, Debian 9, CentOS 7 (and also Oracle Linux 7), Red Hat Enterprise Linux (RHEL), OpenSUSE 42.2, Fedora 25, Fedora 26, Arch Linux.
All packages are available on Microsoft’s GitHub releases page.
All those distributions have a simple package repository that you can add (this task depends on the distribution) and then you can simply add the powershell package.
For example, for CentOS 7, Oracle Linux 7 or RHEL7:
1
2
3
4
5
|
# Register the Microsoft RedHat repository
curl <a href=“https://packages.microsoft.com/config/rhel/7/prod.repo” target=“_blank”>https://packages.microsoft.com/config/rhel/7/prod.repo</a> | sudo tee /etc/yum.repos.d/microsoft.repo
# Install PowerShell
sudo yum install –y powershell
|
Latest stable release is version 6.0.2: https://github.com/PowerShell/PowerShell/releases/tag/v6.0.2
But there is already also the first preview of the new v6.1: https://github.com/PowerShell/PowerShell/releases/tag/v6.1.0-preview.1
For Linux, PowerShell builds portable binaries for all Linux distributions. But .NET Core runtime requires different dependencies on different distributions, and hence PowerShell does the same.
The following table shows the .NET Core 2.0 dependencies on different Linux distributions that are officially supported.
OS | Dependencies |
Ubuntu 14.04 | libc6, libgcc1, libgssapi-krb5-2, liblttng-ust0, libstdc++6, libcurl3, libunwind8, libuuid1, zlib1g, libssl1.0.0, libicu52 |
Ubuntu 16.04 | libc6, libgcc1, libgssapi-krb5-2, liblttng-ust0, libstdc++6, libcurl3, libunwind8, libuuid1, zlib1g, libssl1.0.0, libicu55 |
Ubuntu 17.04 | libc6, libgcc1, libgssapi-krb5-2, liblttng-ust0, libstdc++6, libcurl3, libunwind8, libuuid1, zlib1g, libssl1.0.0, libicu57 |
Debian 8 (Jessie) | libc6, libgcc1, libgssapi-krb5-2, liblttng-ust0, libstdc++6, libcurl3, libunwind8, libuuid1, zlib1g, libssl1.0.0, libicu52 |
Debian 9 (Stretch) | libc6, libgcc1, libgssapi-krb5-2, liblttng-ust0, libstdc++6, libcurl3, libunwind8, libuuid1, zlib1g, libssl1.0.2, libicu57 |
CentOS 7 Oracle Linux 7 RHEL 7 OpenSUSE 42.2 Fedora 25 |
libunwind, libcurl, openssl-libs, libicu |
Fedora 26 | libunwind, libcurl, openssl-libs, libicu, compat-openssl10 |
In order to deploy PowerShell binaries on Linux distributions that are not officially supported, you would need to install the necessary dependencies for the target OS in separate steps. Unfortunately, the real dependencies are not easy to guess and could be quite difficult.
For Linux distributions that are not officially supported, you can try using the PowerShell AppImage. Using a recent Linux distribution, download the AppImage from the releases page into the Linux machine. This is a binary version that will help you in the dependencies, if possible.
Note that actually the latest version of AppImage it’s only the version 6.0.1:
1
2
3
4
5
6
7
8
|
# Grab the latest App Image
wget <a href=“https://github.com/PowerShell/PowerShell/releases/download/v6.0.1/powershell-6.0.1-x86_64.AppImage” target=“_blank”>https://github.com/PowerShell/PowerShell/releases/download/v6.0.1/powershell-6.0.1-x86_64.AppImage</a>
# Make executable
chmod a+x powershell–6.0.1–x86_64.AppImage
# Start PowerShell
./powershell–6.0.1–x86_64.AppImage
|
Another option is just to grab the binaries files, that are more recently:
1
2
3
4
5
|
# Create the destination directory
mkdir –p /opt/microsoft/powershell; cd /opt/microsoft/powershell
# Grab the latest stable version
wget <a href=“https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-linux-x64.tar.gz” target=“_blank”>https://github.com/PowerShell/PowerShell/releases/download/v6.0.2/powershell-6.0.2-linux-x64.tar.gz</a>
|
or
1
2
|
# Grab the preview version
wget <a href=“https://github.com/PowerShell/PowerShell/archive/v6.1.0-preview.1.tar.gz” target=“_blank”>https://github.com/PowerShell/PowerShell/archive/v6.1.0-preview.1.tar.gz</a>
|
Then
1
2
3
4
5
6
7
8
|
# Extract the file
tar zxf PowerShellFileName.tar.gz
# Set execute permissions
sudo chmod +x pwsh
# Start PowerShell
./pwsh
|
But in both cases, you will expect several issues, for example in libraries dependencies.
For example, on a CentOS 6.9 system (64 bit version):
1
2
3
4
5
6
7
|
[root@centos6 tmp]# ./pwsh
./pwsh: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.18‘ not found (required by ./pwsh)
./pwsh: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.17′ not found (required by ./pwsh)
./pwsh: /usr/lib64/libstdc++.so.6: version `CXXABI_1.3.5‘ not found (required by ./pwsh)
./pwsh: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14′ not found (required by ./pwsh)
./pwsh: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15‘ not found (required by ./pwsh)
|
Libraries dependencies is totally a mess, maybe was better provide those binaries with the option of static link to the required libraries, instead of relay on external shared libraries.
And it’s not so easy fix the requirements, for example on a CentOS 6.9 the installed libstdc++ library is quite old:
1
2
|
rpm –qa | grep libstdc++
libstdc++–4.4.7–18.el6_9.2.x86_64
|
Trying to install a more recent lib from the repositories does not work, because it’s still too old:
1
|
yum install libstdc++.so.6
|
Also PowerShell AppImage does not help at all:
1
2
|
[root@centos6 tmp]# ./powershell-6.0.1-x86_64.AppImage
./powershell–6.0.1–x86_64.AppImage: error while loading shared libraries: libfuse.so.2: cannot open shared object file: No such file or directory
|
You can fix the first requirement easily by installing the fuse-libs package (fuse-libs-2.8.3-5.el6.x86_64)
But then you will again have the issues with the shared libraries:
1
2
3
4
5
|
[root@centos6 tmp]# ./powershell-6.0.1-x86_64.AppImage
which: no desktop–file–validate in (/tmp/.mount_GlYLI6/usr/bin/:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin)
desktop–file–validate is missing. Skipping /tmp/.mount_GlYLI6/usr/bin/pwsh.wrapper.
/tmp/.mount_GlYLI6/usr/bin/pwsh: /lib64/libc.so.6: version `GLIBC_2.14‘ not found (required by /tmp/.mount_GlYLI6/usr/lib/libstdc++.so.6)
/tmp/.mount_GlYLI6/usr/bin/pwsh: /lib64/libc.so.6: version `GLIBC_2.17′ not found (required by /tmp/.mount_GlYLI6/usr/lib/libstdc++.so.6)
|
There is a dirty trick that potentially can help, and it’s use the libraries packages from the CentOS 7 distribution or another distribution from pkgs.org, then unpack them.
For example for libstdc++:
1
2
3
4
5
6
7
8
9
|
# Get the CentOS7 package
wget http://mirror.centos.org/centos/7/os/x86_64/Packages/<a id=”post-7919-_Hlk511964957″></a>libstdc++-4.8.5-16.el7.x86_64.rpm
# Extract the package and copy the lib in /usr/local/lib
rpm2cpio libstdc++–4.8.5–16.el7.x86_64.rpm |cpio –idmv
cp ./usr/lib64/libstdc++.so.6.0.19 /usr/local/lib
# Run pwsh with the custom lib
LD_PRELOAD=/usr/lib/local/lib/libstdc++.so.6.0.19 ./pwsh
|
But it’s not enough, because there are a lot of other libraries that are needed.
Is too much easy using a latest distribution and install just a package. For CentOS7:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
[root@centos7 ~]# sudo yum install -y powershell
Loaded plugins: fastestmirror
base | 3.6 kB 00:00
extras | 3.4 kB 00:00
packages–microsoft–com–prod | 2.9 kB 00:00
updates | 3.4 kB 00:00
packages–microsoft–com–prod/primary_db | 85 kB 00:00
Loading mirror speeds from cached hostfile
* base: mi.mirror.garr.it
* extras: centosmirror.netcup.net
* updates: mi.mirror.garr.it
Resolving Dependencies
—> Running transaction check
—-> Package powershell.x86_64 0:6.1.0~preview.1–1.rhel.7 will be installed
—> Processing Dependency: libunwind for package: powershell–6.1.0~preview.1–1.r hel.7.x86_64
—> Running transaction check
—-> Package libunwind.x86_64 2:1.2–2.el7 will be installed
—> Finished Dependency Resolution
Dependencies Resolved
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
powershell x86_64 6.1.0~preview.1–1.rhel.7 packages–microsoft–com–prod 49 M
Installing for dependencies:
libunwind x86_64 2:1.2–2.el7 base 57 k
Transaction Summary
================================================================================
Install 1 Package (+1 Dependent package)
Total download size: 49 M
Installed size: 50 M
|
That’s it, isn’t simple? And just stating from a minimal installation using the minimal ISO of CentOS.
Using PowerShell Core
Once you installed PowerShell, to start the PowerShell console/session you can run the pwsh from a local terminal or a remote SSH session.
Note that actually, PowerShell Core provides only a subset of all the available PowerShell commands!
Just compare the available modules in Linux and Windows and the difference is huge:
But it’s just a first step.
To view the version of the PowerShell, enter:
1
|
$PSVersionTable
|
Then you can start using PowerShell command, but note that the output could be different if you run on Linux or on a Windows system. For example, compare the result of the command:
1
|
Get–Process
|
Note that on Linux, also if the OS is case sensitive, you can run the commands in the PowerShell sessions in lower case and the command will be converted with the right capital letters. And like it happen on Windows, you can still use all the other command from the standard CLI (like ls, for example).
Also, like in the bash, you can have some command aliases. To view the list of available aliases, run:
Get-Alias
Remote PowerShell
The beauty of PowerShell on Windows is the ability to launch remote sessions, in this way you can use your client and manage different servers.
A PowerShell remote session communicates using Windows Remote Management (WinRM), that is an implementation of the Web Services for Management (WS-Man) specification.
The network channel requires a HTTP (TCP port 5985) or HTTPS (TCP port 5986) connection, usually utilized on “traditional” XML/SOAP web services.
Linux supports WS-Man through a combination of PowerShell Remoting Protocol (MS-PSRP) and an Open Management Infrastructure (OMI) provider. OMI is a standard interface for exposing Common Information Model (CIM) data on non-Windows systems. OMI can be downloaded from The Open Group: Open Management Infrastructure (OMI).
1
2
3
4
5
6
7
8
9
|
# Download and install the OMI (Open Management Infrastructure) package:
# More information on OMI can be found at: <a href=”https://github.com/Microsoft/omi” target=”_blank”>https://github.com/Microsoft/omi</a>
wget <a href=“https://github.com/Microsoft/omi/releases/download/v1.4.2-2/omi-1.4.2-2.ssl_100.ulinux.x64.rpm” target=“_blank”>https://github.com/Microsoft/omi/releases/download/v1.4.2-2/omi-1.4.2-2.ssl_100.ulinux.x64.rpm</a>
rpm –ihv omi–1.4.2–2.ssl_100.ulinux.x64.rpm
#Download and install the PSRP package
wget <a href=“https://github.com/PowerShell/psl-omi-provider/releases/download/v1.4.1-28/psrp-1.4.1-28.universal.x64.rpm” target=“_blank”>https://github.com/PowerShell/psl-omi-provider/releases/download/v1.4.1-28/psrp-1.4.1-28.universal.x64.rpm</a>
rpm –ihv psrp–1.4.1–28.universal.x64.rpm
|
To configure the Linux machine for WSMAN, you’ll need to open the right port in the personal firewall:
1
2
|
firewall–cmd —add–port=5986/tcp —permanent
firewall–cmd —reload
|
Now you can run a PowerShell session from another system.
For example, from a Windows 10 client:
1
2
3
|
$Options = New–PSSessionOption –SkipCACheck –SkipRevocationCheck –SkipCNCheck
Enter–PSSession –ComputerName 192.168.233.130 –Credential root –Authentication basic –UseSSL –SessionOption $Options
$PSVersionTable
|
Nice, isn’t it?
But why using PowerShell?
For Windows system is quite clear that it’s the main command line but also the primary way to configure a Window system (from CLI you can do more compared from the CLI, as discussed in a previous post).
But why using PowerShell instead of other (cross-platform) languages? And why on Linux?
One reason is the beauty of the language and the powerful capability of the object-piping.
For example, let’s consider that you need the PID of the crond service. Using the ps command provide this information on a fixed formatting, but you need to filter it with grep to find the right line (and maybe you can found more lines).
1
2
3
4
|
[root@centos7 ~]# ps -aux | grep cron
root <strong>674</strong> 0.0 0.1 126268 1704 ? Ss 08:35 0:00 /usr/sbin/crond –n
root 2224 0.0 0.1 125332 1104 ? Ss 09:01 0:00 /usr/sbin/anacron –s
root 6092 0.0 0.0 112660 972 pts/0 R+ 09:45 0:00 grep —color=auto cron
|
The you need other tools (like cut command) to select the right part. Not easy and this is an easy case, because the columns are fixed!
Let’s see the same with PowerShell:
1
2
|
PS /root> Get–Process –Name crond | % { $_.Id }
674
|
Another reason, very interesting for VMware vSphere admin (but there is something similar also for other VMware’s products), it’s using PowerCLI from Linux machine! I will discuss this option on a future post.
Another reason is using the DSC (Desired State Configuration). Windows PowerShell Desired State Configuration (DSC) is a configuration management platform to function reliably and consistently in each stage of the deployment lifecycle (development, test, pre-production, production), as well as during scale-out. To learn more, there is a nice article (https://www.upguard.com/blog/articles/declarative-vs.-imperative-models-for-configuration-management) that describe the difference between declarative and imperative models.
The following Linux operating system versions are supported for DSC for Linux.
- CentOS 5, 6, and 7 (x86/x64)
- Debian GNU/Linux 6, 7 and 8 (x86/x64)
- Oracle Linux 5, 6 and 7 (x86/x64)
- Red Hat Enterprise Linux Server 5, 6 and 7 (x86/x64)
- SUSE Linux Enterprise Server 10, 11 and 12 (x86/x64)
- Ubuntu Server 12.04 LTS, 14.04 LTS and 16.04 LTS (x86/x64)
Desired State Configuration for Linux requires the Open Management Infrastructure (OMI) CIM server, version 1.0.8.1 or later.
If you already have installed OMI (needed also for WS-Man) you just need DSC:
1
2
3
4
5
|
# Download and install the DSC for Linux package:
# (Other packages can be found at: <a href=”https://github.com/Microsoft/PowerShell-DSC-for-Linux/releases” target=”_blank”>https://github.com/Microsoft/PowerShell-DSC-for-Linux/releases</a>)
wget <a href=“https://github.com/Microsoft/PowerShell-DSC-for-Linux/releases/download/v1.1.1-294/dsc-1.1.1-294.ssl_100.x64.rpm” target=“_blank”>https://github.com/Microsoft/PowerShell-DSC-for-Linux/releases/download/v1.1.1-294/dsc-1.1.1-294.ssl_100.x64.rpm</a>
rpm –Uvh dsc–1.1.1–294.ssl_100.x64.rpm
|
For more information on DSC on Linux and how can be used see also:
- Built-In Desired State Configuration Resources for Linux: https://docs.microsoft.com/en-us/powershell/dsc/lnxbuiltinresources
- Get started with Desired State Configuration (DSC) for Linux: https://docs.microsoft.com/en-us/powershell/dsc/lnxgettingstarted
- PowerShell-DSC-for-Linux on GitHub: https://github.com/Microsoft/PowerShell-DSC-for-Linux
What’s the future of PowerShell?
PowerShell Core will be provided with new feature updates and fixes while the older PowerShell will just be provided bug fixes and security updates.
This is an official statement from Microsoft about the future of PowerShell:
However, there are currently no plans to introduce new functionality to Windows PowerShell. This means that the risk of regression will be very low for Windows PowerShell, so you can count on it as a stable platform for your existing workloads.
But actually, PowerShell Core is not as powerful as the full PowerShell, so it will some time to have both aligned. For now, PowerShell Core isn’t a drop-in replacement for Windows PowerShell because Core has a different audience and intent.
PowerShell | PowerShell Core | |
Versions | 1.0 to 5.1 | 6 |
Platforms Supported | Only Windows client and Server) | Windows, Linux, and MacOS |
Dependency | .NET Framework | .NET Core |
Usage | Depends on .NET Framework Runtime | Depends on .NET Core Runtime |
Launched as | powershell.exe | pwsh.exe on Windows and pwsh on MacOS and Linux |
Future Updates for | Bug fixes and Security Updates only | Feature Update, Bug Fixes as well as Security Updates |
Read the original post on the StarWind blog site.