运维工程师的利器:用PowerShell脚本批量收集局域网内Win电脑的硬件资产信息
企业级硬件资产盘点:基于PowerShell的自动化解决方案
在IT资产管理领域,准确掌握每台设备的硬件配置是运维工作的基础。想象一下,当CEO突然询问"我们有多少台电脑内存低于8GB?"或者审计部门要求提供所有设备的CPU型号清单时,传统的手动记录方式将耗费大量人力。这正是自动化资产盘点的价值所在——通过PowerShell脚本,我们可以在30分钟内完成过去需要三天的工作量。
1. 环境准备与基础架构设计
1.1 选择正确的远程管理协议
在企业环境中执行批量操作,首先需要建立可靠的远程连接机制。WinRM(Windows Remote Management)是目前最推荐的协议,相比传统的WMI,它采用标准的HTTP/HTTPS端口(5985/5986),更易于通过防火墙:
# 启用WinRM服务(需管理员权限) Enable-PSRemoting -Force Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*" -Force Restart-Service WinRM对于已加入Active Directory域的环境,更高效的方案是直接通过AD查询目标计算机:
# 获取域内所有Windows工作站列表 $computers = Get-ADComputer -Filter {OperatingSystem -Like "*Windows*"} | Select-Object -ExpandProperty Name1.2 构建健壮的异常处理机制
批量执行时,网络波动、权限不足等情况不可避免。以下模板展示了如何实现带错误重试的逻辑:
$retryCount = 3 $retryDelay = 5 foreach ($computer in $computers) { $attempt = 0 while ($attempt -lt $retryCount) { try { $session = New-PSSession -ComputerName $computer -ErrorAction Stop Invoke-Command -Session $session -ScriptBlock { # 硬件信息收集代码块 } Remove-PSSession $session break } catch { $attempt++ if ($attempt -eq $retryCount) { Write-Warning "无法连接 $computer : $_" Add-Content -Path ".\FailedComputers.log" -Value "$computer : $_" } Start-Sleep -Seconds $retryDelay } } }2. 核心硬件信息采集技术
2.1 多维度CPU信息获取
专业级的CPU信息采集不应仅限于型号名称。以下代码可获取包括核心数、线程数、缓存等完整规格:
$cpuInfo = Get-CimInstance -ClassName Win32_Processor | Select-Object @{ Name = "Model"; Expression = {$_.Name.Trim()} }, @{ Name = "Cores"; Expression = {$_.NumberOfCores} }, @{ Name = "Threads"; Expression = {$_.NumberOfLogicalProcessors} }, @{ Name = "L2Cache"; Expression = {"$([math]::Round($_.L2CacheSize/1KB)) KB"} }, @{ Name = "L3Cache"; Expression = {"$([math]::Round($_.L3CacheSize/1KB)) KB"} }, MaxClockSpeed, SocketDesignation2.2 内存的精细化分析
内存信息采集应当区分物理插槽分布和总容量,这对硬件升级规划至关重要:
$memoryModules = Get-CimInstance -ClassName Win32_PhysicalMemory | Select-Object Manufacturer, PartNumber, @{Name="CapacityGB"; Expression={[math]::Round($_.Capacity/1GB, 2)}}, Speed, DataWidth, FormFactor, BankLabel, DeviceLocator $memorySummary = @{ TotalGB = [math]::Round(($memoryModules | Measure-Object -Property Capacity -Sum).Sum/1GB, 2) Modules = $memoryModules.Count SlotsUsed = ($memoryModules | Group-Object BankLabel).Count }2.3 存储设备的专业级报告
存储设备信息需要区分SSD和HDD,并识别NVMe协议:
$disks = Get-CimInstance -ClassName Win32_DiskDrive | ForEach-Object { $isSSD = $_ -match "SSD|Solid State" -or $_.MediaType -eq "Fixed hard disk media" -and (Get-PhysicalDisk -SerialNumber $_.SerialNumber).MediaType -eq "SSD" [PSCustomObject]@{ Model = $_.Model.Trim() SizeGB = [math]::Round($_.Size/1GB) Interface = if ($_.InterfaceType -eq "SCSI") {"SATA"} else {$_.InterfaceType} Protocol = if ($_.Model -match "NVMe") {"NVMe"} elseif ($isSSD) {"AHCI"} else {"Rotational"} Serial = $_.SerialNumber.Trim() Partitions = (Get-Disk -Number $_.Index | Get-Partition).Count } }3. 企业级报表生成系统
3.1 多格式输出引擎
根据不同使用场景,我们需要支持多种输出格式:
function Export-AssetReport { param( [Parameter(Mandatory=$true)] $Data, [ValidateSet('CSV','HTML','JSON')] $Format = 'CSV' ) $timestamp = Get-Date -Format "yyyyMMdd-HHmmss" $filename = "HardwareAssets_$timestamp.$($Format.ToLower())" switch ($Format) { 'CSV' { $Data | Export-Csv -Path $filename -NoTypeInformation -Encoding UTF8 } 'HTML' { $html = $Data | ConvertTo-Html -Title "硬件资产报告" -PreContent "<h1>硬件资产清单</h1><p>生成时间: $(Get-Date)</p>" $html = $html -replace "<table>", '<table class="table table-striped table-bordered">' $html | Out-File -FilePath $filename -Encoding UTF8 } 'JSON' { $Data | ConvertTo-Json -Depth 5 | Out-File -FilePath $filename -Encoding UTF8 } } return (Get-Item $filename).FullName }3.2 可视化仪表板生成
对于管理层汇报,可生成直观的HTML仪表板:
function New-AssetDashboard { param($AssetData) $template = @" <!DOCTYPE html> <html> <head> <title>硬件资产仪表板</title> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <style> .card { margin:10px; padding:15px; border-radius:5px; box-shadow:0 2px 5px rgba(0,0,0,0.1); } .grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(300px, 1fr)); } </style> </head> <body> <h1>企业硬件资产概览</h1> <div class="grid"> <div class="card"> <h3>CPU型号分布</h3> <canvas id="cpuChart"></canvas> </div> <div class="card"> <h3>内存容量分布</h3> <canvas id="memoryChart"></canvas> </div> </div> <script> const cpuData = $($AssetData | Group-Object CPU | ConvertTo-Json); const memoryData = $($AssetData | Group-Object {[math]::Floor($_.MemoryGB/8)*8} | ConvertTo-Json); new Chart(document.getElementById('cpuChart'), { type: 'pie', data: { labels: cpuData.Name, datasets: [{ data: cpuData.Count }] } }); new Chart(document.getElementById('memoryChart'), { type: 'bar', data: { labels: memoryData.Name.map(x => x + 'GB+'), datasets: [{ data: memoryData.Count }] } }); </script> </body> </html> "@ $template | Out-File "AssetDashboard.html" -Encoding UTF8 }4. 生产环境部署策略
4.1 定时任务自动化
通过Windows任务计划实现定期自动收集:
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File C:\Scripts\AssetCollection.ps1" $trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At 2am Register-ScheduledTask -TaskName "Weekly Asset Collection" -Action $action -Trigger $trigger -RunLevel Highest4.2 安全与权限最佳实践
- 最小权限原则:创建专用服务账户,仅授予必要的远程管理权限
- 传输加密:强制使用HTTPS进行WinRM通信
- 日志审计:记录所有收集操作的时间、执行者和目标设备
# 配置受限的管理端点 $sessionConfig = New-PSSessionConfigurationFile -Path .\AssetCollection.pssc -ModulesToImport 'ActiveDirectory' -SessionType 'RestrictedRemoteServer' -LanguageMode 'NoLanguage' Register-PSSessionConfiguration -Name 'AssetCollection' -Path .\AssetCollection.pssc -Force4.3 性能优化技巧
当处理数百台设备时,需要优化执行效率:
# 并行执行设置 $maxThreads = 10 $runspacePool = [runspacefactory]::CreateRunspacePool(1, $maxThreads) $runspacePool.Open() $jobs = foreach ($computer in $computers) { $powershell = [powershell]::Create() $powershell.RunspacePool = $runspacePool [void]$powershell.AddScript({ param($computer) # 收集脚本内容 }).AddArgument($computer) @{ Instance = $powershell Handle = $powershell.BeginInvoke() } } # 等待所有任务完成 while ($jobs.Handle.IsCompleted -contains $false) { Start-Sleep -Milliseconds 500 }