# AVD-Custom-Image-to-SIG-Script.ps1 ################################ # Download AzCmdlets # ################################ New-Item -Path C:\ -Name AzCmdlets -ItemType Directory -ErrorAction SilentlyContinue $LocalPath = "C:\AzCmdlets\" $LanguagepackURL = 'https://www.knowledgebase.it/aib/Az-Cmdlets/Az-Cmdlets-6.1.0.34441-x64.msi' $LanguagepackInstaller = "Az-Cmdlets-6.1.0.34441-x64.msi" $ProgressPreference = 'SilentlyContinue' Invoke-WebRequest ` -Uri $LanguagepackURL ` -OutFile "$Localpath$LanguagepackInstaller" Set-Location -Path C:\AzCmdlets\ Start-Process -FilePath msiexec.exe -Args "/I C:\AzCmdlets\Az-Cmdlets-6.1.0.34441-x64.msi /quiet /norestart" -Wait Install-Module Az.ManagedServiceIdentity -force Install-Module Az.ImageBuilder -force <# Import-Module and Connect-AzAccount #> Import-Module -Name Az Connect-AzAccount -Environment AzureCloud <# Import-Module and AzureADPreview #> Import-Module AzureADPreview Connect-AzureAD <# Set up the base variables & create a new Resource Group #> . "C:\Users\DennisWesterman\OneDrive - Westerman.it\_Azure\WVD\AIB\Variables.ps1" $currentAzContext = Get-AzContext $subscriptionID = $currentAzContext.Subscription.Id ########################################################## # create resource group for image and image template resource if ($null -eq (Get-AzResourceGroup -Name $imageResourceGroup -ErrorAction SilentlyContinue)) { New-AzResourceGroup -Name $imageResourceGroup -Location $location } ########################################################## #Registering the Resource Provider for AIB $resourceproviderfeature = Get-AzProviderFeature -ProviderNamespace Microsoft.VirtualMachineImages -FeatureName VirtualMachineTemplatePreview If ($resourceproviderfeature.RegistrationState -ne "Registered") { Write-Host "Resource Provider not yet Registered! Registering now..." Register-AzResourceProvider -ProviderNamespace Microsoft.VirtualMachineImages Write-Host "Waiting loop until Resource Provider is Registered..." Do { Start-Sleep -Seconds 5 } While ((Get-AzResourceProvider -ProviderNamespace Microsoft.VirtualMachineImages).RegistrationState -ne "Registered") Write-Host "Registering Feature now..." Register-AzProviderFeature -ProviderNamespace Microsoft.VirtualMachineImages -FeatureName VirtualMachineTemplatePreview Do { Start-Sleep -Seconds 5 } While ((Get-AzProviderFeature -ProviderNamespace Microsoft.VirtualMachineImages -FeatureName VirtualMachineTemplatePreview).RegistrationState -ne "Registered") } Write-Host "Resource Provider OK." Get-AzResourceProvider -ProviderNamespace Microsoft.Compute, Microsoft.KeyVault, Microsoft.Storage | Where-Object RegistrationState -ne Registered | Register-AzResourceProvider ########################################################## # Create the Managed Identity # Use current time to verify names are unique $userRandom = "u$(Get-Random)" $imageRoleDefName="Azure Image Builder Image Def"+$userRandom $identityName = "myIdentity"+$userRandom # Create the User Identity New-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName $idenityNameResourceId=$(Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).Id $idenityNamePrincipalId=$(Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).PrincipalId # Assign the identity resource and principle ID's to a variable $identityNamePrincipalId = (Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).PrincipalId # Assign permissions for identity to distribute images # downloads a .json file with settings, update with subscription settings $myRoleImageCreationUrl = 'https://raw.githubusercontent.com/danielsollondon/azvmimagebuilder/master/solutions/12_Creating_AIB_Security_Roles/aibRoleImageCreation.json' $myRoleImageCreationPath = ".\myRoleImageCreation.json" # Download the file $ProgressPreference = 'SilentlyContinue' Invoke-WebRequest -Uri $myRoleImageCreationUrl -OutFile $myRoleImageCreationPath -UseBasicParsing # Update the file $Content = Get-Content -Path $myRoleImageCreationPath -Raw $Content = $Content -replace '<subscriptionID>', $subscriptionID $Content = $Content -replace '<rgName>', $imageResourceGroup $Content = $Content -replace 'Azure Image Builder Service Image Creation Role', $imageRoleDefName $Content | Out-File -FilePath $myRoleImageCreationPath -Force # Create the Role Definition New-AzRoleDefinition -InputFile $myRoleImageCreationPath Start-Sleep -s 60 # Grant the Role Definition to the Image Builder Service Principle $RoleAssignParams = @{ ObjectId = $identityNamePrincipalId RoleDefinitionName = $imageRoleDefName Scope = "/subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup" } New-AzRoleAssignment @RoleAssignParams # Verify Role Assignment Get-AzRoleAssignment -ObjectId $identityNamePrincipalId | Select-Object DisplayName,RoleDefinitionName ########################################################## # create gallery New-AzGallery -GalleryName $sigGalleryName -ResourceGroupName $imageResourceGroup -Location $location # create gallery definition New-AzGalleryImageDefinition -GalleryName $sigGalleryName -ResourceGroupName $imageResourceGroup -Location $location -Name $imageDefName -OsState generalized -OsType Windows -Publisher 'IRISone' -Offer 'Windows' -Sku '10avd' ########################################################## #Download template and configure $templateUrl="https://www.knowledgebase.it/aib/avdimage/avdimage04.json" $templateFilePath = "armTemplateWVD.json" Invoke-WebRequest -Uri $templateUrl -OutFile $templateFilePath -UseBasicParsing ((Get-Content -path $templateFilePath -Raw) -replace '<subscriptionID>',$subscriptionID) | Set-Content -Path $templateFilePath ((Get-Content -path $templateFilePath -Raw) -replace '<rgName>',$imageResourceGroup) | Set-Content -Path $templateFilePath ((Get-Content -path $templateFilePath -Raw) -replace '<region>',$location) | Set-Content -Path $templateFilePath ((Get-Content -path $templateFilePath -Raw) -replace '<runOutputName>',$runOutputName) | Set-Content -Path $templateFilePath ((Get-Content -path $templateFilePath -Raw) -replace '<imageDefName>',$imageDefName) | Set-Content -Path $templateFilePath ((Get-Content -path $templateFilePath -Raw) -replace '<sharedImageGalName>',$sigGalleryName) | Set-Content -Path $templateFilePath ((Get-Content -path $templateFilePath -Raw) -replace '<imgBuilderId>',$idenityNameResourceId) | Set-Content -Path $templateFilePath ########################################################## #Check if image template already exists and remove if needed $resourcetowatch = Get-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -ImageTemplateName $ImageTemplateName -ErrorAction SilentlyContinue If ($null -ne $resourcetowatch) { Write-Host "Template found, removing ..." Remove-AzImageBuilderTemplate -ImageTemplateName $ImageTemplateName -ResourceGroupName $imageResourceGroup } #Deploy the AIB image template New-AzResourceGroupDeployment -ResourceGroupName $imageResourceGroup -TemplateFile $templateFilePath -api-version "2019-05-01-preview" -imageTemplateName $imageTemplateName -svclocation $location #Invoke the AIB Build Invoke-AzResourceAction -ResourceName $imageTemplateName -ResourceGroupName $imageResourceGroup -ResourceType Microsoft.VirtualMachineImages/imageTemplates -ApiVersion "2020-02-14" -Action Run -Force #Get Status of the Image Build and Query $resourcetowatch = Get-AzResource -ResourceGroupName $imageResourceGroup -ResourceType Microsoft.VirtualMachineImages/imageTemplates -Name $imageTemplateName do { $status = (Get-AzResource -ResourceGroupName $imageResourceGroup -ResourceType Microsoft.VirtualMachineImages/imageTemplates -Name $imageTemplateName).Properties.lastRunStatus $status | Format-Table * Start-Sleep -Seconds 30 } while ($status.runState -eq "Running") #Remove the Image Template Remove-AzImageBuilderTemplate -ResourceGroupName $imageResourceGroup -Name $imageTemplateName #Delete the role assignment Remove-AzRoleAssignment -ObjectId $idenityNamePrincipalId -RoleDefinitionName $imageRoleDefName -Scope "/subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup" ## remove definitions Remove-AzRoleDefinition -Name $idenityNamePrincipalId -Force -Scope "/subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup" ## delete identity Remove-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName -Force