## Chawn Limited - WVDHostBuilder V1.1 ## v1.1 - Added MOM - Logging & Analytics agent install option ## February 2021 - Deploy Windows 10 Enterpise VMs for Windows Virtual Desktops - Ephemeral Disks ## No Liability Accepted - Use at your own risk ## Specify required parameters below ## Specify VMName parameter on the command line ## Connect-AzAccount ## .\CreateWVDvm.ps1 "NPWVD001" ## This will create a single VM ######################################## ## To create multiple VMs in the same resource group, location, virtual network, subnet, domain, ou and WVD host pool ## Define all paremeters below except for the VM name, then run ## Connect-AzAccount ## $NPWVD001=Start-Job -Name "NPWVD001" -FilePath .\createWVDvm.ps1 -ArgumentList "NPWVD001" ## $NPWVD002=Start-Job -Name "NPWVD002" -FilePath .\createWVDvm.ps1 -ArgumentList "NPWVD002" ## $NPWVD003=Start-Job -Name "NPWVD003" -FilePath .\createWVDvm.ps1 -ArgumentList "NPWVD003" ## You can get feedback at any time by typing ## $NPWVD001 ## You can get detailed feedback at any time by typing ## receive-job -Job $NPWVD001 -keep #### Parameters param( [String]$VMName= "VMName", # Set the New VM Name [String]$ResourceGroup= "Virtual_Machine_Resource_Group", # Set the Target Resource Group for the VM - Get-AzResourceGroup | select ResourceGroupName [String]$location= "westeurope", # Set the Target Azure Location for the VM -- Get-AzLocation | select Location [String]$vmSize= "Standard_DS3_v2", # Set the VM Size -- Get-AzVMSize -Location $Location | select Name [String]$AVSet= "N", # Set the ARM (not Classic) Availability set name - Type "N" if no AVset is used -- Get-AzAvailabilitySet | select name [String]$networkName= "Virtual_Network_Name", # Set the Virtual Network Name [String]$subnetName= "Virtual_Subnet", # Set the Virtual Subnet Name [String]$CustomImage= "N", # Use a custom image Y or use an Azure Gallery Image N [String]$CustomSourceImage= "W10Multi2004_Feb142021", # If using a custom image, specify the name of the image object [String]$publisherName= "microsoftwindowsdesktop", # If using a Gallery Image, specify the Publisher [String]$offer= "office-365", # If using a Gallery Image, specify the Offer [String]$skus= "20h1-evd-o365pp", # If using a Gallery Image, specify the SKUS [String]$LicType= "Windows_Client", # Set the License Type - W10=Windows_Client Server=Windows_Server [String]$LocalAdmin= "LocAdmin", # Set the name of the local administrator account [String]$LocalPW= "Complex_P@55w0rd!!!", # Set the password for the local administrator account [String]$JoinDomain= "Y", # Join a domain Y or N [String]$ADDomain= "domain.local", # Set the domain name in FQDN format [String]$OU= "ou=WVD,ou=Services,dc=domain,dc=local", # Set the Organisational Unit for the VM [String]$ADAdmin= "adminuser@domain.local", # Set the domain join user account [String]$ADAdminPW= "Complex_P@55w0rd!!!", # Set the domain join user account password [String]$JoinHostPool= "Y", # Join a WVD HostPool - HostPool must have been precreated [String]$HostPool= "Host_Pool_Name", # Set the WVD HostPool name [String]$HostPoolResourceGroup= "Host_Pool_Resource_Group", # Set the WVD HostPool Resource Group name [String]$InstallFSLogix= "Y", # Install FSLogix Y or N [String]$InstallTeams= "N", # Install Microsoft Teams Y or N [String]$InstallLA= "N", # Install Log Analytics Y or N [String]$LAWSID= '"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"', # Specify the Log analytics Workspace ID [String]$LAWSKEY= '"QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ=="' # Specify the Log analytics Workspace Key ) #### End of Parameters $d1=get-Date write-host `n"Start Time:" `t`t$d1 write-host `n"Virtual Machine:" `t`t$VMName write-host "VM Resource Group:" `t`t$ResourceGroup write-host "Azure Location:" `t`t$location write-host "VM Size:" `t`t`t$vmSize write-host "Availability Set:" `t`t$AVSet write-host "Virtual Network:" `t`t$networkName write-host "Virtual Subnet:" `t`t$subnetName if ($CustomImage -eq "Y") {write-host "Use Custom Image:" `t`t$CustomImage write-host "Custom Image Name:" `t`t$CustomSourceImage} if ($CustomImage -eq "N") {write-host "Publisher:" `t`t`t$publisherName write-host "Offer:" `t`t`t`t$offer write-host "SKUs:" `t`t`t`t$skus} write-host "License:" `t`t`t$LicType write-host "Local Admin:" `t`t`t$LocalAdmin write-host "Local Password:"`t`t"********" if ($JoinDomain -eq "Y") {write-host "Join Domain:" `t`t`t$JoinDomain write-host "AD Domain:" `t`t`t$ADDomain write-host "Organisational Unit:" `t`t$OU write-host "AD Domain account:" `t`t$ADAdmin write-host "AD Admin Password:"`t`t"********"} if ($JoinHostPool -eq "Y") {write-host "Join WVD Host Pool:" `t`t$JoinHostPool write-host "Host Pool Name:" `t`t$HostPool write-host "Host Pool Resource Group:" `t$HostPoolResourceGroup} write-host "Install FSLogix:" `t`t$InstallFSLogix write-host "Install Teams:" `t`t`t$InstallTeams write-host "Install Logging & Analytics:" `t$InstallLA `n $LAWSID `n $LAWSKEY write-host ### Pre-Reqs %{ if (get-module -listavailable -Name Az.Compute) {write-host -ForegroundColor Green `n"Az Powershell module available"} Else {write-host -ForegroundColor Red `n"Az.Compute Powershell module NOT available - Exit" write-host -ForegroundColor Yellow `n"Please install Azure Powershell: https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-5.5.0" break} } ### End of Pre-Reqs $d1=get-Date ### Login to Azure %{ $AccessToken=Get-AzAccessToken -ErrorAction SilentlyContinue if ($AccessToken.ExpiresOn -lt $d1) {Connect-AzAccount -ErrorAction SilentlyContinue} $AccessToken=Get-AzAccessToken -ErrorAction SilentlyContinue if (-not ($AccessToken)) {Write-Host -ForegroundColor Red `n"Not logged into Azure. Exit" break} } $subscription=Get-AzSubscription Select-AzSubscription -SubscriptionId $subscription.Id ### Create the Local admin PSCredential $LocalCred = New-Object pscredential -ArgumentList ([pscustomobject]@{ UserName = $LocalAdmin Password = (ConvertTo-SecureString -String $LocalPW -AsPlainText -Force)[0]}) #### Validation Checks ############################ ### Check VM does not exist already %{ If (Get-AzVM -Name $VMName -ErrorAction SilentlyContinue) {Write-Host -ForegroundColor Red `n"VM: " $VMName " already exists. Exit" break} Else {Write-Host -ForegroundColor Green `n"VM: " $VMName " does not exist - will create."} } ### Check VM Resource Group does exist %{ If (Get-AzResourceGroup -Name $ResourceGroup -ErrorAction SilentlyContinue) {Write-Host -ForegroundColor Green `n"Resource Group: " $ResourceGroup " exists."} Else {Write-Host -ForegroundColor Red `n"Resource Group: " $ResourceGroup " does not exist. Please create the Resource Group. Exit." break} } ### Check Location is valid %{ $valid=0 $Locations=Get-AzLocation | select Location if ($Locations.location.Contains($Location.tolower())) {write-host -ForegroundColor Green `n"Location: " $Location " is valid."} Else {Write-Host -ForegroundColor Red `n`n"Location: " $Location " is NOT valid. Exit" break} } ### Check VMSize is valid %{ $valid=0 $VMSizes=Get-AzVMSize -Location $Location | select Name if ($vmSizes.name.tolower().Contains($vmSize.tolower())) {write-host -ForegroundColor Green `n"VMSize: " $VMSize " is valid."} Else {Write-Host -ForegroundColor Red `n"VMSize: " $VMSize " is NOT valid. Exit" break} } ### Check AVSet is valid, if not, set to "N" if (-not($AVSet -eq "N")) { if (Get-AzAvailabilitySet -Name $AVSet) {write-host -ForegroundColor Green `n"Availability Set: " $AVSet " is valid."} Else {Write-Host -ForegroundColor Red `n"Availability Set: " $AVSet " is NOT valid. Will not set an availability set." $AVSet="N"} } ### Check Source Image or Disk is valid %{ if ($CustomImage -eq "Y") { if ($CustomSourceImageUri=(get-AzImage -name $CustomSourceImage).id) {write-host -ForegroundColor Green `n"SourceImage: " $CustomSourceImage " is valid."} Else {Write-Host -ForegroundColor Red `n"SourceImage: " $CustomSourceImage " is NOT valid." break} if ((get-AzImage -name $CustomSourceImage).location -ne $Location) {write-host -ForegroundColor Red `n"SourceImage: " $CustomSourceImage " is not located in" $Location " Exit" break} Else {Write-Host -ForegroundColor Green `n"SourceImage: " $CustomSourceImage " is located in." $Location} } else {write-host -ForegroundColor Green `n"Will use Azure Gallery Image." $validimage=get-azvmimagesku -Location $location -PublisherName $publisherName -Offer $offer if ($validimage.skus.Contains($skus)) {write-host `n"Valid Gallery Image selected: " $PublisherName $Offer $skus} else {write-host `n"Invalid Gallery Image selected: " $PublisherName $Offer $skus break} } } ### Check VNet is valid %{ if (Get-AzVirtualNetwork -Name $networkName -ErrorAction SilentlyContinue) {write-host -ForegroundColor Green `n"Virtual Network: " $networkName " is valid."} Else {Write-Host -ForegroundColor Red `n"Virtual Network: " $networkName " is NOT valid." break} } ### Check SubnetName is valid and get the Subnet ID %{ $subnetId=0 $subnets=Get-AzVirtualNetwork -Name $networkName | select Subnets foreach ($subnet in $subnets.Subnets) {if ($subnet.Name -eq $subnetName) {write-host write-host -ForegroundColor Green $subnet.Name " is valid" $subnetid=$subnet.Id write-host -ForegroundColor Green $subnetId " is valid"} } if ($SubnetId -eq 0) {write-host -ForegroundColor Red `n"Subnet name: " $subnetName " does NOT appear to be valid." break} } ### Check WVD HostPool is valid if ($JoinHostPool -eq "Y") { if (Get-AzWvdHostPool -Name $HostPool -ResourceGroupName $HostPoolResourceGroup -ErrorAction SilentlyContinue) {write-host -ForegroundColor Green `n"WVD HostPool: " $HostPool " is valid."} Else {Write-Host -ForegroundColor Red `n"WVD HostPool: " $HostPool " is NOT valid." break} If (Get-AzResourceGroup -Name $HostPoolResourceGroup -ErrorAction SilentlyContinue) {Write-Host -ForegroundColor Green `n"HostPool Resource Group: " $HostPoolResourceGroup " exists."} Else {Write-Host -ForegroundColor Red `n"Resource Group: " $HostPoolResourceGroup " does not exist. Please create the Resource Group. Exit." break} $now=(get-date).addhours(2) if ($now -gt (Get-AzWvdRegistrationInfo -ResourceGroupName $HostPoolResourceGroup -HostPoolName $HostPool).ExpirationTime) {write-Host `n"Generate new WVD Token to join WVD Hostpool:" $HostPool $WVDToken=(New-AzWvdRegistrationInfo -ResourceGroupName $HostPoolResourceGroup -HostPoolName $HostPool -ExpirationTime $((get-date).ToUniversalTime().AddHours(12).ToString('yyyy-MM-ddTHH:mm:ss.fffffffZ'))).Token} Else {write-Host -ForegroundColor Green `n"WVDToken exists for Hostpool:" $HostPool $WVDToken=(Get-AzWvdRegistrationInfo -ResourceGroupName $HostPoolResourceGroup -HostPoolName $HostPool).Token} } Write-Host -ForegroundColor Green `n"Validation Checks complete - Create VM" #### END OF VALIDATION CHECK ############################ #### CREATE THE VM ############################ Function deleteNIC { try {$nic | remove-AzNetworkInterface -force -ErrorAction SilentlyContinue write-host -ForegroundColor Green `n"Deleted Virtual Machine NIC: " $nic.id} catch {write-host -ForegroundColor Red `n"Error encountered deleting Virtual Machine NIC: " $nic.id + $_} } # Create the VM NIC $nicName = "NIC-"+$VMName try{$NIC = New-AzNetworkInterface -Name $nicName -ResourceGroupName $ResourceGroup -Location $location -SubnetId $subnetid -Force Write-Host -ForegroundColor Green `n"NIC created"} catch{Write-Host -ForegroundColor Red `n"Could not create the NIC - Check your permissions to the VM Resource Group and the Virtual Network" + $_ break} #Define the parameters for the new virtual machine. if ($AVSet -eq "N") { $VirtualMachine = New-AzVMConfig -VMName $VMName -VMSize $VMSize -LicenseType $LicType } if ($AVSet -ne "N") {$AVsetID=Get-AzAvailabilitySet -Name $AVSet write-host -ForegroundColor Green `n"Add " $VMName " to Availability set" $AVSet try {$VirtualMachine = New-AzVMConfig -VMName $VMName -VMSize $VMSize -LicenseType $LicType -AvailabilitySetId $AVSetID.id} catch {write-host -ForegroundColor red "Could not add `n" $VMName " to Availability set. Check Availability Set is ARM and not Classic" deleteNIC break} } $VirtualMachine = Set-AzVMOperatingSystem -VM $VirtualMachine -Windows -ComputerName $VMName -Credential $LocalCred -ProvisionVMAgent -PatchMode Manual $VirtualMachine = Add-AzVMNetworkInterface -VM $VirtualMachine -Id $NIC.Id # Set Source Image Image Custom or Gallery if ($CustomImage -eq "Y") {$VirtualMachine = Set-AzVMSourceImage -VM $VirtualMachine -Id $CustomSourceImageUri} Else {$VirtualMachine = Set-AzVMSourceImage -VM $VirtualMachine -PublisherName $publisherName -Offer $offer -Skus $skus -Version "latest"} $VirtualMachine = Set-AzVMOSDisk -VM $VirtualMachine -CreateOption FromImage -DiffDiskSetting Local -Caching ReadOnly -Windows $VirtualMachine = Set-AzVMBootDiagnostic -VM $VirtualMachine -Disable # Create VM write-host `n"Create Virtual Machine: " $VMName try{New-AzVM -ResourceGroupName $ResourceGroup -Location $location -VM $VirtualMachine -ErrorAction SilentlyContinue -Verbose write-host -ForegroundColor Green `n"Created Virtual Machine: " $VMName} catch{write-host -ForegroundColor Red `n"Could not create Virtual Machine: " $VMName + $_ deleteNIC break} #### END OF CREATE THE VM ############################ $d2=get-Date $dur=$d2-$d1 write-Host `n"Duration:"`t`t $dur.Hours "hours" $dur.Minutes "mins" $dur.Seconds "secs"`n ##### ------------------------------- Join Active Directory Domain # NETSETUP_JOIN_DOMAIN = 0x00000001 NETSETUP_ACCT_CREATE = 0x00000002 NETSETUP_DOMAIN_JOIN_IF_JOINED = = 0x00000020 # https://docs.microsoft.com/en-us/windows/win32/api/lmjoin/nf-lmjoin-netjoindomain if ($JoinDomain -eq "Y") {write-host `n"Join AD Domain: " $ADDomain `n $ADDomainCred = New-Object pscredential -ArgumentList ([pscustomobject]@{ UserName = $ADAdmin Password = (ConvertTo-SecureString -String $ADAdminPW -AsPlainText -Force)[0]}) try {$VirtualMachine=Set-AzVMADDomainExtension -VMName $VMname -ResourceGroupName $ResourceGroup -DomainName $ADDomain -OUPath $OU -JoinOption 0x00000023 -Credential $ADDomainCred -Restart -ErrorAction stop write-host -ForegroundColor Green `n"Joined Active Directory Domain: " $ADDomain `n} catch {write-host -ForegroundColor Red `n"Could not join Active Directory Domain: " $ADDomain + $_ break} } # You can't join WVD HostPool if not a domain member and internet installs will like fail due to lack of DNS Else {$JoinHostPool="N" $InstallFSLogix="N" $InstallTeams="N" } $d2=get-Date $dur=$d2-$d1 write-Host `n"Duration:"`t`t $dur.Hours "hours" $dur.Minutes "mins" $dur.Seconds "secs"`n ##### ------------------------------- Install WVD Agents if ($JoinHostPool -eq "Y") { if ($WVDToken) { write-Host `n"WVD Token to join WVD Hostpool: " $HostPool `n$WVDToken ### Install RDAgent write-host `n"Install Remote Desktop Services Infrastructure Agent" `n $URI="https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RWrmXv" $Settings = @{"commandToExecute" = "powershell.exe -ExecutionPolicy Unrestricted -Command new-item -Path c:\temp -ItemType Directory -ErrorAction SilentlyContinue;Invoke-WebRequest -Uri $URI -OutFile c:\temp\RDAgent.msi;Start-Process msiexec.exe -Wait -ArgumentList '/I c:\temp\RDAgent.msi REGISTRATIONTOKEN=$WVDToken /qb'"} Set-AzVMExtension -Location $Location -ResourceGroupName $ResourceGroup -VMName $VMname -Name DeploySW -Publisher "Microsoft.Compute" -ExtensionType "CustomScriptExtension" -TypeHandlerVersion "1.0" -Settings $Settings ### Install RDBroker write-host `n"Install Remote Desktop Agent Boot Loader" `n $URI="https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RWrxrH" $Settings = @{"commandToExecute" = "powershell.exe -ExecutionPolicy Unrestricted -Command new-item -Path c:\temp -ItemType Directory -ErrorAction SilentlyContinue;Invoke-WebRequest -Uri $URI -OutFile c:\temp\RDBoot.msi;Start-Process msiexec.exe -Wait -ArgumentList '/I c:\temp\RDBoot.msi /qb'"} Set-AzVMExtension -Location $Location -ResourceGroupName $ResourceGroup -VMName $VMname -Name DeploySW -Publisher "Microsoft.Compute" -ExtensionType "CustomScriptExtension" -TypeHandlerVersion "1.0" -Settings $Settings # - Put the new WVD Member in DrainMode to stop new connections write-host `n"Place Session Host into Drain Mode to prevent connections" `n $HPName=$VMname + "." + $ADDomain Update-AzWvdSessionHost -HostPoolName $HostPool -ResourceGroupName $HostPoolResourceGroup -Name $HPName -AllowNewSession:$false } Else {write-Host -Foreground Red `n "Could not retrieve a WVD Host Token for HostPool: " $HostPool "Skip join WVD Hostpool"} } ##### ------------------------------- End of WVD Agents $d2=get-Date $dur=$d2-$d1 write-Host `n"Duration:"`t`t $dur.Hours "hours" $dur.Minutes "mins" $dur.Seconds "secs" `n ####### Install FSLogix If ($InstallFSLogix -eq "Y") {write-host `n"Installing Microsoft FSLogix" `n $URI="https://aka.ms/fslogix_download" $Settings = @{"commandToExecute" = "powershell.exe -ExecutionPolicy Unrestricted -Command new-item -Path c:\temp -ItemType Directory -ErrorAction SilentlyContinue;Invoke-WebRequest -Uri $URI -OutFile c:\temp\FSlogix.zip;Expand-Archive -Path C:\temp\FSlogix.zip -DestinationPath C:\temp\FSlogix;Start-Process C:\temp\FSlogix\x64\Release\FSLogixAppsSetup.exe -Wait -ArgumentList '/install /quiet /norestart'"} Set-AzVMExtension -Location $Location -ResourceGroupName $ResourceGroup -VMName $VMname -Name DeploySW -Publisher "Microsoft.Compute" -ExtensionType "CustomScriptExtension" -TypeHandlerVersion "1.0" -Settings $Settings } ####### Install Teams If ($InstallTeams -eq "Y") { write-host `n"Installing Microsoft Teams" `n ### Teams per machine ## OLD$URI="https://teams.microsoft.com/downloads/desktopurl?env=production&plat=windows&arch=x64&managedInstaller=true&download=true" ## WHY PUT "&" in a URL???? $URI="https://teams.microsoft.com/downloads/" $URI2="desktopurl?env=production&plat=windows&arch=x64&managedInstaller=true&download=true" Add-Type -AssemblyName System.Web $URI2=[system.web.httputility]::UrlEncode($URI2) $URI=$URI + $URI2 write-host `n"Installing Teams per machine" `n $Settings = @{"commandToExecute" = "powershell.exe -ExecutionPolicy Unrestricted -Command new-item -Path c:\temp -ItemType Directory -ErrorAction SilentlyContinue;New-Item -Path HKLM:SOFTWARE\Microsoft\Teams -Force -ErrorAction SilentlyContinue;New-ItemProperty -Path HKLM:SOFTWARE\Microsoft\Teams -PropertyType DWORD -Name IsWVDEnvironment -Value 1 -Force -ErrorAction SilentlyContinue;(Invoke-WebRequest -Uri $URI -OutFile c:\temp\Teams.msi);Start-Process msiexec.exe -Wait -ArgumentList '/I c:\temp\Teams.msi ALLUSER=1 /qb'"} Set-AzVMExtension -Location $Location -ResourceGroupName $ResourceGroup -VMName $VMname -Name DeploySW -Publisher "Microsoft.Compute" -ExtensionType "CustomScriptExtension" -TypeHandlerVersion "1.0" -Settings $Settings ### Remote Desktop WebRTC Redirector Service $URI="https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE4AQBt" write-host `n"Installing Teams Remote Desktop WebRTC Redirector Service" `n $Settings = @{"commandToExecute" = "powershell.exe -ExecutionPolicy Unrestricted -Command new-item -Path c:\temp -ItemType Directory -ErrorAction SilentlyContinue;Invoke-WebRequest -Uri $URI -OutFile c:\temp\TeamsRDR.msi;Start-Process msiexec.exe -Wait -ArgumentList '/I c:\temp\TeamsRDR.msi /qb'"} Set-AzVMExtension -Location $Location -ResourceGroupName $ResourceGroup -VMName $VMname -Name DeploySW -Publisher "Microsoft.Compute" -ExtensionType "CustomScriptExtension" -TypeHandlerVersion "1.0" -Settings $Settings } ####### Log Analytics Agent If ($InstallLA -eq "Y") { write-host `n"Installing Log Analytics Agent" `n $URI="https://go.microsoft.com/fwlink/?LinkId=828603" $Settings = @{"commandToExecute" = "powershell.exe -ExecutionPolicy Unrestricted -Command new-item -Path c:\temp -ItemType Directory -ErrorAction SilentlyContinue;New-Item -Path 'HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2' -Force -ErrorAction SilentlyContinue;New-Item -Path 'HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -Force -ErrorAction SilentlyContinue;New-ItemProperty -Path 'HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -PropertyType DWORD -Name Enabled -Value 1 -Force -ErrorAction SilentlyContinue;New-ItemProperty -Path 'HKLM:SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client' -PropertyType DWORD -Name DisabledByDefault -Value 0 -Force -ErrorAction SilentlyContinue;New-ItemProperty -Path HKLM:SOFTWARE\Microsoft\.NETFramework\v4.0.30319 -PropertyType DWORD -Name SchUseStrongCrypto -Value 1 -Force -ErrorAction SilentlyContinue;New-ItemProperty -Path HKLM:SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319 -PropertyType DWORD -Name SchUseStrongCrypto -Value 1 -Force -ErrorAction SilentlyContinue;(Invoke-WebRequest -Uri $URI -OutFile c:\temp\MMASetup.exe);Start-Process c:\temp\MMASetup.exe -Wait -ArgumentList '/c /t:C:\temp\mma';Start-Process c:\temp\MMA\Setup.exe -Wait -ArgumentList '/qn AcceptEndUserLicenseAgreement=1 NOAPM=1 ADD_OPINSIGHTS_WORKSPACE=1 OPINSIGHTS_WORKSPACE_AZURE_CLOUD_TYPE=0 OPINSIGHTS_WORKSPACE_ID=$LAWSID OPINSIGHTS_WORKSPACE_KEY=$LAWSKEY'"} Set-AzVMExtension -Location $Location -ResourceGroupName $ResourceGroup -VMName $VMname -Name DeploySW -Publisher "Microsoft.Compute" -ExtensionType "CustomScriptExtension" -TypeHandlerVersion "1.0" -Settings $Settings } ####### Restart VM - Need FSLogix GPO to apply write-Host `n"Restart VM: " $vmname " to apply any group Policies" `n get-azvm -Name $VMname | Restart-AzVM # Turn Off Drain Mode write-Host `n"Turn off Drain Mode on " $vmname " to enable connections" `n if ($JoinHostPool -eq "Y") { $HPName=$VMname + "." + $ADDomain Update-AzWvdSessionHost -HostPoolName $HostPool -ResourceGroupName $HostPoolResourceGroup -Name $HPName -AllowNewSession:$true} ############ FINISHED write-Host `n`n`n`n"********************** Deployment Completed *************************" # Get End Time $d2=get-Date $dur=$d2-$d1 %{ $newvm=get-azvm -Name $VMname write-host `n"VMName:"`t`t`t $newvm.Name $nic=$newvm.NetworkProfile.NetworkInterfaces.id $nic=Get-AzNetworkInterface -ResourceId $nic write-host "IP Address:"`t`t $nic.IpConfigurations.privateIPAddress write-host "Admin User:"`t`t $newvm.OSProfile.AdminUsername write-host "VM Size:"`t`t $newvm.HardwareProfile.VmSize write-host "Update Enabled:"`t $newvm.OSProfile.WindowsConfiguration.EnableAutomaticUpdates write-host "Publisher:"`t`t $newvm.StorageProfile.ImageReference.Publisher write-host "Offer:"`t`t`t $newvm.StorageProfile.ImageReference.Offer write-host "SKU:"`t`t`t $newvm.StorageProfile.ImageReference.SKU write-host "Version:"`t`t $newvm.StorageProfile.ImageReference.ExactVersion write-host "State:"`t`t`t $newvm.ProvisioningState write-host "Status:"`t`t $newvm.statuscode write-Host "Duration:"`t`t $dur.Hours "hours" $dur.Minutes "mins" $dur.Seconds "secs" }