How to Reduce Bills (Save $) For Your Applications Deployed On Windows Azure Virtual Machines

Azure VMs continue to be billed if they're shutdown from within the virtual machine. In Azure management portal, if the VM status is "Stopped", you are still being billed. Only status "Stopped (Deallocated)" means that VM is no longer incurring charges. This is also indicated in .

 Also, it's good to keep at least one VM of each cloud service that's not in "Stopped (Deallocated)" state. This is to prevent changes to the IP which require manual and additional steps for reconfiguration. This is because the Cloud Service Virtual IP (VIP) stays with the cloud service it is assigned to, until all the virtual machines in that cloud service are all Stop (Deallocated) or deleted. At that point, it is released. This is indicated in . 

This blog post is an attempt to demo such a shutdown so as to reduce billing while also trying to avoid the VIP from getting de-allocated, so as minimize downtime and minimize manual intervention during VM startup.


So let's start and save $$!!


Assume my setup has a domain controller and cluster nodes. All are in the same cloud service (same DNS Name).

DC (Domain Controller) - ContosoDC

Cluster nodes - ContosoSQL1 (primary replica for Availability Group with listener), ContosoSQL2, ContosoWSFCNode.


 We'll shutdown all the servers from portal, except the domain controller. The order of shutdown does not matter though typically the primary is shutdown last, so as to prevent an unrequired Availability Group failover. In Azure portal, the status for the VMs should say Stopped Deallocated. An equivalent command in Powershell is Stop-AzureVM (without -StayProvisioned).



 To minimize resource/billing further, can remote desktop to the remaining node (Domain Controller) and Shutdown from within VM. It's important not to shut down this last VM from Azure portal, since otherwise the VIP will be deallocated as indicated earlier. This is an optional step, considering the DC may anyways consume minimal resources since there are no VMs connected to it (because they've been shut down through earlier steps). In Azure portal, the status should say Stopped. An equivalent command in Powershell is Stop-AzureVM -StayProvisioned .

 Assume off hours have ended and it's time to start the VMs. All VMs can be started from Azure portal.

For each machine that was shut down from portal (three VMs in this case), connect to each of these VMs using a local administrator account. It's important not to use a domain user account, since the shutdown process from Azure portal has changed the DNS mapping for each of these servers, so the VM may not be able to authenticate domain credentials. In my case, "vijayrod" is my local administrator account.

For each of these VMs, go to Network Connections. Change properties of Internet Protocol Version 4 from "Obtain DNS server address automatically" to "Use the following DNS server addresses" and specify the IP of the DNS server (in my case DC and DNS are same server). Click OK to apply changes. This had got changed earlier during VM shutdown from portal.



 On primary replica, open Failover Cluster Manager with "Run as different user" and enter domain credentials. Then start Availability Group resources from Failover Cluster Manager. Alternatively reboot primary replica and remote desktop to VM with domain user account.

 Verify connectivity to listener from on premise SSMS.

  Additional note:

 The below should be avoided where possible since it requires manual steps that can increase downtime. The benefits may also be marginal since the last VM (domain controller in this example) is already shut down through a remote desktop connection. If a business requirement requires all VMs to be shut down from Azure portal (Stopped Deallocated), then the same steps like above can be followed. In addition,


  • The DNS IP points to itself so should be
  • Also, the listener IP still points to the earlier cloud IP. During de-allocation (since all VMs have been shutdown through Azure portal), this IP gets automatically released from cloud service. During first VM startup, a new IP may be given the cloud service. This new IP needs to be updated for the listener IP in Failover Cluster Manager using Get-ClusterResource (the same command used to configure the earlier IP during setup of listener). After this configuration, bring AG resource online through Failover Cluster Manager. Go to SQL Management Studio and to the listener properties. Enter the port number. The port number would have got removed earlier during configuration of new IP. Now should be able to connect using on premise SSMS.

 Vijay Rodrigues.

 SME - SQL AlwaysOn Availability Groups.

Comments (2)

  1. Dylan Nicholson says:

    There has to be better way of doing this – having to log into each server and reassign the DNS settings is very painful – we're aiming to have a test SharePoint farm with 10+ servers. But we certainly don't want to be billed for having it up and running 24×7, given it will only be used a few hours each week to run some tests.

  2. Noah Stahl says:

    With Azure's static IP support now the shutdown shouldn't be a problem in that respect. You can schedule the shutdown/startup using an Azure Automation runbook like this:…/scheduled-virtual-machine-shutdown-startup-microsoft-azure

Skip to main content