PowerShell

PowerShell 7

There are some great new features in PowerShell 7 that are not found in PowerShell 5 and 6

PowerShell 7 will automatically use PowerShell 5 modules when it has to

In PowerShell 6 there were things that you could not do so you would have to drop back to PowerShell 5 with PowerShell 7 it uses PowerShell 5 when it needs to so you can use the one shell.

ForEach-Object -Parallel

ForEach-Object now has a parallet paramter so you can run multiple tasks at the same time.

This can save a lot of time if you want to run a command that takes 5 minutes per computer instead of taking 5 minutes times the number of computers it can take 5 for the amount of computers you want to process in parallel which you can control with the -ThrottleLimit parameter

            $computers = 'Server1', 'Server2', 'Server3', 'Server99'
            $computers | ForEach-Object   -Parallel  {Get-CimInstance win32_product -computername $_  } -ThrottleLimit 5
        

Ternary Operator

This is a short cut oneliner for a if else statement and the syntax works like this

(if condition) ? (do this bit) : (if not met do this)

As an example

            $path = "c:\doesnotexits"
            (Test-Path $path) ? (write-host "This path exists" -ForegroundColor Green) : (write-Host "This path does not exist" -ForegroundColor red)
            This path does not exist
            $path = 'c:\temp'
            (Test-Path $path) ? (write-host "This path exists" -ForegroundColor Green) : (write-Host "This path does not exist" -ForegroundColor red)
            This path exists
        

Pipeline Chain Operators

There are two pipeline chain operators the && and the ||

With the && if the first task completes the second task runs

            Get-ChildItem c:\temp | out-null && new-item -itemtype file -Path c:\temp\newTempFile.txt
            
            Directory: C:\temp
    
            Mode                 LastWriteTime         Length Name
            ----                 -------------         ------ ----
            -a---           3/06/2021  2:07 PM              0 newTempFile.txt
        
        

With this condition assuming c:\temp exists the newTempFile gets created

            Get-ChildItem c:\bogus | out-null && new-item -itemtype file -Path c:\temp\newTempFile.txt
            Get-ChildItem: Cannot find path 'C:\bogus' because it does not exist.
        

With the || either the first condition is true or the second condition is true

            Get-ChildItem c:\DemoDirectory || new-item -ItemType Directory -Path c:\DemoDirectory
            Get-ChildItem: Cannot find path 'C:\DemoDirectory' because it does not exist.
    
                Directory: C:\
    
            Mode                 LastWriteTime         Length Name
            ----                 -------------         ------ ----
            d----           3/06/2021  2:18 PM                DemoDirectory
        

In this case DemoDirectory did not exist so the second part ran and it got created.

If we run this again

            Get-ChildItem c:\DemoDirectory || new-item -ItemType Directory -Path c:\DemoDirectory
        

Nothing happens because the second part does not get executed.

Null-Coalescing Operator

This takes the form of value ?? newValue

If the first value is $null then the statement returns the new value

example

 
            $eggs = $null
            $eggs ?? 42
            42
        

You can assign this value with ??=

            $eggs = $null
            $eggs ??= 42
            $eggs 
            42
        

So now $eggs equalls 42

A practical example of how to use this is to test if a feature has been installed and if it hasn't install it

Or in this example it checks if the hyper-v module has been installed and if it has good and if not it installs it.

            (Get-Module -ListAvailable Hyper-V) ?? (Install-Module Hyper-V)
        

One this to note is that null and false are not the same thing. If something evalutates to false like Test-Path it is not the same as $Null