PowerShell用Invoke-Command采集远程进程的HTML报告存储与合并问题咨询
问题根因
- 文件写入操作全部置于
Invoke-Command脚本块内部,远程执行时Out-File的相对路径会解析为远程服务器的当前工作目录,导致HTML文件被保存在每台远程节点上,而非本地执行端。 - 原逻辑在每台远程服务器上独立触发HTML生成流程,未将采集到的原始数据回传本地聚合,无法输出整合式单份报告。
实现方案
- 剥离脚本块内所有HTML渲染、文件写入逻辑,仅保留原始进程数据采集功能,将结构化结果回传到本地执行端。
- 在本地统一定义HTML样式、拼接多服务器的内容片段,一次性完成单份报告的写入操作,从根源上避免文件写到远程节点。
- 逐节点拼接采集到的进程数据,在同一份HTML中用分隔线区隔不同服务器的内容块,实现全量信息整合。
可直接复用的调整后代码
# 本地读取待采集服务器列表 $serversname = Get-Content -Path Server_list.text -ErrorAction Stop # 本地定义统一HTML样式头,减少远程执行冗余 $Header = @" <style> h1 { font-family: Arial, Helvetica, sans-serif; color: #e68a00; font-size: 28px; text-align: center; margin: 0 auto; } h2 { font-family: Arial, Helvetica, sans-serif; color: #000099; font-size: 16px; text-align: center; margin: 100 auto; } table { width: 50%; margin-left: auto; margin-right: auto; font-size: 12px; border: 0px; font-family: Arial, Helvetica, sans-serif; } td { padding: 4px; margin: 0px; border: 0; } th { background: #395870; background: linear-gradient(#49708f, #293f50); color: #fff; font-size: 11px; text-transform: uppercase; padding: 10px 15px; vertical-align: middle; } tbody tr:nth-child(even) { background: #f0f0f2; } p { font-family: Arial, Helvetica, sans-serif; color: #ff3300; font-size: 12px; text-align: center; margin: 0 auto; } </style> "@ # 远程节点仅执行数据采集,不做任何文件IO操作,直接返回结构化数据 $collectResult = Invoke-Command -ComputerName $serversname -ScriptBlock { $processProperties = @( @{Name = "Process Name"; Expression = {$_.name}}, @{Name = "Memory (MB)"; Expression = {[Math]::Round(($_.WorkingSet / 1mb), 2)}} ) # 采集三类核心进程数据 $allProcessList = Get-Process | Select-Object $processProperties | Sort-Object -Property "Memory (MB)" -Descending $firefoxProcessList = Get-Process firefox -ErrorAction SilentlyContinue | Select-Object $processProperties | Sort-Object -Property "Memory (MB)" -Descending $highMemFirefoxList = Get-Process firefox -ErrorAction SilentlyContinue | Select-Object @{Name="Process Name"; Expression={$_.name}}, @{Name="Memory (MB)"; Expression={[Math]::Round(($_.WorkingSet /1mb),2)}} | Where-Object {$_.'Memory (MB)' -gt 300} # 回传节点标识与采集到的数据集 [PSCustomObject]@{ ServerName = $env:COMPUTERNAME AllProcess = $allProcessList FirefoxProcess = $firefoxProcessList HighMemFirefox = $highMemFirefoxList } } # 本地逐节点拼接HTML内容片段 $totalHtmlBody = @() foreach ($node in $collectResult) { $nodeTitle = "<h1>Nom du serveur : $($node.ServerName)</h1>" # 生成单节点各进程表的HTML片段 $allProcessHtml = $node.AllProcess | ConvertTo-Html -PreContent "<h2>Informations sur les processus</h2>" $firefoxHtml = $node.FirefoxProcess | ConvertTo-Html -PreContent "<h2>Informations sur les processus Firefox</h2>" $highMemHtml = $node.HighMemFirefox | ConvertTo-Html -PreContent "<h2>Informations sur les processus Firefox qui utilise plus que 300mb de RAM</h2>" # 将当前节点的内容追加到总页面主体,用分隔线区隔不同节点 $totalHtmlBody += "$nodeTitle $allProcessHtml $firefoxHtml $highMemHtml <hr style='width:80%;margin:30px auto;border-top:1px solid #ccc'>" } # 本地生成最终整合报告,直接写入本地磁盘 $finalReport = ConvertTo-Html -Body $totalHtmlBody -Head $Header -Title "Rapport consolidé des processus serveurs" -PostContent "<p>Date de creation : $(Get-Date)</p>" $finalReport | Out-File -Path ".\Consolidated_Server_Process_Report.html" -Encoding utf8
注意事项
- 远程执行PowerShell需要提前配置WinRM服务,确保本地对所有目标服务器有管理员权限
- 原脚本中高内存Firefox的判断逻辑为内存大于300MB,但页面文案标注为200MB,代码已做逻辑与文案的统一,可根据实际需求调整阈值
- 相对路径
.\的解析基于本地执行脚本时的当前工作目录,可根据需要替换为绝对路径指定报告保存位置
内容的提问来源于stack exchange,提问作者xCCIE
相关产品推荐
相关产品推荐

