如何分组和求和整数值

时间:2018-10-08 10:06:28

标签: powershell

我有一个变量,其内容如下:

VMName  Drive Size
------- ----- ----
Server1 D:     100
Server1 E:     150
Server1 E:     100
Server2 E:     200
Server2 E:     250

现在,我想根据名称和驱动器将VMName分组,然后对其大小求和,以便其返回以下内容:

VMName  Drive Size
------- ----- ----
Server1 D:    100
Server1 E:    250
Server2 E:    450

另外(甚至更好)采用以下格式:

VMName  D     E
------- ----- ----
Server1 100   250
Server2 0     450

这是我正在使用的当前脚本:

$VMs = Get-VM -ComputerName "FOOBAR"
foreach ($VM in $VMs) {
  $HardDrives = $VM.HardDrives
  foreach ($HardDrive in $HardDrives) {
    $objVM = New-Object System.Object
    $objVM | Add-Member -MemberType NoteProperty -Name VMName -Value $VM.VMName
    $objVM | Add-Member -MemberType NoteProperty -Name Drive -Value $HardDrive.path.Substring(0,2).ToUpper()

    $HDs = (Get-VHD -ComputerName "FOOBAR" -Path $HardDrive.path)
    $objVM | Add-Member -MemberType NoteProperty -Name Size -Value ($HDs.Size/1GB)

    $objVM |
    Group-Object VMName, Drive |
    Select-Object @{n='VMName----------------';e={$_.Group | Select -Expand VMName -First 1}} ,
              @{n='Drive';e={$_.Group | Select -Expand Drive -First 1}},
              @{n='Size';e={($_.Group | Measure-Object Size -Sum).Sum}}
  }
}

当前输出:

VMName---------------- Drive Size
---------------------- ----- ----
TEST01                 E:     127
TEST02                 E:     127
TEST03                 E:      40
TEST03                 E:     100
TEST03                 E:     100

所需的输出:

VMName---------------- Drive Size
---------------------- ----- ----
TEST01                 E:     127
TEST02                 E:     127
TEST03                 E:     240

1 个答案:

答案 0 :(得分:0)

使用Group-Object对项目进行分组,并使用Measure-Object计算总和。

$VM.HardDrives |
    Select-Object VMName, @{n='Drive';e={$_.path.Substring(0,2).ToUpper()}},
                  @{n='Size';e={(Get-Vhd -Computer "FOOBAR" -Path $_.path).Size/1GB}} |
    Group-Object VMName, Drive |
    Select-Object @{n='VMName';e={$_.Group | Select -Expand VMName -First 1}},
                  @{n='Drive';e={$_.Group | Select -Expand Drive -First 1}},
                  @{n='Size';e={($_.Group | Measure-Object Size -Sum).Sum}}

如果您不想使用计算所得的属性,则可以在ForEach-Object循环中构建新的自定义对象:

$VM.HardDrives | ForEach-Object {
    New-Object -Type PSObject -Property @{
        'VMName' = $_.VMName
        'Drive'  = $_.path.Substring(0,2).ToUpper()
        'Size'   = (Get-Vhd -Computer "FOOBAR" -Path $_.path).Size/1GB
    }
} | Group-Object VMName, Drive | ForEach-Object {
    New-Object -Type PSObject -Property @{
        'VMName' = $_.Group | Select -Expand VMName -First 1
        'Drive'  = $_.Group | Select -Expand Drive -First 1
        'Size'   = ($_.Group | Measure-Object Size -Sum).Sum
    }
}

对于您在问题中提到的替代输出格式,这与PowerShell组织数据的方式不太匹配。您可以通过transposing从上方获取数据来获取该格式,但这确实很尴尬。