2

I have tried creating a batch file using PsExec to update registry settings on remote computers without success so I am now trying to use Powershell. I have compiled the following script by using Google and playing about with scripts available on different forums.

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

Now for my Problem, running the script, I get the following error

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.

But the path is correct, is there something blatantly obviously wrong with the script I am using, this is my 2nd push into Powershell so any help would be appreciated

1
  • Please edit your question and show the PsExec call.
    – JosefZ
    May 31, 2016 at 13:39

2 Answers 2

4

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

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

delete this winrm quickconfig out of your script. it wants to configure your WinRM service but it's already set up, so there's no need for this. WinRM lets you access Remote Computer via its Service, it's needed for e.g invoke-command {}.

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

the reason for this is, that your $newfile variable uses $servers instead of $server as it should (because it's inside the foreach() block) so $servers is $null. that's the cause of the error.

if the Registry File you're using writes to HKCU:, you don't need to elevate the script, if it's writing to HKLM: you have to. Only Admins can write to HKLM. The elevation is the whole part from the beginning up to winrm quickconfig.

this should give you the following end-product (I left the elevation in there):

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

please do also take a look at this line:

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

it's not dynamic yet. it will always read in test.reg instead of your desired reg-file.

instead of start-process you could also simply use regedit /s $regfile /f PowerShell can execute batch-like commands (but that's detail. if it works like this, leave it like it is).

0
2

I prefer not to mess with double hop and other authentication issues and pass contents of registry file as paramater to Invoke-Command. This provides certain advantages over making remote server trying to reach out to some file share somewhere trying to pull file and can be run even from computers accross domains.

$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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.