【问题标题】:Breaking a ForEach loop in Azure Workflow runbook在 Azure Workflow Runbook 中中断 ForEach 循环
【发布时间】:2014-12-23 02:27:17
【问题描述】:

如何在 Azure 自动化的 PowerShell 工作流中中断 ForEach 循环?

其他信息:

我在 Azure 自动化中有一个 VM 恢复运行手册,它循环连接附加的数据磁盘。每个 VHD 的 blobcopy 备份的名称正在使用数组输入到 Runbook,并与要还原的当前数据磁盘匹配。

备份的名称采用以下格式:MM-DD-YYYY--BlobName.vhd

示例:

数据盘名称:TestDisk-1.vhd

备份名称:12-22-2014--TestDisk-1.vhd

对于每个数据盘,这段代码正在运行:

$dataDisksRestored = 0
ForEach ( $vmDataDisk in $vmDataDisks ) {
  $vmDataDiskName = $vmDataDisk.DiskName
  $vmDataDiskuris = $vmDataDisk.MediaLink
  $vmDataBlobName = $vmDataDiskuris.Segments[-1]
  $vmDataOrigContainerName = $vmDataDiskuris.Segments[-2].Split('/')[0]
  $attached = $false
  While ($attached -eq $False) {
    if ((Get-AzureDisk -DiskName $vmDataDiskName).AttachedTo) {
      Write-Output "Sleeping for 5"
      Start-Sleep 5
    } else {
      $attached = $true
    }
  }
  $dataDiskBlobBackupName = $null
  ForEach ($backupName in $vmDataDisksBackupNames) {
    $b = $backupName.Split('-')[-1]
    Write-Output $b
    Write-Output $vmDataBlobName
    if ($b.CompareTo($vmDataBlobName) -eq 0) {
      $dataDiskBlobBackupName = $backupName
      break                               # <- *** Break here if the names match ***
    }
  }
  #Remove-AzureDisk -DiskName $vmDataDiskName –DeleteVHD
  #Start-AzureStorageBlobCopy -SrcContainer $backupContainerName -SrcBlob $dataDiskBlobBackupName -DestContainer $vmDataOrigContainerName -DestBlob $vmDataBlobName –Force
  #Get-AzureStorageBlobCopyState -Container $vmDataOrigContainerName -Blob $vmDataBlobName –WaitForComplete
  #Add-AzureDisk -DiskName $vmDataDiskName -MediaLocation $vmDataDiskuris.AbsoluteUri
  $dataDisksRestored++
}

我得到的错误是:

Runbook definition is invalid. Break and Continue statements are not supported in a Windows
PowerShell Workflow. Instead, use an 'if' statement to control loop execution.

我认为添加检查以查看 $dataDiskBlobBackupName 是否仍为 null 将阻止代码块的其余部分运行,但它仍会循环遍历数组的其余部分。有没有更简单的方法来打破循环?

【问题讨论】:

    标签: powershell azure azure-automation powershell-workflow


    【解决方案1】:

    TechNetdosent 确实为如何解决这个问题提供了任何建议。只是声明:

    Break 和 Continue 语句在工作流中无效。相反,使用 If 语句来控制循环执行。

    不太了解工作流程,但如何在 while 循环中使用布尔标志。使用$index 循环遍历数组并使用If 设置$flag

    $flag = $false
    $index = 0
    $max = $vmDataDisksBackupNames.Count - 1
    # Run through the loop until $flag is true or we hit the end of the array. 
    While($flag -eq $false -or ($index -le $max)){
        $b = $vmDataDisksBackupNames[$index].Split('-')[-1]
        Write-Output $b
        Write-Output $vmDataBlobName
        if ($b.CompareTo($vmDataBlobName) -eq 0) {
            $dataDiskBlobBackupName = $vmDataDisksBackupNames[$index]
            # Found a match. Flip the flag to exit the loop
            $flag = $true 
        }
        $index++
    }
    

    谨慎测试,因为我没有使用此逻辑的环境。另外,对您的需求有更好理解的人也可能会有所帮助。

    【讨论】:

    • 为我工作,感谢您的帮助,马特。我调整了 while 循环,因为它不能与 !$flag 一起使用,但可以与 ($flag -eq $false -and ($index -le $max)) 一起使用
    • 我在 Azure 自动化服务上工作,是的,我建议您这样做。你也可以使用你最初拥有的 for each 循环来做类似的事情,只需在循环内的所有其他逻辑周围放置一个 if 语句“if($flag -eq $false)”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    • 1970-01-01
    • 2017-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多