1

Я попытался создать командный файл с помощью 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 уже настроен для удаленного управления на этом компьютере.

Copy-item: Не удается найти путь «C:\OfficeDocumentfix.reg», так как он не существует.

Но путь правильный, есть что-то явно явно неправильное в сценарии, который я использую, это мой второй шаг в Powershell, поэтому любая помощь будет оценена

2 ответа2

3

WinRM уже настроен для получения запросов на этом компьютере.

WinRM уже настроен для удаленного управления на этом компьютере.

удалите этот winrm quickconfig из вашего скрипта. он хочет настроить службу WinRM, но он уже настроен, поэтому в этом нет необходимости. WinRM позволяет вам получить доступ к удаленному компьютеру через его службу, например, для invoke-command {} .

Copy-item: Не удается найти путь «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 может выполнять пакетные команды (но это подробно. Если это работает так, оставьте все как есть).

1

Я предпочитаю не связываться с двойным прыжком и другими проблемами аутентификации и передавать содержимое файла реестра в качестве параметра в 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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .