Today we have a guest post from Honorary Script Guy and Microsoft Premier Field Engineer Ashley McGlone, also known as GoateePFE.
This is deeper than Coke vs. Pepsi or Ford vs. Chevy. We are breaking down the barriers. Cats and dogs living together. Are you ready for this?
What is PowerShell Core?
The next release of PowerShell (6.0) was open-sourced last year and is currently in beta. However, it is PowerShell Core designed to run cross-platform on Windows, Mac, and Linux. PowerShell Core runs on top of .NET Core, a cross-platform, open-source version of the code base powering most of the Windows world. This version of PowerShell will be different than the Windows PowerShell edition you see built into Windows today.
My Mac Demo Rig
I have the coolest job, and I love my Microsoft Surface Pro 4. But now in my bag I also carry a MacBook Pro running VMs of Windows and Linux for one ultimate demo machine. Now I can demo PowerShell Core 6 and Visual Studio Code side-by-side on three different operating systems. I can even demo PowerShell remoting between all three operating systems.
How cool is that?!
The beta release of PowerShell Core 6 supports a significant list of Linux distributions. For my demos I chose Ubuntu Desktop so that I could do both PowerShell Core and Visual Studio Code. According to http://distrowatch.com this is one of the most popular Linux flavors.
Every customer who has seen this Microsoft guy demo PowerShell on three operating systems from a MacBook Pro has been impressed with the direction Microsoft is taking. Customers are excited about the cross-platform administrative opportunities now with PowerShell everywhere.
What do I need?
To get started with PowerShell Core you want to install and configure these three items on your operating system(s) of choice:
I was surprised how quickly I was up-and-running following the installation instructions. Each process involved relatively little tweaking for a beta experience.
If you are a Linux person you might be thinking, “OK. I already have OpenSSH installed.” Please read the OpenSSH link above for the step of editing the sshd_config
file for PowerShell remoting support.
Validate the install
From Mac or Linux simply open the terminal window and type powershell
. You should see the copyright banner (no year for beta) and get the PS prompt. Type $PSVersionTable
to see your version.
goatee@ub:~$ powershell
PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS /home/goatee> $PSVersionTable
Name Value
---- -----
PSVersion 6.0.0-beta
PSEdition Core
BuildVersion 3.0.0.0
CLRVersion
GitCommitId v6.0.0-beta.1
OS Linux 4.4.0-78-generic #99-Ubuntu SMP Thu Apr...
Platform Unix
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Type Get-Command
to see what cmdlets are available in your session.
PS /home/goatee> Get-Command
You might find it tricky to launch PowerShell Core 6 on a Windows VM that already has PowerShell natively installed. Here is one way to launch it:
- Navigate to the beta install directory: C:\Program Files\PowerShell*beta_directory*\
- Type
$PSVersionTable
to see the native version of PowerShell - Now type
.\powershell.exe
and press Enter - Type
$PSVersionTable
again to see thatPSEdition
is shown asCore
and with a different version number
Note the trick here is the .\ in front of the EXE, otherwise it will find the native EXE for Windows PowerShell.
Now for something new! Try this:
Get-Variable Is*
Notice that you now have built-in variables indicating the operating system version. These variables enable you to check the current OS and perform different behaviors from within a script.
PS /home/goatee> Get-Variable Is*
Name Value
---- -----
IsCoreCLR True
IsLinux True
IsOSX False
IsWindows False
Things to know
- Case-sensitivity
Windows is not case-sensitive, so neither is PowerShell on Windows. However, Linux is case-sensitive. PowerShell commands on Mac and Linux are not case-sensitive, but sometimes the operating system-specific values (e.g. the names of environment variables likePATH
) are case-sensitive. - Slashes
PowerShell on Windows has always allowed forward slashes and backward slashes in paths, so moving to Mac and Linux has minimal issues with the direction of the slashes. (However, it’s always a best practice to use variables like$pwd
and$PSScriptRoot
, and cmdlets likeSplit-Path
/Join-Path
to generate paths which conform to any given platform.) - Aliases
PowerShell on Windows has always had Linux aliases likels
,cat
,man
, etc. However, these PowerShell aliases do not exist on Mac and Linux to avoid conflict with the native binary equivalents.
Now what can I do?
For Windows people trying Mac or Linux
- Get a list of available modules:
PS /home/goatee> Get-Module -ListAvailable Directory: /home/goatee/.local/share/powershell/Modules ModuleType Version Name ExportedCommands ---------- ------- ---- ---------------- Manifest 1.1.0.0 Microsoft.PowerShell.Archive {Compress-Archive,... Manifest 3.0.0.0 Microsoft.PowerShell.Host {Start-Transcript,... Manifest 3.1.0.0 Microsoft.PowerShell.Management {Add-Content, Clea... Manifest 3.0.0.0 Microsoft.PowerShell.Security {Get-Credential, G... Manifest 3.1.0.0 Microsoft.PowerShell.Utility {Format-List, Form... Script 1.1.2.0 PackageManagement {Find-Package, Get... Script 3.3.9 Pester {Describe, Context... Script 1.1.2.0 PowerShellGet {Install-Module, F... Script 0.0 PSDesiredStateConfiguration {ThrowError, Get-P... Script 1.2 PSReadLine {Get-PSReadlineKey...
- PowerShell commands and pipelines work like they always have:
PS /home/goatee> Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName ------ ----- ----- ------ -- -- ----------- 0 0.00 38.65 8.04 1259 259 Xorg 0 0.00 64.11 4.79 1985 985 compiz 0 0.00 101.68 3.42 2104 949 gnome-software 0 0.00 90.87 2.86 2693 568 powershell 0 0.00 9.47 2.36 2110 949 prlcc
- Use Windows aliases on Mac and Linux:
dir cd
- Because PowerShell Core is based on .NET Standard, you can do .NET stuff from the console just like on Windows:
PS /home/goatee> [math]::pi 3.14159265358979 PS /home/goatee> [math]::pow(2,8) 256 PS /home/goatee> (Get-Date).AddDays(7) Monday, May 29, 2017 3:51:47 PM
- PSReadline and tab completion work as well, but the default
EditMode
is set toEmacs
, resulting in slightly different behavior: when you hitTab
, if you have not typed enough characters to match a single completion, you will get a list of available commands starting with those characters instead of a full completion.
For Mac or Linux people trying PowerShell
The cmdlet Get-Command
will tell you all the commands available in your session. Then pass the command name to Get-Help
just like man
:
PS /home/goatee> Get-Command
PS /home/goatee> Get-Help Get-Process
You will find that PowerShell help looks much like familiar man pages. You should first download the help file content on any new install like this:
PS /home/goatee> Update-Help
Notice that you can blend native commands and PowerShell in a single, object-oriented pipeline.
cat /etc/passwd | ConvertFrom-Csv -Delimiter ':' -Header Name,Passwd,UID,GID,Description,Home,Shell | Sort-Object Name | Format-Table
Here are some of the many similarities between PowerShell and bash (with more here):
Linux | PowerShell |
---|---|
compgen / man builtin | Get-Command |
man | Get-Help |
ls | Get-ChildItem |
cat / tail | Get-Content |
ps / top | Get-Process |
wc | Measure-Object |
sort | Sort-Object |
tee | Tee-Object |
grep | Select-String |
touch | New-Item |
tar | Compress-Archive / Expand-Archive |
history | Get-History / Invoke-History |
cd ~ | cd ~ / cd $home |
pwd | $pwd |
env | Get-ChildItem env:\ |
These command all have a wide assortment of parameters viewable with Get-Help
. In PowerShell, parameter names are intuitive, verbose, and largely shared across commands for uniformity.
Here is an example of tail
in PowerShell:
# Linux
tail -f my.log
# PowerShell
Get-Content -Path my.log -Tail 10 -Wait
Here is an example of wc
in PowerShell. Note that the results are slightly different, because the output of ps
is different than Get-Process
.
PS /home/goatee> ps aux | wc
191 2240 19045
PS /home/goatee> Get-Process | Measure-Object
Count : 190
Average :
Sum :
Maximum :
Minimum :
Property :
PS /home/goatee> Get-Process | Measure-Object -Line -Word -Character
Lines Words Characters Property
----- ----- ---------- --------
188 376 7394
CTRL+R will let you search and execute command history in PowerShell on all operating systems. This functionality is just one feature of the PSReadline module automatically loaded for you.
PowerShell Remoting over SSH
PowerShell Core 6 includes new parameters for remoting over SSH. This is why you had to install and configure OpenSSH on each box.
Enter-PSSession -Hostname <IP or FQDN> -Username <username> -SSHTransport
This area required a bit of tweaking to get working for me, so pay close attention to the steps in the guide. Windows people will need to learn a bit of vi
or nano
to edit the sshd_config
file on Linux with the entries from the guide.
Here is what it looks like to browse a Windows machine from a Linux SSH remoting session:
PS /home/goatee> Enter-PSSession -HostName 10.211.55.3 -UserName goatee10\testadmin -SSHTransport
goatee10\testadmin@10.211.55.3's password:
[10.211.55.3]: PS C:\Users\testadmin\Documents> cd\
[10.211.55.3]: PS C:\> dir
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 5/3/2017 8:20 PM MSOTraceLite
d----- 3/18/2017 5:03 PM PerfLogs
d-r--- 4/27/2017 1:38 PM Program Files
d-r--- 4/19/2017 11:57 AM Program Files (x86)
d----- 5/13/2017 3:24 PM Source
d-r--- 5/2/2017 7:50 AM Users
d----- 5/5/2017 9:24 AM Windows
[10.211.55.3]: PS C:\> exit
PS /home/goatee>
Visual Studio Code
After installing Visual Studio Code, you want to add the PowerShell extension. Open Code, click the square on the left bar, type powershell
, and install the extension. It will ask you to click to reload the window.
With the release of the PowerShell v1.x extension for Visual Studio Code it is now possible to have a cross-platform PowerShell editing experience very similar to the ISE on Windows boxes:
- F5 and F8 will run all or selection of a script.
- You have the interactive output window at the bottom.
- Intellisense and tab-completion make coding faster.
CTRL+SPACE
works here also. - The debugger has breakpoints and stepping.
And it is also better than the ISE in many ways:
- Typing paired punctuation is automatic ( () [] {} ” “”).
- Select some code, right click, and choose
Format Selection
orFormat Document
to format your code according to standard practices. (My favorite new feature!) - Right click a function and choose
Go To Definition
orFind All References
. - Searching highlights results in the scroll bar.
- Script Analyzer provides coding best practices alerts.
If you are editing a new file in Code you need to trigger the PowerShell experience in one of two ways:
- Save the file with a
.ps1
or.psm1
extension. - In the bottom right corner click on
Plain Text
and then choosePowerShell
for the language mode.
These steps trigger the interactive output window and syntax completion. It is amazing to have full parity in the editing experience across Windows, Mac, and Linux.
If you would like to learn more about editing PowerShell with VS Code, check out David Wilson’s presentation to the AZPosh user group or his presentation from the PowerShell and DevOps Global Summit 2017.
Desired State Configuration
This blog post is getting quite long, so I will not get into Desired State Configuration today. However, you can read Get started with Desired State Configuration (DSC) for Linux in the documentation site.
Truly Cross-Platform Code
Depending on the task at hand we can run the exact same code on PowerShell Core on all three platforms. For example, on the operating system of your choice run this REST call and process the JSON response:
(Invoke-WebRequest -Uri 'http://jsonplaceholder.typicode.com/posts?userid=1' -Method Get).Content | ConvertFrom-Json
It is remarkable to see the same code run on all platforms. This paints a bright future for sysadmins everywhere.
Your Turn
I hope you have enjoyed this quick tour of the new cross-platform PowerShell scripting experience. Try it today on your favorite operating system. If you find things that do not work as you expected, then please submit an issue on GitHub.
Cheers!