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).
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).
Learn from this video about:
- Daily vSphere management challenges
- Interacting with vSphere via PowerShell
- Automating vSphere processes using PowerShell
- Technical demonstration, script examples and tips
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 is a cross-platform solution, which 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 the 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" rel="noopener noreferrer">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 |
The latest stable release is version 6.0.2: https://github.com/PowerShell/PowerShell/releases/tag/v6.0.2
But there is already a 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 is only 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" rel="noopener noreferrer">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 to just grab the binaries files that are more recent:
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" rel="noopener noreferrer">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" rel="noopener noreferrer">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 experience 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 are a total mess; maybe it would be better to provide those binaries with the option of a static link to the required libraries instead of relying on external shared libraries.
And it’s not so easy fix the requirements, for example, on 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 have the issues with the shared libraries again:
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 can potentially help, and it is to 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 10 |
# Get the CentOS7 package wget http://mirror.centos.org/centos/7/os/x86_64/Packages/ 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.
It’s way easier to use the latest distribution and just install the 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. Quite simple, right? And that’s just starting with a minimal installation using the minimal ISO of CentOS.
Using PowerShell Core
Once you’ve 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 the 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 it on a Linux or 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 in Windows, you can still use all the other commands 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), which 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" rel="noopener noreferrer">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" rel="noopener noreferrer">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" rel="noopener noreferrer">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 use PowerShell?
For Windows systems, it 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 to the CLI, as discussed in a previous post).
But why use 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 fixed formatting, but you need to filter it with grep to find the right line (and maybe you can find 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 admins (but there is something similar also to other VMware’s products), is using PowerCLI from a Linux machine! I will discuss this option on a future post.
Yet another reason is using the DSC (Desired State Configuration). Windows PowerShell Desired State Configuration (DSC) is a configuration management platform that functions 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 describes the difference between declarative and imperative models.
The following Linux operating system versions are supported by 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 an Open Management Infrastructure (OMI) CIM server, version 1.0.8.1 or later.
If you have already 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" rel="noopener noreferrer">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" rel="noopener noreferrer">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 for Linux and how it can be used, see also:
- Get started with Desired State Configuration (DSC) for Linux: https://docs.microsoft.com/en-us/powershell/dsc/getting-started/lnxgettingstarted?view=dsc-1.1
- 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 with 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 need some time to have both guises 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 |