我曾尝试使用 PsExec 创建批处理文件来更新远程计算机上的注册表设置,但没有成功,所以我现在尝试使用 Powershell。我使用 Google 编写了以下脚本,并尝试了不同论坛上提供的脚本。
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
if ($myWindowsPrincipal.IsInRole($adminRole))
{
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
$Host.UI.RawUI.BackgroundColor = "Darkred"
clear-host
}
else
{
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
$newProcess.Arguments = $myInvocation.MyCommand.Definition;
$newProcess.Verb = "runas";
[System.Diagnostics.Process]::Start($newProcess);
exit
}
winrm quickconfig
$servers = Get-Content c:\temp\servers.txt
$HostedRegFile = "temp\OfficeDocumentfix.reg"
foreach ($server in $servers)
{
$newfile = "\\$servers\c`$\Downloads\RegistryFiles\"
New-Item -ErrorAction SilentlyContinue -ItemType directory -Path \\$servers\C$\Downloads\RegistryFiles\
Copy-Item $HostedRegFile -Destination $newfile
Invoke-Command -ComputerName $server -ScriptBlock {
Start-Process -filepath "C:\windows\regedit.exe" -argumentlist "/s C:\Downloads\RegistryFiles\test.reg"
Write-Host -NoNewLine "Press any key to continue..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
$returncode = $?+":"+$lastexitcode;
$codearr = $returncode.split(":");
write-host $codearr[0];
write-host $codearr[1];
#echo Registry_updated_successfully
#:Failed
#echo Registry_update_failed
Write-Host -NoNewLine "Press any key to continue..."
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}
}
现在对于我的问题,运行脚本,我收到以下错误
WinRM 已设置为在此机器上接收请求。
WinRM 已在此机器上设置远程管理。
复制项:找不到路径“C:\OfficeDocumentfix.reg”,因为它不存在。
但是路径是正确的,我使用的脚本是否存在明显的错误,这是我第二次使用 Powershell,因此任何帮助都将不胜感激
答案1
WinRM 已设置为在此机器上接收请求。
WinRM 已在此机器上设置远程管理。
从脚本中删除它winrm quickconfig
。它想要配置你的 WinRM 服务,但它已经设置好了,所以不需要这样做。WinRM 允许你通过其服务访问远程计算机,例如,它是必需的invoke-command {}
。
复制项:找不到路径“C:\OfficeDocumentfix.reg”,因为它不存在。
原因是,您的$newfile
变量使用了$servers
而不是$server
它应该使用的 (因为它在foreach()
块内)所以$servers
是$null
。这就是错误的原因。
如果您使用的注册表文件写入 HKCU:,则无需提升脚本,如果写入 HKLM:,则必须提升。只有管理员可以写入 HKLM。提升是从开始到的整个部分winrm quickconfig
。
这应该会给你以下最终产品(我把海拔留在了那里):
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
if ($myWindowsPrincipal.IsInRole($adminRole))
{
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
$Host.UI.RawUI.BackgroundColor = "Darkred"
clear-host
}
else
{
$newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
$newProcess.Arguments = $myInvocation.MyCommand.Definition;
$newProcess.Verb = "runas";
[System.Diagnostics.Process]::Start($newProcess);
exit
}
$servers = Get-Content c:\temp\servers.txt
$HostedRegFile = "C:\temp\CyclopsOfficeDocumentfix.reg"
foreach ($server in $servers)
{
$newfile = "\\$server\c`$\Downloads\RegistryFiles\"
New-Item -ErrorAction SilentlyContinue -ItemType directory -Path \\$server\C$\Downloads\RegistryFiles\
Copy-Item $HostedRegFile -Destination $newfile
Invoke-Command -ComputerName $server -ScriptBlock {
Start-Process -filepath "C:\windows\regedit.exe" -argumentlist "/s C:\Downloads\RegistryFiles\test.reg"
Write-Host -NoNewLine "Press any key to continue..."
}
}
请看一下这一行:
Start-Process -filepath "C:\windows\regedit.exe" -argumentlist "/s C:\Downloads\RegistryFiles\test.reg"
它还不是动态的。它将始终读取test.reg
您想要的 reg 文件。
您start-process
也可以简单地使用regedit /s $regfile /f
PowerShell 执行批处理命令(但那是细节。如果它像这样工作,请保持原样)。
答案2
我不喜欢处理双跳和其他身份验证问题,而是将注册表文件的内容作为参数传递给Invoke-Command
。这比让远程服务器尝试联系某个文件共享以尝试提取文件具有某些优势,甚至可以从跨域的计算机运行。
$regFile = @"
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters]
"MaxUserPort"=dword:00005000
"TcpTimedWaitDelay"=dword:0000001e
"@
Invoke-Command -ComputerName comp -ScriptBlock {param($regFile) $regFile | out-file $env:temp\a.reg;
reg.exe import $env:temp\a.reg } -ArgumentList $regFile