PowerShell脚本调试:多远程机器EXAMPLE.ENG文件大小自动收集
自动化收集子网机器文件大小的PowerShell脚本问题
需求概述
需要自动化收集同子网内140余台机器中D:\Dump\logs\default\Rk7\base\EXAMPLE.ENG文件的大小,将包含IP的结果写入Excel表格。机器可通过VPN/TeamViewer访问,尝试用PowerShell实现但脚本运行异常。
现有脚本
$targetIP = "10.168.0.45" $remotePath = "D:\Dump\logs\default\Rk7\base\EXAMPLE.ENG" $resultPath = "C:\result.csv" if (-not (Test-Path $resultPath)) { "Computer,FileSize(Bytes)" | Out-File -FilePath $resultPath -Encoding utf8 } $credential = Get-Credential -Message "Enter credentials for remote access to $targetIP" if ($null -eq $credential) { Write-Host "Error: Credential is null. Please provide valid credentials." exit } try { $session = New-PSSession -ComputerName $targetIP -Credential $credential -ErrorAction Stop $result = Invoke-Command -Session $session -ScriptBlock { param($path) if (Test-Path $path) { $fileInfo = Get-Item $path -ErrorAction Stop return $fileInfo.Length } else { throw "File not found at the specified path: $path" } } -ArgumentList $remotePath "$targetIP,$result" | Out-File -FilePath $resultPath -Append -Encoding utf8 Write-Host "Processed $targetIP: File size is $result bytes" -ForegroundColor Green } catch { $errorMessage = "Error processing ${targetIP}: $($_.Exception.Message)" Write-Host $errorMessage -ForegroundColor Red "$targetIP,Error: $($_.Exception.Message)" | Out-File -FilePath $resultPath -Append -Encoding utf8 } finally { Remove-PSSession -Session $session -ErrorAction SilentlyContinue } Write-Host "Process completed. Results saved to $resultPath"
具体问题
- 脚本无法收集或写入正确的文件大小
- 抛出文件未找到错误,例如:
Error processing 10.168.0.45: File not found at the specified path: \\10.168.0.45\D$\D:\Dump\logs\files\EXAMPLE.ENG - 有时仅写入表头
Computer,FileSize(Bytes),无实际数据
环境
- 机器可通过VPN或TeamViewer访问
- 运行环境:Windows 11 + PowerShell 5.1
疑问
- 是否应继续调试该脚本,还是有可简化流程的关键点被忽略?
- 如何排查文件访问问题,确保正确收集文件大小?
解决方案
1. 核心问题排查:路径解析错误
错误提示中的路径\\10.168.0.45\D$\D:\Dump\logs\files\EXAMPLE.ENG是因为远程会话中路径被错误解析。Invoke-Command的脚本块在远程机器执行,直接用本地格式路径D:\...即可,若PSSession建立异常,会导致PowerShell错误拼接UNC路径。
2. 脚本修复要点
(1)确保远程会话基础环境正常
- 目标机器需启用WinRM:在目标机执行
Enable-PSRemoting -Force(管理员权限) - VPN连接后,确认本地能ping通目标IP,且WinRM默认端口5985未被防火墙拦截
(2)修正路径传递与验证逻辑
修改远程脚本块,强制解析本地路径格式:
$result = Invoke-Command -Session $session -ScriptBlock { param($localPath) $resolvedPath = [System.IO.Path]::GetFullPath($localPath) if (Test-Path -Path $resolvedPath -PathType Leaf) { (Get-Item -Path $resolvedPath).Length } else { throw "File not found: $resolvedPath" } } -ArgumentList $remotePath
(3)优化CSV写入逻辑
用Export-Csv替代手动拼接字符串,避免格式错误:
# 构造输出对象 $outputObject = [PSCustomObject]@{ Computer = $targetIP 'FileSize(Bytes)' = if ($result) { $result } else { "Error: $($_.Exception.Message)" } } # 写入CSV $outputObject | Export-Csv -Path $resultPath -Append -NoTypeInformation -Encoding UTF8
(4)批量处理140台机器的优化
将IP列表存入ips.txt(每行一个IP),循环处理:
$ipList = Get-Content -Path "C:\ips.txt" $resultPath = "C:\result.csv" # 初始化CSV表头 if (-not (Test-Path $resultPath)) { [PSCustomObject]@{ Computer = "" 'FileSize(Bytes)' = "" } | Export-Csv -Path $resultPath -NoTypeInformation -Encoding UTF8 } $credential = Get-Credential -Message "Enter credentials for remote machines" foreach ($targetIP in $ipList) { $remotePath = "D:\Dump\logs\default\Rk7\base\EXAMPLE.ENG" try { $session = New-PSSession -ComputerName $targetIP -Credential $credential -ErrorAction Stop $fileSize = Invoke-Command -Session $session -ScriptBlock { param($path) $resolvedPath = [System.IO.Path]::GetFullPath($path) if (Test-Path $resolvedPath -PathType Leaf) { (Get-Item $resolvedPath).Length } else { throw "File not found" } } -ArgumentList $remotePath [PSCustomObject]@{ Computer = $targetIP 'FileSize(Bytes)' = $fileSize } | Export-Csv -Path $resultPath -Append -NoTypeInformation -Encoding UTF8 Write-Host "Success: $targetIP - $fileSize bytes" -ForegroundColor Green } catch { $errorMsg = $_.Exception.Message [PSCustomObject]@{ Computer = $targetIP 'FileSize(Bytes)' = "Error: $errorMsg" } | Export-Csv -Path $resultPath -Append -NoTypeInformation -Encoding UTF8 Write-Host "Failed: $targetIP - $errorMsg" -ForegroundColor Red } finally { if ($session) { Remove-PSSession $session -ErrorAction SilentlyContinue } } }
3. 流程简化建议
- 若WinRM配置困难,可改用
Get-CimInstance替代PSSession:
Get-CimInstance -ComputerName $targetIP -Credential $credential -ClassName CIM_DataFile -Filter "Name='D:\\Dump\\logs\\default\\Rk7\\base\\EXAMPLE.ENG'" | Select-Object @{Name='Computer';Expression={$targetIP}}, @{Name='FileSize(Bytes)';Expression={$_.Size}}
- 若仅能通过TeamViewer访问,可结合TeamViewer命令行工具执行远程操作,但复杂度较高,优先确保VPN下WinRM正常工作。
内容的提问来源于stack exchange,提问作者mr Flexer
相关产品推荐
相关产品推荐

