1

Is it possible to write and save some kind of script that launches azure powershell, then authenticate azure subscription then start/shutdown multiple VMs in one step?

I have 5 VMs that I use regularly at specific unscheduled time, so I don't want do the steps of logging into azure portal, starting VMs one by one then do the same to shut them down, at every time I need to use them! I need to automate this process.

  • Why don't you just leave them running instead of shutting them down? – joeqwerty Jan 8 '16 at 17:28
  • because leaving them running means pay more money :) – Sisyphus Jan 8 '16 at 18:45
  • My bad, forgot about per hour pricing. – joeqwerty Jan 8 '16 at 19:17
  • @joeqwerty Not that it impacts the question, but it's per-minute pricing on VM's.... – David Makogon Jan 9 '16 at 2:01
1

Definitively, you should use Azure Automation to run on schedule a PowerShell Script to shutdown or start your VM in Azure. It is already well documented on Microsoft Web site.

Here are 3 links that explains step by step how to do this

Stop Azure Virtual Machine using Azure Automation Runbook https://gallery.technet.microsoft.com/scriptcenter/Stop-Azure-Virtual-Machine-0b1fea97

Shutting down a Azure VM with Azure Automation http://blogs.technet.com/b/georgewallace/archive/2014/11/05/shutting-down-a-azure-vm-with-azure-automation.aspx

Using Azure Automation to run VMs during office hours only https://blogs.endjin.com/2015/01/using-azure-automation-to-run-vms-during-office-hours-only/

Regards

Stanislas

0

There are a number of solutions to this

You could have a Powershell script in Azure automation, that will connect to your subscription(s) and shut down or start up the servers dependent upon a parameter.

You could then have a webhook attached to those servers, that you can connect to a HTTP Post button somewhere to stop or start them.

Or you could do a similar thing with a c# app that you can call in a similar fashion. The benefit of this approach is that you can have authentication on the HTTP stack before you accept the webhook

Personally I have a few servers managed from an API app, that is connected to an automation app on my phone. When I leave the office it shuts down my dev server (and starts it up when I arrive!)

0

You can use any server in a datacenter to run a scheduled PowerShell script. Mark Hick has a good post on doing all of this https://www.petri.com/manage-scheduled-tasks-windows-8-windows-server-2012-powershell-part-2. I would add to this that you'll want to pass in login parameters, and if you want to shut everything down on one server then something like get-VM | stop-VM. If you want to quiesce services first on the VM then you'll need to get into remote powershell in a foreach(VM inVMList) {} loop for each VM but this is not that hard if the VMs are in the same domain as the server. if not you'll need to use credssp to create trust between the server and the VM.

0

There is a Service Management API call that will do it for you using REST (assuming you are using classic VMs). For some reason, this wasn't implemented in the PowerShell cmdlets (perhaps you can contribute :) )

Have a look at Shutdown Roles This API can Shutdown (and optionally deallocate) one or more VMs at a time.

<ShutdownRolesOperation xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <OperationType>ShutdownRolesOperation</OperationType>
      <Roles>
        <Name>name-of-virtual-machine</Name>
      </Roles>
      <PostShutdownAction>shutdown-action</PostShutdownAction>
</ShutdownRolesOperation>

Similarly, Start Roles can start multiple VMs at a time.

0

You can also use the Azure Virtual Machine scheduler from SmiKar Software. AVMS as it is known will connect to your Azure Subscriptions and allow you to select the VMs and a power on or down schedule to suit.

Works with V1 and V2 Azure Virtual Machines

http://www.smikar.com/automate-scheduled-power-azure-vms/

0

For those using the Resource Manager API here's a script I wrote to restart multiple VMs in parallel. Restart-AzureRmVM doesn't return until a VM finishes restarting, so this script starts multiple such commands as background jobs.

function Restart-VMs
{
    param
    (
        [Parameter(Mandatory=$true, HelpMessage="LIKE pattern for VM name (use * for all)")] [string] $vmNamePattern,
        [Parameter(Mandatory=$true, HelpMessage="LIKE pattern for Resource Group name (use * for all)")] [string] $resourceGroupNamePattern
    )

    $vmsToRestart = Get-AzureRmVm | Where-Object { $_.Name -like $vmNamePattern -and $_.ResourceGroupName -like $resourceGroupNamePattern }
    Write-Host "Restarting $($vmsToRestart.Length) VMs"

    # Need to save the profile so that the login from Login-AzureRmAccount works in the background jobs
    $profilePath = [System.IO.Path]::GetTempFileName()
    Remove-Item $profilePath
    Write-Host "Temporarily saving Azure profile to $profilePath"
    Save-AzureRmProfile -Path $profilePath
    $ErrorActionPreference = "Continue" # Continue restarting other machines if some fail

    try
    {
        $restartScriptBlock =
        {
            param ($vmToRestart, $profilePath)

            Select-AzureRmProfile -Path $profilePath | Out-Null
            Write-Host "Restarting VM: $($vmToRestart.Name)"

            try
            {
                Restart-AzureRmVM -Name $vmToRestart.Name -ResourceGroupName $vmToRestart.ResourceGroupName
            }
            catch
            {
                Write-Error "FAILED to restart VM: $($vmToRestart.Name)"
                Write-Error -ErrorRecord $_
            }

            Write-Host "DONE restarting VM: $($vmToRestart.Name)"
        }

        $jobs = @()
        foreach ($vmToRestart in $vmsToRestart)
        {
            $jobs += Start-Job -ScriptBlock $restartScriptBlock -ArgumentList $vmToRestart,$profilePath
        }

        Write-Host "Restart jobs started, waiting..."
        Wait-Job -Job $jobs | Out-Null
        Receive-Job -Job $jobs
        Write-Host "DONE restarting $($vmsToRestart.Length) VMs"
    }
    finally
    {
        Write-Host "Deleting saved Azure profile $profilePath"
        Remove-Item $profilePath -Force
        $ErrorActionPreference = "Stop"
    }
}

Before calling the above function you'll need to log in by calling

Login-AzureRmAccount

Note that it temporarily saves your login token to disk and loads it in each background job, otherwise you'll get an error about not being logged in in the background job (see https://github.com/Azure/azure-powershell/issues/1288).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.