For the automated start and stop of several VMs in Azure there are many possibilities. The most flexible is certainly the Automation Service. Any scripts can be created or obtained from galleries and executed on-demand or time-controlled. Especially for the VM Start-/Stop, the Automation Service offers a separate blade. But for my taste there are too many setup steps necessary to control a few VMs. In my opinion, a simpler solution is to use a simple script from the gallery.

I like the following variants in concrete terms:

After creating the Automation Services, the PowerShell scripts can be imported:

and are then listed unter the Runbooks blade:

They have the status New, which means that they have yet to be plublished. To publish the runbooks, open the runbook and switch to the edit mode (click Edit) and Publish.

You can now start the runbook directly to test the script. A panel will prompt for all necessary input parameters. If you check the status afterwards, you see the status es successfully Completed, but if you check All Logs, you will recognize some errors:

The VMs start/stop correctly, there is only an error in the output of the script. The line 108 is not correct and must be adjusted. This error does not exists in the referenced graphical runbooks.

# Start each of the VMs
foreach ($VM in $VMs) {
	$StartRtn = $VM | Start-AzureRmVM -ErrorAction Continue

	if (!$StartRtn.IsSuccessStatusCode) {
		# The VM failed to start, so send notice
        Write-Output ($VM.Name + " failed to start")
        Write-Error ($VM.Name + " failed to start. Error was:") -ErrorAction Continue
		Write-Error (ConvertTo-Json $StartRtn) -ErrorAction Continue
	}
	else {
		# The VM started, so send notice
		Write-Output ($VM.Name + " has been started")
	}
}

The problem is that the Start-Azure-RmVM response object is a PSComputeLongRunningOperation. For example, the correct line might therefore look like this:

	if ($StartRtn.Status -ne "Succeeded") {
		# The VM failed to start, so send notice

After this adjustment (1), save (2) and publishing (3):

starting and stopping will still work, of course, but now the output also matches the correct behavior.

To automate the behavior, you can now add schedules, to start or stop VMs via time or add webhooks, to start or stop VMs via POST requests. In both cases, you can specify the parameters needed for the selected script.