When I started learning more about PowerShell I realised that there are actually two different versions, Windows PowerShell (Version 5.1) and PowerShell Core (Currently version 7.4.x).
One of the benefits of using PowerShell Core is that it is cross platform and works on Linux and MacOS as well as Windows and it is also the version that is being updated with new features.
Windows PowerShell is still the default on Windows OS but no new features are being added.
The following are just a few examples of language and cmdlet changes that I have found handy in PowerShell 7.
Null-coalescing operator
This operator is a game-changer when it comes to handling null values efficiently.
What is the Null-coalescing Operator?
The Null-coalescing operator (`??`) returns the value of its left-hand operand if it isn't null; otherwise, it returns the right-hand operand. It's a concise way to handle default values and avoid null reference errors.
Let's dive into an example
Get-ADUser -Identity happy.gilmore -Properties description | select-object name, @{label='Description';expression={ $_.description ?? "No Description" } }
In this script, we're using the Null-coalescing operator to ensure that if there is no description, it defaults to `No Description`.
The Long Way with `if` Statement
For those using PowerShell 5.1 or earlier, here's how you can achieve the same result using an `if` statement:
Get-ADUser -Identity happy.gilmore -Properties description | select-object name, @{label='Description';expression={ if($_.description) {$_.description } else { "No Description" } } }
Why Use It?
Simplicity: Reduces the need for verbose null checks.
Readability: Makes your code cleaner and easier to understand.
Efficiency: Streamlines handling of default values.
Parallelization
There is a new paramter for the ForEach-Object command that allows whatever is in the script block to be executed at the same time for multiple objects, normally each object that is piped to foreach-object is processed one after the other. So if you are doing something that takes 1 second for each object and you have 5 objects it would still take 1 second for all of them to complete instead of 5 seconds.
This is one example from the foreach-object help page examples.
$Message = "Output:"
1..8 | ForEach-Object -Parallel {
"$using:Message $_"
Start-Sleep 1
} -ThrottleLimit 4
Output: 1
Output: 2
Output: 3
Output: 4
Output: 5
Output: 6
Output: 7
Output: 8
One thing to note is that the -Parallel parameter creates a new runspace for each object. Therefore you would need to use $using: when referencing a variable outside of it’s scope. The throttlelimit parameter becomes useful as running many things in parallel can be put a strain on system resources.
Another thing to note is that the order of execution is not guaranteed.
New Cmdlets
Some of the new cmdlets were added in PowerShell 6. I have only used Remove-Alias, but I can see that Get-Uptime could be useful. You can find the new cmdlets here:
https://learn.microsoft.com/en-us/powershell/scripting/whats-new/differences-from-windows-powershell?view=powershell-7.4#new-cmdlets
Conclusion
There are some reasons why you would still use PowerShell 5.1, for example if you were working in an environment where you were not allowed to make any changes or install PowerShell 7. Also since it comes preinstalled in Windows at the moment most organizations won’t bother upgrading especially since some commands used in Windows PowerShell are missing from PowerShell 7. I’m sure there are many more and I’ll add them here when I come across them.