PowerShell脚本问题:AD用户应用报告重复且记录不全
问题分析与修复:AD用户应用程序报告脚本异常
问题现象
- 生成的所有AD用户应用报告内容完全一致,均为本地机器的全局安装程序
- 应用列表不完整,缺少用户个人安装的程序,且遗漏部分非MSI格式安装的软件
问题根源
- 脚本中所有应用获取逻辑都指向
localhost的全局系统路径,完全未关联具体AD用户的个人配置 - 依赖
Win32_Product和wmic product获取程序:这两个仅能返回MSI格式安装的软件,且Win32_Product可能触发程序自动修复操作,存在风险 - 未读取用户个人注册表(
HKEY_CURRENT_USER)下的应用安装信息
修复方案
核心修改点
- 加载目标AD用户的注册表配置单元(NTUSER.DAT),读取其个人安装的应用
- 移除
Win32_Product和wmic调用,改用更可靠的注册表读取方式获取全局应用 - 合并全局应用与用户个人应用,生成完整的应用列表
修复后完整脚本
$users = Get-ADUser -Filter * -Properties DisplayName, ProfilePath foreach ($user in $users) { $username = $user.SamAccountName $displayName = $user.DisplayName $userProfilePath = $user.ProfilePath # 1. 获取机器全局安装的应用(32/64位) $globalRegistryPaths = @( "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*", "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" ) $globalSoftware = foreach ($path in $globalRegistryPaths) { Get-ChildItem "Registry::HKEY_LOCAL_MACHINE\$path" -ErrorAction SilentlyContinue | Get-ItemProperty -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -and -not $_.SystemComponent -and -not $_.ParentKeyName } | Select-Object -ExpandProperty DisplayName } # 2. 获取用户个人安装的应用 $userSoftware = @() if ($userProfilePath -and (Test-Path "$userProfilePath\NTUSER.DAT")) { # 加载用户注册表 hive $regHivePath = "HKU\Temp_$username" reg load $regHivePath "$userProfilePath\NTUSER.DAT" | Out-Null $userRegistryPaths = @( "Software\Microsoft\Windows\CurrentVersion\Uninstall\*" ) $userSoftware = foreach ($path in $userRegistryPaths) { Get-ChildItem "Registry::$regHivePath\$path" -ErrorAction SilentlyContinue | Get-ItemProperty -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -and -not $_.SystemComponent } | Select-Object -ExpandProperty DisplayName } # 卸载注册表 hive reg unload $regHivePath | Out-Null } # 合并并去重应用列表 $allSoftware = $globalSoftware + $userSoftware $uniqueSoftware = $allSoftware | Where-Object { $_ } | Select-Object -Unique | Sort-Object # 生成HTML报告 $reportContent = @" <html> <head> <style> table { border-collapse: collapse; width: 80%; margin: 20px auto; } th, td { border: 1px solid #ddd; padding: 12px; text-align: left; } th { background-color: #f2f2f2; } h1 { text-align: center; color: #333; } </style> </head> <body> <h1>已安装应用 - $displayName ($username)</h1> <table> <tr> <th>应用名称</th> </tr> "@ foreach ($app in $uniqueSoftware) { $reportContent += "<tr><td>$app</td></tr>" } $reportContent += @" </table> </body> </html> "@ # 保存报告到桌面文件夹 $desktopPath = [Environment]::GetFolderPath('Desktop') $reportFolder = Join-Path -Path $desktopPath -ChildPath '应用报告' if (-not (Test-Path -Path $reportFolder)) { New-Item -Path $reportFolder -ItemType Directory | Out-Null } $reportFileName = "应用报告_$username$((Get-Date).ToString('yyyyMMdd')).html" $reportFilePath = Join-Path -Path $reportFolder -ChildPath $reportFileName $reportContent | Out-File -FilePath $reportFilePath -Encoding UTF8 }
注意事项
- 运行脚本需要管理员权限,否则无法加载用户注册表配置单元
- 仅能获取已配置本地用户配置文件的AD用户(即用户至少登录过一次本地机器)
- 部分应用可能不会在Uninstall注册表项中记录,这类软件无法被捕获
内容的提问来源于stack exchange,提问作者A K
相关产品推荐
相关产品推荐

