PowerShell has been the native automation language for Windows Operating systems for many years. Over the years, it has evolved from supporting Windows OS to other technologies like Azure and VMware. With the increasing popularity of this great tool, PowerShell has now become a cross-platform solution. Apart from Windows, you can now run PowerShell on macOS and various distributions of Linux.
Until version 5.1, PowerShell ran on top of Windows .NET framework and was bundled as part of Windows Management framework package. In early 2018, PowerShell 6 came along with the concept of ‘Core’ version. Windows PowerShell Core runs on top of .NET core instead of full .NET framework.
PowerShell core is open source and one can easily try their hands on it by getting it from Microsoft owned GitHub. Here, you can find PowerShell core for various Operating Systems. As an admin, you need not have to be anxious about migrating from native PowerShell to PowerShell core. That’s because PowerShell core is not here to replace native PowerShell (at least for now and some more years to come) but is designed in a way that it can run parallelly with native PowerShell. Yes, you got it right! You can have both PowerShell and PowerShell core on the same system. Check this blog on how to install PowerShell Core.
So, what’s changed in PowerShell core?
Well, there are many newly added features as well as improved / changed existing features, we will see some of the major and useful new features as it will be a difficult task to list all the features here. You can always refer to the documentation on GitHub to look for newly added capabilities with each version.
New features in PowerShell core:
1) Process each object in an array simultaneously
This feature lets you process multiple objects simultaneously. What this means is that ForEach-Object will process multiple objects at the same time. This can be achieved by using Parallel and ThrottleLimit parameters. To illustrate this, we have used an example below where the PowerShell script will fetch 6000 event log entries from different types of event log.
There are two same scripts with minor changes. The first script uses the native method of processing different event logs using ForEach-Object. The next event log in the queue will be processed only after the current event is finished processing. So, when 6000 entries of Security logs are fetched, only after that the script will start fetching Application logs. We will run this script in PowerShell 5 and see the total execution time of the script.
The next script is exactly the same however we have added two more parameters in ForEach-Object loop, Parallel and ThrottleLimit. Parallel parameter will tell the script to execute objects parallelly and ThrottleLimit parameter limits the number of script blocks running in parallel at a given time, and its default value is 5. We will run this script in PowerShell 7 and see the total execution time.
In the next image we can see both scripts executed successfully. We can see the total time it took to fetch 5*6000 = 30,000 logs. PowerShell 5 script took 61.44 seconds to fetch 30k logs whereas PowerShell 7 took just 4.89 seconds to fetch the exact same number of logs. That’s because in the second script, all the logs were processed simultaneously.
With this, we can conclude that the execution time of PS 7 scripts can be reduced drastically if there are multiple objects that needs to be processed. In the above example, the execution time was reduced by 92.05 percent.
2) Pipeline chain operators && and ||
The && and || operators are like AND and OR lists in shells like Bash and Zsh. The && operator executes right hand pipeline if the left-hand pipeline succeeds. Conversely, the || operator executes the right-hand pipeline if the left-hand pipeline fails.
Here, in the first example, when we run Invoke-WebRequest command against Google’s URL, we get some data in return and hence the command runs successfully. Hence the right-hand pipeline was executed thereby displaying the message “Command Succeeded”.
In the second example, we ran Invoke-WebRequest against a non-existent URL and hence the command would ultimately fail. In this case, the right-hand operator was not executed and hence we cannot see the message “Command Succeeded”.
Conversely, here in the first example, when we run Invoke-WebRequest command against Google’s URL, we get some data in return and hence the right-hand pipeline will not execute.
In the second example, we ran Invoke-WebRequest against a non-existent URL and hence the command failed. In this case, the right-hand operator was executed and hence we can see the message “Command Succeeded”.
3) New ConciseView to view error
PowerShell 7 by default uses new ConciseView to display error which means that instead of seeing lot of details about the error, you will see a short one liner message that makes sense.
This doesn’t mean that you are missing out the option to see detailed error as you were used to. To display detailed error just like native PowerShell, you need to set default $ErrorView variable to “NormalView”.
4) Get-Error command
With the addition of new Get-Error command, you can now have a detailed view about the last error. You can view the exception type, message, TargetObject, HResult. Although this is similar to something we used to do by accessing $Error[0], having a dedicated command to list all the error details at once is something which is very useful.
5) Null coalescing operator
The null-coalescing operator ?? will return the value of its left-hand operand if it is not null. If it's null, it will evaluate the right-hand operand and will return its result. The ?? operator doesn't evaluate its right-hand operand if the left-hand operand evaluates to non-null.
In this example, C:\Temp\5.1.ps1 exists, hence result of Get-Item i.e. file details will be displayed as the variable $file is not null.
Next, if do a Get-Item on non-existing file, the $file will be null. When we evaluate this to ?? the right operand will evaluate.
6) Null conditional assignment operator
The null conditional assignment operator ??= will assign the value of its right-hand operand to its left-hand operand only if the left-hand operand will evaluate to null. The ??= operator doesn't evaluate its right-hand operand if the left-hand operand evaluates to non-null.
In this example, since $a was null, value of “abc" was assigned $a. Next, $b was assigned valued of “def”, hence, after applying null conditional operator, new value “xyz” will not be assigned since $b was already having value and was not null.
7) Ternary Operator
A ternary operator simply is an if-else condition.
Syntax: <condition> ? <if-true> : <if-false>
Example:
8) Some useful commands
Get-Uptime command will give details about the server’s uptime.
$PSVersionTable command now includes OS information. This can be useful when you have Linux and Mac on your network.
With this, we come to end of this blog. But we will have many more topics on PowerShell core. So do subscribe to get notified via email when there’s something new on PowerShellStore.com. Goodbye!
Great Post. Thanks for sharing!