PowerShell远程注册表恶意项查找删除脚本求助(附代码)
解决远程注册表Run项恶意条目排查与删除问题
首先,咱们先拆解你现有脚本里的几个核心问题:
Get-ChildItem $regkey不能直接作用于RegistryKey对象,而且你要处理的是注册表值(Run项里的开机启动项都是值,不是子键),所以这个用法完全不对——这也是脚本会去搜本地目录的原因:PowerShell把$regkey当成了普通对象,找不到对应路径就默认用当前目录了。- 要删除注册表值,得用
Remove-ItemProperty,而不是Remove-Item(后者是用来删除注册表子键的)。 - 循环里重复打开远程注册表根键,没必要且效率低,应该把这步放到循环外面。
修正后的完整脚本
# 获取目标主机名 $computer = Read-Host -Prompt 'Input target host' # 恶意条目数组(可匹配值名称或值数据,按需调整) $mallist = @("mazqnjrurg","mazqnjrurg.vbs","Angry Birds","Angry Birds.vbe") try { # 打开远程主机的LocalMachine注册表根键 $remoteReg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $computer) # 定位到64位系统默认的Run启动项(可写模式打开) $runKey = $remoteReg.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Run", $true) # 64位系统建议同时检查32位视图的Run项,取消下面注释即可 # $runKey32 = $remoteReg.OpenSubKey("Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run", $true) # 处理64位Run项 if ($runKey) { # 获取所有值名称 $valueNames = $runKey.GetValueNames() foreach ($valueName in $valueNames) { # 获取对应值的数据 $valueData = $runKey.GetValue($valueName) # 检查值名称或值数据是否匹配恶意条目 if ($mallist -contains $valueName -or $mallist | Where-Object { $valueData -match $_ }) { Write-Host "Found malicious entry on $computer : $valueName -> $valueData" # 用PowerShell原生注册表路径删除值 Remove-ItemProperty -Path "Registry::\\$computer\HKLM\Software\Microsoft\Windows\CurrentVersion\Run" -Name $valueName -Force Write-Host "Successfully removed entry: $valueName" } } $runKey.Close() } # 处理32位Run项(如需启用取消注释) # if ($runKey32) { # $valueNames32 = $runKey32.GetValueNames() # foreach ($valueName in $valueNames32) { # $valueData = $runKey32.GetValue($valueName) # if ($mallist -contains $valueName -or $mallist | Where-Object { $valueData -match $_ }) { # Write-Host "Found 32-bit malicious entry on $computer : $valueName -> $valueData" # Remove-ItemProperty -Path "Registry::\\$computer\HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Run" -Name $valueName -Force # Write-Host "Successfully removed 32-bit entry: $valueName" # } # } # $runKey32.Close() # } $remoteReg.Close() } catch { Write-Error "Failed to operate on $computer : $_" }
关键改进点说明
- 正确操作注册表值:用
GetValueNames()获取Run项下的所有值名称,再通过GetValue()拿到对应数据,判断是否匹配恶意条目,最后用Remove-ItemProperty精准删除值。 - 远程注册表路径写法:用
Registry::\\$computer\HKLM\...这种PowerShell原生格式,比直接用.NET对象更直观,也更容易处理删除操作。 - 可写模式打开:
OpenSubKey的第二个参数$true表示以可写模式打开,确保能修改/删除注册表值。 - 异常捕获:加入
try/catch块捕获连接失败、权限不足等异常,避免脚本直接崩溃,同时给出明确错误信息。
安全运维场景额外建议
- 远程注册表服务依赖:确保目标主机的
Remote Registry服务已启动(可通过Get-Service -ComputerName $computer -Name RemoteRegistry检查,未启动则用Start-Service启动)。 - 权限验证:执行脚本的账号需要目标主机的本地管理员权限,否则无法修改HKLM下的敏感注册表项。
- 日志审计:可以添加日志记录,比如
Add-Content -Path ".\RegCleanup.log" -Value "$(Get-Date) - $computer : Removed entry $valueName",方便后续溯源。 - 扩展排查范围:恶意软件常藏在
RunOnce、RunServices、RunServicesOnce等启动项,你可以把这些路径加入脚本循环处理。
内容的提问来源于stack exchange,提问作者RJK
相关产品推荐
相关产品推荐

