【发布时间】:2021-01-07 10:12:30
【问题描述】:
我创建了一个运行手册来载入 Azure VM 以进行更新管理。 这个想法来自 MS 提供的运行手册 (https://github.com/azureautomation/runbooks/blob/master/Utility/ARM/Enable-AutomationSolution.ps1)。 MS Runbook 使用旧的 AzureRM 模块,不能满足我的需求,而且不能直接开箱即用。
我的 Runbook 本质上是做同样的事情,查找带有标签的 VM,安装 Microsoft Monitoring Agent 并将其配置为向工作区报告。
然后它会更新工作区中的查询以包含 VM。
所有这些工作并成功完成,但更新管理门户中显示“1 台计算机未启用‘更新管理’”和“这些计算机正在向 Log Analytics 工作区‘工作区名称’报告,但它们确实没有对它们启用“更新管理”。”
我不确定我还遗漏了哪些其他步骤,或者某些内容是否发生了变化,而且我看不到我的 MS Runbook 做了什么。
运行手册中的模块:
Az.Accounts
1/6/2021, 3:15 PM
Available
2.2.3
Az.Compute
1/6/2021, 3:17 PM
Available
4.8.0
Az.OperationalInsights
1/6/2021, 3:17 PM
Available
2.3.0
Az.Resources
1/6/2021, 3:17 PM
Available
3.1.1
Az.Storage
1/6/2021, 3:18 PM
Available
3.2.0
我的运行手册:
#Import-module -Name Az.Profile, Az.Automation, Az.OperationalInsights, Az.Compute, Az.Resources
#exit
#if ($oErr)
#{
# Write-Error -Message "Failed to load needed modules for Runbook, check that Az.Automation, Az.OperationalInsights, Az.Compute and Az.Resources are imported into the Automation Account" -ErrorAction Stop
#}
# Fetch AA RunAs account detail from connection object asset
$ServicePrincipalConnection = Get-AutomationConnection -Name "AzureRunAsConnection" -ErrorAction Stop
$Connection = Add-AzAccount -ServicePrincipal -TenantId $ServicePrincipalConnection.TenantId `
-ApplicationId $ServicePrincipalConnection.ApplicationId -CertificateThumbprint $ServicePrincipalConnection.CertificateThumbprint -ErrorAction Continue -ErrorVariable oErr
if ($oErr)
{
Write-Error -Message "Failed to connect to Azure" -ErrorAction Stop
}
else
{
write-output "connected to Azure"
}
#get the LA subscription
$LogAnalyticsSolutionSubscriptionId = Get-AutomationVariable -Name "LASolutionSubscriptionId"
#get the LA workspace RG
$LogAnalyticsSolutionWorkspaceRG = Get-AutomationVariable -Name "LASolutionWorkspaceRG"
#get the LA workspace Name
$LogAnalyticsSolutionWorkspaceName = Get-AutomationVariable -Name "LASolutionWorkspaceName"
#get the LA workspace Id
$LogAnalyticsSolutionWorkspace = Get-AzOperationalInsightsWorkspace -Name $LogAnalyticsSolutionWorkspaceName -ResourceGroupName $LogAnalyticsSolutionWorkspaceRG
#$LogAnalyticsSolutionWorkspaceId = Get-AutomationVariable -Name "LASolutionWorkspaceId"
#get the LA workspace key
$LogAnalyticsSolutionWorkspaceKey = AzOperationalInsightsWorkspaceSharedKey -ResourceGroupName $LogAnalyticsSolutionWorkspaceRG -Name $LogAnalyticsSolutionWorkspaceName
#$PublicSettings=@{"workspaceId" = $LogAnalyticsSolutionWorkspace.CustomerId};
#write-output "public settings are: "
#write-output $PublicSettings
write-output "sid is $LogAnalyticsSolutionSubscriptionId, wid is $($LogAnalyticsSolutionWorkspace.CustomerId), key is $($LogAnalyticsSolutionWorkspaceKey.PrimarySharedKey)"
if ($null -eq $LogAnalyticsSolutionSubscriptionId -or $Null -eq $LogAnalyticsSolutionWorkspace -or $null -eq $LogAnalyticsSolutionWorkspaceKey)
{
Write-Error -Message "Unable to retrieve variables from automation account."
exit
}
#get VM list
$VMsWantingPatching=Get-AzResource -TagName "patching" -TagValue "true" -ResourceType "Microsoft.Compute/virtualMachines" -ErrorAction Continue -ErrorVariable oErr
if ($oErr)
{
Write-Error -Message "Could not retrieve VM list" -ErrorAction Stop
}
elseif ($Null -eq $VMsWantingPatching)
{
Write-Error -Message "No VMs need patching" -ErrorAction Stop
}
else
{
write-output "Successfully retrieved VM list"
}
foreach ($VM in $VMsWantingPatching)
{
Try
{
#Configure MMA on the VM to report to the UM LA workspace, unfortunately the workspace ID and key need to be hardcoded
#as passing a parameter does not work.
#Using this method preserves existing workspaces on the MMA agent, this method only adds, not replaces like using ARM would do
$CurrentVM=Get-AzVM -name $VM.name
Set-AzVMExtension -ExtensionName "MicrosoftMonitoringAgent" `
-ResourceGroupName $VM.ResourceGroupName `
-VMName $VM.Name `
-Publisher "Microsoft.EnterpriseCloud.Monitoring" `
-ExtensionType "MicrosoftMonitoringAgent" `
-TypeHandlerVersion "1.0" `
-Settings @{"workspaceId" = "xxx" } `
-ProtectedSettings @{"workspaceKey" = "xxx"} `
-Location $VM.location
#Add VM to string list for LA function
$VMList += "`"$($CurrentVM.vmid)`", "
}
catch
{
write-error -Message $_.Exception.message
}
<# if ($VMAgentConfig.StatusCode -ne 0)
{
Write-Error -Message "Failed to add workspace to $($VM.Name)"
exit
}
else
{
write-output "Successfully added the workspace to $($VM.Name)"
}#>
}
write-output "VMList to use is: " $($VMList)
#Get the saved queries in LA
$SavedGroups = Get-AzOperationalInsightsSavedSearch -ResourceGroupName $LogAnalyticsSolutionWorkspaceRG `
-WorkspaceName $LogAnalyticsSolutionWorkspaceName -AzureRmContext $LASubscriptionContext -ErrorAction Continue -ErrorVariable oErr
#Find the Update Management saved query from the entire list and put it into a variable
$UpdatesGroup = $SavedGroups.Value | Where-Object {$_.Id -match "MicrosoftDefaultComputerGroup" -and $_.Properties.Category -eq "Updates"}
write-output "group is " $UpdatesGroup | out-string -Width 1000
#set the query/function
#remove trailing comma from list of VMs
$VMList = $($VMList).TrimEnd(', ')
#we use Resource as UUID is not useful when troubleshooting the query and computer gets truncated
$NewQuery="Heartbeat | where VMUUID in ( $($VMList) ) | distinct Computer"
write-output "Newquery is" $($NewQuery)
#just left in for info but no longer use Powershell to update LA query, using ARM as this has etag parameter, which is needed to avoid 409 conflict.
#New-AzOperationalInsightsSavedSearch -ResourceGroupName $LogAnalyticsSolutionWorkspaceRG -WorkspaceName $LogAnalyticsSolutionWorkspaceName `
# -SavedSearchID "Updates|MicrosoftDefaultComputerGroup" -Category "Updates" -FunctionAlias "Updates__MicrosoftDefaultComputerGroup" `
# -Query $NewQuery -DisplayName "MicrosoftDefaultComputerGroup" -Force
#write arm template to a file then make a new resource deployment to update the LA function
#configure arm template
$ArmTemplate = @'
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": ""
},
"id": {
"type": "string",
"defaultValue": ""
},
"resourceName": {
"type": "string",
"defaultValue": ""
},
"category": {
"type": "string",
"defaultValue": ""
},
"displayName": {
"type": "string",
"defaultValue": ""
},
"query": {
"type": "string",
"defaultValue": ""
},
"functionAlias": {
"type": "string",
"defaultValue": ""
},
"etag": {
"type": "string",
"defaultValue": ""
},
"apiVersion": {
"defaultValue": "2017-04-26-preview",
"type": "String"
}
},
"resources": [
{
"apiVersion": "2017-04-26-preview",
"type": "Microsoft.OperationalInsights/workspaces/savedSearches",
"location": "[parameters('location')]",
"name": "[parameters('resourceName')]",
"id": "[parameters('id')]",
"properties": {
"displayname": "[parameters('displayName')]",
"category": "[parameters('category')]",
"query": "[parameters('query')]",
"functionAlias": "[parameters('functionAlias')]",
"etag": "[parameters('etag')]",
"tags": [
{
"Name": "Group", "Value": "Computer"
}
]
}
}
]
}
'@
#Endregion
# Create temporary file to store ARM template in
$TempFile = New-TemporaryFile -ErrorAction Continue -ErrorVariable oErr
if ($oErr)
{
Write-Error -Message "Failed to create temporary file for solution ARM template" -ErrorAction Stop
}
Out-File -InputObject $ArmTemplate -FilePath $TempFile.FullName -ErrorAction Continue -ErrorVariable oErr
if ($oErr)
{
Write-Error -Message "Failed to write ARM template for solution onboarding to temp file" -ErrorAction Stop
}
# Add all of the parameters
$QueryDeploymentParams = @{}
$QueryDeploymentParams.Add("location", $($LogAnalyticsSolutionWorkspace.Location))
$QueryDeploymentParams.Add("id", $UpdatesGroup.Id)
$QueryDeploymentParams.Add("resourceName", ($LogAnalyticsSolutionWorkspaceName+ "/Updates|MicrosoftDefaultComputerGroup").ToLower())
$QueryDeploymentParams.Add("category", "Updates")
$QueryDeploymentParams.Add("displayName", "MicrosoftDefaultComputerGroup")
$QueryDeploymentParams.Add("query", $NewQuery)
$QueryDeploymentParams.Add("functionAlias", $SolutionType + "__MicrosoftDefaultComputerGroup")
$QueryDeploymentParams.Add("etag", "*")#$UpdatesGroup.ETag) etag is null for the query and referencing null property doesn't work so * instead
#$QueryDeploymentParams.Add("apiVersion", $SolutionApiVersion)
# Create deployment name
$DeploymentName = "EnableMultipleAutomation" + (Get-Date).ToFileTimeUtc()
$ObjectOutPut = New-AzResourceGroupDeployment -ResourceGroupName $LogAnalyticsSolutionWorkspaceRG -TemplateFile $TempFile.FullName `
-Name $DeploymentName `
-TemplateParameterObject $QueryDeploymentParams `
-AzureRmContext $SubscriptionContext -ErrorAction Continue -ErrorVariable oErr
if ($oErr)
{
Write-Error -Message "Failed to add VM: $VMName to solution: $SolutionType" -ErrorAction Stop
}
else
{
Write-Output -InputObject $ObjectOutPut
Write-Output -InputObject "VM: $VMName successfully added to solution: $SolutionType"
}
# Remove temp file with arm template
Remove-Item -Path $TempFile.FullName -Force
就像我说的,运行手册似乎已成功完成,但我想知道有人能告诉我没有执行什么任务吗? 谢谢, 尼尔。
【问题讨论】:
标签: azure azure-runbook