To complement Don Cruickshank's helpful answer:
As an aside: Below I'm using Get-CimInstance
rather than Get-WmiObject
, because the CIM cmdlets (e.g., Get-CimInstance
) superseded the WMI cmdlets (e.g., Get-WmiObject
) in PowerShell v3 (released in September 2012). Therefore, the WMI cmdlets should be avoided, not least because PowerShell (Core) 7+, where all future effort will go, doesn't even have them anymore. For more information, see this answer.
If you can operate on a single collection, you don't even need a foreach
loop and can use a single pipeline with a call to ForEach-Object
:
Get-CimInstance win32_logicaldisk | ForEach-Object {
"Statistic: " + ($_.Size - $_.FreeSpace)
}
As for enumerating multiple collections in parallel (without the use of indices):
[Linq.Enumerable]::Zip()
can do that for two collections:
# Two sample arrays to enumerate in parallel:
[string[]] $a1 = 'one', 'two', 'three'
[int[]] $a2 = 1, 2, 3
foreach ($tuple in [Linq.Enumerable]::Zip($a1, $a2)) {
'{0}: {1}' -f $tuple[0], $tuple[1]
}
Note: In earlier PowerShell (Core) versions and in Windows PowerShell you'll have to use .Item1
/ .Item2
instead of [0]
/ [1]
However, as the above shows, this is a somewhat obscure solution that isn't PowerShell-idiomatic, because PowerShell doesn't support .NET extension methods and requires strong typing of the input collections to enable PowerShell to enable PowerShell to infer the specific types the generic method should be called with.
Also, with differently sized input collections, enumeration stops once the smaller collection has run out of items.
[Was declined] GitHub proposal #14732 suggests introducing a PowerShell-idiomatic feature that additionally supports more than just 2 collections:
- Update: The proposal has since been rejected.
# Two sample arrays to enumerate in parallel:
$a1 = 'one', 'two', 'three'
$a2 = 1, 2, 3
# WISHFUL THINKING, as of PowerShell 7.2
foreach ($a1Element, $a2Element in $a1, $a2) {
'{0}: {1}' -f $a1Element, $a2Element
}
If this feature were implemented, the above would output:
one: 1
two: 2
three: 3