在Azure Workflow Runbook中打破ForEach循环

时间:2014-12-22 16:44:14

标签: powershell azure azure-automation powershell-workflow

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

其他信息:

我在Azure自动化中有一个VM恢复Runbook,它遍历附加的数据磁盘。每个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将阻止代码块的其余部分运行,但它仍将循环遍历数组的其余部分。是否有更简单的方法来打破循环?

1 个答案:

答案 0 :(得分:1)

TechNet dosent确实对如何解决这个问题提出了任何建议。仅仅说明:

  

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++
}

谨慎测试,因为我没有使用此逻辑的环境。也可以帮助更好地了解您的需求的人。