Get-CimInstance获取服务器总内存结果拆分问题及代码优化请求
批量获取服务器总内存:解决多记录返回问题
问题背景
使用以下PowerShell代码批量获取服务器总内存:
ForEach ($servername in $server) { Get-CimInstance -Class CIM_PhysicalMemory -ComputerName $servername.ItemArray[0] -ErrorAction Stop | Select-Object PSComputerName ,@{Name="GB";Expression={$_.Capacity/1GB}} }
代码可运行,但返回结果按单条内存模块拆分,而非单台服务器总内存:
PSComputerName GB -------------- -- Server1 16 Server1 16 Server1 16 Server1 16 Server2 4 Server3 8 Server4 16 Server4 16 Server4 16 Server4 8 Server5 16
例如Server1实际总内存64GB,却返回4条16GB记录;Server4总内存56GB,拆分为3条16GB+1条8GB记录;仅单/双CPU的服务器(如Server5)返回单条总容量记录。
原因分析
CIM_PhysicalMemory类的设计是按物理内存模块(或虚拟机模拟的内存插槽)返回记录,每条记录对应一个内存插槽中的内存容量:
- 物理机中,每个内存条对应一条记录;
- 虚拟机中,虚拟化平台会模拟多个内存插槽来分配总内存,比如Server1模拟了4个16GB的插槽,Server4模拟了3个16GB+1个8GB的插槽,因此返回多条记录;
- 单/双CPU虚拟机可能仅模拟了一个插槽,所以返回单条记录。
解决方法:修改代码计算单台服务器总内存
通过Group-Object按服务器名称分组,再对每组的内存容量求和,即可直接返回单台服务器的总内存:
修改后的完整代码
ForEach ($servername in $server) { Get-CimInstance -Class CIM_PhysicalMemory -ComputerName $servername.ItemArray[0] -ErrorAction Stop | Select-Object PSComputerName, @{Name="GB";Expression={$_.Capacity/1GB}} | Group-Object PSComputerName | ForEach-Object { [PSCustomObject]@{ ServerName = $_.Name TotalMemoryGB = [math]::Round($_.Group.GB | Measure-Object -Sum).Sum } } }
代码说明
- 保留原有的
Get-CimInstance获取内存模块数据; - 使用
Group-Object PSComputerName将同一服务器的所有内存记录分组; - 对每组的
GB字段求和,用[math]::Round()确保结果格式整洁(可选,若不需要取整可去掉); - 输出自定义对象,包含服务器名称和总内存容量。
预期返回结果
ServerName TotalMemoryGB ---------- ------------- Server1 64 Server2 4 Server3 8 Server4 56 Server5 16
内容的提问来源于stack exchange,提问作者Erik Berglund
相关产品推荐
相关产品推荐

