Breaking a ForEach loop in Azure Workflow runbook

3k views Asked by At

How do I break a ForEach loop in a PowerShell Workflow in Azure Automation?

Additional Info:

I have a VM recovery runbook in Azure Automation that loops through attached Data Disks. The name of the blobcopy backups of each VHD is being input into the runbook using an array, and matched to the current data disk to be restored.

The backup's name is in the following format: MM-DD-YYYY--BlobName.vhd

example:

Data Disk Name: TestDisk-1.vhd

Backup Name: 12-22-2014--TestDisk-1.vhd

For each data disk this piece of code is being run:

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

The Error I get is:

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.

I think adding a check to see if $dataDiskBlobBackupName is still null will prevent the remainder of the code block from running, but it will still loop through the rest of the array. Is there an easier way to break the loop?

1

There are 1 answers

2
Matt On BEST ANSWER

TechNet dosent really give any suggestions for how to get around this. Merely states that:

Break and Continue statements are not valid in workflows. Instead, use an If statement to control loop execution.

Don't know much about work flows but how about using a Boolean flag inside a while loop. Loop through the array with an $index and use the If to set the $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++
}

Test with caution since I don't have an environment to use this logic on. Also someone with better understanding of your needs might help as well.