-
Notifications
You must be signed in to change notification settings - Fork 1
/
UpdateManagement-HybridWorker.ps1
132 lines (97 loc) · 4.14 KB
/
UpdateManagement-HybridWorker.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<#PSScriptInfo
.VERSION 1.1
.GUID b5eb0470-89af-4302-8200-144d19c454a8
.AUTHOR zachal
.COMPANYNAME Microsoft
.COPYRIGHT
.TAGS UpdateManagement, Automation
.LICENSEURI
.PROJECTURI
.ICONURI
.EXTERNALMODULEDEPENDENCIES
.REQUIREDSCRIPTS
.EXTERNALSCRIPTDEPENDENCIES
.RELEASENOTES
.PRIVATEDATA
#>
<#
.DESCRIPTION
This script is intended to be run as a part of Update Management Pre/Post scripts.
It requires hybrid workers to be configured on the machines which need to run scripts locally.
Runs a child Automation Runbook on a hybrid worker
#>
<#
.SYNOPSIS
Runs a child Automation Runbook on a hybrid worker
.DESCRIPTION
This script is intended to be run as a part of Update Management Pre/Post scripts.
It requires hybrid workers to be configured on the machines which need to run scripts locally.
.PARAMETER RunbookName
The name of the Azure Automation runbook you wish to execute on the hybrid workers in a local context
.PARAMETER HybridWorkerGroups
A hybrid worker group which should run another runbook from a local context.
To guarantee execution on the right machine, each hybrid worker group should contain only one machine.
KNOWN ISSUE: Pre/Post scripts will not accept arrays or objects as arguments.
.PARAMETER SoftwareUpdateConfigurationRunContext
This is a system variable which is automatically passed in by Update Management during a deployment.
#>
param(
[parameter(Mandatory=$true)] [string]$RunbookName,
[parameter(Mandatory=$true)] [string]$HybridWorkerGroups,
[string]$SoftwareUpdateConfigurationRunContext
)
#region BoilerplateAuthentication
#This requires a System Managed Identity
$AzureContext = (Connect-AzAccount -Identity).context
$AzureContext = Set-AzContext -SubscriptionName $AzureContext.Subscription -DefaultProfile $AzureContext
#endregion BoilerplateAuthentication
$runStatus = New-Object System.Collections.Generic.List[System.Object]
$finalStatus = New-Object System.Collections.Generic.List[System.Object]
#If you wish to use the run context, it must be converted from JSON
$context = ConvertFrom-Json $SoftwareUpdateConfigurationRunContext
#https://github.com/azureautomation/runbooks/blob/master/Utility/ARM/Find-WhoAmI
# In order to prevent asking for an Automation Account name and the resource group of that AA,
# search through all the automation accounts in the subscription
# to find the one with a job which matches our job ID
$AutomationResource = Get-AzResource -ResourceType Microsoft.Automation/AutomationAccounts
foreach ($Automation in $AutomationResource)
{
$Job = Get-AzAutomationJob -ResourceGroupName $Automation.ResourceGroupName -AutomationAccountName $Automation.Name -Id $PSPrivateMetadata.JobId.Guid -ErrorAction SilentlyContinue
if (!([string]::IsNullOrEmpty($Job)))
{
$ResourceGroup = $Job.ResourceGroupName
$AutomationAccount = $Job.AutomationAccountName
break;
}
}
#Start script on each machine
foreach($machine in $HybridWorkerGroups)
{
$output = Start-AzAutomationRunbook -Name $RunbookName -ResourceGroupName $ResourceGroup -AutomationAccountName $AutomationAccount -RunOn $machine
$runStatus.Add($output)
}
#Determine status of all runs.
foreach($job in $runStatus)
{
#First, wait for each job to complete
$currentStatus = Get-AzAutomationJob -Id $job.jobid -ResourceGroupName $ResourceGroup -AutomationAccountName $AutomationAccount
while ($currentStatus.status -ne "Completed")
{
Start-Sleep -Seconds 5
$currentStatus = Get-AzAutomationJob -Id $job.jobid -ResourceGroupName $ResourceGroup -AutomationAccountName $AutomationAccount
}
#Then, store the summary
$summary = Get-AzAutomationJobOutput -Id $job.jobid -ResourceGroupName $ResourceGroup -AutomationAccountName $AutomationAccount
$finalStatus.Add($summary)
}
#In this case, we want to terminate the patch job if any run fails.
#This logic might not hold for all cases - you might want to allow success as long as at least 1 run succeeds
foreach($summary in $finalStatus)
{
if ($summary.Type -eq "Error")
{
#We must throw in order to fail the patch deployment.
throw $summary.Summary
}
}