使用Azure Automation(自动化)定时关闭和启动虚拟机

1. 概述

作为Windows Azure的用户,使用Azure的过程中,最担心的事情就是还没到月底,预设的费用就快消耗完了(下面两张账单图是我最讨厌看到的)。但是仔细分析自己的费用列表,发现绝大部分费用消耗在虚拟机上,而Azure的虚拟机是按照开机时间来计费的,因此迫切需要找到一个方案来节省虚拟机的开销。最简单的方案就是在不需要的时候将虚拟机自动关闭,需要的时间让其自动开机。在Google了一通以后,发现可以通过Azure的自动化(Automation)功能达到上述目的。下面介绍我在Azure上的实践,通过设置Azure Automation,实现定时自动启动和关闭虚拟机。

使用Azure Automation(自动化)定时关闭和启动虚拟机_第1张图片  使用Azure Automation(自动化)定时关闭和启动虚拟机_第2张图片

2. 必要条件

1. Windows Azure的订阅账户

2. 在Azure中有可以正常启动和关闭的虚拟机。可以参考这个链接创建一个虚拟机https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-windows-tutorial/ 

3. 创建自动化账户 Automation

按照Azure的描述,Automation自动化账户是自动化资源的容器,使用Automation自动化账户可以将自动化的资源与分配给其他自动化账户的资源隔离。如果你从未在Azure订阅中创建过自动化账户,参考下面介绍创建一个:

使用Azure Automation(自动化)定时关闭和启动虚拟机_第3张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第4张图片

4. 创建和管理证书

4.1 在IIS中创建证书

在Azure订阅中运行自动化的任务(脚本),需要使用基于证书的认证。你可以使用第三方的商业证书,也可以在任意一台安装了Internet Infomation Services (IIS)的服务器上创建一个证书。下面介绍如何在Windows Server 2012中使用IIS创建一个自签名的证书:

使用Azure Automation(自动化)定时关闭和启动虚拟机_第5张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第6张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第7张图片

4.2 从IIS中导出.pfx证书

使用Azure Automation(自动化)定时关闭和启动虚拟机_第8张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第9张图片

4.3 从IIS中导出.cer证书

使用Azure Automation(自动化)定时关闭和启动虚拟机_第10张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第11张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第12张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第13张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第14张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第15张图片

4.4 将.cer证书上传到订阅账户

使用Azure Automation(自动化)定时关闭和启动虚拟机_第16张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第17张图片

5. 配置自动化脚本

  5.1 配置资产,准备自动化脚本运行过程中需要的素材

使用Azure Automation(自动化)定时关闭和启动虚拟机_第18张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第19张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第20张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第21张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第22张图片

(上传之前导出的.pfx证书)

使用Azure Automation(自动化)定时关闭和启动虚拟机_第23张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第24张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第25张图片

(自动化证书名称需要使用证书在IIS中的友好名称;订阅ID可以在Azure的设置中查询到)

5.2 配置自动化脚本

Runbook是执行自动化操作的脚本。可以通过左下角的“新建”按钮从脚本库中快速创建一个脚本,也可以完全自定义一个脚本:

使用Azure Automation(自动化)定时关闭和启动虚拟机_第26张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第27张图片

(创建好脚本后,选择脚本,进入编辑页面)

使用Azure Automation(自动化)定时关闭和启动虚拟机_第28张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第29张图片

(在“创作”中编辑自动化运行的脚本,脚本如下,其中高亮部分是需要根据实际情况修改的内容:)

workflow Start-VM-danzhang-win7
{
    param()
    #connection      
       $MyConnection = "AzureConnection-1"
       $MyCert = "AutomationCredential-1"
 
    # Get the Azure Automation Connection
    $Con = Get-AutomationConnection -Name $MyConnection
    if ($Con -eq $null)
    {
        Write-Output "Connection entered: $MyConnection does not exist in the automation service. Please create one `n"  
    }
    else
    {
        $SubscriptionID = $Con.SubscriptionID
        $ManagementCertificate = $Con.AutomationCertificateName
      
    }  

    # Get Certificate & print out its properties
    $Cert = Get-AutomationCertificate -Name $MyCert
    if ($Cert -eq $null)
    {
        Write-Output "Certificate entered: $MyCert does not exist in the automation service. Please create one `n"  
    }
    else
    {
        $Thumbprint = $Cert.Thumbprint
    }

        #Set and Select the Azure Subscription
         Set-AzureSubscription `
            -SubscriptionName "My Azure Subscription" `
            -Certificate $Cert `
            -SubscriptionId $SubscriptionID `

        #Select Azure Subscription
         Select-AzureSubscription `
            -SubscriptionName "My Azure Subscription"


    Write-Output "-------------------------------------------------------------------------"

       Write-Output "Starting the VM.."

       # Please type the name of your Domain Controllers

   
    inlinescript{
  
# function to get local time (example Convert UTC tome to Indian Time Zone)
Function Get-LocalTime($UTCTime)
{
$strCurrentTimeZone = 'India Standard Time'
$TZ = [System.TimeZoneInfo]::FindSystemTimeZoneById($strCurrentTimeZone)
$LocalTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($UTCTime, $TZ)
Return $LocalTime
}

#convert date time to UTC time Zone
$date = (Get-Date).ToUniversalTime()
# call function to get local time
$locatTime= Get-LocalTime($date)
#get day of week eg. Friday
$locatTimeDayOfWeek= ($locatTime).DayOfWeek
#get current day of the date eg. if current date is 21 November 2014 09:55:18 then day will be 21
$localTimeDay= ($locatTime).Day

#$locatTimeDayOfWeek
#$localTimeDay


#do not start VM on saturday and Sunday

if($locatTimeDayOfWeek -ne "Saturday" -and $locatTimeDayOfWeek -ne "Sunday")
{
#$sample = Get-AzureWinRMUri -ServiceName $Using:CloudServiceName -Name $Using:VMName
$StartOutPut = Start-AzureVM -ServiceName "danzhang-win7" -Name "danzhang-win7"
Write-Output $"Virtual Machine danzhang-win7 started."
Write-Output $StartOutPut

}
elseif($localTimeDay -le 7 -and $locatTimeDayOfWeek -eq "Saturday")
{
$StartOutPut = Start-AzureVM -ServiceName "danzhang-win7" -Name "danzhang-win7"

Write-Output $"Virtual Machine danzhang-win7 started."
Write-Output $StartOutPut
}
else{
Write-Output "Virtual Machine is not started, because today is not a working day."
}
}
      
}

使用Azure Automation(自动化)定时关闭和启动虚拟机_第30张图片

(保存并点击“测试”按钮运行脚本)

使用Azure Automation(自动化)定时关闭和启动虚拟机_第31张图片

(如果脚本正确,你会在输出窗口中看到成功的提示,同时看到虚拟机已经启动了;点击“发布”按钮发布脚本)

创建关闭虚拟机脚本的过程与上面完全一致,脚本的内容参考下表:

workflow Stop-VM-danzhang-win7
{
    param()
    #connection
       $MyConnection = "AzureConnection-1"
       $MyCert = "AutomationCredential-1"
      
    # Get the Azure Automation Connection
    $Con = Get-AutomationConnection -Name $MyConnection
    if ($Con -eq $null)
    {
        Write-Output "Connection entered: $MyConnection does not exist in the automation service. Please create one `n"  
    }
    else
    {
        $SubscriptionID = $Con.SubscriptionID
        $ManagementCertificate = $Con.AutomationCertificateName
      
    }  

    # Get Certificate & print out its properties
    $Cert = Get-AutomationCertificate -Name $MyCert
    if ($Cert -eq $null)
    {
        Write-Output "Certificate entered: $MyCert does not exist in the automation service. Please create one `n"  
    }
    else
    {
        $Thumbprint = $Cert.Thumbprint
    }

        #Set and Select the Azure Subscription
         Set-AzureSubscription `
            -SubscriptionName "My Azure Subscription" `
            -Certificate $Cert `
            -SubscriptionId $SubscriptionID `

        #Select Azure Subscription
         Select-AzureSubscription `
            -SubscriptionName "My Azure Subscription"


    Write-Output "-------------------------------------------------------------------------"

       Write-Output "Stoping the VM.."

       # Please type the name of your Domain Controllers

   
    inlinescript{
  
# function to get local time (example Convert UTC tome to Indian Time Zone)
Function Get-LocalTime($UTCTime)
{
$strCurrentTimeZone = 'India Standard Time'
$TZ = [System.TimeZoneInfo]::FindSystemTimeZoneById($strCurrentTimeZone)
$LocalTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($UTCTime, $TZ)
Return $LocalTime
}

#convert date time to UTC time Zone
$date = (Get-Date).ToUniversalTime()
# call function to get local time
$locatTime= Get-LocalTime($date)
#get day of week eg. Friday
$locatTimeDayOfWeek= ($locatTime).DayOfWeek
#get current day of the date eg. if current date is 21 November 2014 09:55:18 then day will be 21
$localTimeDay= ($locatTime).Day

#$locatTimeDayOfWeek
#$localTimeDay


#do not start VM on saturday and Sunday

if($locatTimeDayOfWeek -ne "Saturday" -and $locatTimeDayOfWeek -ne "Sunday")
{

 

#$StopOutPut = Start-AzureVM -ServiceName "mkadamvm" -Name $Using:test

#$sample = Get-AzureWinRMUri -ServiceName $Using:CloudServiceName -Name $Using:VMName

$StopOutPut = Stop-AzureVM -ServiceName "danzhang-win7" -Name "danzhang-win7" -Force
Write-Output $"Virtual Machine danzhang-win7 Stopped."
Write-Output $StopOutPut

}
elseif($localTimeDay -le 7 -and $locatTimeDayOfWeek -eq "Saturday")
{
$StopOutPut = Stop-AzureVM -ServiceName "danzhang-win7" -Name "danzhang-win7" -Force

Write-Output $"Virtual Machine danzhang-win7 Stopped."
Write-Output $StartOutPut
}
else{
Write-Output "Virtual Machine is not started, because today is not a working day."
}
}
}

  5.3配置日程,实现定时运行脚本

脚本调试成功以后,就可以通过“计划日程”定期运行脚本,以实现定期启动和关机的目标。

使用Azure Automation(自动化)定时关闭和启动虚拟机_第32张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第33张图片

使用Azure Automation(自动化)定时关闭和启动虚拟机_第34张图片

(注意这里的时间是20小时格式的,并且你不需要考虑时区,系统会自动按照你本地的时区做转换)

可以按照上面的操作,设置关闭虚拟机的时间。

6. 总结

你可能感兴趣的:(使用Azure Automation(自动化)定时关闭和启动虚拟机)