One of the reasons you want to adopt PowerShell 7 on your desktop, is that it can be used cross-platform. Theoretically, you can write a PowerShell script or function that works on Windows, Linux, and Mac. However, this is not without challenges. In some ways, it feels like we are back to the early days of PowerShell scripting where we are all trying to figure out what to do. Based on my experiences, let me share some thoughts on what I think you should keep in mind.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
Remember, I am focusing on PowerShell code you will write in script files and modules. Using PowerShell interactively and cross-platform has its own set of rules. Although let me add that the more experience you have working interactively cross-platform, the easier it will be to write cross-platform code.
No Aliases
A long established community best practice in PowerShell scripting is not using command and parameter aliases. In a cross-platform world, this is even more critical. You may have been in the habit of using Sort in your code in place of Sort-Object. I know I have. I didn't mind bending the no alias rule abit because there was nothing cryptic about Sort.
But in the Linux world, sort is a native command. There is no PowerShell alias. If your code uses sort, on Linux it will call the native command which will most likely break your code.
You need to get in the habit now of using full cmdlet and parameter names. In Visual Studio Code with the PowerShell extension, it is very easy to convert all aliases. In the command palette use PowerShell: Expand Alias or the keyboard shortcut Shift+Alt+E.
No CIM
Another key thing to watch for is the lack of WMI and CIM on non-Windows platforms. This probably doesn't come as much of a surprise. CIM support is part of the Windows Management Framework. The name gives it away. Any script that is using a CIM cmdlet will fail on a non-Windows system. This also includes commands like Get-Volume, that are using CIM under the hood. If the command you are using has a -CimSession parameter, it won't work cross-platform.
Testing for Version and Edition
What this means is that you will need to include additional error handling in your commands. You will need to check items like $PSVersionTable.
Here's what I have for PowerShell 7 on Windows.
And Windows PowerShell.
By the way, you can use $PSEdition on PowerShell 7 and Windows PowerShell to get the same value you see here.
In addition to testing values from $PSVersionTable, there are a number of new variables that might come in handy.
These variables do not exist in Windows PowerShell. Here's one way you might use them.
if ($psedition -eq 'core' -AND $IsWindows) { "PS7 on Windows" } elseif ($psedition -eq 'core' -AND (-Not $IsWindows) ) { "PS7 on Linux OR MacOS" } elseif ($PSEdition -eq "Desktop" -AND ($psversiontable.PSVersion.Major -eq 5 -AND $psversiontable.PSVersion.Minor -eq 1)) { "Must be Windows PowerShell 5.1" } else { "All other Windows PowerShell versions" }
Testing is important and can be tricky. For example, even though you don't have Get-Ciminstance in PowerShell 7 on Linux, you do on Windows. You will need to be familiar with Get-Command and Get-Module and be able to run them on non-Windows platforms.
Here's a code snippet you might use to validate a requirement for your code.
Try { Get-Command -name Get-Volume -erroraction stop } Catch { Write-Warning "Command not available on this system." #bail out of the command return }
If you've ignored learning how to properly use Try/Catch, now would be a good time. Another option you might consider adding is the use of Dynamic Parameters. This is a complex topic that I don't want to get into here. But you could define some parameters of your command dynamically, depending on the PowerShell flavor.
Require Minimal Versions
If you are writing stand-alone scripts that might be run on different PowerShell versions, you need to insert a #requires statement at the beginning of your script.
# requires -version 7.0
This is very important if you are using any of the new features in PowerShell 7 such as the new parallel parameter with ForEach-Object. Read the about_requires help topic for more detail.
Scripting with Remoting
The scripting element you might incorporate is PowerShell remoting. I often use this feature to make my command easily scale. What you have to take into account is how your command will be used with remote machines. You might need to define separate parameter sets with clear documentation that one set is used for Windows machines and another set for Linux. Or Windows PowerShell vs PowerShell 7.
I love that PowerShell 7 remoting can now use ssh. If you enable and configure it on your remote machines, you can then use ssh remoting in your code. Or, if you will have a mix of remote machines, perhaps you write your code to only accept PSSessions. The user of your code would be responsible for creating PSSessions. Some sessions could use WinRM and some could be using SSH. Your command can be designed to take an array of PSSessions from the pipeline and internally you could pass them to Invoke-Command. Of course, you still need to take other error handling, validation and testing into account. But this could be a simple way to manage multiple remote systems, regardless of whether they are running Windows or Linux.
Your Plan
What does all of this mean for you? First, I'd say you need to become comfortable with PowerShell 7 and all the new features it brings to the party. Assuming you are going to be running PowerShell 7 on your desktop, you can begin testing if the code still works. I have yet to find any scripts or functions that I wrote for Windows PowerShell fail to run locally under PowerShell 7.
Assuming you have a need for PowerShell 7 on remote servers, then you can begin assessing what you need to manage and how you will go about it. I always stress to students that you have to think about who is going to run your code. Now, you also have to think about where.
Even if most of your scripting work is for Windows PowerShell, if you begin to pay attention to PowerShell 7 scripting requirements, I think the quality of your code overall will improve.
https://en.wikipedia.org/wiki/Common_Information_Model_(computing)
CIM isn’t Windows only, WMI is an implementation of CIM for Windows.
I’m probably being a bit casual on the page. What I’m saying is that the CIM cmdlets, like Get-CimInstance, aren’t available on non-Windows systems.