如何用PowerShell向HTML文件追加数据实现服务状态前后对比
PowerShell系统健康检查报告追加状态对比实现方案
要实现再次运行脚本时追加新状态列并对比变化,核心思路是判断现有报告是否存在,不存在则生成初始报告,存在则解析并修改现有HTML表格,具体步骤和代码如下:
核心步骤
- 提前定义报告路径、当前日期等变量,确保存储目录存在
- 收集本次检查的服务数据,保留唯一标识(服务名称
Name)以便后续匹配 - 检查报告文件:
- 文件不存在:生成包含初始状态列的HTML报告
- 文件存在:解析现有HTML的服务表格,添加新状态列,匹配已有服务的状态变化,同时处理新增/删除的服务
完整代码实现
# 基础配置 $computer = $env:COMPUTERNAME $CurrentDate = Get-Date -Format "yyyy-MM-dd" $reportDir = "C:\HealthCheck\$computer" $reportPath = Join-Path $reportDir "Health Report $CurrentDate.html" # 确保报告目录存在 New-Item -ItemType Directory -Path $reportDir -Force | Out-Null # 定义HTML样式(替换为你原有的$Style内容) $Style = @" <style> body { font-family: Arial, sans-serif; margin: 20px; } table { border-collapse: collapse; width: 90%; margin: 20px 0; } th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } th { background-color: #f2f2f2; } .changed { background-color: #ffcccc; } .new { background-color: #ccffcc; } </style> "@ # 收集本次服务检查数据(用Name作为唯一标识,状态列带日期后缀) $newServiceData = Get-CimInstance Win32_Service -ComputerName $computer | Select-Object DisplayName, Name, StartMode, @{Name="State_$CurrentDate"; Expression={$_.State}} | Sort-Object StartMode, State, DisplayName # 处理报告生成/追加 if (-not (Test-Path $reportPath)) { # 生成初始报告 $servHead = ConvertTo-Html -As Table -Fragment -PreContent '<H2>Services Information</H2>' | Out-String $serviceFragment = $newServiceData | ConvertTo-Html -Fragment ConvertTo-Html -Head $Style -PostContent "$servHead $serviceFragment" -Title "System Health Check Report" | Out-File $reportPath -Encoding UTF8 } else { # 读取并解析现有HTML $htmlContent = Get-Content $reportPath -Raw -Encoding UTF8 $htmlDoc = New-Object -ComObject "HTMLFile" $htmlDoc.write($htmlContent) # 定位服务信息表格(通过前置的H2标题匹配) $serviceTable = $null foreach ($table in $htmlDoc.getElementsByTagName("table")) { $prevElement = $table.previousSibling while ($prevElement -and $prevElement.tagName -ne "H2") { $prevElement = $prevElement.previousSibling } if ($prevElement -and $prevElement.innerText -eq "Services Information") { $serviceTable = $table break } } if ($serviceTable) { # 1. 添加新状态列的表头 $headerRow = $serviceTable.rows[0] $newHeader = $htmlDoc.createElement("TH") $newHeader.innerText = "新状态($CurrentDate)" $headerRow.appendChild($newHeader) | Out-Null # 2. 遍历现有表格行,匹配并填充新状态 $existingServiceNames = @() for ($i = 1; $i -lt $serviceTable.rows.length; $i++) { $row = $serviceTable.rows[$i] $serviceName = $row.cells[1].innerText.Trim() $existingServiceNames += $serviceName $matchingService = $newServiceData | Where-Object { $_.Name -eq $serviceName } $newCell = $htmlDoc.createElement("TD") if ($matchingService) { $newCell.innerText = $matchingService."State_$CurrentDate" # 状态变化时高亮 if ($row.cells[$row.cells.length -1].innerText -ne $matchingService."State_$CurrentDate") { $newCell.className = "changed" } } else { $newCell.innerText = "服务已删除" $newCell.className = "changed" } $row.appendChild($newCell) | Out-Null } # 3. 处理本次新增的服务(现有表格中没有的) $newServices = $newServiceData | Where-Object { $existingServiceNames -notcontains $_.Name } foreach ($service in $newServices) { $newRow = $serviceTable.insertRow() # 填充基础列:DisplayName、Name、StartMode $cell = $newRow.insertCell() $cell.innerText = $service.DisplayName $cell = $newRow.insertCell() $cell.innerText = $service.Name $cell = $newRow.insertCell() $cell.innerText = $service.StartMode # 补全历史状态列(标记为"新增服务") for ($j = 3; $j -lt $headerRow.cells.length -1; $j++) { $cell = $newRow.insertCell() $cell.innerText = "新增服务" } # 填充本次状态列并高亮 $cell = $newRow.insertCell() $cell.innerText = $service."State_$CurrentDate" $cell.className = "new" } # 保存修改后的HTML $updatedHtml = $htmlDoc.documentElement.outerHTML $updatedHtml | Out-File $reportPath -Encoding UTF8 } else { Write-Warning "未找到服务信息表格,无法追加数据。" } }
关键细节说明
- 用
Get-CimInstance替代Get-WmiObject:这是PowerShell的现代cmdlet,性能和兼容性更好 - 服务匹配逻辑:使用
Name属性作为唯一标识,比DisplayName更可靠(避免显示名称重复) - 状态变化高亮:通过CSS类标记状态变化的单元格(红色背景)和新增服务(绿色背景),直观展示变化
- 边界处理:覆盖了服务新增、删除、状态变更三种场景,保证报告的完整性
内容的提问来源于stack exchange,提问作者VrindaPrash
相关产品推荐
相关产品推荐

