powershell批量替换注册表
起因是我公司的电脑在初始化⽤户名时⽤了花名(别往),所以⽤户⽂件夹命名为中⽂,由此导致了python、ruby⽆法加载⾃⾝模块(因为他们的模块放在当前⽤户的⽂件夹下,这样路径就带了中⽂,就会报编码异常)。
然后我通过新建另⼀个管理员来修改当前⽤户⽂件夹名为拼⾳后再修改注册表指定的⽤户⽂件
夹HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList,再删除新增的管理员这样的操作来修改了⽤户⽂件夹名并使计算机正常运⾏
但是后来发现很多vscode等右键菜单⽆法使⽤,环境变量也需要改变,因为他们的注册表路径仍是旧的C:\Users\别往⽽不
是C:\Users\biewang,需要⽤批量修改替换注册表的路径,然⽽微软的注册表⽬前并不提供批量替换功能,只能⾃⼰查⼿动替换,⽹上也没有⽅法
因此作为⼯程师,没有⽅法就⾃⼰做⽅法,我的想法是⽤powershell脚本查询注册表中匹配的数据再对ta进⾏修改
注意事项
1.windows默认编码为GBK,否则中⽂简本乱码
2.注册表修改有风险,注意备份,或者debug实验,在我本地运⾏是ok的但是可能会有其他bug
3.全局替换时匹配的数据不能太短,不然容易改到其他不应该改的东西导致⽆法开机
4.如果涉及修改注册表需要管理员权限开启的powershell来执⾏
5.如果powershell⽆法执⾏脚本,按照提⽰开启权限(需要管理员)
Set-ExecutionPolicy RemoteSigned本地机器脚本执⾏权限设置为下载的脚本需要签名
get-ExecutionPolicy -list查看
开发
regedit.psm1注册表函数模块,主要封装修改注册表⽅法和写⽇志防⽌出错
#设置注册表并⽇志
function SetAndLong($Path,$Name,$Value,$OldValue){
#Requires -RunAsAdministrator
$command="Set-ItemProperty -Path $Path -Name $Name -Value $Value "+';$?'
$status=iex$command
if($status){
"$(Get-Date)$command oldvalue $OldValue"|Out-File-Append -Encoding $(if($PSVersionTable.PSVersion.Major -ge 6){"utf8NoBOM"}else{"utf8"})-FilePath "regchange.log"
}
}
#替换注册表stackoverflow/questions/26680410/powershell-find-and-replace-on-registry-values#
function RegistryValue-Replace(
$path = $(throw"path为必填(即注册表路径)"),
$NewValue = $(throw"NewValue为必填(即替换的值)"),
$key,#可选为指定键
$OldValue,#OldValue可选(即当前值),有则进⾏校验
$DoMethod#DoMethod可选,⾃定义处理函数
){
Get-Item-ErrorAction SilentlyContinue -path  "Microsoft.PowerShell.Core\Registry::$path"|
foreach{
Get-ItemProperty-Path "Microsoft.PowerShell.Core\Registry::$_"|
foreach{
$CurrentUserShellFoldersPath = $_.PSPath
$_.PSObject.Properties |
foreach{
if(!::IsNullOrEmpty($key)-and!($_.name -like$key)){#键校验
return
powershell创建目录
}
if(!::IsNullOrEmpty($OldValue)-and!($_.Value -eq$OldValue)){#旧值校验
return
}
if($DoMethod-ne$Null){
$DoMethod.invoke($_,$CurrentUserShellFoldersPath)
return
}
SetAndLong -Path $CurrentUserShellFoldersPath-Name $_.Name -Value $newValue-OldValue $_.Value
}
}
}
}
# 测试
# RegistryValue-Replace "HKCR\Installer\Products\744364B64946E5F42B50D57B45FC3471\SourceList" "test" -DoMethod {par
am($Propert) $Propert.Na me} #回调测试
# RegistryValue-Replace "HKCR\Installer\Products\744364B64946E5F42B50D57B45FC3471\SourceList" "test" -key "LastUsedSource" #指定key测试
# RegistryValue-Replace "HKCR\Installer\Products\744364B64946E5F42B50D57B45FC3471\SourceList" "test" -OldValue "MfeEEPc64.msi" #指定旧值测试# RegistryValue-Replace "HKCR\Installer\Products\744364B64946E5F42B50D57B45FC3471\SourceList" -key "LastUsedSource" "MfeEEPc64.msi" #常规赋值还原
regDataBatchChange.ps1批量修改脚本
# 脚本⽤于扫描替换注册表值,⽐如修改⽤户⽂件夹名后
Import-Module.\regedit.psm1 #引⼊脚本
$replaceKey=@('C:\Users\别往','C:\Users\biewang')#C:\Users\别往替换为 C:\Users\biewang
# check param num
if($unt -ne 2)
{
throw"参数不匹配,replaceKey需要两个参数"
}
$re=$replaceKey[0]-replace"\\","\\"
# query regdata
function Shell-Do(){
#遍历注册表5个根项
Foreach($hkey in @('HKCR','HKCU','HKLM','HKU','HKCC')){
$querydata=reg query $hkey/s /d /f $replaceKey[0]#HKCR HKCU HKLM HKU HKCC
::matches($querydata,'(?m)(?<path>\S+) {5}\S+ {4}\S+ {4}')|
foreach{
RegistryValue-Replace$_.Groups['path'].value $null-DoMethod {
param($Propert,$path)
if($Propert.Value -match$re){
$new=$Propert.Value -replace$re,$replaceKey[1]
SetAndLong -Path "'$path'"-Name "`"$($Propert.Name)`""-Value "'$new'"-OldValue "$($Propert.Value)"
}
}
}
}
}
Shell-Do
结果
替换了4280个项,会在运⾏脚本的位置⽣成⽇志⽂件regchange.log记录成功修改的路径、新值、旧值,以下给出部分⽇志:
06/01/2021 12:35:08 Set-ItemProperty -Path 'Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\U ninstall\{f684de81-73c2-4924-ad43-e7ae400d47b5}' -Name "BundleCachePath" -Value 'C:\Users\biewang\AppData\Local\Package Cache\{f684de81-73c2 -4924-ad43-e7ae400d47b5}\python-3.' ;$? oldvalue C:\Users\别往\AppData\Local\Package Cache\{f684de81-73c2-4924-ad43-e7ae400d47 b5}\python-3.
06/01/2021 12:35:08 Set-ItemProperty -Path 'Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\U ninstall\{f684de81-73c2-4924-ad43-e7ae400d47b5}' -Name "DisplayIcon" -Value 'C:\Users\biewang\AppData\Local\Package Cache\{f684de81-73c2-4924-ad43-e7ae400d47b5}\python-3.,0' ;$? oldvalue C:\Users\别往\AppData\Local\Package Cache
\{f684de81-73c2-4924-ad43-e7ae400d47b5}\ python-3.,0
06/01/2021 12:35:08 Set-ItemProperty -Path 'Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\U ninstall\{f684de81-73c2-4924-ad43-e7ae400d47b5}' -Name "ModifyPath" -Value '"C:\Users\biewang\AppData\Local\Package Cache\{f684de81-73c2-4924 -ad43-e7ae400d47b5}\python-3." /modify' ;$? oldvalue "C:\Users\别往\AppData\Local\Package Cache\{f684de81-73c2-4924-ad43-e7ae400 d47b5}\python-3." /modify
其他
Q: 为什么不⽣成*.reg⽂件,这样⽅便出错回滚
A: 因为reg export导出reg⽂件时对于hex类型中⽂会乱码,不⽅便匹配中⽂,还有其他未知数据类型不好处理,如果理解了脚本⾃⼰写逻辑回滚也很快,综合评判我的空余时间不⽀持这样做,如果有兴趣可以去尝试

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。