virtualerror
virtualerror

Reputation: 31

Powershell script only starts first VM in list

I have an Azure powershell script to start a list of VMs. When it runs it sucessfully starts the first VM in the list then nothing. No errors are reported, it appears to never return from the start command

Code as follows:

$vmList = "VM1", "VM2", "VM3"

Write-Output "Starting VMs in '$($AzureResourceGroup)' resource group"; 

Foreach ($vm in $vmList) 
{ 
    Write-Output "Starting VM...$vm" 
    $result = Start-AzureRmVM -Name $vm -ResourceGroupName AzureResourceGroup
    Write-Output "Result of Start VM...$result"
}

When this run it outputs the "Starting VM....VM1", it starts the VM then nothing...

Upvotes: 3

Views: 234

Answers (1)

mklement0
mklement0

Reputation: 439692

It sounds like your Start-AzureVM call is simply waiting for the VM to finish starting up.

That is, Start-AzureVm is by default a blocking, synchronous operation - despite its name[1]

To make it asynchronous, use the -AsJob switch, which uses a background job to start the VM; the call ends once that job has been created and returns a job object that you can use to track start-up progress later, via the usual *-Job cmdlets, such as Receive-Job.


[1] Regarding the name Start-AzureVM:

It is a misnomer in that PowerShell's nomenclature calls for the Start verb to exhibit asynchronous behavior:

From https://learn.microsoft.com/en-us/powershell/developer/cmdlet/approved-verbs-for-windows-powershell-commands (emphasis added):

Invoke vs. Start The Invoke verb is used to perform an operation that is generally a synchronous operation, such as running a command. The Start verb is used to begin an operation that is generally an asynchronous operation, such as starting a process.

Note that the core Start-Sleep cmdlet is similarly misnamed.

With synchronous-by-default behavior, there is no good naming solution, because the name Invoke-AzureVm would be confusing.

The better approach - which would obviously be a breaking change - would have been to make the cmdlet asynchronous by default and offer a -Wait switch for to opt-into synchronous operation.

Upvotes: 1

Related Questions