如何将 Powershell 中的拒绝访问和所有其他错误重定向到变量(循环直到命令不失败)

How to redirect Access Denied and all other errors in Powershell to a variable (Loop until command doesnt fail)

我正在尝试创建一个 bootstrap 脚本来设置服务器并将它们添加到域中。问题是一些网络更改在不同的时间内没有得到实施,导致加入域的命令失败(总是出现相同的错误)。要解决这个问题,我所要做的就是 运行 一分钟后再次执行命令,但这作为长脚本的一部分是不切实际的。

我的解决方案是:

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

但是 $exit 始终为 0/false,即使我输入了一些注定会失败的不存在的命令。

我的另一个想法是将所有错误重定向到一个变量,并在变量中搜索包含我经常遇到的错误的文本,如果不存在该错误,则停止循环。

尝试在 powershell 中重定向 stderr 对我也不起作用

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

所以这里我特意将 ExecPol 设置为未提升的提示:

你可以使用-errorvariable

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

或者,如果您想对错误执行某些操作:

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

然后在文本文件中搜索您的错误

编辑

所以有些事情实际正确使用 errorVariable 不使用 $ 所以它会是 -errorvariable myError

如果您想搜索错误,更好的方法是:

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
}

所有错误都可以在 $error 中找到,如果您想检查最后一个错误,您可以使用 $error[0],它会告诉您收到的最后一个错误。

我通常会做类似下面的事情,并将其放在一个单独的函数中以保持主代码路径干净。可以添加一个计数器来限制重试次数。

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

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