如何修改PowerShell脚本获取域内所有AD计算机的软硬件信息
域内批量获取计算机硬件/系统信息的解决方法
嘿,我一眼就瞅出你当前脚本的问题啦!那些获取WIN32_ComputerSystem、WIN32_OperatingSystem的命令,都是在你本地机器上执行的,循环里只是把本地数据反复塞进哈希表,根本没去远程访问每台AD里的目标计算机——这当然拿不到批量结果啦😉
核心问题拆解
你原来的脚本逻辑是:先在本地把所有硬件信息存成变量,再循环AD计算机,但循环里完全没针对每台机器做远程查询,相当于把本地数据复制了N遍,自然不是你想要的批量效果。
修正后的实现方案
下面是调整后的脚本,核心思路是遍历每台AD计算机时,远程执行硬件/系统查询命令,同时加入异常处理来应对机器离线、权限不足等情况:
# 1. 获取域内所有AD计算机对象 $ADComps = Get-ADComputer -Filter * # 2. 创建空数组存储所有机器的最终信息 $allComputerDetails = @() foreach($comp in $ADComps){ $compName = $comp.Name Write-Host "正在查询计算机: $compName" -ForegroundColor Cyan try{ # 3. 针对当前AD计算机,远程获取各类系统/硬件信息 $System = Get-CimInstance WIN32_ComputerSystem -ComputerName $compName -ErrorAction Stop $OS = Get-CimInstance WIN32_OperatingSystem -ComputerName $compName -ErrorAction Stop $Core = Get-CimInstance win32_processor -ComputerName $compName -ErrorAction Stop $GPU = Get-CimInstance WIN32_VideoController -ComputerName $compName -ErrorAction Stop $Disk = Get-CimInstance win32_logicaldisk -ComputerName $compName -ErrorAction Stop # 4. 构建哈希表存储当前机器的信息(优化了数据可读性) $machineInfo = @{ Computer_Name = $System.Name Manufacturer = $System.Manufacturer Model = $System.Model OS_Version = $OS.Caption OS_Install_Date = $OS.InstallDate Total_RAM_GB = [math]::Round($System.TotalPhysicalMemory / 1GB, 2) # 转换为GB单位 CPU_Model = $Core.Caption | Select-Object -First 1 # 多CPU场景取第一个型号 Total_CPU_Cores = ($Core.NumberOfCores | Measure-Object -Sum).Sum # 累加所有CPU核心数 GPU_Models = $GPU.Caption -join ";" # 多GPU场景用分号分隔 Total_Disk_Space_GB = [math]::Round(($Disk.Size | Measure-Object -Sum).Sum / 1GB, 2) Total_Disk_Free_GB = [math]::Round(($Disk.FreeSpace | Measure-Object -Sum).Sum / 1GB, 2) } # 5. 把哈希表转为PS对象,存入结果数组 $allComputerDetails += New-Object PSObject -Property $machineInfo } catch{ # 处理查询失败的情况(比如机器离线、无权限) Write-Warning "查询计算机 $compName 失败: $_" # 可选:把失败信息也存入数组,方便后续排查 $allComputerDetails += [PSCustomObject]@{ Computer_Name = $compName Error_Message = $_.Exception.Message } } } # 6. 输出结果,也可以导出为CSV文件方便分析 $allComputerDetails | Format-Table -AutoSize # $allComputerDetails | Export-Csv -Path "域内计算机硬件信息.csv" -Encoding UTF8 -NoTypeInformation
进阶优化:并行处理提升速度
如果域内机器数量较多,上面的串行foreach效率会很低,推荐用Invoke-Command做并行查询:
# 获取所有AD计算机名称 $compNames = Get-ADComputer -Filter * | Select-Object -ExpandProperty Name # 并行查询所有机器 $allComputerDetails = Invoke-Command -ComputerName $compNames -ScriptBlock { $System = Get-CimInstance WIN32_ComputerSystem $OS = Get-CimInstance WIN32_OperatingSystem $Core = Get-CimInstance win32_processor $GPU = Get-CimInstance WIN32_VideoController $Disk = Get-CimInstance win32_logicaldisk [PSCustomObject]@{ Computer_Name = $System.Name Manufacturer = $System.Manufacturer Model = $System.Model OS_Version = $OS.Caption OS_Install_Date = $OS.InstallDate Total_RAM_GB = [math]::Round($System.TotalPhysicalMemory / 1GB, 2) CPU_Model = $Core.Caption | Select-Object -First 1 Total_CPU_Cores = ($Core.NumberOfCores | Measure-Object -Sum).Sum GPU_Models = $GPU.Caption -join ";" Total_Disk_Space_GB = [math]::Round(($Disk.Size | Measure-Object -Sum).Sum / 1GB, 2) Total_Disk_Free_GB = [math]::Round(($Disk.FreeSpace | Measure-Object -Sum).Sum / 1GB, 2) } } -ErrorAction SilentlyContinue # 排查失败的机器 $failedComps = $compNames | Where-Object { $_ -notin $allComputerDetails.PSComputerName } if($failedComps){ Write-Warning "以下计算机查询失败: $($failedComps -join ', ')" } # 输出或导出结果 $allComputerDetails | Format-Table -AutoSize
注意事项
- 确保执行脚本的账号拥有域内计算机的管理员权限,能远程访问WMI/CIM服务
- 目标机器需要开启
WinRM服务(可通过Enable-PSRemoting命令手动开启,或通过组策略批量配置) - 如果机器数量极多,可以通过
-ThrottleLimit参数限制并行数量(默认是32)
内容的提问来源于stack exchange,提问作者Grimy
相关产品推荐
相关产品推荐

