You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

远程计算机软件编目PowerShell脚本故障排查求助

问题排查与修正方案

首先,你的脚本在远程执行时生成空CSV的核心问题集中在远程目标引用错误、权限/服务启动失败未处理以及缺少32位软件检测这几个方面。以下是具体问题分析和修正后的脚本:

核心问题分析

  • 远程计算机名引用错误:取消注释foreach循环后,$sysname=hostname仍然获取本地主机名,而非CSV中的远程计算机名,导致始终查询本地注册表。
  • 服务操作参数错误:Get-Service -ComputerName $system中的$system是CSV对象,需指定具体列名(假设CSV列名为ComputerName),否则无法识别远程主机。
  • 缺少错误处理:远程连接失败、服务启动失败时没有捕获异常,导致脚本静默失败且无日志。
  • 未检测32位软件:仅查询64位注册表路径,遗漏安装在Wow6432Node下的32位软件。

修正后的脚本

$computers = Import-Csv "C:\Temp\AssetList.csv" -Delimiter ","
$results = @()
$errorLog = @()

foreach ($system in $computers) {
    $computerName = $system.ComputerName  # 确保CSV包含ComputerName列
    Write-Host "正在处理计算机: $computerName"

    try {
        # 尝试启动RemoteRegistry服务
        $remoteRegService = Get-Service -ComputerName $computerName -Name RemoteRegistry -ErrorAction Stop
        if ($remoteRegService.Status -ne 'Running') {
            Set-Service -InputObject $remoteRegService -StartupType Manual -ErrorAction Stop
            Start-Service -InputObject $remoteRegService -ErrorAction Stop
            $serviceChanged = $true
        }

        # 定义需要查询的注册表路径(64位+32位)
        $registryPaths = @(
            "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
            "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
        )

        foreach ($path in $registryPaths) {
            $regBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computerName, [Microsoft.Win32.RegistryView]::Registry64)
            $regKey = $regBase.OpenSubKey($path)

            if ($regKey) {
                foreach ($subKeyName in $regKey.GetSubKeyNames()) {
                    $subKey = $regKey.OpenSubKey($subKeyName)
                    $displayName = $subKey.GetValue("DisplayName")
                    
                    if ($displayName) {  # 过滤无显示名称的条目
                        $results += [PSCustomObject]@{
                            ComputerName     = $computerName
                            DisplayName      = $displayName
                            DisplayVersion   = $subKey.GetValue("DisplayVersion")
                            Publisher        = $subKey.GetValue("Publisher")
                            InstallLocation  = $subKey.GetValue("InstallLocation")
                            RegistryPath     = $path  # 标记是64位还是32位软件
                        }
                    }
                }
                $regKey.Close()
            }
            $regBase.Close()
        }

        # 如果修改了服务状态,恢复为Disabled
        if ($serviceChanged) {
            Set-Service -InputObject $remoteRegService -StartupType Disabled -ErrorAction Stop
            Stop-Service -InputObject $remoteRegService -ErrorAction Stop
        }
    }
    catch {
        $errorLog += [PSCustomObject]@{
            ComputerName = $computerName
            ErrorMessage = $_.Exception.Message
            TimeStamp    = Get-Date
        }
        Write-Warning "处理$computerName失败: $($_.Exception.Message)"
    }
}

# 导出结果
$results | Export-CSV "C:\Temp\CatalogedSoftware.csv" -NoTypeInformation -Encoding UTF8
$errorLog | Export-CSV "C:\Temp\SoftwareCatalog_Errors.csv" -NoTypeInformation -Encoding UTF8

Write-Host "处理完成,结果已导出到C:\Temp\CatalogedSoftware.csv,错误日志在C:\Temp\SoftwareCatalog_Errors.csv"

关键修正点说明

  1. 正确引用远程计算机名:使用$system.ComputerName获取CSV中的目标主机名,确保查询远程注册表。
  2. 添加错误处理:用try/catch捕获连接失败、服务操作失败等异常,并生成错误日志,便于排查问题。
  3. 包含32位软件检测:新增Wow6432Node路径查询,避免遗漏32位应用。
  4. 优化服务操作:先检查服务状态,仅在未运行时启动,处理完成后恢复原状态(如果修改过)。
  5. 过滤无效条目:仅保留有DisplayName的软件条目,减少无效数据。
  6. 编码与格式优化:导出CSV时指定UTF8编码,避免中文乱码,使用PSCustomObject替代New-Object提升效率。

前置要求

  • 执行脚本的账号需具备远程计算机的管理员权限。
  • 远程计算机需开启RemoteRegistry服务(脚本会尝试临时启动)。
  • 网络需允许远程注册表访问(防火墙需放行Remote Registry服务端口)。
  • CSV文件需包含ComputerName列,每行对应一个目标计算机名或IP地址。

内容的提问来源于stack exchange,提问作者mc3mcintyre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 01:33:23