解决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这里显示的命令版本都是非常非常低的了。。


image012.png



    实际上我们只需要更新一波即可,点击update azure modules

image014.png

可以看到module已经正在更新了

image016.png



 更新完成

image018.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    
}




猜你喜欢

转载自blog.51cto.com/mxyit/2348123
今日推荐