I am trying to create a bootstrap script to setup servers and add them to the domain. The problem is some of the networking changes do not get implemented for a varying amount of time causing the command to join the domain to fail (always with the same error). TO get around this all I have to do is run the command again a minute later but this is not practical as part of a long script.

My solution is along the lines of:

$exit = 1
while ($exit -ne 0){
    $exit = 0
    join-domain-command
    $exit = $?
    sleep 20
}

However $exit is always 0/false even when I put in some non existent command that is bound to fail.

My other idea was to redirect all errors to a variable and search the variable for text containing the error I commonly come across and if that error is not present, stop the loop.

Trying to redirect the stderr in powershell doesn't work for me either

$exit = & (dummy-command -confirm:$false) 2>$exit
echo "exit = $exit"

SO here I deliberately set the ExecPol in an un-elevated prompt:

No Exit Code

2

There are 2 best solutions below

3
Dane Boulton On BEST ANSWER

you can use -errorvariable

$exit = 1
while ($exit -ne 0){
    $exit = 0
    join-domain-command -errorvariable $error
    $exit = $?
    sleep 20
}

Or if you want to do something with the error:

    try {
    join-domain-command -errorvariable $error
    }
    catch{
    $error | out-file C:\errors.txt -append
    #or if $error -contains "something" 
    #...do something
    }

then search the text file for your errors

EDIT

So a few things the actual correct use of errorVariable doesnt use the $ so it would be -errorvariable myError

If you want to search an error a better way to do it would be this:

while ($exit -ne 0)
{ 
try {
    join-domain-command
    }
catch{
    if(!($error[0].tostring().contains("specific error text"))) #error text is not your specific error
      {$exit = 1}
    }
sleep 20
}

All errors can be found in $error and if you want to check that last error you use $error[0] which give you the last error that was received.

0
Tony Hinkle On

I usually do something like the following and I put it in a separate function to keep the main code path clean. A counter can be added to limit the number of retries.

$Succeeded = $false
while($Succeeded -eq $false){

  try{
    #commands that may fail
    $Succeeded = $true
  }
  catch{
    #write a message or log something
  } 
  start-sleep -s 60
}