今天来分析一波Azure automation的报错问题,Azure automation是个不错的东东,通过 Azure automation可以自动完成频繁的、耗时的、易出错的云管理任务。 有了这 样的自动化,我们可以专注于能够让业务增值的工作,automation可以实现很多功能,比如定时开关机,调整size以节省成本,或者是自动备份、删除文件到blob中,乃至结合一些业务逻辑,定制专门的automation runbook来完成业务需求等
在使用automation的过程中,有遇到过一些大大小小的问题,拿出来和各位分享一下
首先是一个小问题,之前有个需求是要根据业务场景自动创建blob存储,然后将数据传输到这个blob中,完成任务后,再由别的逻辑触发自动删除,这个需求实际上很简单,用automation也可以很方便的完成任务
但是在实际使用中遇到了一点小问题
这是一个之前做测试的runbook,只是简单测试创建storage account然后删除,但是发现居然报错了
点开报错信息,发现报错信息如下:
其实代码很简单,只是一个remove-azurermstorage account,然后加了一个-force的开关,但是为啥会报错呢,报错信息提示的是找不到匹配的参数,一般来说这种问题都是处在这个命令的版本上
因此特地输出了一下remove-azurermstorageaccount这个命令的版本来看下,顿时我就被惊到了,居然是他么的1.0.3..难怪不支持-force
而我电脑上这个命令的版本是多少呢。。是5.2.0
问题很明显了,就是出在命令的版本上,那么就来尝试强制导入5.2.0这个版本
可是尝试之后发现居然告诉我没有可用的版本。。难道这个东西智障到连版本都没办法选的吗
当然不是了,简单看了看automation account的设置,才发现自己犯了一个很傻的错误,这个automation account是很久前创建的,在module这里显示的命令版本都是非常非常低的了。。
实际上我们只需要更新一波即可,点击update azure modules
更新完成
如果没有module的,可以尝试在gallery里添加
到此为止,问题就算是解决了,那么如何防止这类问题再发生呢?其实可以创建一个定期更新module的runbook,然后定期运行,以下是微软提供的代码
<# .SYNOPSIS ThisAzureAutomationrunbookimportsthelatestversionoftheAzuremodulesfromthePowerShellGallery. .DESCRIPTION ThisAzureAutomationrunbookimportsthelatestversionoftheAzuremodulesfromthePowerShellGallery. ItrequiresthatthisrunbookberunfromtheautomationserviceandthattheRunAsaccountisenabledonthe automationaccount. Youcouldputthisrunbookonaschedulesothatitupdatesthemoduleseachmonthorcallthroughawebhook asneeded. .PARAMETERAutomationResourceGroup Required.ThenameoftheAzureResourceGroupcontainingtheAutomationaccount. .PARAMETERAutomationAccountName Required.ThenameoftheAutomationaccount. .PARAMETERModuleVersionOverrides Optional.APowerShellHashTableoraJSONdictionarywhichcontainsmoduleversionoverrides.Pleasebe carefulofversionincompatibilitybetweenmoduleswhenoverridingmoduleversions. .PARAMETERAzureEnvironment Optional.ThenameofthetargetAzureenvironment(oneofthevaluesreturnedby'Get-AzureRmEnvironment|selectName'). .EXAMPLE Update-AzureModule-AutomationResourceGroupcontoso-AutomationAccountNamecontosoaccount .EXAMPLE Update-AzureModule-AutomationResourceGroupcontoso-AutomationAccountNamecontosoaccount-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-AutomationResourceGroupcontoso-AutomationAccountNamecontosoaccount-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:AutomationTeam,ChaseDafnis LASTEDIT:Nov6th,2018 #> Param ( [Parameter(Mandatory=$True)] [String]$AutomationResourceGroup, [Parameter(Mandatory=$True)] [String]$AutomationAccount, [Parameter(Mandatory=$False)] [object]$ModuleVersionOverrides, [Parameter(Mandatory=$False)] [String]$AzureEnvironment='AzureCloud' ) $versionOverrides="" #Trytoparsemoduleversionoverrides if($ModuleVersionOverrides){ if($ModuleVersionOverrides.GetType()-eq[HashTable]){ $versionOverrides=ConvertTo-Json$ModuleVersionOverrides }elseif($ModuleVersionOverrides.GetType()-eq[String]){ #VerifythattheModuleVersionOverridescanbedeserialized try{ $temp=ConvertFrom-Json$ModuleVersionOverrides-ErrorActionStop } catch[System.ArgumentException]{ $ex=$_ #rethrowintended throw"ThevalueoftheparameterModuleVersionOverridesisnotavalidJSONstring:",$ex } $versionOverrides=$ModuleVersionOverrides }else{ $ex=[System.ArgumentException]::new("ThevalueoftheparameterModuleVersionOverridesshouldbeaPowerShellHashTableoraJSONstring") throw$ex } } try { #PullAzureenvironmentsettings $AzureEnvironmentSettings=Get-AzureRmEnvironment-Name$AzureEnvironment #Azuremanagementuri $ResourceAppIdURI=$AzureEnvironmentSettings.ActiveDirectoryServiceEndpointResourceId #Pathtomodulesinautomationcontainer $ModulePath="C:\Modules" #LoginuriforAzureAD $LoginURI=$AzureEnvironmentSettings.ActiveDirectoryAuthority #FindAzureRM.ProfilemoduleandloadtheAzureADclientlibrary $PathToProfileModule=Get-ChildItem(Join-Path$ModulePathAzureRM.Profile)-Recurse Add-Type-Path(Join-Path$PathToProfileModule"Microsoft.IdentityModel.Clients.ActiveDirectory.dll") #GetRunAsConnection $RunAsConnection=Get-AutomationConnection-Name"AzureRunAsConnection" $Certifcate=Get-AutomationCertificate-Name"AzureRunAsCertificate" $SubscriptionId=$RunAsConnection.SubscriptionId #Setupauthenticationusingserviceprincipalclientcertificate $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) #Setupheaderwithauthorizationtoken $AuthToken=$AuthResult.CreateAuthorizationHeader() $RequestHeader=@{ "Content-Type"="application/json"; "Authorization"="$AuthToken" } #Createarunbookjob $JobId=[GUID]::NewGuid().ToString() $URI="$($AzureEnvironmentSettings.ResourceManagerUrl)subscriptions/$SubscriptionId/"` +"resourceGroups/$($AutomationResourceGroup)/providers/Microsoft.Automation/"` +"automationAccounts/$AutomationAccount/jobs/$($JobId)?api-version=2015-10-31" #Runbookandparameters 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" } } } "@ } #Startrunbookjob Invoke-RestMethod-Uri$URI-MethodPut-body$body-Headers$requestHeader } catch { throw$_.Exception }