Editor's note: Adam Bertram originally wrote this article and Brien Posey has expanded it.
Microsoft partnered with Linux vendor Canonical Ltd. to port Bourne Again Shell, or Bash, to Windows in 2016. Bash integration with the Windows environment enables users to forgo dual booting with Canonical's Ubuntu OS to get native Linux capabilities. Script-savvy Windows admins might wonder if Bash on Windows replaces PowerShell, which is similar to Unix and Linux systems and also already provides OpenSSH connectivity over the Secure Shell protocol.
What is Windows PowerShell?
PowerShell might best be described as Microsoft's next-generation command-line environment. Prior to the creation of Windows in the 1980s, Microsoft's PC OS was entirely command-line based. This OS, which was known as Disk Operating System (DOS), never completely went away. Early Windows builds were little more than graphical platforms that ran on top of DOS. Subsequent Microsoft OSes, including Windows 10 and 11, don't require DOS, but emulate DOS through the Windows command prompt.
Although Microsoft has made various updates to the Windows command prompt over the years, it's still essentially just a modern representation of a command-line environment that is more than 40 years old. As such, the Windows command prompt environment is quite limited in its capabilities.
This is where PowerShell comes into play. Like the Windows command prompt, PowerShell is a command-line environment that is integrated into the Windows environment. There are also cross-platform versions of PowerShell that can be used with Linux and macOS.
PowerShell functions as both a management tool and a full-fledged scripting language. Although it's possible to build applications on top of PowerShell, PowerShell scripting is more often used for automation purposes. Administrators commonly use Windows PowerShell to automate various management tasks.
There are many thousands of built-in PowerShell commands, but additional commands can be added through the use of external modules. Some of these modules are commercial, while others are open source. It's also relatively easy to create your own modules.
PowerShell cmdlets adhere to a standard syntax and are made up of a verb followed by a dash and a noun, such as Get-Help. The PowerShell environment supports many of the old DOS commands, but these DOS commands are aliases to modern PowerShell cmdlets. The dir command, for example, is an alias to PowerShell's Get-ChildItem cmdlet, which functions similarly to the DOS dir command.
What is Bash?
Like PowerShell, Bash is a command-line environment through which you can interact with an OS. Bash has many similarities to PowerShell and, like PowerShell, can be used as a management tool or a scripting language.
Bash was originally designed for use in Linux environments. In recent years, however, Bash has rapidly gained traction in Windows environments. Much of this can be attributed to the Windows Subsystem for Linux (WSL).
WSL makes it possible to install multiple Linux distributions on Windows machines. It's even possible to launch a Linux shell from File Explorer. In the past, admins could install Cygwin Bash to use the shell within Windows, but that didn't offer a native Bash experience or proper integration with Windows.
Thanks to WSL, however, it's possible to run a true Linux shell on top of Windows. This means you can use the Bash shell to interact with Linux in the same way that you would on a native Linux machine without having to install Cygwin Bash.
Differences between Bash and PowerShell
Purpose and scope. PowerShell is typically thought of as a configuration management tool that brings the capabilities of Linux CLI control into the historically point-and-click Windows environment, although PowerShell can also be used for complex scripting tasks. PowerShell is most often used to manage Windows environments at scale, particularly in virtualized deployments.
Bash, on the other hand, is more traditionally suited for development environments. It was introduced to complement and strengthen CLI-based interaction. With the addition of Bash to Windows, code that developers or infrastructure engineers write for Linux works on their Windows systems too. Picture Linux-first tools -- Python, Ruby, Git -- that are common in DevOps shops running directly on Windows.
Syntax. PowerShell isn't just a shell; it's a complete scripting environment. PowerShell invokes lightweight commands called cmdlets at runtime. In addition, PowerShell is able to use external components such as the Windows Management Instrumentation (WMI) and the .NET Framework. This means PowerShell scripts aren't limited by the native PowerShell cmdlets. Although PowerShell is a command-line environment, you can build a GUI interface for a PowerShell script by making calls to .NET.
The commands ls -la in Bash and dir in PowerShell are two separate CLI concepts, but the output isn't wildly different. Figure 1 shows the output of PowerShell dir commands and how a directory list displays in PowerShell. The output is in the form of file objects with properties, such as date created and size, listed beside the files.
By contrast, the Bash output in Figure 2 is in the form of a set of strings, which are the text representations of file names. The end result is especially important: The scripts you write take the data that is returned and pass it on to another function or use it to perform an action.
PowerShell relies on an object pipeline. PowerShell cmdlets can be joined, or piped, together in a way that passes along the output of one cmdlet as the input for the next. The same data can be manipulated with multiple cmdlets in sequence. By piping objects, PowerShell scripts can share complex data, passing entire data structures between commands. Bash, on the other hand, passes output and input as plain text, which means it's easy for the user to move information to the next program.
The PowerShell output in Figure 3 demonstrates how one directory entry contains a wealth of properties. Use the command Get-ChildItem | Select-Object * -First 1 to show the many available properties on a single file system object.
Capabilities. PowerShell enables admins to edit the registry, manage Microsoft Azure or Microsoft 365 cloud environments, and conduct Windows Management Instrumentation. The Bash shell and command language doesn't offer these capabilities in Windows. By using Bash as a developer tool on Windows, however, users can code and build functions or services while working on the same files from both the Linux and Windows CLI.
PowerShell makes it easy to access the Windows registry, even allowing you to navigate the registry in the same way that you would navigate a file system. Similarly, XML processing in PowerShell is also straightforward.
The value of PowerShell vs. Bash comes down to the user. If you're working on several Windows systems, Bash is of little use; you'll need PowerShell to write scripts. Admins can't access local Linux files with Windows apps -- such as Windows Notepad -- via Bash.
Although Bash is great for managing text files in a scripting environment, everything is managed through APIs, not files. So, Bash is useful primarily for importing Linux code into Windows machines and developing that code.
Conversely, PowerShell is the best choice for managing Windows workloads. In addition to PowerShell's ability to use .NET and WMI, there are also many add-on modules that extend the tool's functionality to manage Windows-centric tasks on Active Directory, Exchange Server and other environments.
It's worth noting that PowerShell isn't exclusive to Microsoft. For example, PowerShell can be used to manage resources in AWS. VMware is also easily managed via PowerShell.
Ultimately, however, PowerShell is far more than just a management tool. It's an extremely capable scripting language. The PowerShell CLI has good tracing and debugging tools built in, and multiple integrated development environments exist for coding and testing PowerShell scripts.
Formerly, PowerShell couldn't compete with Bash on Linux. Bash boasts an ecosystem of tools built from the ground up with Linux in mind. With the advent of PowerShell Core, however, all that has changed. PowerShell can run as a primary shell within Linux that contains all the object properties for which PowerShell is famous.
Learning PowerShell and Bash
PowerShell deals with a lot of scripting. If you're from a Unix/Linux background, this tool looks familiar. However, for Windows GUI adherents, there's a steep learning curve. PowerShell Core, currently at version 6 and nearing version 7 at the time of updated publication, contains hundreds of cmdlets, each with a variety of parameters and the unique ability to run on different OSes.
Bash on Windows comes with fewer than 40 internal functions and around 100 helper programs. With a slimmer syntax, Bash is faster, but PowerShell has the advantage of a consistent syntax structure. If you're just starting out, it will take some time to thoroughly exploit PowerShell's reach. Users familiar with the tool can deploy, manage and repair hundreds of systems from any remote location, automate runbooks, and use C#-based PowerShell script files to automate repetitive tasks.