Shutting down your Azure Virtual Machines during non-working hours

I have a few Azure accounts which I use for labs, mainly virtual machines running various applications such as System Center. It works great but I want to limit the utilization of these virtual machines to minimize the associated costs. Since these are just labs I usually don’t need them late at night and possibly on weekends. I wrote some runbooks that use PowerShell and thought this might be useful for the community. The runbooks start the VMs at 7am starting with the DC, then SQL, and finally the Application VMs. The runbooks then stop the VMs at 11pm starting with the application VMs, then SQL, and finally the DC.

Steps Required

  • Generate your publish settings file and put it in c:\azurescripts (https://windows.azure.com/download/publishprofile.aspx)
  • Install the Windows PowerShell module on your Orchestrator Runbook Server (https://www.windowsazure.com/en-us/downloads/)
  • Copy the ManageAzureVMs.ps1 script to c:\azurescripts
  • Modify the script to include your VMs
    • Replace rslaten-<vmname> with your VMs
    • If they are domain controller’s, make sure and put them in the DC ‘if’ section
    • If they are database server’s, make sure and put them in the DB ‘if’ section
    • Anything else, add under the ‘else’ section
  • Modify the script to change the azureSubscription variable to point to your subscription
  • Modify the script to change the Import-AzurePublishSettingsFile call to point to the path of your publishsettings file
 Param(            
    [parameter(Mandatory=$true)]            
    $type,
    [parameter(Mandatory=$true)]
    $action
    )

#Logging Function
function LogIt
{
  param($text)
  Add-Content 'c:\azurescripts\output.log' -Value ("{0} -- {1}" -f (Get-Date), $text) -Force
}

#Log Params
LogIt -text ("Action Param:{0}" -f $action)
LogIt -text ("Type Param:{0}" -f $type)

#Azure Setup
$azureSubscription = "azure-rslaten"
Import-Module "C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\Azure\Azure.psd1"
Import-AzurePublishSettingsFile 'c:\azurescripts\mycredentials.publishsettings'
Set-AzureSubscription -SubscriptionName $azureSubscription

#Virtual Machines
$vmS = @()
if ($type.ToUpper() -eq 'DC') { $vmS += 'rslaten-DC01' }
elseif ($type.ToUpper() -eq 'DB') { $vmS += 'rslaten-SQL2012' }
else
{
  $vmS += 'rslaten-SCCM2012PRI'
  $vmS += 'rslaten-SCOM2012'
  $vmS += 'rslaten-EX2010'
  $vmS += 'rslaten-SCORCH2012'
  $vmS += 'rslaten-SM2012'
  $vmS += 'rslaten-SM2012DW'
  $vmS += 'rslaten-SP2010'
  $vmS += 'rslaten-JUMP'
}

#Log VMs
foreach ($vm in $vmS) { LogIt -text ("VM:{0}" -f $vm) }

#Action
if ($action.ToUpper() -eq 'START') { foreach ($vm in $vmS) { Get-AzureVM -ServiceName $vm -Name $vm | Start-AzureVM } }
else { foreach ($vm in $vmS) { Get-AzureVM -ServiceName $vm -Name $vm | Stop-AzureVM -Force} }

#End Runbook
LogIt -text "Actions Completed"
$objCurrentPSProcess = [System.Diagnostics.Process]::GetCurrentProcess()
Stop-Process -Id $objCurrentPSProcess.ID
  • Open the Orchestrator Runbook Designer
  • Create a new runbook
  • Drag the “Runbook Control\Initialize Data” activity into the new runbook
    • Under “Details” add two strings, Action and Type

image

    • Click “Finish”
  • Drag the “System\Run Program” activity into the new runbook

  • Link “Initialize Data” to “Run Program”

    • Under “Details” fill in the following properties
      • Program path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
      • Parameters: -File c:\azurescripts\ManageAzureVMs.ps1 –type {Type from “Initialize Data”}  -action {Action from “Initialize Data”}
      • *Right click in the white area where {} should be to choose the applicable variables in the Parameters property

image

    • Click “Finish”
  • Check in the runbook

image

  • Create a new runbook
  • Drag the “Scheduling\Check Schedule” activity into the new runbook
  • Rename it to 11:00PM
  • Set the Interval to 11:00 PM under “Details”

image

  • Click “Finish”
  • Drag the “Runbook Control\Invoke Runbook” activity into the new runbook
  • Rename it to “Stop App VMs”
  • Link “11:00PM” to “Stop App VMs”
  • Fill out the following properties under “Details”
    • Runbook: <existing runbook created previously>
    • Action: Stop
    • Type: App

image

  • Click “Finish”
  • Check in and start the runbook

image

  • Repeat the steps used in creating the runbook above. Create 5 more runbooks with the following settings:

    • Stop DB VMs

      • Time: 11:15PM
      • Action: Stop
      • Type: DB
    • Stop DC VMs

      • Time: 11:30PM
      • Action: Stop
      • Type: DC
    • Start DC VMs

      • Time: 7:00AM
      • Action: Start
      • Type: DC
    • Start DB VMs

      • Time: 7:15AM
      • Action: Start
      • Type: DB
    • Start App VMs

      • Time: 7:30AM
      • Action: Start
      • Type: App
  • View the c:\azurescripts\output.log for details on how well things are working

ManageAzureVMs.renametops1