【问题标题】:Powershell loop iteration countPowershell 循环迭代次数
【发布时间】:2019-12-12 16:22:12
【问题描述】:

脚本的目的是捕捉到 Elasticsearch 的错误登录,并提供机会重新尝试输入密码。这个想法是通过在$result = Invoke-RestMethod $uri -Credential $credential 步骤之后添加i++ 来计算循环迭代,但事实证明-ErrorAction SilentlyContinue 进程在它位于try{} 部分的情况下被忽略,所以我将循环计数移动到finally {$i++} 部分,但缺点是最后一个Attempt 5 没有通过条件while ($i -lt 6) 因为它是5+1finally {$i++} 部分。

$elasticsearch_pass = Read-Host "Enter ELASTICSEARCH password"
$uri = "https://${elasticsearch_ip}:9200"
$user = "static_user"
$i = 1
while ($i -lt 6) {
        try {       
        Write-Host -ForegroundColor Cyan `n ("Trying to connect to elasticsearch. Attempt $i")
        $secpasswd = ConvertTo-SecureString $elasticsearch_pass -AsPlainText -Force
        $credential = New-Object System.Management.Automation.PSCredential($user, $secpasswd)     
        $result = Invoke-RestMethod $uri -Credential $credential
            if ($result.tagline -eq 'You Know, for Search') {
                Write-Host -ForegroundColor Green `n ("Connection to elasticsearch {0} established..." -f $elasticsearch_ip)
                break
            }
        } 
        catch {
          Write-Host -ForegroundColor Red $_
          if ("$_" -eq "Unauthorized") {
            $elasticsearch_pass = Read-Host `n "Wrong elasticsearch password! Pls enter correct one"
          }
        }
        finally {$i++} 
    }

设置静态循环迭代计数和执行最后一次尝试的最佳方法是什么?

【问题讨论】:

  • For 循环对我来说似乎是一个合理的替代方案。

标签: powershell loops iteration


【解决方案1】:

为什么使用 While,如果需要一个交互变量,通常的解决方案是传统的:

$uri = "https://${elasticsearch_ip}:9200"
$user = "static_user"
$i = 1
$maxTry = 5

For( $i = 1; $i -le $maxTry; ++$i )
{
    try {       
        Write-Host -ForegroundColor Cyan `n ("Trying to connect to elasticsearch. Attempt $i of $maxtry ")
        $secpasswd = ConvertTo-SecureString $elasticsearch_pass -AsPlainText -Force
        $credential = New-Object System.Management.Automation.PSCredential($user, $secpasswd)     
        $result = Invoke-RestMethod $uri -Credential $credential
            if ($result.tagline -eq 'You Know, for Search') {
                Write-Host -ForegroundColor Green `n ("Connection to elasticsearch {0} established..." -f $elasticsearch_ip)
                break
            }
    }
    Catch {
        Write-Host -ForegroundColor Red $_.Exception.Message
        if ($_.Exception.Message -match "Unauthorized") {
        }
    }
}

在这两种情况下,我认为您不需要在 finally 块中执行 ++$i,您可以在 catch 中执行并继续。然而,for 循环允许您在每次迭代的正确位置执行此操作,而不会造成混淆。

还添加了 $maxTry 可以提供更好的回声...

由于这是交互式的,我更改了一些 catch 块以更清晰地回显。

还将读取主机移动到循环中。并稍微改变了语言。虽然有几种方法可以做到这一点......

【讨论】:

  • 问题是$elasticsearch_pass在Catch部分给出,执行在try部分,女巫是下一次迭代,所以无论使用While还是For,最后一次尝试不会工作。
  • 我不明白,但再次重读您的问题...... For 循环将使迭代正确,正好 5 次尝试。如果您希望 Invoke-WebRequest 触发捕获,您可能需要使用 -ErrorAction Stop 。这会将非终止错误转换为终止以触发捕获。否则,您可以像以前一样将结果分配给变量,然后手动检查它。让我知道这是否有帮助。
  • -ErrorAction 进程如果位于try 部分,则将被忽略,问题的开头也对此进行了描述。出于某种原因,您在示例中错过了$elasticsearch_pass = Read-Host `n "Wrong elasticsearch password! Pls enter correct one" 过程。
  • catch 部分我添加$i -le 4 检查哪个解决了我的问题,("$_" -match "Unauthorized" -and $i -le 4) {
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-01
  • 2020-05-26
  • 2013-12-14
  • 2013-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多