【问题标题】:Powershell -- Command throws exception, retry previous command (loops) until successfulPowershell -- 命令抛出异常,重试上一个命令(循环)直到成功
【发布时间】:2020-03-06 19:47:07
【问题描述】:

有一个命令(在 2008 机器上)由于缓冲区限制而引发异常。

基本上,脚本会停止 WAUA,破坏 SoftwareDistribution,然后重建 SD 并检查针对 WSUS 的更新,然后重新签入以使 WSUS 中的警报停止。

如果抛出异常,我希望特定行重试,直到它完成而没有异常,然后我们可以告诉它向 WSUS 报告以清除它。

Stop-Service WUAUSERV
Remove-Item -Path C:\WINDOWS\SoftwareDistribution -recurse
Start-Service WUAUSERV
GPUpdate /force
WUAUCLT /detectnow
sleep 5

## This is the command I'd like to loop, if possible, when an exception is thrown ##
$updateSession = new-object -com "Microsoft.Update.Session"; $updates=$updateSession.CreateupdateSearcher().Search($criteria).Updates

WUAUCLT /reportnow 

任何形式的帮助将不胜感激。我所能找到的一切都是如何创建自己的异常,而不是如何在抛出异常时处理它并重试直到它完成而没有错误。



编辑:

然后根据下面的答案,我希望它是这样写的,所以它会继续检查,直到它成功运行,然后它会重新报告?

Stop-Service WUAUSERV
Remove-Item -Path C:\WINDOWS\SoftwareDistribution -recurse
Start-Service WUAUSERV
GPUpdate /force
WUAUCLT /detectnow
sleep 5
while(-not $?) {$updateSession = new-object -com "Microsoft.Update.Session"; $updates=$updateSession.CreateupdateSearcher().Search($criteria).Updates}
WUAUCLT /reportnow

【问题讨论】:

    标签: windows powershell exception


    【解决方案1】:

    你可以使用特殊字符 $? 如果最后一个命令返回错误,这将返回 false,所以你的 while 循环看起来像:

    while(-not $?)
    

    what is $? in powershell.

    或者,$error[0] 给出最后抛出的错误消息,以便您可以围绕它构建一个 while 循环,类似于:

    while($error[0] -ne "error message")
    

    【讨论】:

    • 但是在这种情况下,While 循环不需要是这样的:while (-not $?) {$updateSession = new-object -com "Microsoft.Update.Session"; $updates=$updateSession.CreateupdateSearcher().Search($criteria).Updates } 这样它会一直运行直到成功?
    【解决方案2】:

    将值设置为 false 并且仅在完全成功时才翻转它。循环直到您成功或您的超时超过您定义的值 - 如果您不包括超时,您创建了一个无限循环条件,如果主机永远不会成功,它将一直运行直到重新启动。

    $sts = $false
    $count = 0
    do {
        try {
            $updateSession = new-object -com "Microsoft.Update.Session"
            $updates=$updateSession.CreateupdateSearcher().Search($criteria).Updates
            $sts = $true
        } catch {
            ## an exception was thrown before we got to $true
        }
    
        $Count++
        Start-Sleep -Seconds 1
    } Until ($sts -eq $true -or $Count -eq 100)
    

    【讨论】:

    • 我需要在其中包含“Finally”块吗?还是直到没有处理它所以没有必要?
    • 你根本不需要需要最后{}。当我使用 finally 时,它是 Dispose() 或 Close() 需要释放或关闭的对象,无论命令是成功还是失败(释放资源等)。您必须查看 $UpdateSession 和 $Updates 以查看它们是否实现 IDisposable 或 .Close()
    • 明白了。所以你要做的是重试100次直到它成功,然后它会自动移动到下一行,对吗? sleep 5 WUAUCLT /reportnow
    • 好吧,条件是 OR 所以如果 $UpdateSession 和 $Updates 都没有抛出异常,那么循环将第一次退出。但是,如果它们在大约 100 秒内出错 100 次,则循环也将终止,因此它不会永远运行。请根据自己的喜好调整迭代的秒数或次数。
    • 今天第一次使用它时(公司新人,这是由同事分享的),有时需要 2 或 3 分钟才能在该线路上运行一次。它会失败,我需要再次运行它。然后再次。他们最近刚刚更新到一个新的 WSUS 盒子,所以关键是把它吹出来,从新盒子开始“新鲜”,忘记旧盒子。我猜它只是有太多更新,有时会引发异常。认为有一个好方法可以循环它直到它成功,所以你不需要照看
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 2017-01-19
    • 2019-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-01
    相关资源
    最近更新 更多