2

Both this stack post as well as this one looked similar but I couldn't find my solution there. I'm having an issue understanding the difference between the behaviour in reg export versus reg import.

When running reg export inside powershell, it returns "operation completed successfully" but reg import throws a terminating error saying "operation completed successfully". The registry file is correctly imported even though it is thrown as an error. An example:

PS C:\Windows\System32> reg export HKLM\Software\MySoftware C:\Scripts\MyFile.reg
The operation completed successfully.

PS C:\Windows\System32> reg import C:\Scripts\MyFile.reg
reg : The operation completed successfully.
At line:1 char:1
+ reg import C:\Scripts\MyFile.reg
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (The operation completed successfully.:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

Microsoft's documentation of the reg import command says that the return codes are 0 for Success and 1 for Failure. Why would Powershell return the success as a regular success message for reg export, but throw it as a terminating error for reg import?

I'm running Powershell as an Admin and the logged in user is a local administrator on the server. Any assistance is appreciated.

Tanaka Saito
  • 943
  • 1
  • 17
  • 40
  • `$out = .{ reg import "\\$CurServer\MySharedPath\RegistryBackup.reg" } 2>$null` – Mathias R. Jessen Apr 28 '20 at 15:04
  • 2
    That ignores any errors, so when I deliberately specify an incorrect path to the file name it doesn't throw any error. – Tanaka Saito Apr 28 '20 at 15:06
  • 1
    Can't you test `$LASTEXITCODE` after the regedit call, and then throw your own exception. – JPBlanc Apr 28 '20 at 15:29
  • I updated the article to remove the Invoke-Command issues and only focus on the difference between reg export and reg import. $LASTEXITCODE returns 0, which seems correct if we look in the microsoft article on reg import. The question is why reg export returns it as a regular message while reg import throws it as a terminating error. – Tanaka Saito Apr 28 '20 at 15:31
  • Ooooh, you mean I use the $LASTEXITCODE to create my own exception with a if 0 then this if 1 then that, sorry I didn't read your statement fully! Yes, I was thinking that was one solution :) It doesn't really look nice though, doing a try/catch where I solve things in the catch just because it always throws an error. – Tanaka Saito Apr 28 '20 at 16:17

1 Answers1

5

Your "problem" is, you are using PowerShell in ISE. Try using PowerShell directly. The difference? Two strange things first:

  1. reg export writes its output on success to stdout. reg import writes its output on success to stderr (I would consider that as "strange").
  2. ISE throws an exception, if an external program writes to stderr. PowerShell does not do that.

In conclusion, ISE throws an error on an actual success message, because it has been written to stderr. You can prevent that, using the Start-Process cmdlet:

Start-Process reg -ArgumentList "import C:\Scripts\MyFile.reg"

Because stdout and stderr of the external program are then not forwarded to your terminal. Instead, you can access them through the parameters -RedirectStandardOutput and -RedirectStandardError, if needed.

If you want to evaluate the exit code, you can do it like this:

$process = Start-Process reg -ArgumentList "import C:\Scripts\MyFile.reg" -PassThru -Wait
$process.ExitCode
stackprotector
  • 10,498
  • 4
  • 35
  • 64
  • 4
    Just in case there is a space in the registry file path, it makes sense to escape it like (replace BACKTICK with the actual backtick character): $process = Start-Process reg -ArgumentList "import BACKTICK"C:\My Scripts\My File.regBACKTICK"" -PassThru -Wait – Alek Davis Aug 08 '20 at 08:33