-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdeployNewImage.ps1
219 lines (181 loc) · 8.09 KB
/
deployNewImage.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
param (
[string]$projectId = $(throw "-projectId is required.")
)
Update-AzConfig -DisplayBreakingChangeWarning $false | out-null
$ErrorActionPreference = "Stop"
$ProgressPreference = 'SilentlyContinue'
$rgName = $projectId + "-RG"
function Show-PoolHosts{
""
$currentHosts = Get-AzWvdSessionHost `
-ResourceGroupName $rgName `
-HostPoolName $outputs.hostPoolName.value
$format = "{0,-35}{1,-13}{2,-10}{3,-15}{4}"
$format -f "Name", "Status", "Sessions", "Image Version", "VM Power State"
foreach ($ahost in $currentHosts){
$vmPowerState = (Get-AzVM -ResourceId $ahost.ResourceId -Status).Statuses[1].Code
$imgVer = (Get-AzVM -ResourceId $ahost.ResourceId).StorageProfile.ImageReference.ExactVersion
$format -f $ahost.Name, $ahost.Status, $ahost.Session, $imgVer, $vmPowerState
}
""
}
#
# Validate VDI environment and get needed outputs
#
$context = get-azcontext
if ($context.Account.Type -eq 'User'){
$userObjectId = $context.Account.ExtendedProperties.HomeAccountId.Split('.')[0]
}
elseif ($context.Account.Type -eq 'ServicePrincipal') {
$userObjectId = (Get-AzADServicePrincipal -ApplicationId $context.Account.Id).id
}
else{
throw "Current user account type is neither User or ServicePrincipal. Re-run Connect-AzAccount."
}
$deploymentName = "VDIdeployment-" + (get-date).ToString('yyyyMMddHHmm')
$outputs = (New-AzResourceGroupDeployment -ResourceGroupName $rgName `
-Name $deploymentName `
-TemplateFile '.\vdi.bicep' `
-projectId $projectId `
-tenantId $context.Tenant.Id `
-keyVaultUser $userObjectId).Outputs
Show-PoolHosts
#
# Determine what is the latest golden image version in the Gallery.
#
$imgVersions = Get-AzGalleryImageVersion `
-ResourceGroupName $rgName `
-GalleryName $outputs.galleryName.value `
-GalleryImageDefinitionName $outputs.imageName.value
$latestImage = $imgVersions | Select-Object -first 1
foreach ($ver in $imgVersions){
if ($latestImage.PublishingProfile.PublishedDate -lt $ver.PublishingProfile.PublishedDate){
$latestImage = $ver
}
}
"Latest image version: " + $latestImage.Name
#
# Determine how many of the current hosts were deployed using and older image version.
#
$hostsToReplace = @()
$activeHosts = Get-AzWvdSessionHost `
-ResourceGroupName $rgName `
-HostPoolName $outputs.hostPoolName.value `
| Where-Object {$_.AllowNewSession -eq $true}
foreach ($ahost in $activeHosts){
$vm = Get-AzVM -ResourceId $ahost.ResourceId
$vm.Name + " version: " + $vm.StorageProfile.ImageReference.ExactVersion
if ($vm.StorageProfile.ImageReference.ExactVersion -ne $latestImage.name){
$hostsToReplace += $ahost
}
}
#
# If there are no hosts created with an older image version, end the script.
#
if ( $hostsToReplace.Count -eq 0 ){
"All host are at the latest image version"
Exit
}
"Number of hosts to replace: " + $hostsToReplace.Count
#
# Get the information required to deploy new hosts, i.e, Pool registration key, Username and Password.
#
$hpToken = New-AzWvdRegistrationInfo `
-ResourceGroupName $rgName `
-HostPoolName $outputs.hostPoolName.value `
-ExpirationTime $((get-date).ToUniversalTime().AddDays(1).ToString('yyyy-MM-ddTHH:mm:ss.fffffffZ'))
"Issued and retrieved hostpool registration token"
#
# Momentarily allow public network access to the KeyVault.
#
Update-AzKeyVaultNetworkRuleSet -DefaultAction Allow -VaultName $outputs.keyVaultName.value -WarningAction Ignore
"Set keyVault DefaultAction to Allow"
$vdiHostAdminUsername = Get-AzKeyVaultSecret -VaultName $outputs.keyVaultName.value -Name vdiHostAdminUsername -AsPlainText `
-ErrorAction SilentlyContinue -ErrorVariable kvError
$textPassword = Get-AzKeyVaultSecret -VaultName $outputs.keyVaultName.value -Name vdiHostAdminPassword -AsPlainText `
-ErrorAction SilentlyContinue -ErrorVariable +kvError
#
# Sometimes it takes a few seconds for the DefaultAction to take effect, so we retry.
#
while ($kvError.Count -ne 0) {
$vdiHostAdminUsername = Get-AzKeyVaultSecret -VaultName $outputs.keyVaultName.value -Name vdiHostAdminUsername -AsPlainText `
-ErrorAction SilentlyContinue -ErrorVariable kvError
$textPassword = Get-AzKeyVaultSecret -VaultName $outputs.keyVaultName.value -Name vdiHostAdminPassword -AsPlainText `
-ErrorAction SilentlyContinue -ErrorVariable +kvError
}
"Retrieved vm admin username and password from KeyVault"
Update-AzKeyVaultNetworkRuleSet -DefaultAction Deny -VaultName $outputs.keyVaultName.value
"Set keyVault DefaultAction to Deny"
$vdiHostAdminPassword = ConvertTo-SecureString $textPassword -AsPlainText -Force
$storageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $rgName -Name $outputs.storageAccountName.value)[0].Value
"Retrieved storage account key"
$storageAccountKeySecure = ConvertTo-SecureString $storageAccountKey -AsPlainText -Force
#
# Upload the script that the CustomScriptExtension will use to add the vm to the hostpool
#
$context = New-AzStoragecontext -StorageAccountName $outputs.storageAccountName.value -StorageAccountKey $storageAccountKey
#
# Momentarily allow public network access to the storage account.
# The user uploading must have access from RBAC, SAS key or access token.
#
$newDefault = Update-AzStorageAccountNetworkRuleSet -ResourceGroupName $rgName -Name $outputs.storageAccountName.value `
-DefaultAction Allow
"Changed storage account DefaultAction to " + $newDefault.DefaultAction
$upload = (Set-AzStorageBlobContent -Container "scripts" -File ".\setWVDClient.ps1" -Blob "setWVDClient.ps1" -context $context `
-Force -ErrorAction SilentlyContinue -ErrorVariable saError)
#
# Sometimes it takes a few seconds for new default action to take effect, so we retry the upload.
#
while ($saError.Count -ne 0) {
Start-Sleep -Seconds 5
"Retrying file upload..."
$upload = (Set-AzStorageBlobContent -Container "scripts" -File ".\setWVDClient.ps1" -Blob "setWVDClient.ps1" -context $context `
-Force -ErrorAction SilentlyContinue -ErrorVariable saError)
}
"Uploaded to blob storage script " + $upload.Name + " to add VMs to hostpool."
#
# Upload done. Change back the default action to Deny.
#
$newDefault = Update-AzStorageAccountNetworkRuleSet -ResourceGroupName $rgName -Name $outputs.storageAccountName.value `
-DefaultAction Deny
"Changed storage account DefaultAction to " + $newDefault.DefaultAction
$fileUri = $outputs.blobEndpoint.value + "scripts/setWVDClient.ps1"
#
# Deploy hostpool VMs based on the latest golden image.
#
"Deploying " + $hostsToReplace.Count + " replacement hostpool VMs"
$vmName = "hp" + (get-date).ToString('ddHHmm') + "v" + $latestImage.name.Replace(".","")
$deploymentName = "hostPoolVMdeployment-" + (get-date).ToString('yyyyMMddHHmm')
$deployment = New-AzResourceGroupDeployment -ResourceGroupName $rgName `
-Name $deploymentName `
-TemplateFile '.\vm.bicep' `
-vmName $vmName `
-vmType 'hostPool' `
-vmCount $hostsToReplace.Count `
-adminUserName $vdiHostAdminUsername `
-adminPassword $vdiHostAdminPassword `
-subnetId $outputs.subnetId.value `
-osImageId $latestImage.id `
-storageAccountName $outputs.storageAccountName.value `
-storageAccountKey $storageAccountKeySecure `
-fileUri $fileUri `
-registrationToken $hpToken.Token
$deployment.DeploymentName + " " + $deployment.ProvisioningState
#
# Disable and deallocate previous-version hosts.
#
foreach ($shost in $hostsToReplace){
$vm = Get-AzVM -ResourceId $shost.ResourceId
"Disabling new sessions on VM: " + $vm.Name
Update-AzWvdSessionHost `
-ResourceGroupName $rgName `
-HostPoolName $outputs.hostPoolName.value `
-Name $vm.Name `
-AllowNewSession:$false `
| Select-Object Name, Session, Status, AllowNewSession | Format-Table
if ($shost.Session -eq 0){
"Stopping VM: " + $vm.Name
Stop-AzVM -Id $vm.Id -Force | Select-Object Status
}
}
Show-PoolHosts