With so many differences between Linux and Windows, it's incredible that developers can create cross-platform software, especially products that offer similar or identical experiences on different OSes.
While Microsoft strives to make PowerShell look and feel similar on all systems, there are a few important differences in using PowerShell on Linux vs. Windows. Some might be obvious to developers already familiar with the two platforms, but others might come as a surprise.
PowerShell vs. Windows PowerShell
Because this tutorial refers to PowerShell, not Windows PowerShell, it's important to understand the differences between the two. PowerShell is an open source program built on .NET Core that is compatible with Windows, macOS and Linux OSes. Windows PowerShell is exclusive to Windows -- where it is included by default -- and is built on the .NET Framework. This tutorial uses the latest version of PowerShell -- 7.3.2 at the time of writing -- on both Windows and Linux.
.NET Core enables PowerShell to work across OSes. In 2014, Microsoft introduced .NET Core, which made its proprietary .NET software framework compatible with Linux and macOS. This created a path for any software built on the Windows-specific .NET Framework to be built in a cross-platform manner, including PowerShell. While the vast majority of .NET Framework's core functionalities and features are available in .NET Core, changes have been made and are detailed in Microsoft's .NET documentation.
Of all the differences in PowerShell between platforms, case sensitivity is one of the most significant. As a longtime Windows user, I've spent more time than I care to admit troubleshooting a script on Linux only to realize that I used case incorrectly in a file or module name.
While file and module systems are case sensitive, PowerShell users can still tab-complete file names without worrying about case sensitivity.
For example, if there is a file named Test.txt in the current working directory, running a script to test for both test.txt and Test.txt will only return True for Test.txt, as seen in Figure 1. However, typing ./test will tab-complete to Test.txt unless there is another file or folder that starts with test.
Another key difference between Windows and Linux is the file system. Windows uses lettered drives and backslashes as the directory separator, whereas Linux uses a tree structure and forward slashes.
PowerShell enables paths to pass to cmdlets using either a forward slash or backslash, interpreting either as a proper directory separator for the current platform. This is useful when writing cross-platform scripts, as it eliminates the need for logic to check for the OS and apply the appropriate directory separator.
To demonstrate, the script shown in Figure 2 returns True when testing for a .\Test.txt file on Linux. Even though Linux uses forward slashes, backslashes are accepted as a directory separator in PowerShell.
Aliases are a convenience feature in PowerShell to save time and typing. In an attempt to increase familiarity for Linux users, Windows PowerShell introduced several aliases that mapped Unix commands to their PowerShell equivalents.
For example, the command ls lists the directory content in Linux and macOS. Running the ls alias in PowerShell on Windows calls the PowerShell command Get-ChildItem. Figure 3 shows the results of running ls in PowerShell on Ubuntu.
In contrast, Figure 4 displays the results of running ls in PowerShell on Windows.
The problem is that a Linux user running ls -- even in PowerShell -- expects the actual ls command to execute, not Get-ChildItem.
Due to issues like this, Microsoft removed the ls alias from PowerShell on Linux, along with several other Unix aliases:
However, these aliases still exist in PowerShell on Windows and in Windows PowerShell.
PowerShell remoting over SSH
With the advent of PowerShell on Linux, Microsoft also introduced the option to connect to a remote device over SSH with PowerShell, enabling PowerShell to use security rules already in place for remotely enabled Linux systems. PowerShell remoting over SSH can even be set up for non-Linux devices. However, the difference between remoting on Linux and Windows is that remoting over SSH is the only option for Linux devices.
Sudo and PowerShell
Because PowerShell runs commands in memory, it is not possible to call sudo within PowerShell, which might be unintuitive to Linux users accustomed to using sudo in various shells. However, users can still call PowerShell directly with sudo and specify which commands to run.
For instance, the sudo pwsh Remove-Item /path/to/item.ext -Config:$false -Force command removes files that require root access privileges.
Or they can simply launch PowerShell with sudo: sudo pwsh and all PowerShell commands executed in that shell will execute with sudo privileges.
Testing for the current OS
With these differences and the differences of the OSes in mind, there may be times where you will need to have your script do different things depending on the current OS. Thankfully, PowerShell makes this very easy using the OS-specific automatic variables shown in Figure 5.
If you do need to do different things based on your OS, simply use the if-elseif-else statement shown in Figure 6.
Despite the differences between PowerShell on Windows and Linux, they're fundamentally the same familiar, object-based shell. By staying aware of where the two differ, IT admins can troubleshoot and fix problems quickly. Before you know it, you'll be writing cross-platform PowerShell scripts with no trouble at all.