解決Azure automation 報錯問題

   今天來分析一波Azure automation的報錯問題,Azure automation是個不錯的東東,通過 Azure automation可以自動完成頻繁的、耗時的、易出錯的雲管理任務。 有了這 樣的自動化,我們可以專注於能夠讓業務增值的工作,automation可以實現很多功能,比如定時開關機,調整size以節省成本,或者是自動備份、刪除文件到blob中,乃至結合一些業務邏輯,定製專門的automation runbook來完成業務需求等


    

   在使用automation的過程中,有遇到過一些大大小小的問題,拿出來和各位分享一下

首先是一個小問題,之前有個需求是要根據業務場景自動創建blob存儲,然後將數據傳輸到這個blob中,完成任務後,再由別的邏輯觸發自動刪除,這個需求實際上很簡單,用automation也可以很方便的完成任務

 

   但是在實際使用中遇到了一點小問題

這是一個之前做測試的runbook,只是簡單測試創建storage account然後刪除,但是發現居然報錯了

image001.png



    點開報錯信息,發現報錯信息如下:

    其實代碼很簡單,只是一個remove-azurermstorage account,然後加了一個-force的開關,但是爲啥會報錯呢,報錯信息提示的是找不到匹配的參數,一般來說這種問題都是處在這個命令的版本上


    image003.png

    

  因此特地輸出了一下remove-azurermstorageaccount這個命令的版本來看下,頓時我就被驚到了,居然是他麼的1.0.3..難怪不支持-force

image005.png




    而我電腦上這個命令的版本是多少呢。。是5.2.0

image006.png



    問題很明顯了,就是出在命令的版本上,那麼就來嘗試強制導入5.2.0這個版本

image008.png


    可是嘗試之後發現居然告訴我沒有可用的版本。。難道這個東西智障到連版本都沒辦法選的嗎

image010.png



    

  當然不是了,簡單看了看automation account的設置,才發現自己犯了一個很傻的錯誤,這個automation account是很久前創建的,在module這裏顯示的命令版本都是非常非常低的了。。



    實際上我們只需要更新一波即可,點擊update azure modules

image014.png


 更新完成

1.png




    如果沒有module的,可以嘗試在gallery裏添加

image031.jpg



到此爲止,問題就算是解決了,那麼如何防止這類問題再發生呢?其實可以創建一個定期更新module的runbook,然後定期運行,以下是微軟提供的代碼


<#    
.SYNOPSIS     
    This Azure Automation runbook imports the latest version of the Azure modules from the PowerShell Gallery.    
.DESCRIPTION    
    This Azure Automation runbook imports the latest version of the Azure modules from the PowerShell Gallery.    
    It requires that this runbook be run from the automation service and that the RunAs account is enabled on the     
    automation account.    
    You could put this runbook on a schedule so that it updates the modules each month or call through a webhook    
    as needed.    
.PARAMETER AutomationResourceGroup    
    Required. The name of the Azure Resource Group containing the Automation account.    
.PARAMETER AutomationAccountName    
    Required. The name of the Automation account.    
.PARAMETER ModuleVersionOverrides    
    Optional. A PowerShell HashTable or a JSON dictionary which contains module version overrides. Please be    
    careful of version incompatibility between modules when overriding module versions.    
.PARAMETER AzureEnvironment    
    Optional. The name of the target Azure environment (one of the values returned by 'Get-AzureRmEnvironment | select Name').    
.EXAMPLE    
    Update-AzureModule -AutomationResourceGroup contoso -AutomationAccountName contosoaccount    
.EXAMPLE    
    Update-AzureModule -AutomationResourceGroup contoso -AutomationAccountName contosoaccount -ModuleVersionOverrides @{'Azure'="4.0.2"; 'Azure.Storage'="3.0.2"; 'AzureRM.Profile'="3.0.1"; 'AzureRM.Automation'="3.0.1"; 'AzureRM.Compute'="3.0.1"; 'AzureRM.Resources' = "4.0.1"; 'AzureRM.Sql' = "3.0.1"; 'AzureRM.Storage'="3.0.2"} -AzureEnvironment 'AzureCloud'    
.EXAMPLE    
    Update-AzureModule -AutomationResourceGroup contoso -AutomationAccountName contosoaccount -ModuleVersionOverrides '{"Azure" : "4.0.2", "AzureRM.Sql" : "3.0.1", "AzureRM.Automation" : "3.0.1", "Azure.Storage" : "3.0.2", "AzureRM.Resources" : "4.0.1", "AzureRM.Storage" : "3.0.2", "AzureRM.Compute" : "3.0.1", "AzureRM.Profile" : "3.0.1"}'    
.NOTES    
    AUTHOR: Automation Team, Chase Dafnis    
    LASTEDIT: Nov 6th, 2018     
#>    
Param    
(    
[Parameter(Mandatory=$True)]    
[String] $AutomationResourceGroup,    
[Parameter(Mandatory=$True)]    
[String] $AutomationAccount,    
[Parameter(Mandatory=$False)]    
[object] $ModuleVersionOverrides,    
[Parameter(Mandatory=$False)]    
[String] $AzureEnvironment = 'AzureCloud'    
)    
$versionOverrides = ""    
# Try to parse module version overrides    
if ($ModuleVersionOverrides) {    
if ($ModuleVersionOverrides.GetType() -eq [HashTable]) {    
$versionOverrides = ConvertTo-Json $ModuleVersionOverrides    
} elseif ($ModuleVersionOverrides.GetType() -eq [String]) {    
# Verify that the ModuleVersionOverrides can be deserialized    
try{    
$temp = ConvertFrom-Json $ModuleVersionOverrides -ErrorAction Stop    
}    
catch [System.ArgumentException] {    
$ex = $_     
# rethrow intended    
throw "The value of the parameter ModuleVersionOverrides is not a valid JSON string: ", $ex    
}    
$versionOverrides = $ModuleVersionOverrides    
} else {    
$ex = [System.ArgumentException]::new("The value of the parameter ModuleVersionOverrides should be a PowerShell HashTable or a JSON string")    
throw $ex    
}    
}    
try    
{    
# Pull Azure environment settings    
$AzureEnvironmentSettings = Get-AzureRmEnvironment -Name $AzureEnvironment    
# Azure management uri    
$ResourceAppIdURI = $AzureEnvironmentSettings.ActiveDirectoryServiceEndpointResourceId    
# Path to modules in automation container    
$ModulePath = "C:\Modules"    
# Login uri for Azure AD    
$LoginURI = $AzureEnvironmentSettings.ActiveDirectoryAuthority    
# Find AzureRM.Profile module and load the Azure AD client library    
$PathToProfileModule = Get-ChildItem (Join-Path $ModulePath AzureRM.Profile) -Recurse    
Add-Type -Path (Join-Path $PathToProfileModule "Microsoft.IdentityModel.Clients.ActiveDirectory.dll")    
# Get RunAsConnection    
$RunAsConnection = Get-AutomationConnection -Name "AzureRunAsConnection"    
$Certifcate = Get-AutomationCertificate -Name "AzureRunAsCertificate"    
$SubscriptionId = $RunAsConnection.SubscriptionId    
# Set up authentication using service principal client certificate    
$Authority = $LoginURI + $RunAsConnection.TenantId    
$AuthContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $Authority    
$ClientCertificate = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate" -ArgumentList $RunAsConnection.ApplicationId, $Certifcate    
$AuthResult = $AuthContext.AcquireToken($ResourceAppIdURI, $ClientCertificate)    
# Set up header with authorization token    
$AuthToken = $AuthResult.CreateAuthorizationHeader()    
$RequestHeader = @{    
"Content-Type" = "application/json";    
"Authorization" = "$AuthToken"    
}    
# Create a runbook job    
$JobId = [GUID]::NewGuid().ToString()    
$URI =  "$($AzureEnvironmentSettings.ResourceManagerUrl)subscriptions/$SubscriptionId/"`    
+"resourceGroups/$($AutomationResourceGroup)/providers/Microsoft.Automation/"`    
+"automationAccounts/$AutomationAccount/jobs/$($JobId)?api-version=2015-10-31"    
# Runbook and parameters    
if($versionOverrides){    
$Body = @"    
            {    
               "properties":{    
               "runbook":{    
                   "name":"Update-AutomationAzureModulesForAccount"    
               },    
               "parameters":{    
                    "AzureEnvironment":"$AzureEnvironment",    
                    "ResourceGroupName":"$AutomationResourceGroup",    
                    "AutomationAccountName":"$AutomationAccount",    
                    "ModuleVersionOverrides":"$versionOverrides"    
               }    
              }    
           }    
"@    
} else {    
$Body = @"    
            {    
               "properties":{    
               "runbook":{    
                   "name":"Update-AutomationAzureModulesForAccount"    
               },    
               "parameters":{    
                    "AzureEnvironment":"$AzureEnvironment",    
                    "ResourceGroupName":"$AutomationResourceGroup",    
                    "AutomationAccountName":"$AutomationAccount"    
               }    
              }    
           }    
"@    
}    
# Start runbook job    
Invoke-RestMethod -Uri $URI -Method Put -body $body -Headers $requestHeader            
}    
catch     
{    
throw $_.Exception    
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章