如何将HKCU格式的PowerShell注册表代码适配为HKEY_USERS格式?
解决SOLIDWORKS 2019升级时跨用户注册表自动登录项迁移的坑
我懂你首次捣鼓PowerShell处理SOLIDWORKS 2019升级时的头疼:原脚本是针对当前登录用户(HKCU)保存自动登录注册表项,但卸载脚本需要遍历所有用户的HKEY_USERS路径,把两者结合后,居然出现了注册表项导入到当前用户而非目标用户配置文件的问题,最后只能手动添加解决。下面我帮你把逻辑理顺,给出能直接跑的完整脚本。
核心问题拆解
HKCU是当前登录用户的注册表 hive 快捷映射,而HKEY_USERS包含了所有加载到系统里的用户配置文件(每个用户对应一个唯一的SID路径)。- 你之前的调整代码有语法错误(比如
$autologinpath的字符串拼接写错了),而且**reg import默认会把内容导入到当前用户的HKCU**,根本不会识别你指定的HKEY_USERS下的SID路径——这是新手很容易踩的坑。
修正后的完整可运行脚本
这个脚本会遍历所有加载的用户配置文件,先抓取保存每个用户的SOLIDWORKS自动登录项,清理旧版本注册表后,再精准恢复到目标用户的注册表路径:
# 定义固定配置 $vaultRegPath = "Software\SolidWorks\Applications\PDMWorks Enterprise\ServerConfig\FakeVaultName" $tempRegTemplate = "$env:TEMP\SolidWorksAutoLogin_{0}.reg" $defaultRegFile = "\\fakecompanyname.com\Files\Public\IT\Protected\Projects\SOLIDWORKS 2019 deployment\Vault fakeusername auto login keys.reg" # 遍历所有正常用户的SID(排除系统默认的特殊SID) Get-ChildItem -Path "Registry::HKEY_USERS" | Where-Object { $_.Name -match "^HKEY_USERS\\S-1-5-21-" } | ForEach-Object { $userSID = $_.PSChildName $targetRegPath = "Registry::HKEY_USERS\$userSID\$vaultRegPath" $targetRegKey = "HKU\$userSID\$vaultRegPath" $tempRegFile = $tempRegTemplate -f $userSID try { # 第一步:导出当前用户的自动登录项(如果不是默认用户) if (Test-Path -Path $targetRegPath) { $currentUser = (Get-ItemProperty -Path $targetRegPath -Name User).User.ToLower() if ($currentUser -ne 'fakeusername' -and $currentUser) { reg export $targetRegKey $tempRegFile /y Write-Host "已导出用户[$userSID]的自动登录项到临时文件:$tempRegFile" } } # 第二步:插入你的SOLIDWORKS旧版本清理代码(比如卸载脚本里的删除逻辑) # Remove-Item -Path "Registry::HKEY_USERS\$userSID\Software\SolidWorks" -Recurse -Force -ErrorAction SilentlyContinue # Remove-Item -Path "Registry::HKEY_USERS\$userSID\Software\SRAC" -Recurse -Force -ErrorAction SilentlyContinue # 第三步:恢复自动登录项(用PowerShell直接修改,避开reg import的路径坑) if (Test-Path -Path $tempRegFile) { # 从临时文件里提取保存的用户名 $savedUser = Get-Content $tempRegFile | Select-String -Pattern '"User"="(.*)"' | ForEach-Object { $_.Matches.Groups[1].Value } if ($savedUser) { # 确保注册表路径存在,然后写入值 New-Item -Path $targetRegPath -Force | Out-Null Set-ItemProperty -Path $targetRegPath -Name "User" -Value $savedUser -Type String -Force Set-ItemProperty -Path $targetRegPath -Name "SettingsFromServer" -Value 0 -Type DWord -Force # 替换为你实际需要的数值 Write-Host "已恢复用户[$userSID]的自动登录项" } # 清理临时文件 Remove-Item $tempRegFile -Force } else { # 没有导出项的话,设置默认自动登录配置 New-Item -Path $targetRegPath -Force | Out-Null Set-ItemProperty -Path $targetRegPath -Name "User" -Value "fakeusername" -Type String -Force Set-ItemProperty -Path $targetRegPath -Name "SettingsFromServer" -Value 0 -Type DWord -Force # 替换为你手动添加时用的数值 Write-Host "已为用户[$userSID]设置默认自动登录项" } } catch { Write-Warning "处理用户[$userSID]时出错:$_" } }
关键修正细节
- 精准遍历用户SID:筛选出标准用户的SID(匹配
S-1-5-21-前缀),排除系统自带的特殊SID(比如默认用户、本地服务等)。 - 避开
reg import的坑:直接用PowerShell的Set-ItemProperty修改目标用户的注册表项,彻底避免reg import默认导入到当前用户HKCU的问题。 - 独立临时文件:为每个用户生成专属的临时注册表文件,防止多用户操作时互相覆盖。
- 异常防护:加入
try/catch块捕获错误,避免单个用户处理失败导致整个脚本中断。
备选方案:临时加载用户Hive(适合坚持用reg import的场景)
如果你一定要用reg export/import,可以先临时加载目标用户的NTUSER.DAT文件,这样reg import就能精准导入到目标用户的注册表:
# 示例:加载某个用户的Hive(需要管理员权限,且用户未登录) $userProfilePath = (Get-WmiObject Win32_UserProfile | Where-Object { $_.SID -eq $userSID }).LocalPath reg load "HKU\TempUser" "$userProfilePath\NTUSER.DAT" reg import $tempRegFile reg unload "HKU\TempUser"
不过这种方式要求用户未登录(否则NTUSER.DAT会被系统锁定),所以还是推荐前面用PowerShell直接修改的方式更可靠。
内容的提问来源于stack exchange,提问作者Don't judge me
相关产品推荐
相关产品推荐

