我正在做的事情太简单了,我正在努力寻找答案。我要从两个相等长度的数组中相减
$free_array = get-wmiobject -class win32_logicaldisk | select -ExpandProperty freespace
$size_array = get-wmiobject -class win32_logicaldisk | select -ExpandProperty size
ForEach ($size in $size_array)
{
Write-Host Statistic: $size - $freespace
}
我不认为PowerShell有一个内置的函数来映射多个数组同时,所以你可以使用一个范围运算符,然后索引到两个数组的需要:
foreach ($Index in (0..($free_array.Count - 1))) {
Write-Host Statistic: ($size_array[$Index] - $free_array[$Index])
}
然而,你的任务也可以这样做,我认为这会更容易读:
$LogicalDisks = Get-CimInstance -ClassName Win32_LogicalDisk
foreach ($LogicalDisk in $LogicalDisks) {
Write-Host Statistic: ($LogicalDisk.Size - $LogicalDisk.FreeSpace)
}
补充Don Cruickshank的有用答案:
作为题外话:下面我使用Get-CimInstance
而不是Get-WmiObject
,因为CIM cmdlet(例如,Get-CimInstance
)取代了PowerShell v3(2012年9月发布)中的WMI cmdlet(例如,Get-WmiObject
)。因此,应该避免使用WMI cmlet,尤其是因为PowerShell (Core) 7+(未来所有的努力都将集中在此)甚至不再具有它们。
如果你可以操作一个集合,你甚至不需要foreach
循环,可以使用一个单独的管道调用ForEach-Object
:
Get-CimInstance win32_logicaldisk | ForEach-Object {
"Statistic: " + ($_.Size - $_.FreeSpace)
}
对于并行枚举多个集合(不使用索引):
[Linq.Enumerable]::Zip()
可以为两个集合做:
# 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]
}
注意:在早期的PowerShell(核心)版本和Windows PowerShell中,您必须使用.Item1
/.Item2
而不是[0]
/[1]
同样,对于大小不同的输入集合,枚举在项用完后停止。
[被拒绝]GitHub提案#14732建议引入一个powershell习惯的特性,它额外支持的不仅仅是2集合:
- 更新:提案已被拒绝。
# 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
}
如果实现了这个特性,上面将输出:
one: 1
two: 2
three: 3