十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
今天来分析一波Azure automation的报错问题,Azure automation是个不错的东东,通过 Azure automation可以自动完成频繁的、耗时的、易出错的云管理任务。 有了这 样的自动化,我们可以专注于能够让业务增值的工作,automation可以实现很多功能,比如定时开关机,调整size以节省成本,或者是自动备份、删除文件到blob中,乃至结合一些业务逻辑,定制专门的automation runbook来完成业务需求等
创新互联专注于企业营销型网站建设、网站重做改版、晋城网站定制设计、自适应品牌网站建设、HTML5建站、商城网站建设、集团公司官网建设、成都外贸网站建设公司、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为晋城等各大城市提供网站开发制作服务。
在使用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 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 }