- Use Azure Bastion as a jump host for RDP and SSH - Tue, Apr 18 2023
- Azure Virtual Desktop: Getting started - Fri, Apr 14 2023
- Understanding Azure service accounts - Fri, Mar 31 2023
If you want to use PowerShell to automate administration on Windows systems, then you have quite a few PowerShell versions to choose from:
- PowerShell 5.1 (called "Windows PowerShell")
- PowerShell 6.x (called "PowerShell Core")
- PowerShell 7.x (called simply "PowerShell")
Which of these is applicable to the work you're doing? Read on to find out.
PowerShell 5.1—Windows only
PowerShell v5.1 is no longer under active development because Microsoft wants PowerShell to be a universal task automation language, usable in Windows, macOS, and Linux. According to the PowerShell team, Microsoft will continue shipping PowerShell v5.1 in Windows Server and Windows 10, but eventually plans to ship PowerShell v7 side-by-side with v5.1.
Thus, we can expect Microsoft to service PowerShell v5.1 periodically with bug fixes and security updates, but not with any new functionality.
Why is PowerShell v5.1 Windows-only? Because the platform relies on the .NET Framework runtime environment, which runs only on Microsoft Windows. Here's what the $PSVersionTable automatic variable outpoint looks like on my Windows Server 2019 system:
PowerShell 5.1—No ISE
Besides PowerShell v5.1, guess what else relies on the Windows-only .NET Framework? You guessed it—the PowerShell Integrated Scripting Environment (ISE), shown in the following figure.
Therefore, you cannot use PowerShell ISE with PowerShell v6 or v7.
As convenient as the ISE is, the tool no longer has any future. Consequently, you should shift your development environment over to Visual Studio Code or another integrated development environment (IDE) as soon as possible.
Specifically, I suggest you install Microsoft's PowerShell extension in VS Code so you have full support for the PowerShell language in your scripts. As you can see in the next screenshot, on Windows systems you can choose which PowerShell version you want to use in VS Code's integrated terminal:
Microsoft created the .NET Core runtime environment to support cross-platform development. Accordingly, PowerShell v6.x is the first PowerShell version written for .NET Core; it runs on Windows, macOS, and Linux.
In PowerShell Core v6, Microsoft used their .NET Standard specification; .NET Standard apps can run inside either .NET Framework or .NET Core-based systems.
.NET Core and PowerShell v6.x are both open source at GitHub, which represents a gigantic leap forward for Microsoft. Now the technical community at large can not only inspect Microsoft's source code, but can even make contributions!
PowerShell Core v6.2 is the final generally available PowerShell Core v6.2 release. The latest PowerShell version is called PowerShell 7, and this is the version I suggest you and your team standardize upon. For this reason, I'll compare PowerShell v5.1 only with PowerShell 7 from now on.
Here's the $PSVersionTable output on the same Windows Server 2019 system in my test lab:
The PowerShell team designed PowerShell v7 such that it can be installed side-by-side with PowerShell v5.1. That said, you definitely need to understand that PowerShell v5.1 and PowerShell v7 have separate module paths. Check 'em out in the following figures:
Note that my system has some module paths you might not have due to additional products I've installed.
The two PowerShell versions also have separate profile paths:
- PowerShell v5.1: $HOME\Documents\WindowsPowerShell
- PowerShell v7: $HOME\Documents\PowerShell
PowerShell v7 now supports Secure Shell (SSH)-based remoting in addition to the traditional WS-Management remoting. I wrote a 4sysops tutorial on PowerShell v7 SSH remoting not too long ago.
PowerShell 7—Backward compatibility
Okay, now we get to what is truly the heart of the matter—what do we lose by standardizing on PowerShell v7?
Well, it's not so much what you lose as it is what you'll have to adapt to in the short to medium term. The big issue is module compatibility. The PowerShell team has been working really hard to ensure PowerShell v7 is compatible with earlier modules written for the .NET Framework and PowerShell v5.1. Microsoft calls these modules "Windows PowerShell modules."
PowerShell v6.x included a WindowsCompatibility module, but the team integrated that functionality into v7 natively so we don't have to install anything extra.
One way to load Windows PowerShell modules in PowerShell v7 is to invoke the -UseWindowsPowerShell switch parameter of the Import-Module command.
For example, let's say I need to work with the ADSync module on my Windows Server 2019 Azure AD Connect server. As you can see in the following screenshot, attempting to load and use the module in PowerShell v7 initially fails:
However, when we employ the -UseWindowsPowerShell switch, the module load succeeds and we're able to use the Azure AD Connect PowerShell commands, seemingly under PowerShell v7. What's going on here?
When you invoke -UseWindowsPowerShell, the following actions occur:
- PowerShell v7 uses implicit remoting to create local aliases to the source commands.
- The .NET Framework module is actually loaded in a PowerShell v5.1 session behind the scenes.
- Any objects you retrieve from a session are incomplete.
The third bullet point bears further explanation. Notice the methods available for the Get-ADSyncScheduler cmdlet under Windows PowerShell v5.1:
Now contrast that methods list with the following screenshot, which shows output under PowerShell v7 implicit remoting:
Using the implicit remoting module loading method results in your Windows PowerShell commands running in a separate, hidden session. Thus, the objects that are returned to your PowerShell v7 pipeline are deserialized objects, not the original types.
The other way to invoke the PowerShell v7 compatibility feature is to perform module autoload or explicit module loading of a supported module. For example, the ActiveDirectory Windows PowerShell module can be called within PowerShell v7 through command discovery or an Import-Module command. Review the list of natively compatible modules in the Microsoft Docs library.
While we're at it, you should also study the About Windows PowerShell Compatibility conceptual help article.
So do you have the lay of the land now? Let me sum up my recommendations:
Subscribe to 4sysops newsletter!
- Skip PowerShell Core v6 and load the latest supported PowerShell v7 engine.
- Install Visual Studio Code and commit to using PowerShell v7 wherever possible.
- Keep abreast of the ever-expanding compatible modules list, and don't forget about the Import-Module command's -UseWindowsPowerShell switch parameter.
Join the 4sysops PowerShell group!
Your question was not answered? Ask in the PowerShell forum!
Much thanks Mr Warner, your article is excellent. It clarifies the various versions of Powershell and clearly highlights the road map to the future of Powershell for those who use it.
I didn't understand the use of the -UseWindowsPowerShell parameter.
The two images seem to be the same.
Otherwise, good article.
Then why bother using -UseWindowsPowerShell !?
Its not fully compatible, reading your words it seems its COMPLETELY incompatible, nothing will work from scratch, everything has to be checked & verified, so why even bother?!
Ms hell again. 🙁
Thanks for the post. One thing to mention – Powershell 7 does not parse HTML as does 5.1. There are 3rd party modules that might help
Greg, do you have a source for this information?
Invoke-Webrequest is missing some properties, like .ParsedHtml and .AllElements · Issue #2867 · PowerShell/PowerShell (github.com)
Greg, thanks! I guess this is another feature that has fallen victim to the cross-platform compatibility because HTML parsing requires Internet Explorer. It doesn't really makes sense. Who really uses PowerShell on non-Windows systems?
Do you know of a third-party module for HTML parsing?
Yeah, all the cross-platform thing… Its weird sometimes.
I, for one, use Powershell on linux. It's a better scripting tool than bash (don't tell anyone I said that). No recommendation – but near the bottom of the issue I posted there was one
PowerShell is easier to learn than Bash, but it doesn’t really fit to Linux because it is object-oriented and Linux is all about text. I mean what can you do with a scripting language on Linux that is isn’t even able to parse HTML?
I POSH can bring great value to Linux because it is object oriented. Not despite it.
That was not my point. This is not about object-oriented vs. functional programming. The thing is that PowerShell is so useful for Windows because you can access all the Windows classes. This why you can easily manage Windows services, Active Directory objects etc. All those classes don't exists on Linux and PowerShell totally loses its appeal.
The bit about losing classes isn't correct. .Net core brings those classes to Linux. Run get-process and you get objects of linux processes. Install the importexcel module and you can import/export data to xlsx files. Use get-childitem and you manipulate files just like on Windows. I don't think it has the full richness, but it is still a useful tool there.
I think you still didn't get my point. On Linux everything is text-based whereas on Windows everything is object-oriented. For instance, an Active Directory user account is an object so PowerShell is very useful for managing AD. On Linux it is just text. No need for an object-oriented console here. And if you need to script, you have a plethora of languages with countless solutions and examples that perfectly fit to the Linux environment and that you just need to adapt to your needs. No Linux admin needs PowerShell. And who uses Excel on Linux? Nobody needs xlsx files on Linux.
I wonder what you would tell a Linux admin who wants to manage Windows but refuses to learn PowerShell and instead insists on only working with the Windows Subsystem for Linux so he can bring his Linux skills to Windows? You think he is going to have a career as a Windows admin?
Microsoft makes the same mistakes again and again. They tried to bring Windows to mobile phones and it hopelessly failed. If you are in a new environment you have to start from scratch and adapt. You cannot force an old technology onto another environment that is totally different.
I do see you point – but, I don't buy it. Linux is not text-based – it's file-based. Everything is a file. Both Windows and Linux are developed with object-oriented languages. The interfaces you refer to (awk/sed/grep) are popular because Linux (like Unix) only had text-based tools to deal with them until Python came along. Windows had the same issue under .cmd and .vbs file. Text manipulation is not inherent to Linux. But it was a requirement – and clunky, difficult and very fragile.
Objects usually make it easier.
"No Linux admin needs Powershell". Maybe. Perhaps some just want it.
Now one can use Powershell or python to deal with streams of info as objects. So maybe folks prefer python or sed/awk/grep or, um, pwsh. Great. More tools is better. If Powershell matures on Linux, I will love it. Just like I love it on Windows.
I would tell the Linux admin to use the tools that get the job done.
Don't worry – your Windows world (and mine) isn't going anywhere. The cheese hasn't moved far. And the generic-ification of pwsh and .net core across platforms doesn't threaten that. If anything, they left behind pieces like the html parsing so that the old tool (it was based on IE – yuck) can be replaced by something better. And they've sped up devlopment and moved it away from Windows releases so it is upgraded constantly. Not every 3 years.
Greg, of course everything in any OS is stored in files. Ever heard the term “flat file”? Most configurations in Linux are in flat files very much unlike as in Windows. You can have a discussion about the usefulness of PowerShell on Linux but whether Linux is a text-based OS or not is not oben for debate.
This is from Wikipedia:
So please don’t spread fake news 😉
Just because you have to workaround using the switch to run 5.1 modules I will not go to 7.anything.
This is has been the big problem of PowerShell 6 and it is the same with PowerShell 7. For many Windows admins it feels like as if they are "downgrading" from 5.1 to 7. Why would you risk that all your scripts no longer work?
This cross-platform thing was an ideological decision and it was strategically wrong because Microsoft weakened PowerShell as a language. Imagine a car maker decides that all their new models should also be able to "run" on water with the little downside that you can no longer use the cars on highways. Who would buy such a car?
Completely agree. What was once built as a scripting language to manage Windows machines, it should stay as such.
I am so glad it came to Linux. I use Linux almost as much as Windows and now I can bring my posh skills over there with me. I hope MS continues this push. As posh is adopted wider, more modules get build to do more things…AND THEY ALL WORK EVERYWHERE!
This is a great step forward for interoperability.
Keep using Linux and eventually you will like it better than Windows. 😉 This is the reason why Microsoft made a strategic mistake with bringing PowerShell to Linux. It drives Windows admins to Linux, however, no Linux admin will ever consider using PowerShell. The latest Linux Journal Awards don’t even mention PowerShell in the scripting category and according to the TIBOE Index, PowerShell is not even in the top 20 and listed under “others.” Even Prolog, a language I used 25 years ago is still more popular.
Don’t get me wrong, PowerShell is a great language and it is the only option for scripting in a Microsoft environment. However, if you are serious about Linux you need learn how to work on a Bash console and if you are serious about DevOps it is all about Python. Don’t stick with PowerShell just because you can “bring your skills.” If you want to work cross-platform, you need to learn every platform from scratch and this includes the dominant languages on the platform. If you want to live in France, you learn French and you don’t bring your English skills.
@Michael Pietroforte : On an absolut level don't you think that the object model of Powershell is better than the text model of Linux ?
For exemple you don't have to rely on overly complex, unreadable and error-prone regexps and greps/sed/awk to do something.
Of course I understand that the fundamental approach of Linux is not going to change and so Powershell might not be the best tool to work with linux fut fundamentally I think the object.model is better
I don’t think you can decide this question on an absolute level. It all very much depends on your environment because both approaches have advantages and disadvantages.
The object-orientation of Windows makes it easier for humans to interact with the OS and of course it is a must for an OS where a graphical user interface is dominant. This is what made Windows big and helped create a quasi-monopoly on the desktop and on-premises. I don’t see this changing any time soon.
However, the downside of object-orientation is that it creates a lot of bloat and complexity if you start using this approach at lower levels. The complexity makes an OS unreliable (ever heard of DLL hell?) and if you add the sloppy attitude of many Microsoft engineers you end up with an OS were innovation is hardly possible because all the focus is only on delivering new fixes for the bug fixes of last week.
Microsoft tried hard to get rid of the bloat with Server Core and Nano Server because in the cloud you need a slim OS. The problem is that if you remove all the bloat from Windows you cut off the entire ecosystem behind the OS and no OS can exist in a vacuum. This is why this approach failed and why Microsoft had really no choice and learn how to “love Linux.” Even in Azure Linux is now more used than Windows.
The nice thing about Linux is that you have a very slim core plus a mind-boggling ecosystem that relies on this approach. This is the main reason why Linux dominates the cloud and IoT. However, at the outer layers, where the applications reside, you can certainly work with more complex object-oriented languages. Python is the dominating language for DevOps and it is object-oriented. And if you work with web applications you can very easily create powerful applications with an object-oriented PHP. So with Linux you can have it both. This is how the OS was designed from the beginning.
In general, I see a trend in IT away from bloat. Apple’s move away from the bloated Intel architecture is another recent example.
Interesting point of view, thanks for responding
I love PowerShell on Windows but can't imagine using PowerShell on Linux. Bash is so much more powerful and if I want an OO scripting language, Python is superior. I appreciate Windows' better support for Linux instances running on Windows, but I really don't think anyone in the Linux world was demanding a PowerShell port.
One of the things about powershell on Linux and on Mac – you now have a fairly consistent way of working with all 3 platforms. You can write single scripts/modules that are cross-platform.
I would argue that bash is less powerful than powershell in and of itself. It does not have that much functionality when compared to powershell. When you start leveraging the native utilities, that's where the power comes from. And since powershell is a shell, there's no reason you can't leverage those same utilities inside powershell itself. Powershell is also far FAR more consistent in its behavior and usage than the native *nix utilities, the help system is far superior and easier to use.
The flip side of this is it's not really a 1st class citizen in *nix, it's *much* wordier and for many things it can be much more complex to perform the same tasks, and for heavy Windows powershell users there is a lot of functionality that did not come over from .net to .net core, and is therefore not available in powershell core, requiring a lot more adaptation to work around those missing pieces.
I can't speak to Python as a scripting language. I've started playing with it to learn it, and in practical terms (from my very very limited experience) it is a full blown programming language, and requires a lot more work and syntax than powershell. Python is not a shell, so you can't easily just sit down and start whipping out commands to do things.
And my last word – agreeing with Michael P. – Microsoft created their own poison pill bringing powershell to Linux – it makes it a lot easier to do cross-platform works, and creates a door for Windows admins to start working on Linux, and the seasoned Linux admins aren't going to spend effort on learning yet another completely different way of doing things that doesn't bring in functionality that can be gotten other ways they already know.