Change script to workflow

Hi

I’m quite new to Powershell, learning slowly, but I have something that I need to do quite urgently that is beyond me.

I have a script that is used in an Azure runbook to automatically shutdown/startup VMs. I need it to perform these actions in parallel though, so need it to be a workflow.

However it contains two continues & a break which prevent that from working. I’m hoping someone can help me with changing it so that it can be used as a workflow please.

Script is here:
https://gist.github.com/carlewarl/e6fdd0f36d5da6f0911c85950976db46

Continues are on lines 396 & 403. Break is on 418.

Thanks very much.

Maybe it’s unreasonable to ask for help with such a long script. Perhaps if I just copy the section that I need assistance with?

 

How would I change this so that it can be used as a workflow please?

 

Thanks.

  # For each VM, determine
    #  - Is it directly tagged for shutdown or member of a tagged resource group
    #  - Is the current time within the tagged schedule 
    # Then assert its correct power state based on the assigned schedule (if present)
    Write-Output "Processing [$($resourceManagerVMList.Count)] virtual machines found in subscription"
    foreach($vm in $resourceManagerVMList)
    {
        $schedule = $null

        # Check for direct tag or group-inherited tag
        if($vm.ResourceType -eq "Microsoft.Compute/virtualMachines" -and $vm.Tags -and $vm.Tags.Name -contains "AutoShutdownSchedule")
        {
            # VM has direct tag (possible for resource manager deployment model VMs). Prefer this tag schedule.
            $schedule = ($vm.Tags | where Name -eq "AutoShutdownSchedule")["Value"]
            Write-Output "[$($vm.Name)]: Found direct VM schedule tag with value: $schedule"
        }
        elseif($taggedResourceGroupNames -contains $vm.ResourceGroupName)
        {
            # VM belongs to a tagged resource group. Use the group tag
            $parentGroup = $taggedResourceGroups | where ResourceGroupName -eq $vm.ResourceGroupName
            $schedule = ($parentGroup.Tags | where Name -eq "AutoShutdownSchedule")["Value"]
            Write-Output "[$($vm.Name)]: Found parent resource group schedule tag with value: $schedule"
        }
        else
        {
            # No direct or inherited tag. Skip this VM.
            Write-Output "[$($vm.Name)]: Not tagged for shutdown directly or via membership in a tagged resource group. Skipping this VM."
            continue
        }

        # Check that tag value was succesfully obtained
        if($schedule -eq $null)
        {
            Write-Output "[$($vm.Name)]: Failed to get tagged schedule for virtual machine. Skipping this VM."
            continue
        }

        # Parse the ranges in the Tag value. Expects a string of comma-separated time ranges, or a single time range
        $timeRangeList = @($schedule -split "," | foreach {$_.Trim()})
        
        # Check each range against the current time to see if any schedule is matched
        $scheduleMatched = $false
        $matchedSchedule = $null
        foreach($entry in $timeRangeList)
        {
            if((CheckScheduleEntry -TimeRange $entry) -eq $true)
            {
                $scheduleMatched = $true
                $matchedSchedule = $entry
                break
            }
        }

I am sorry but the paste of your script in the second post is not legible but as generally with a workflow you wrap it around your code similar to a function.

Workflow Do-Something {
CODE GOES HERE
} #End of workflow

You can then call the workflow with something like:

Do-Something -PSPersist $true

 

This is of course a very brief overview, you could extend the workflow by running certain parts in parallel or creating checkpoints

 

Woops sorry about that, I’ve pasted again, hopefully it appears okay now. The problem is that continue & break can’t be used in a workflow. I’m not sure how to change the script to remove the continue & break…

# For each VM, determine
# - Is it directly tagged for shutdown or member of a tagged resource group
# - Is the current time within the tagged schedule 
# Then assert its correct power state based on the assigned schedule (if present)
Write-Output "Processing [$($resourceManagerVMList.Count)] virtual machines found in subscription"
foreach($vm in $resourceManagerVMList)
{
$schedule = $null

# Check for direct tag or group-inherited tag
if($vm.ResourceType -eq "Microsoft.Compute/virtualMachines" -and $vm.Tags -and $vm.Tags.Name -contains "AutoShutdownSchedule")
{
# VM has direct tag (possible for resource manager deployment model VMs). Prefer this tag schedule.
$schedule = ($vm.Tags | where Name -eq "AutoShutdownSchedule")["Value"]
Write-Output "[$($vm.Name)]: Found direct VM schedule tag with value: $schedule"
}
elseif($taggedResourceGroupNames -contains $vm.ResourceGroupName)
{
# VM belongs to a tagged resource group. Use the group tag
$parentGroup = $taggedResourceGroups | where ResourceGroupName -eq $vm.ResourceGroupName
$schedule = ($parentGroup.Tags | where Name -eq "AutoShutdownSchedule")["Value"]
Write-Output "[$($vm.Name)]: Found parent resource group schedule tag with value: $schedule"
}
else
{
# No direct or inherited tag. Skip this VM.
Write-Output "[$($vm.Name)]: Not tagged for shutdown directly or via membership in a tagged resource group. Skipping this VM."
continue
}

# Check that tag value was succesfully obtained
if($schedule -eq $null)
{
Write-Output "[$($vm.Name)]: Failed to get tagged schedule for virtual machine. Skipping this VM."
continue
}

# Parse the ranges in the Tag value. Expects a string of comma-separated time ranges, or a single time range
$timeRangeList = @($schedule -split "," | foreach {$_.Trim()})

# Check each range against the current time to see if any schedule is matched
$scheduleMatched = $false
$matchedSchedule = $null
foreach($entry in $timeRangeList)
{
if((CheckScheduleEntry -TimeRange $entry) -eq $true)
{
$scheduleMatched = $true
$matchedSchedule = $entry
break
}
}