Script Powershell para executar um arquivo .reg em computadores remotos

1

Eu tentei criar um arquivo em lotes usando o PsExec para atualizar as configurações do registro em computadores remotos sem sucesso, então agora estou tentando usar o Powershell. Eu compilei o seguinte script usando o Google e brincando com scripts disponíveis em fóruns diferentes.

 $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")
 }

 }

Agora, para o meu problema, executando o script, recebo o seguinte erro

WinRM already is set up to receive requests on this machine.

WinRM already is set up for remote management on this machine.

Copy-item : Cannot find path 'C:\OfficeDocumentfix.reg' because it does not exist.

Mas o caminho está correto, há algo descaradamente obviamente errado com o script que estou usando, este é o meu segundo empurrão no Powershell então qualquer ajuda seria apreciada

    
por Paul508 31.05.2016 / 14:58

2 respostas

3

WinRM already is set up to receive requests on this machine.

WinRM already is set up for remote management on this machine.

exclua este winrm quickconfig do seu script. ele quer configurar seu serviço WinRM mas já está configurado, então não há necessidade disso. O WinRM permite que você acesse o computador remoto através do seu serviço, por exemplo, é necessário invoke-command {} .

Copy-item : Cannot find path 'C:\OfficeDocumentfix.reg' because it does not exist.

a razão para isso é que sua variável $newfile usa $servers em vez de $server como deveria (porque está dentro do bloco foreach() ), então $servers é $null . essa é a causa do erro.

se o arquivo do registro que você está usando grava no HKCU :, você não precisa elevar o script, se estiver gravando no HKLM: você precisa. Somente administradores podem gravar no HKLM. A elevação é toda a parte desde o início até winrm quickconfig .

isto deve dar-lhe o seguinte produto final (deixei a elevação lá):

$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..."
    }
}

por favor, também dê uma olhada nesta linha:

Start-Process -filepath "C:\windows\regedit.exe" -argumentlist "/s C:\Downloads\RegistryFiles\test.reg"

ainda não é dinâmico. ele sempre lerá em test.reg ao invés do arquivo reg desejado.

em vez de start-process você também pode simplesmente usar regedit /s $regfile /f O PowerShell pode executar comandos em lote (mas isso é detalhe. Se funcionar assim, deixe como está).

    
por 31.05.2016 / 15:39
1

Eu prefiro não mexer com salto duplo e outros problemas de autenticação e passar o conteúdo do arquivo de registro como parâmetro para Invoke-Command . Isso fornece certas vantagens sobre fazer com que o servidor remoto tente alcançar algum compartilhamento de arquivos em algum lugar que tente puxar arquivos e possa ser executado até mesmo em computadores através de domínios.

$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
    
por 12.07.2017 / 16:34