0
votes

I have a PowerShell script running in an Azure Powershell task in VSTS, that starts several Azure virtual machines in a DevTest lab, but starts the domain controller first, waits for it to start, and then starts the others one after the other.

I'd like to start all the others in parallel and I tried to do this using Start-Job but that spawns a new Powershell process which doesn't have the security context of the Azure login, so it fails. I'm trying something like this:

[cmdletbinding()]
param (
    [ValidateSet("Start","Stop")][string]$Action,
    $labName = "DevTestLab",
    $labResourceGroup = "DevTestLabRG"
)

if ($Action -eq "Start") {
    Write-Verbose "Starting the domain controller first"
    Get-AzureRmResource | Where-Object {
        $_.Name -match "dc" -and 
        $_.ResourceType -eq "Microsoft.Compute/virtualMachines" -and
        $_.ResourceGroupName -match $labResourceGroup } | Start-AzureRmVM

    Write-Verbose "Starting other machines in the lab as background jobs"
    foreach ($AzureRMResource in Get-AzureRmResource | 
    Where-Object {
        $_.Name -notmatch "dc" -and 
        $_.ResourceType -eq "Microsoft.Compute/virtualMachines" -and
        $_.ResourceGroupName -match $labResourceGroup } )
        {
            Start-Job { 
                $myResource = $using:AzureRMResource                
                Start-AzureRMVM -Name $myResource.Name -ResourceGroupName $myResource.ResourceGroupName
               }            
        }

    # wait for all machines to start before exiting the session
    Get-Job | Wait-Job
    Get-Job | Remove-Job
}

I am using a Hosted Agent to run the script, so I can't have many agents running at once, and VSTS doesn't support parallel tasks as far as I am aware.

Any ideas on how to solve this?

2
Doesn't the -AsJob switch help? docs.microsoft.com/en-us/powershell/module/azurerm.compute/…user2226112
Yes but Azure Powershell task in VSTS doesn't support the latest version of the Powershell module that has that switch. Is there a way to upgrade the Hosted Agent?Mark Allison
why do you assume its safe to not even check the job output?4c74356b41
@4c74356b41 yeah I should probably do that too, will add it in thanks.Mark Allison
I've had a similar issue, there's no easy way to run Start-AzureVM asynchronously, it's a real pain. You can use the Azure API's to start VMs, it's pretty easy. Other options are to use PowerShell runspaces or workflows. The APIs might be easier, that's the way I went.Tim Tharratt

2 Answers

0
votes

Instead of creating a PowerShell script you can also use the Azure CLI. The Azure CLI has a vm start and vm stop command that takes a list of ids. You can also use the CLI to query for all the ids you want. The following is a simple Bash snippet that starts/stops all vms where the id contains Test.

# example usage
az vm start --ids $(
    az vm list --query "[].id"
        -o tsv | grep "Test"
)

az vm stop --ids $(
    az vm list --query "[].id"
        -o tsv | grep "Test"
)

Source: Azure CLI 2.0: Quickly Start / Stop ALL VMs

0
votes

You also can try it with az vm start command with --no-wait parameter through Azure CLI task.