1. 概述
作為Windows Azure的用戶,使用Azure的過程中,最擔心的事情就是還沒到月底,預設的費用就快消耗完了(下面兩張賬單圖是我最討厭看到的)。但是仔細分析自己的費用列表,發現絕大部分費用消耗在虛擬機上,而Azure的虛擬機是按照開機時間來計費的,因此迫切需要找到一個方案來節省虛擬機的開銷。最簡單的方案就是在不需要的時候將虛擬機自動關閉,需要的時間讓其自動開機。在Google了一通以后,發現可以通過Azure的自動化(Automation)功能達到上述目的。下面介紹我在Azure上的實踐,通過設置Azure Automation,實現定時自動啟動和關閉虛擬機。

2. 必要條件
1. Windows Azure的訂閱賬戶
2. 在Azure中有可以正常啟動和關閉的虛擬機。可以參考這個鏈接創建一個虛擬機https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-windows-tutorial/
3. 創建自動化賬戶 Automation
按照Azure的描述,Automation自動化賬戶是自動化資源的容器,使用Automation自動化賬戶可以將自動化的資源與分配給其他自動化賬戶的資源隔離。如果你從未在Azure訂閱中創建過自動化賬戶,參考下面介紹創建一個:


4. 創建和管理證書
4.1 在IIS中創建證書
在Azure訂閱中運行自動化的任務(腳本),需要使用基於證書的認證。你可以使用第三方的商業證書,也可以在任意一台安裝了Internet Infomation Services (IIS)的服務器上創建一個證書。下面介紹如何在Windows Server 2012中使用IIS創建一個自簽名的證書:



4.2 從IIS中導出.pfx證書


4.3 從IIS中導出.cer證書






4.4 將.cer證書上傳到訂閱賬戶


5. 配置自動化腳本
5.1 配置資產,准備自動化腳本運行過程中需要的素材





(上傳之前導出的.pfx證書)



(自動化證書名稱需要使用證書在IIS中的友好名稱;訂閱ID可以在Azure的設置中查詢到)
5.2 配置自動化腳本
Runbook是執行自動化操作的腳本。可以通過左下角的“新建”按鈕從腳本庫中快速創建一個腳本,也可以完全自定義一個腳本:


(創建好腳本后,選擇腳本,進入編輯頁面)


(在“創作”中編輯自動化運行的腳本,腳本如下,其中高亮部分是需要根據實際情況修改的內容:)
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." } } } |

(保存並點擊“測試”按鈕運行腳本)

(如果腳本正確,你會在輸出窗口中看到成功的提示,同時看到虛擬機已經啟動了;點擊“發布”按鈕發布腳本)
創建關閉虛擬機腳本的過程與上面完全一致,腳本的內容參考下表:
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配置日程,實現定時運行腳本
腳本調試成功以后,就可以通過“計划日程”定期運行腳本,以實現定期啟動和關機的目標。



(注意這里的時間是20小時格式的,並且你不需要考慮時區,系統會自動按照你本地的時區做轉換)
可以按照上面的操作,設置關閉虛擬機的時間。
http://www.cnblogs.com/danzhang/ ALM MVP 張洪君