-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathWindows365_AzureImage_Automation.ps1
183 lines (129 loc) · 6.96 KB
/
Windows365_AzureImage_Automation.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
##*===============================================
##* START - PARAMETERS
##*===============================================
Param
(
[Parameter (Mandatory= $True)]
[String] $NewImageName
)
#Name of your Custom Image VM
$CustomImageVMName = ""
##*===============================================
##* END - PARAMETERS
##*===============================================
##*===============================================
##* START - SCRIPT BODY
##*===============================================
#Connect to Azure
Write-Output "Connecting to Azure..."
Connect-AzAccount -Identity | out-null
$VM = Get-AzVM -Name $CustomImageVMName
$VMName = $VM.Name
#Check if Image name is valid
$CheckImageName = get-azimage -name $NewImageName
if ($CheckImageName) {
Write-Error "Image name already exist choose another Image Name"
}
#Check if VM is running
Write-Output "Checking if VM is deallocated..."
$VMStatus = (get-azvm -ResourceGroupName $VM.ResourceGroupName -Name $VMName -Status).Statuses.DisplayStatus
if ($VMStatus -like "VM Deallocated") {
Write-Output "$VMName is already deallocated..."
}
else {
Write-Output "$VMName is not deallocated, deallocating VM..."
Stop-AzVM -Name $VMName -ResourceGroupName $vm.ResourceGroupName -Force | out-null
}
Write-Output "Getting VM information for $VMName..."
#Get Disk, and create snapshot
Write-Output "Getting Disk information for $VMName.."
$VMOSDiskConfig = $VM.StorageProfile.OsDisk
$VMOSDiskName = $VMOSDiskConfig.Name
Write-Output "Creating disk Snapshot"
$SnapshotName = "$($VMOSDiskName)_SnapshotTempVM"
$SnapshotConfig = New-AzSnapshotConfig -SourceUri $vm.StorageProfile.OsDisk.ManagedDisk.Id -Location $VM.Location -CreateOption copy -SkuName Standard_LRS
New-AzSnapshot -Snapshot $SnapshotConfig -SnapshotName $SnapshotName -ResourceGroupName $VM.ResourceGroupName | out-null
#Create Temp Disk for VM
Write-Output "Creating Temp Disk"
$osDiskName = "$($VMOSDiskName)_TempVM"
$snapshot = Get-AzSnapshot -ResourceGroupName $VM.ResourceGroupName -SnapshotName $snapshotName
$diskConfig = New-AzDiskConfig -Location $snapshot.Location -SourceResourceId $snapshot.Id -CreateOption Copy
$disk = New-AzDisk -Disk $diskConfig -ResourceGroupName $vm.ResourceGroupName -DiskName $osDiskName
#Create Temp VM Nic
Write-Output "Creating Temp NIC"
$TempNicName = "$($VM.Name)_TempNic"
$Virtualnetworksettings = $VM.NetworkProfile.NetworkInterfaces[0].Id | Get-AzNetworkInterface
$nic = New-AzNetworkInterface -Name $TempNicName -ResourceGroupName $vm.ResourceGroupName -Location $snapshot.Location -SubnetId $Virtualnetworksettings.IpConfigurations.subnet.id
#Create Temp VM
Write-Output "Creating Temp VM"
$TempVMName = "$($VM.Name)_TempVM"
$VirtualMachine = New-AzVMConfig -VMName $TempVMName -VMSize $VM.HardwareProfile.VmSize
$VirtualMachine = Set-AzVMOSDisk -VM $VirtualMachine -ManagedDiskId $disk.Id -CreateOption Attach -Windows
$VirtualMachine = Add-AzVMNetworkInterface -VM $VirtualMachine -Id $nic.Id
$VirtualMachine = Set-AZVMBootDiagnostic -VM $VirtualMachine -Disable
New-AzVM -VM $VirtualMachine -ResourceGroupName $vm.ResourceGroupName -Location $snapshot.Location -DisableBginfoExtension | out-null
$TempVM = Get-AzVM -Name $TempVMName
Write-Output "Checking if temp VM is started..."
$VMStatus = (get-azvm -Name $TempVMName -ResourceGroupName $TempVM.ResourceGroupName -Status).Statuses.DisplayStatus
#Timer variables
$Timer = [Diagnostics.Stopwatch]::StartNew()
$TimerRetryInterval = "10"
$Timerout = "900"
While (($Timer.Elapsed.TotalSeconds -lt $Timerout) -and (-not ($VMStatus -like "VM running"))) {
Start-Sleep -Seconds $TimerRetryInterval
$TotalSecs = [math]::Round($Timer.Elapsed.TotalSeconds, 0)
Write-Output -Message "$TempVMName has not started waiting for VM to start. Task been running for $TotalSecs seconds..."
$VMStatus = (get-azvm -Name $TempVMName -ResourceGroupName $TempVM.ResourceGroupName -Status).Statuses.DisplayStatus
}
$Timer.Stop()
If ($Timer.Elapsed.TotalSeconds -gt $Timerout) {
Write-Error "$TempVMName did not start before timeout period ending script..."
Write-Error "Ending script"
exit
}
#Start sysprep
$RunCommandscript =
@"
Start-Process -FilePath C:\Windows\System32\Sysprep\Sysprep.exe -ArgumentList '/generalize /oobe /shutdown /quiet'
"@
#Save Script to local file
$LocalPath = "C:\Temp"
Set-Content -Path "$LocalPath\RunCommandScript.ps1" -Value $RunCommandscript
Write-Output "Running 'Sysprep' on vm: $TempVMName"
$RunCommand = Invoke-AzVMRunCommand -VMName $TempVM.Name -ResourceGroupName $TempVM.ResourceGroupName -CommandId RunPowerShellScript -ScriptPath "$LocalPath\RunCommandScript.ps1"
Write-Output "Check if VM is stopped..."
$VMStatus = (get-azvm -ResourceGroupName $TempVM.ResourceGroupName -Name $TempVMName -Status).Statuses.DisplayStatus
#Timer variables
$Timer = [Diagnostics.Stopwatch]::StartNew()
$TimerRetryInterval = "10"
$Timerout = "900"
While (($Timer.Elapsed.TotalSeconds -lt $Timerout) -and (-not ($VMStatus -like "VM Stopped"))) {
Start-Sleep -Seconds $TimerRetryInterval
$TotalSecs = [math]::Round($Timer.Elapsed.TotalSeconds, 0)
Write-Verbose -Message "$TempVMName has not stopped waiting for VM to stop. Task been running for $TotalSecs seconds..." -Verbose
$VMStatus = (get-azvm -ResourceGroupName $TempVM.ResourceGroupName -Name $TempVMName -Status).Statuses.DisplayStatus
}
$Timer.Stop()
If ($Timer.Elapsed.TotalSeconds -gt $Timerout) {
Write-Error "$TempVMName did not stopped before timeout period ending script..."
}
Write-Output "$TempVMName is stopped, Starting to deallocate it..."
stop-AzVM -Name $TempVMName -ResourceGroupName $TempVM.ResourceGroupName -Force | out-null
#Set VM to Generalized
Write-Output "Genealizing temp VM."
Set-AzVm -Name $TempVMName -ResourceGroupName $TempVM.ResourceGroupName -Generalized | out-null
#Create managed Image
Write-Output "Creating Azure Managed Image from temp VM"
$GeneralizedVM = Get-azvm -name $TempVMName -ResourceGroupName $TempVM.ResourceGroupName
$image = New-AzImageConfig -Location $GeneralizedVM.location -SourceVirtualMachineId $GeneralizedVM.Id -HyperVGeneration V2
New-AzImage -Image $image -ImageName $NewImageName -ResourceGroupName $GeneralizedVM.resourcegroupname | out-null
#Delete Temp ressources
Write-Output "Removeing Temp Ressources"
Remove-AzVM -Name $TempVM.Name -resourcegroupname $TempVM.ResourceGroupName -Force
Remove-AzDisk -DiskName $tempvm.StorageProfile.OsDisk.Name -ResourceGroupName $TempVM.ResourceGroupName -Force
Remove-AzNetworkInterface -Name $TempNicName -ResourceGroupName $TempVM.ResourceGroupName -Force
Remove-AzSnapshot -SnapshotName $SnapshotName -ResourceGroupName $TempVM.ResourceGroupName -Force
Remove-Item -Path "$LocalPath\RunCommandScript.ps1"
##*===============================================
##* END - SCRIPT BODY
##*===============================================