# This powershell script is part of WVDAdmin and Project Hydra - see https://blog.itprocloud.de/Windows-Virtual-Desktop-Admin/ for more information # Current Version of this script: 4.7 param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [ValidateSet('Generalize','JoinDomain','DataPartition','RDAgentBootloader','RestartBootloader','StartBootloader','CleanFirstStart', 'RenameComputer')] [string] $Mode, [string] $StrongGeneralize='0', [string] $ComputerNewname='', #Only for SecureBoot process (workaround, normaly not used) [string] $LocalAdminName='localAdmin', #Only for SecureBoot process (workaround, normaly not used) [string] $LocalAdminPassword='', [string] $DomainJoinUserName='', [string] $DomainJoinUserPassword='', [string] $LocalAdminName64='bG9jYWxBZG1pbg==', #Base64-coding is used if not empty - providing the older parameters to be compatible [string] $LocalAdminPassword64='', [string] $DomainJoinUserName64='', [string] $DomainJoinUserPassword64='', [string] $DomainJoinOU='', [string] $AadOnly='0', [string] $JoinMem='0', [string] $MovePagefileToC='0', [string] $DomainFqdn='', [string] $WvdRegistrationKey='', [string] $LogDir="$env:windir\system32\logfiles", [string] $HydraAgentUri='', #Only used by Hydra [string] $HydraAgentSecret='', #Only used by Hydra [string] $DownloadNewestAgent='0' #Download the newes agent, event if a local agent exist ) function LogWriter($message) { $message="$(Get-Date ([datetime]::UtcNow) -Format "o") $message" write-host($message) if ([System.IO.Directory]::Exists($LogDir)) {try {write-output($message) | Out-File $LogFile -Append} catch {}} } function ShowDrives() { $drives = Get-WmiObject -Class win32_volume -Filter "DriveType = 3" LogWriter("Drives:") foreach ($drive in $drives) { LogWriter("Name: '$($drive.Name)', Letter: '$($drive.DriveLetter)', Label: '$($drive.Label)'") } } function ShowPageFiles() { $pageFiles = Get-WmiObject -Class Win32_PageFileSetting LogWriter("Pagefiles:") foreach ($pageFile in $pageFiles) { LogWriter("Name: '$($pageFile.Name)', Maximum size: '$($pageFile.MaximumSize)'") } } function RedirectPageFileToC() { $CurrentPageFile = Get-WmiObject -Query 'select * from Win32_PageFileSetting' LogWriter("Pagefile name: '$($CurrentPageFile.Name)', max size: $($CurrentPageFile.MaximumSize)") $CurrentPageFile.delete() LogWriter("Pagefile deleted") $CurrentPageFile = Get-WmiObject -Query 'select * from Win32_PageFileSetting' if ($null -eq $CurrentPageFile) { LogWriter("Pagefile deletion successful") } else { LogWriter("Pagefile deletion failed") } Set-WMIInstance -Class Win32_PageFileSetting -Arguments @{name='c:\pagefile.sys';InitialSize = 0; MaximumSize = 0} $CurrentPageFile = Get-WmiObject -Query 'select * from Win32_PageFileSetting' if ($null -eq $CurrentPageFile) { LogWriter("Pagefile not found") } else { LogWriter("New pagefile name: '$($CurrentPageFile.Name)', max size: $($CurrentPageFile.MaximumSize)") } } function UnzipFile ($zipfile, $outdir) { # Based on https://gist.github.com/nachivpn/3e53dd36120877d70aee Add-Type -AssemblyName System.IO.Compression.FileSystem $files = [System.IO.Compression.ZipFile]::OpenRead($zipfile) foreach ($entry in $files.Entries) { $targetPath = [System.IO.Path]::Combine($outdir, $entry.FullName) $directory = [System.IO.Path]::GetDirectoryName($targetPath) if(!(Test-Path $directory )){ New-Item -ItemType Directory -Path $directory | Out-Null } if(!$targetPath.EndsWith("/")){ [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $targetPath, $true); } } } function DownloadFile ( $url, $outFile) { $i=3 $ok=$false; do { try { LogWriter("Try to download file") Invoke-WebRequest -Uri $url -OutFile $outFile -UseBasicParsing $ok=$true } catch { $i--; if ($i -le 0) { throw } LogWriter("Re-trying download after 10 seconds") Start-Sleep -Seconds 10 } } while (!$ok) } # Define static variables $LocalConfig="C:\ITPC-WVD-PostCustomizing" $unattend="PD94bWwgdmVyc2lvbj0nMS4wJyBlbmNvZGluZz0ndXRmLTgnPz48dW5hdHRlbmQgeG1sbnM9InVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206dW5hdHRlbmQiPjxzZXR0aW5ncyBwYXNzPSJvb2JlU3lzdGVtIj48Y29tcG9uZW50IG5hbWU9Ik1pY3Jvc29mdC1XaW5kb3dzLVNoZWxsLVNldHVwIiBwcm9jZXNzb3JBcmNoaXRlY3R1cmU9ImFtZDY0IiBwdWJsaWNLZXlUb2tlbj0iMzFiZjM4NTZhZDM2NGUzNSIgbGFuZ3VhZ2U9Im5ldXRyYWwiIHZlcnNpb25TY29wZT0ibm9uU3hTIiB4bWxuczp3Y209Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vV01JQ29uZmlnLzIwMDIvU3RhdGUiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiPjxPT0JFPjxTa2lwTWFjaGluZU9PQkU+dHJ1ZTwvU2tpcE1hY2hpbmVPT0JFPjxTa2lwVXNlck9PQkU+dHJ1ZTwvU2tpcFVzZXJPT0JFPjwvT09CRT48L2NvbXBvbmVudD48L3NldHRpbmdzPjwvdW5hdHRlbmQ+" # Define logfile $LogFile=$LogDir+"\AVD.Customizing.log" # Main LogWriter("Starting ITPC-WVD-Image-Processing in mode ${Mode}") # Generating variables from Base64-coding if ($LocalAdminName64) {$LocalAdminName=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($LocalAdminName64))} if ($LocalAdminPassword64) {$LocalAdminPassword=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($LocalAdminPassword64))} if ($DomainJoinUserName64) {$DomainJoinUserName=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($DomainJoinUserName64))} if ($DomainJoinUserPassword64) {$DomainJoinUserPassword=[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($DomainJoinUserPassword64))} # check for the existend of the helper scripts if ((Test-Path ($LocalConfig+"\ITPC-WVD-Image-Processing.ps1")) -eq $false) { # Create local directory for script(s) and copy files (including the RD agent and boot loader - rename it to the specified name) LogWriter("Copy files to local session host or downloading files from Microsoft") new-item $LocalConfig -ItemType Directory -ErrorAction Ignore try {(Get-Item $LocalConfig -ErrorAction Ignore).attributes="Hidden"} catch {} if ((Test-Path ("${PSScriptRoot}\ITPC-WVD-Image-Processing.ps1")) -eq $false) { LogWriter("Creating ITPC-WVD-Image-Processing.ps1") Copy-Item "$($MyInvocation.InvocationName)" -Destination ($LocalConfig+"\ITPC-WVD-Image-Processing.ps1") } else {Copy-Item "${PSScriptRoot}\ITPC-WVD-Image-Processing.ps1" -Destination ($LocalConfig+"\")} } if ($ComputerNewname -eq "" -or $DownloadNewestAgent -eq "1") { if ((Test-Path ($LocalConfig+"\Microsoft.RDInfra.RDAgent.msi")) -eq $false -or $DownloadNewestAgent -eq "1") { if ((Test-Path ($ScriptRoot+"\Microsoft.RDInfra.RDAgent.msi")) -eq $false -or $DownloadNewestAgent -eq "1") { LogWriter("Downloading RDAgent") DownloadFile "https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RWrmXv" ($LocalConfig+"\Microsoft.RDInfra.RDAgent.msi") #Invoke-WebRequest -Uri "https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RWrmXv" -OutFile ($LocalConfig+"\Microsoft.RDInfra.RDAgent.msi") } else {Copy-Item "${PSScriptRoot}\Microsoft.RDInfra.RDAgent.msi" -Destination ($LocalConfig+"\")} } if ((Test-Path ($LocalConfig+"\Microsoft.RDInfra.RDAgentBootLoader.msi")) -eq $false -or $DownloadNewestAgent -eq "1") { if ((Test-Path ($ScriptRoot+"\Microsoft.RDInfra.RDAgentBootLoader.msi ")) -eq $false -or $DownloadNewestAgent -eq "1") { LogWriter("Downloading RDBootloader") DownloadFile "https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RWrxrH" ($LocalConfig+"\Microsoft.RDInfra.RDAgentBootLoader.msi") #Invoke-WebRequest -Uri "https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RWrxrH" -OutFile ($LocalConfig+"\Microsoft.RDInfra.RDAgentBootLoader.msi") } else {Copy-Item "${PSScriptRoot}\Microsoft.RDInfra.RDAgentBootLoader.msi" -Destination ($LocalConfig+"\")} } } # updating local script (from maybe an older version from the last image process) Copy-Item "$($MyInvocation.InvocationName)" -Destination ($LocalConfig+"\ITPC-WVD-Image-Processing.ps1") -Force -ErrorAction SilentlyContinue # check, if secure boot is enabled (used by the snapshot workaround) $isSecureBoot=$false try { $isSecureBoot=Confirm-SecureBootUEFI } catch {} # Start script by mode if ($mode -eq "Generalize") { LogWriter("Removing existing Remote Desktop Agent Boot Loader") Uninstall-Package -Name "Remote Desktop Agent Boot Loader" -AllVersions -Force -ErrorAction SilentlyContinue LogWriter("Removing existing Remote Desktop Services Infrastructure Agent") Uninstall-Package -Name "Remote Desktop Services Infrastructure Agent" -AllVersions -Force -ErrorAction SilentlyContinue Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\RDMonitoringAgent" -Force -ErrorAction Ignore LogWriter("Disabling ITPC-LogAnalyticAgent and MySmartScale if exist") Disable-ScheduledTask -TaskName "ITPC-LogAnalyticAgent for RDS and Citrix" -ErrorAction Ignore Disable-ScheduledTask -TaskName "ITPC-MySmartScaleAgent" -ErrorAction Ignore LogWriter("Cleaning up reliability messages") $key="HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Reliability" Remove-ItemProperty -Path $key -Name "DirtyShutdown" -ErrorAction Ignore Remove-ItemProperty -Path $key -Name "DirtyShutdownTime" -ErrorAction Ignore Remove-ItemProperty -Path $key -Name "LastAliveStamp" -ErrorAction Ignore Remove-ItemProperty -Path $key -Name "TimeStampInterval" -ErrorAction Ignore # Triggering dotnet to execute queued items $dotnetRoot="$env:windir\Microsoft.NET\Framework" Get-ChildItem -Path $dotnetRoot -Directory | foreach { if (Test-Path "$($_.FullName)\ngen.exe") { LogWriter("Triggering dotnet to execute queued items in: $($_.FullName)") Start-Process -FilePath "$($_.FullName)\ngen.exe" -Wait -ArgumentList "ExecuteQueuedItems" -ErrorAction SilentlyContinue } } # Read property from registry (force imaging, like dism) $force=$StrongGeneralize -eq "1" if (Test-Path -Path "HKLM:\SOFTWARE\ITProCloud\WVD.Force") { $force=$true } # DISM cleanup if ($force -and (Test-Path "$env:windir\system32\Dism.exe")) { LogWriter("DISM cleanup") Start-Process -FilePath "$env:windir\system32\Dism.exe" -Wait -ArgumentList "/online /cleanup-image /startcomponentcleanup /resetbase" -ErrorAction SilentlyContinue } LogWriter("Modifying sysprep to avoid issues with AppXPackages - Start") $sysPrepActionPath="$env:windir\System32\Sysprep\ActionFiles" $sysPrepActionFile="Generalize.xml" $sysPrepActionPathItem = Get-Item $sysPrepActionPath.Replace("C:\","\\localhost\\c$\") -ErrorAction Ignore $acl = $sysPrepActionPathItem.GetAccessControl() $acl.SetOwner((New-Object System.Security.Principal.NTAccount("SYSTEM"))) $sysPrepActionPathItem.SetAccessControl($acl) $aclSystemFull = New-Object System.Security.AccessControl.FileSystemAccessRule("SYSTEM","FullControl","Allow") $acl.AddAccessRule($aclSystemFull) $sysPrepActionPathItem.SetAccessControl($acl) [xml]$xml = Get-Content -Path "$sysPrepActionPath\$sysPrepActionFile" $xmlNode=$xml.sysprepInformation.imaging | where {$_.sysprepModule.moduleName -match "AppxSysprep.dll"} if ($xmlNode -ne $null) { $xmlNode.ParentNode.RemoveChild($xmlNode) $xml.sysprepInformation.imaging.Count $xml.Save("$sysPrepActionPath\$sysPrepActionFile.new") Remove-Item "$sysPrepActionPath\$sysPrepActionFile.old" -Force -ErrorAction Ignore Move-Item "$sysPrepActionPath\$sysPrepActionFile" "$sysPrepActionPath\$sysPrepActionFile.old" Move-Item "$sysPrepActionPath\$sysPrepActionFile.new" "$sysPrepActionPath\$sysPrepActionFile" LogWriter("Modifying sysprep to avoid issues with AppXPackages - Done") } # Preparation for the snapshot workaround if ($isSecureBoot -and $LocalAdminName -ne "" -and $LocalAdminPassword -ne "") { LogWriter("Creating administrator $LocalAdminName") New-LocalUser "$LocalAdminName" -Password (ConvertTo-SecureString $LocalAdminPassword -AsPlainText -Force) -FullName "$LocalAdminName" -Description "Local Administrator" -ErrorAction SilentlyContinue Add-LocalGroupMember -Group "Administrators" -Member "$LocalAdminName" -ErrorAction SilentlyContinue } LogWriter("Removing an older Sysprep state") Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\Sysprep" -Name "SysprepCorrupt" -ErrorAction Ignore New-ItemProperty -Path "HKLM:\SYSTEM\Setup\Status\SysprepStatus" -Name "State" -Value 2 -force New-ItemProperty -Path "HKLM:\SYSTEM\Setup\Status\SysprepStatus" -Name "GeneralizationState" -Value 7 -force New-Item -Path "HKLM:\Software\Microsoft\DesiredStateConfiguration" -ErrorAction Ignore New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\DesiredStateConfiguration" -Name "AgentId" -Value "" -force -ErrorAction Ignore LogWriter("Saving time zone info for re-deploy") $timeZone=(Get-TimeZone).Id LogWriter("Current time zone is: "+$timeZone) New-Item -Path "HKLM:\SOFTWARE" -Name "ITProCloud" -ErrorAction Ignore New-Item -Path "HKLM:\SOFTWARE\ITProCloud" -Name "WVD.Runtime" -ErrorAction Ignore New-ItemProperty -Path "HKLM:\SOFTWARE\ITProCloud\WVD.Runtime" -Name "TimeZone.Origin" -Value $timeZone -force LogWriter("Removing existing Azure Monitoring Certificates") Get-ChildItem "Cert:\LocalMachine\Microsoft Monitoring Agent" -ErrorAction Ignore | Remove-Item # Check, if the optimization script exist (Hydra: use a script inside Hydra) if ([System.IO.File]::Exists("C:\ProgramData\Optimize\Win10_VirtualDesktop_Optimize.ps1")) { LogWriter("Running VDI Optimization script") Start-Process -wait -FilePath PowerShell.exe -WorkingDirectory "C:\ProgramData\Optimize" -ArgumentList '-ExecutionPolicy Bypass -File "C:\ProgramData\Optimize\Win10_VirtualDesktop_Optimize.ps1 -AcceptEULA -Optimizations WindowsMediaPlayer,AppxPackages,ScheduledTasks,DefaultUserSettings,Autologgers,Services,NetworkOptimizations"' -RedirectStandardOutput "$($LogDir)\VirtualDesktop_Optimize.Stage1.Out.txt" -RedirectStandardError "$($LogDir)\VirtualDesktop_Optimize.Stage1.Warning.txt" } # prepare cleanup task for new deployed VMs - solve an issue with the runcommand api giving older log data LogWriter("Preparing CleanFirstStart task") $action = New-ScheduledTaskAction -Execute "$env:windir\System32\WindowsPowerShell\v1.0\Powershell.exe" -Argument "-executionPolicy Unrestricted -File `"$LocalConfig\ITPC-WVD-Image-Processing.ps1`" -Mode `"CleanFirstStart`"" $trigger = New-ScheduledTaskTrigger -AtStartup $principal = New-ScheduledTaskPrincipal 'NT Authority\SYSTEM' -RunLevel Highest $settingsSet = New-ScheduledTaskSettingsSet $task = New-ScheduledTask -Action $action -Principal $principal -Trigger $trigger -Settings $settingsSet Register-ScheduledTask -TaskName 'ITPC-AVD-CleanFirstStart-Helper' -InputObject $task -ErrorAction Ignore Enable-ScheduledTask -TaskName 'ITPC-AVD-CleanFirstStart-Helper' LogWriter("Added new startup task to run the CleanFirstStart") # check if D:-drive not the temporary storage and having three drives $modifyDrives=$false $disks=Get-WmiObject -Class win32_volume | Where-Object { $_.DriveLetter -ne $null -and $_.DriveType -eq 3 } foreach ($disk in $disks) {if ($disk.Name -ne 'D:\' -and $disk.Label -eq 'Temporary Storage') {$modifyDrives=$true}} if ($disks.Count -eq 3 -and $modifyDrives) { LogWriter("VM with 3 drives so prepare change of drive letters of temp and data after deployment") New-ItemProperty -Path "HKLM:\SOFTWARE\ITProCloud\WVD.Runtime" -Name "ChangeDrives" -Value 1 -force # check if default value 'automatic manage pagefile size for all devices' is activated if ($null -eq (Get-WmiObject Win32_Pagefile) ) { # disable 'automatic manage pagefile size for all devices' $sys = Get-WmiObject Win32_Computersystem -EnableAllPrivileges $sys.AutomaticManagedPagefile = $false $sys.put() LogWriter("Automatic manage pagefile size for all devices deactivated") } else { LogWriter("Automatic manage pagefile size for all devices not activated") } # redirect pagefile to C: to rename data partition after deployment RedirectPageFileToC } LogWriter("Starting sysprep to generalize session host") if ([System.Environment]::OSVersion.Version.Major -le 6) { #Windows 7 LogWriter("Enabling RDP8 on Windows 7") New-Item -Path "HKLM:\SOFTWARE" -Name "Policies" -ErrorAction Ignore New-Item -Path "HKLM:\SOFTWARE\Policies" -Name "Microsoft" -ErrorAction Ignore New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft" -Name "Windows NT" -ErrorAction Ignore New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT" -Name "Terminal Services" -ErrorAction Ignore New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" -Name "fServerEnableRDP8" -Value 1 -force Start-Process -FilePath "$env:windir\System32\Sysprep\sysprep" -ArgumentList "/generalize /oobe /shutdown" } else { if ($isSecureBoot) { LogWriter("Secure boot is enabled") write-output([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($unattend))) | Out-File "$LocalConfig\unattend.xml" -Encoding ASCII write-output([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($unattend))) | Out-File "$env:windir\panther\unattend.xml" -Encoding ASCII Start-Process -FilePath "$env:windir\System32\Sysprep\sysprep" -ArgumentList "/generalize /oobe /shutdown /mode:vm /unattend:$LocalConfig\unattend.xml" } else { Start-Process -FilePath "$env:windir\System32\Sysprep\sysprep" -ArgumentList "/generalize /oobe /shutdown /mode:vm" } } } elseif ($mode -eq "RenameComputer") { # Used for the snapshot workaround LogWriter("Renaming computer to: "+$readComputerNewname) Rename-Computer -NewName $ComputerNewname -Force -ErrorAction SilentlyContinue } elseif ($mode -eq "JoinDomain") { # Removing existing agent if exist LogWriter("Removing existing Remote Desktop Agent Boot Loader") Uninstall-Package -Name "Remote Desktop Agent Boot Loader" -AllVersions -Force -ErrorAction SilentlyContinue LogWriter("Removing existing Remote Desktop Services Infrastructure Agent") Uninstall-Package -Name "Remote Desktop Services Infrastructure Agent" -AllVersions -Force -ErrorAction SilentlyContinue Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\RDMonitoringAgent" -Force -ErrorAction Ignore # Storing AadOnly to registry LogWriter("Storing AadOnly to registry: "+$AadOnly) New-Item -Path "HKLM:\SOFTWARE" -Name "ITProCloud" -ErrorAction Ignore New-Item -Path "HKLM:\SOFTWARE\ITProCloud" -Name "WVD.Runtime" -ErrorAction Ignore New-ItemProperty -Path "HKLM:\SOFTWARE\ITProCloud\WVD.Runtime" -Name "AadOnly" -Value $AadOnly -force # Checking for a saved time zone information if (Test-Path -Path "HKLM:\SOFTWARE\ITProCloud\WVD.Runtime") { $timeZone=(Get-ItemProperty -Path "HKLM:\SOFTWARE\ITProCloud\WVD.Runtime" -ErrorAction Ignore)."TimeZone.Origin" if ($timeZone -ne "" -and $timeZone -ne $null) { LogWriter("Setting time zone to: "+$timeZone) Set-TimeZone -Id $timeZone } } # AD / AAD handling LogWriter("Cleaning up previous AADLoginExtension / AAD join") Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows Azure\CurrentVersion\AADLoginForWindowsExtension" -Force -ErrorAction Ignore if (Test-Path -Path "$($env:WinDir)\system32\Dsregcmd.exe") { Start-Process -wait -FilePath "$($env:WinDir)\system32\Dsregcmd.exe" -ArgumentList "/leave" -ErrorAction SilentlyContinue } if ($DomainJoinUserName -ne "" -and $AadOnly -ne "1") { LogWriter("Joining AD domain") $psc = New-Object System.Management.Automation.PSCredential($DomainJoinUserName, (ConvertTo-SecureString $DomainJoinUserPassword -AsPlainText -Force)) $retry=3 $ok=$false do{ try { if ($DomainJoinOU -eq "") { Add-Computer -DomainName $DomainFqdn -Credential $psc -Force -ErrorAction Stop $ok=$true LogWriter("Domain joined successfully") } else { Add-Computer -DomainName $DomainFqdn -OUPath $DomainJoinOU -Credential $psc -Force -ErrorAction Stop $ok=$true LogWriter("Domain joined successfully") } } catch { if ($retry -eq 0) {throw $_} $retry-- LogWriter("Retry domain join because of an error: $_") Start-Sleep -Seconds 10 } } while($ok -ne $true) } else { LogWriter("AAD only is selected. Skipping joining to a native AD, joining AAD") $aadPath=@(Get-ChildItem -Directory "C:\Packages\Plugins\Microsoft.Azure.ActiveDirectory.AADLoginForWindows")[@(Get-ChildItem -Directory "C:\Packages\Plugins\Microsoft.Azure.ActiveDirectory.AADLoginForWindows").count-1].fullname Start-Process -wait -FilePath "$aadPath\AADLoginForWindowsHandler.exe" -WorkingDirectory $aadPath -ArgumentList 'enable' -RedirectStandardOutput "$($LogDir)\Avd.AadJoin.Out.txt" -RedirectStandardError "$($LogDir)\Avd.AadJoin.Warning.txt" if ($JoinMem -eq "1") { LogWriter("Joining Microsoft Endpoint Manamgement is selected. Try to register to MEM") Start-Process -wait -FilePath "$($env:WinDir)\system32\Dsregcmd.exe" -ArgumentList "/AzureSecureVMJoin /debug /MdmId 0000000a-0000-0000-c000-000000000000" -RedirectStandardOutput "$($LogDir)\Avd.MemJoin.Out.txt" -RedirectStandardError "$($LogDir)\Avd.MemJoin.Warning.txt" } try { if ($AadOnly) { $timeOut=(Get-Date).AddSeconds(5*60) do { LogWriter("Waiting for the domain join") Start-Sleep -Seconds 3#AzureAdJoined : YES } while ((Get-Date) -le $timeOut -and (Select-String -InputObject (&dsregcmd /status) -pattern "AzureAdJoined : YES").length -eq 0) } } catch {} } # check for disk handling $modifyDrives=$false if (Test-Path -Path "HKLM:\SOFTWARE\ITProCloud\WVD.Runtime") { if ((Get-ItemProperty -Path "HKLM:\SOFTWARE\ITProCloud\WVD.Runtime").ChangeDrives -eq 1) { $disks=Get-WmiObject -Class win32_volume | Where-Object { $_.DriveLetter -ne $null -and $_.DriveType -eq 3 } foreach ($disk in $disks) {if ($disk.Name -eq 'D:\' -and $disk.Label -eq 'Temporary Storage') {$modifyDrives=$true}} if ($modifyDrives -and $disks.Count -eq 3) { # change drive letters of temp and data drive for VMs with 3 drives LogWriter("VM with 3 drives so delete old pagefile and install runonce key") # create scheduled task executed at startup for next phase $action = New-ScheduledTaskAction -Execute "$env:windir\System32\WindowsPowerShell\v1.0\Powershell.exe" -Argument "-executionPolicy Unrestricted -File `"$LocalConfig\ITPC-WVD-Image-Processing.ps1`" -Mode `"DataPartition`"" $trigger = New-ScheduledTaskTrigger -AtStartup $principal = New-ScheduledTaskPrincipal 'NT Authority\SYSTEM' -RunLevel Highest $settingsSet = New-ScheduledTaskSettingsSet $task = New-ScheduledTask -Action $action -Principal $principal -Trigger $trigger -Settings $settingsSet Register-ScheduledTask -TaskName 'ITPC-AVD-Disk-Mover-Helper' -InputObject $task -ErrorAction Ignore Enable-ScheduledTask -TaskName 'ITPC-AVD-Disk-Mover-Helper' LogWriter("Added new startup task for the disk handling") # change c:\pagefile.sys to e:\pagefile.sys ShowPageFiles $CurrentPageFile = Get-WmiObject -Query 'select * from Win32_PageFileSetting' if ($null -eq $CurrentPageFile) { LogWriter("No pagefile found") } else { if ($CurrentPageFile.Name.tolower().contains('d:')) { $CurrentPageFile.delete() LogWriter("Old pagefile deleted") Set-WMIInstance -Class Win32_PageFileSetting -Arguments @{name='c:\pagefile.sys';InitialSize = 0; MaximumSize = 0} LogWriter("Set pagefile to c:\pagefile.sys") ShowPageFiles } } ShowPageFiles } } } # check to move pagefile finally to C if ($MovePagefileToC -eq "1") { RedirectPageFileToC } # install Hydra Agent (Hydra only) if ($HydraAgentUri -ne "") { $uri=$HydraAgentUri $secret=$HydraAgentSecret $DownloadAdress="https://$($uri)/Download/HydraAgent" try { if ((Test-Path ("$env:ProgramFiles\ITProCloud.de")) -eq $false) { new-item "$env:ProgramFiles\ITProCloud.de" -ItemType Directory -ErrorAction Ignore } if ((Test-Path ("$env:ProgramFiles\ITProCloud.de\HydraAgent")) -eq $false) { new-item "$env:ProgramFiles\ITProCloud.de\HydraAgent" -ItemType Directory -ErrorAction Ignore } Remove-Item -Path "$env:ProgramFiles\ITProCloud.de\HydraAgent\HydraAgent.zip" -Force -ErrorAction Ignore LogWriter("Downloading HydraAgent.zip from $DownloadAdress") DownloadFile $DownloadAdress "$env:ProgramFiles\ITProCloud.de\HydraAgent\HydraAgent.zip" #Invoke-WebRequest -Uri $DownloadAdress -OutFile "$env:ProgramFiles\ITProCloud.de\HydraAgent\HydraAgent.zip" -UseBasicParsing # Stop a running instance LogWriter("Stop a running instance") Stop-ScheduledTask -TaskName 'ITPC-AVD-Hydra-Helper' -ErrorAction Ignore Stop-Process -Name HydraAgent -Force -ErrorAction Ignore Start-Sleep -Seconds 6 UnzipFile "$env:ProgramFiles\ITProCloud.de\HydraAgent\HydraAgent.zip" "$env:ProgramFiles\ITProCloud.de\HydraAgent" # Configuring the agent LogWriter("Configuring the agent") cd "$env:ProgramFiles\ITProCloud.de\HydraAgent" . "$env:ProgramFiles\ITProCloud.de\HydraAgent\HydraAgent.exe" -i -u "wss://$($uri)/wsx" -s $secret } catch { LogWriter("An error occurred while installing Hydra Agent: $_") } } # install AVD Agent if a registration key given if ($WvdRegistrationKey -ne "") { if ([System.Environment]::OSVersion.Version.Major -gt 6) { LogWriter("Installing AVD agent") Start-Process -wait -FilePath "${LocalConfig}\Microsoft.RDInfra.RDAgent.msi" -ArgumentList "/quiet /qn /norestart /passive RegistrationToken=${WvdRegistrationKey}" if ($false) { LogWriter("Installing AVD boot loader - current path is ${LocalConfig}") Start-Process -wait -FilePath "${LocalConfig}\Microsoft.RDInfra.RDAgentBootLoader.msi" -ArgumentList "/quiet /qn /norestart /passive" LogWriter("Waiting for the service RDAgentBootLoader") $bootloaderServiceName = "RDAgentBootLoader" $retryCount = 0 while ( -not (Get-Service "RDAgentBootLoader" -ErrorAction SilentlyContinue)) { $retry = ($retryCount -lt 6) LogWriter("Service RDAgentBootLoader was not found") if ($retry) { LogWriter("Retrying again in 30 seconds, this will be retry $retryCount") } else { LogWriter("Retry limit exceeded" ) throw "RDAgentBootLoader didn't become available after 6 retries" } $retryCount++ Start-Sleep -Seconds 30 } } else { LogWriter("Preparing AVD boot loader task") $action = New-ScheduledTaskAction -Execute "$env:windir\System32\WindowsPowerShell\v1.0\Powershell.exe" -Argument "-executionPolicy Unrestricted -File `"$LocalConfig\ITPC-WVD-Image-Processing.ps1`" -Mode `"RDAgentBootloader`"" $trigger = New-ScheduledTaskTrigger -AtStartup $principal = New-ScheduledTaskPrincipal 'NT Authority\SYSTEM' -RunLevel Highest $settingsSet = New-ScheduledTaskSettingsSet $task = New-ScheduledTask -Action $action -Principal $principal -Trigger $trigger -Settings $settingsSet Register-ScheduledTask -TaskName 'ITPC-AVD-RDAgentBootloader-Helper' -InputObject $task -ErrorAction Ignore Enable-ScheduledTask -TaskName 'ITPC-AVD-RDAgentBootloader-Helper' LogWriter("Added new startup task to run the RDAgentBootloader") $class = cimclass MSFT_TaskEventTrigger root/Microsoft/Windows/TaskScheduler $triggerM = $class | New-CimInstance -ClientOnly $triggerM.Enabled = $true $triggerM.Subscription='' $actionM = New-ScheduledTaskAction -Execute "$env:windir\System32\WindowsPowerShell\v1.0\Powershell.exe" -Argument "-executionPolicy Unrestricted -File `"$LocalConfig\ITPC-WVD-Image-Processing.ps1`" -Mode `"RestartBootloader`"" $settingsM = New-ScheduledTaskSettingsSet $taskM = New-ScheduledTask -Action $actionM -Principal $principal -Trigger $triggerM -Settings $settingsM -Description "Restarts the bootloader in case of an known issue (timeout, download error) while installing the RDagent" Register-ScheduledTask -TaskName 'ITPC-AVD-RDAgentBootloader-Monitor-1' -InputObject $taskM -ErrorAction Ignore Enable-ScheduledTask -TaskName 'ITPC-AVD-RDAgentBootloader-Monitor-1' -ErrorAction Ignore LogWriter("Added new task to monitor the RDAgentBootloader") } } else { if ((Test-Path "${LocalConfig}\Microsoft.RDInfra.WVDAgent.msi") -eq $false) { LogWriter("Downloading Microsoft.RDInfra.WVDAgent.msi") DownloadFile "https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE3JZCm" "${LocalConfig}\Microsoft.RDInfra.WVDAgent.msi" #Invoke-WebRequest -Uri 'https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE3JZCm' -OutFile "${LocalConfig}\Microsoft.RDInfra.WVDAgent.msi" -UseBasicParsing } if ((Test-Path "${LocalConfig}\Microsoft.RDInfra.WVDAgentManager.msi") -eq $false) { LogWriter("Downloading Microsoft.RDInfra.WVDAgentManager.msi") DownloadFile "https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE3K2e3" "${LocalConfig}\Microsoft.RDInfra.WVDAgentManager.msi" #nvoke-WebRequest -Uri 'https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE3K2e3' -OutFile "${LocalConfig}\Microsoft.RDInfra.WVDAgentManager.msi" -UseBasicParsing } LogWriter("Installing AVDAgent") Start-Process -wait -FilePath "${LocalConfig}\Microsoft.RDInfra.WVDAgent.msi" -ArgumentList "/q RegistrationToken=${WvdRegistrationKey}" LogWriter("Installing AVDAgentManager") Start-Process -wait -FilePath "${LocalConfig}\Microsoft.RDInfra.WVDAgentManager.msi" -ArgumentList '/q' } } LogWriter("Enabling ITPC-LogAnalyticAgent and MySmartScale if exist") Enable-ScheduledTask -TaskName "ITPC-LogAnalyticAgent for RDS and Citrix" -ErrorAction Ignore Enable-ScheduledTask -TaskName "ITPC-MySmartScaleAgent" -ErrorAction Ignore if ([System.IO.File]::Exists("C:\ProgramData\Optimize\Win10_VirtualDesktop_Optimize.ps1")) { LogWriter("Running VDI Optimization script") Start-Process -wait -FilePath PowerShell.exe -WorkingDirectory "C:\ProgramData\Optimize" -ArgumentList '-ExecutionPolicy Bypass -File "C:\ProgramData\Optimize\Win10_VirtualDesktop_Optimize.ps1 -AcceptEULA -Optimizations WindowsMediaPlayer,AppxPackages,ScheduledTasks,DefaultUserSettings,Autologgers,Services,NetworkOptimizations"' -RedirectStandardOutput "$($LogDir)\VirtualDesktop_Optimize.Stage2.Out.txt" -RedirectStandardError "$($LogDir)\VirtualDesktop_Optimize.Stage2.Warning.txt" } # Final reboot LogWriter("Finally restarting session host") Restart-Computer -Force -ErrorAction SilentlyContinue } elseif ($Mode -eq "DataPartition") { if ((Get-WmiObject -Class win32_volume | Where-Object { $_.DriveLetter -ne $null -and $_.DriveType -eq 3 }).Count -eq 3) { # change drive letters of temp and data drive for VMs with 3 drives LogWriter("VM with 3 drives so change drive letters of temp and data") ShowDrives # change c:\pagefile.sys to e:\pagefile.sys ShowPageFiles $CurrentPageFile = Get-WmiObject -Query 'select * from Win32_PageFileSetting' if ($null -eq $CurrentPageFile) { LogWriter("No pagefile found") } else { if ($CurrentPageFile.Name.tolower().contains('c:')) { ShowDrives # change temp drive to Z: $drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'd:'" if ($null -ne $drive) { LogWriter("d: drive: $($drive.Label)") Set-WmiInstance -input $drive -Arguments @{ DriveLetter='z:' } LogWriter("changed drive letter to z:") ShowDrives } else { LogWriter("Drive D: not found") } # change data drive to D: $drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'e:'" if ($null -ne $drive) { LogWriter("e: drive: $($drive.Label)") Set-WmiInstance -input $drive -Arguments @{ DriveLetter='D:' } LogWriter("changed drive letter to D:") ShowDrives } else { LogWriter("Drive E: not found") } # change temp drive back to E: $drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'z:'" if ($null -ne $drive) { LogWriter("z: drive: $($drive.Label)") Set-WmiInstance -input $drive -Arguments @{ DriveLetter='E:' } LogWriter("changed drive letter to E:") ShowDrives } else { LogWriter("Drive Z: not found") } # change c:\pagefile.sys to e:\pagefile.sys ShowPageFiles $CurrentPageFile = Get-WmiObject -Query 'select * from Win32_PageFileSetting' if ($null -eq $CurrentPageFile) { LogWriter("No pagefile found") } else { $CurrentPageFile.delete() LogWriter("Old pagefile deleted") } ShowPageFiles Set-WMIInstance -Class Win32_PageFileSetting -Arguments @{name='e:\pagefile.sys';InitialSize = 0; MaximumSize = 0} LogWriter("set pagefile to e:\pagefile.sys") ShowPageFiles # reboot to activate pagefile LogWriter("Finally restarting session host") Restart-Computer -Force LogWriter("After Finally restarting session host") } } } LogWriter("Disable scheduled task") try { # disable startup scheduled task Disable-ScheduledTask -TaskName 'ITPC-AVD-Disk-Mover-Helper' } catch { LogWriter("Disabling scheduled task failed: " + $_.Exception.Message) } } elseif ($Mode -eq "RDAgentBootloader") { LogWriter("Installing AVD boot loader - current path is ${LocalConfig}") Start-Process -wait -FilePath "${LocalConfig}\Microsoft.RDInfra.RDAgentBootLoader.msi" -ArgumentList "/quiet /qn /norestart /passive" LogWriter("Waiting for the service RDAgentBootLoader") $bootloaderServiceName = "RDAgentBootLoader" $retryCount = 0 while ( -not (Get-Service "RDAgentBootLoader" -ErrorAction SilentlyContinue)) { $retry = ($retryCount -lt 6) LogWriter("Service RDAgentBootLoader was not found") if ($retry) { LogWriter("Retrying again in 30 seconds, this will be retry $retryCount") } else { LogWriter("Retry limit exceeded" ) throw "RDAgentBootLoader didn't become available after 6 retries" } $retryCount++ Start-Sleep -Seconds 30 } LogWriter("Disable scheduled task") try { # disable startup scheduled task Disable-ScheduledTask -TaskName 'ITPC-AVD-RDAgentBootloader-Helper' } catch { LogWriter("Disabling scheduled task failed: " + $_.Exception.Message) } } elseif ($Mode -eq "CleanFirstStart") { LogWriter("Cleaning up Azure Agent logs - current path is ${LocalConfig}") Remove-Item -Path "C:\Packages\Plugins\Microsoft.CPlat.Core.RunCommandWindows\*" -Include *.status -Recurse -Force -ErrorAction SilentlyContinue LogWriter("Disable scheduled task") try { # disable startup scheduled task Disable-ScheduledTask -TaskName 'ITPC-AVD-CleanFirstStart-Helper' } catch { LogWriter("Disabling scheduled task failed: " + $_.Exception.Message) } } elseif ($mode -eq "RestartBootloader") { $LogFile=$LogDir+"\AVD.AgentBootloaderErrorHandling.log" LogWriter "Stopping service" Stop-Service -Name "RDAgentBootLoader" LogWriter "Starting service" Start-Service -Name "RDAgentBootLoader" } elseif ($mode -eq "StartBootloader") { $LogFile=$LogDir+"\AVD.AgentBootloaderErrorHandling.log" LogWriter "Start service was triggered by an event" LogWriter "Waiting for 5 seconds" Start-Sleep -Seconds 5 LogWriter "Starting service" Start-Service -Name "RDAgentBootLoader" LogWriter "Waiting for 60 seconds" Start-Sleep -Seconds 60 LogWriter "Starting service (if not running)" Start-Service -Name "RDAgentBootLoader" LogWriter "Waiting for 60 seconds" Start-Sleep -Seconds 60 LogWriter "Starting service (if not running)" Start-Service -Name "RDAgentBootLoader" } # SIG # Begin signature block # MIIyaQYJKoZIhvcNAQcCoIIyWjCCMlYCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU4qJrUnQJN2ErhFHujsk5VW1I # XQyggiuiMIIETjCCAzagAwIBAgINAe5fFp3/lzUrZGXWajANBgkqhkiG9w0BAQsF # ADBXMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEQMA4G # A1UECxMHUm9vdCBDQTEbMBkGA1UEAxMSR2xvYmFsU2lnbiBSb290IENBMB4XDTE4 # MDkxOTAwMDAwMFoXDTI4MDEyODEyMDAwMFowTDEgMB4GA1UECxMXR2xvYmFsU2ln # biBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds # b2JhbFNpZ24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMJXaQeQZ4 # Ihb1wIO2hMoonv0FdhHFrYhy/EYCQ8eyip0EXyTLLkvhYIJG4VKrDIFHcGzdZNHr # 9SyjD4I9DCuul9e2FIYQebs7E4B3jAjhSdJqYi8fXvqWaN+JJ5U4nwbXPsnLJlkN # c96wyOkmDoMVxu9bi9IEYMpJpij2aTv2y8gokeWdimFXN6x0FNx04Druci8unPvQ # u7/1PQDhBjPogiuuU6Y6FnOM3UEOIDrAtKeh6bJPkC4yYOlXy7kEkmho5TgmYHWy # n3f/kRTvriBJ/K1AFUjRAjFhGV64l++td7dkmnq/X8ET75ti+w1s4FRpFqkD2m7p # g5NxdsZphYIXAgMBAAGjggEiMIIBHjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ # BAUwAwEB/zAdBgNVHQ4EFgQUj/BLf6guRSSuTVD6Y5qL3uLdG7wwHwYDVR0jBBgw # FoAUYHtmGkUNl8qJUC99BM00qP/8/UswPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUF # BzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9yb290cjEwMwYDVR0fBCww # KjAooCagJIYiaHR0cDovL2NybC5nbG9iYWxzaWduLmNvbS9yb290LmNybDBHBgNV # HSAEQDA+MDwGBFUdIAAwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFs # c2lnbi5jb20vcmVwb3NpdG9yeS8wDQYJKoZIhvcNAQELBQADggEBACNw6c/ivvVZ # rpRCb8RDM6rNPzq5ZBfyYgZLSPFAiAYXof6r0V88xjPy847dHx0+zBpgmYILrMf8 # fpqHKqV9D6ZX7qw7aoXW3r1AY/itpsiIsBL89kHfDwmXHjjqU5++BfQ+6tOfUBJ2 # vgmLwgtIfR4uUfaNU9OrH0Abio7tfftPeVZwXwzTjhuzp3ANNyuXlava4BJrHEDO # xcd+7cJiWOx37XMiwor1hkOIreoTbv3Y/kIvuX1erRjvlJDKPSerJpSZdcfL03v3 # ykzTr1EhkluEfSufFT90y1HonoMOFm8b50bOI7355KKL0jlrqnkckSziYSQtjipI # cJDEHsXo4HAwggWNMIIEdaADAgECAhAOmxiO+dAt5+/bUOIIQBhaMA0GCSqGSIb3 # DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3Vy # ZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBaFw0zMTExMDkyMzU5NTlaMGIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBH # NDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8MCIw # aTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauyefLK # EdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu34LzB4Tm # dDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+xembu # d8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhAkHnD # eMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1LyuGwN1 # XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2PVld # QnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37AlLTS # YW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD76GSm # M9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqsX40/ybzT # QRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXAj6Kx # fgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIBNjAPBgNVHRMBAf8EBTADAQH/ # MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwPTzAfBgNVHSMEGDAWgBRF66Kv # 9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMCAYYweQYIKwYBBQUHAQEEbTBr # MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUH # MAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ # RFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNl # cnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDARBgNVHSAECjAIMAYG # BFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0NcVec4X6CjdBs9thbX979XB72a # rKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnovLbc47/T/gLn4offyct4kvFID # yE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65ZyoUi0mcudT6cGAxN3J0TU53/o # Wajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFWjuyk1T3osdz9HNj0d1pcVIxv # 76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPFmCLBsln1VWvPJ6tsds5vIy30 # fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9ztwGpn1eqXijiuZQwggWiMIIE # iqADAgECAhB4AxhCRXCKQc9vAbjutKlUMA0GCSqGSIb3DQEBDAUAMEwxIDAeBgNV # BAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIzMRMwEQYDVQQKEwpHbG9iYWxTaWdu # MRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTIwMDcyODAwMDAwMFoXDTI5MDMxODAw # MDAwMFowUzELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex # KTAnBgNVBAMTIEdsb2JhbFNpZ24gQ29kZSBTaWduaW5nIFJvb3QgUjQ1MIICIjAN # BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAti3FMN166KuQPQNysDpLmRZhsuX/ # pWcdNxzlfuyTg6qE9aNDm5hFirhjV12bAIgEJen4aJJLgthLyUoD86h/ao+KYSe9 # oUTQ/fU/IsKjT5GNswWyKIKRXftZiAULlwbCmPgspzMk7lA6QczwoLB7HU3SqFg4 # lunf+RuRu4sQLNLHQx2iCXShgK975jMKDFlrjrz0q1qXe3+uVfuE8ID+hEzX4rq9 # xHWhb71hEHREspgH4nSr/2jcbCY+6R/l4ASHrTDTDI0DfFW4FnBcJHggJetnZ4ir # uk40mGtwEd44ytS+ocCc4d8eAgHYO+FnQ4S2z/x0ty+Eo7+6CTc9Z2yxRVwZYatB # g/WsHet3DUZHc86/vZWV7Z0riBD++ljop1fhs8+oWukHJZsSxJ6Acj2T3IyU3ztE # 5iaA/NLDA/CMDNJF1i7nj5ie5gTuQm5nfkIWcWLnBPlgxmShtpyBIU4rxm1olIbG # mXRzZzF6kfLUjHlufKa7fkZvTcWFEivPmiJECKiFN84HYVcGFxIkwMQxc6GYNVdH # fhA6RdktpFGQmKmgBzfEZRqqHGsWd/enl+w/GTCZbzH76kCy59LE+snQ8FB2dFn6 # jW0XMr746X4D9OeHdZrUSpEshQMTAitCgPKJajbPyEygzp74y42tFqfT3tWbGKfG # kjrxgmPxLg4kZN8CAwEAAaOCAXcwggFzMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUE # DDAKBggrBgEFBQcDAzAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQfAL9GgAr8 # eDm3pbRD2VZQu86WOzAfBgNVHSMEGDAWgBSP8Et/qC5FJK5NUPpjmove4t0bvDB6 # BggrBgEFBQcBAQRuMGwwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLmdsb2JhbHNp # Z24uY29tL3Jvb3RyMzA7BggrBgEFBQcwAoYvaHR0cDovL3NlY3VyZS5nbG9iYWxz # aWduLmNvbS9jYWNlcnQvcm9vdC1yMy5jcnQwNgYDVR0fBC8wLTAroCmgJ4YlaHR0 # cDovL2NybC5nbG9iYWxzaWduLmNvbS9yb290LXIzLmNybDBHBgNVHSAEQDA+MDwG # BFUdIAAwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFsc2lnbi5jb20v # cmVwb3NpdG9yeS8wDQYJKoZIhvcNAQEMBQADggEBAKz3zBWLMHmoHQsoiBkJ1xx/ # /oa9e1ozbg1nDnti2eEYXLC9E10dI645UHY3qkT9XwEjWYZWTMytvGQTFDCkIKjg # P+icctx+89gMI7qoLao89uyfhzEHZfU5p1GCdeHyL5f20eFlloNk/qEdUfu1JJv1 # 0ndpvIUsXPpYd9Gup7EL4tZ3u6m0NEqpbz308w2VXeb5ekWwJRcxLtv3D2jmgx+p # 9+XUnZiM02FLL8Mofnrekw60faAKbZLEtGY/fadY7qz37MMIAas4/AocqcWXsojI # CQIZ9lyaGvFNbDDUswarAGBIDXirzxetkpNiIHd1bL3IMrTcTevZ38GQlim9wX8w # ggauMIIElqADAgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqGSIb3DQEBCwUAMGIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBH # NDAeFw0yMjAzMjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMxCzAJBgNVBAYTAlVT # MRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1 # c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwggIiMA0GCSqG # SIb3DQEBAQUAA4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXHJQPE8pE3qZdRodbS # g9GeTKJtoLDMg/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMfUBMLJnOWbfhXqAJ9 # /UO0hNoR8XOxs+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w1lbU5ygt69OxtXXn # HwZljZQp09nsad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRktFLydkf3YYMZ3V+0 # VAshaG43IbtArF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYbqMFkdECnwHLFuk4f # sbVYTXn+149zk6wsOeKlSNbwsDETqVcplicu9Yemj052FVUmcJgmf6AaRyBD40Nj # gHt1biclkJg6OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP65x9abJTyUpURK1h0 # QCirc0PO30qhHGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzKQtwYSH8UNM/STKvv # mz3+DrhkKvp1KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo80VgvCONWPfcYd6T # /jnA+bIwpUzX6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjBJgj5FBASA31fI7tk # 42PgpuE+9sJ0sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXcheMBK9Rp6103a50g5r # mQzSM7TNsQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4E # FgQUuhbZbU2FL3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5n # P+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcG # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln # aUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8v # Y3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNV # HSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIB # AH1ZjsCTtm+YqUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd4ksp+3CKDaopafxp # wc8dB+k+YMjYC+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiCqBa9qVbPFXONASIl # zpVpP0d3+3J0FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl/Yy8ZCaHbJK9nXzQ # cAp876i8dU+6WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeCRK6ZJxurJB4mwbfe # Kuv2nrF5mYGjVoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYTgAnEtp/Nh4cku0+j # Sbl3ZpHxcpzpSwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/a6fxZsNBzU+2QJsh # IUDQtxMkzdwdeDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37xJV77QpfMzmHQXh6 # OOmc4d0j/R0o08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmLNriT1ObyF5lZynDw # N7+YAN8gFk8n+2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0YgkPCr2B2RP+v6TR # 81fZvAT6gt4y3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJRyvmfxqkhQ/8mJb2 # VVQrH4D6wPIOK+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIGwjCCBKqgAwIBAgIQ # BUSv85SdCDmmv9s/X+VhFjANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEX # MBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0 # ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMB4XDTIzMDcxNDAw # MDAwMFoXDTM0MTAxMzIzNTk1OVowSDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRp # Z2lDZXJ0LCBJbmMuMSAwHgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyMzCC # AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKNTRYcdg45brD5UsyPgz5/X # 5dLnXaEOCdwvSKOXejsqnGfcYhVYwamTEafNqrJq3RApih5iY2nTWJw1cb86l+uU # UI8cIOrHmjsvlmbjaedp/lvD1isgHMGXlLSlUIHyz8sHpjBoyoNC2vx/CSSUpIIa # 2mq62DvKXd4ZGIX7ReoNYWyd/nFexAaaPPDFLnkPG2ZS48jWPl/aQ9OE9dDH9kgt # XkV1lnX+3RChG4PBuOZSlbVH13gpOWvgeFmX40QrStWVzu8IF+qCZE3/I+PKhu60 # pCFkcOvV5aDaY7Mu6QXuqvYk9R28mxyyt1/f8O52fTGZZUdVnUokL6wrl76f5P17 # cz4y7lI0+9S769SgLDSb495uZBkHNwGRDxy1Uc2qTGaDiGhiu7xBG3gZbeTZD+BY # QfvYsSzhUa+0rRUGFOpiCBPTaR58ZE2dD9/O0V6MqqtQFcmzyrzXxDtoRKOlO0L9 # c33u3Qr/eTQQfqZcClhMAD6FaXXHg2TWdc2PEnZWpST618RrIbroHzSYLzrqawGw # 9/sqhux7UjipmAmhcbJsca8+uG+W1eEQE/5hRwqM/vC2x9XH3mwk8L9CgsqgcT2c # kpMEtGlwJw1Pt7U20clfCKRwo+wK8REuZODLIivK8SgTIUlRfgZm0zu++uuRONhR # B8qUt+JQofM604qDy0B7AgMBAAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYD # VR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgG # BmeBDAEEAjALBglghkgBhv1sBwEwHwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxq # II+eyG8wHQYDVR0OBBYEFKW27xPn783QZKHVVqllMaPe1eNJMFoGA1UdHwRTMFEw # T6BNoEuGSWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRH # NFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGD # MIGAMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYB # BQUHMAKGTGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0 # ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQEL # BQADggIBAIEa1t6gqbWYF7xwjU+KPGic2CX/yyzkzepdIpLsjCICqbjPgKjZ5+PF # 7SaCinEvGN1Ott5s1+FgnCvt7T1IjrhrunxdvcJhN2hJd6PrkKoS1yeF844ektrC # QDifXcigLiV4JZ0qBXqEKZi2V3mP2yZWK7Dzp703DNiYdk9WuVLCtp04qYHnbUFc # jGnRuSvExnvPnPp44pMadqJpddNQ5EQSviANnqlE0PjlSXcIWiHFtM+YlRpUurm8 # wWkZus8W8oM3NG6wQSbd3lqXTzON1I13fXVFoaVYJmoDRd7ZULVQjK9WvUzF4UbF # KNOt50MAcN7MmJ4ZiQPq1JE3701S88lgIcRWR+3aEUuMMsOI5ljitts++V+wQtaP # 4xeR0arAVeOGv6wnLEHQmjNKqDbUuXKWfpd5OEhfysLcPTLfddY2Z1qJ+Panx+VP # NTwAvb6cKmx5AdzaROY63jg7B145WPR8czFVoIARyxQMfq68/qTreWWqaNYiyjvr # moI1VygWy2nyMpqy0tg6uLFGhmu6F/3Ed2wVbK6rr3M66ElGt9V/zLY4wNjsHPW2 # obhDLN9OTH0eaHDAdwrUAuBcYLso/zjlUlrWrBciI0707NMX+1Br/wd3H3GXREHJ # uEbTbDJ8WC9nR2XlG3O2mflrLAZG70Ee8PBf4NvZrZCARK+AEEGKMIIG6DCCBNCg # AwIBAgIQd70OBbdZC7YdR2FTHj917TANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQG # EwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEpMCcGA1UEAxMgR2xvYmFs # U2lnbiBDb2RlIFNpZ25pbmcgUm9vdCBSNDUwHhcNMjAwNzI4MDAwMDAwWhcNMzAw # NzI4MDAwMDAwWjBcMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBu # di1zYTEyMDAGA1UEAxMpR2xvYmFsU2lnbiBHQ0MgUjQ1IEVWIENvZGVTaWduaW5n # IENBIDIwMjAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLIO+XHrkB # MkOgW6mKI/0gXq44EovKLNT/QdgaVdQZU7f9oxfnejlcwPfOEaP5pe0B+rW6k++v # k9z44rMZTIOwSkRQBHiEEGqk1paQjoH4fKsvtaNXM9JYe5QObQ+lkSYqs4NPcrGK # e2SS0PC0VV+WCxHlmrUsshHPJRt9USuYH0mjX/gTnjW4AwLapBMvhUrvxC9wDsHU # zDMS7L1AldMRyubNswWcyFPrUtd4TFEBkoLeE/MHjnS6hICf0qQVDuiv6/eJ9t9x # 8NG+p7JBMyB1zLHV7R0HGcTrJnfyq20Xk0mpt+bDkJzGuOzMyXuaXsXFJJNjb34Q # i2HPmFWjJKKINvL5n76TLrIGnybADAFWEuGyip8OHtyYiy7P2uKJNKYfJqCornht # 7KGIFTzC6u632K1hpa9wNqJ5jtwNc8Dx5CyrlOxYBjk2SNY7WugiznQOryzxFdrR # tJXorNVJbeWv3ZtrYyBdjn47skPYYjqU5c20mLM3GSQScnOrBLAJ3IXm1CIE70Aq # HS5tx2nTbrcBbA3gl6cW5iaLiPcDRIZfYmdMtac3qFXcAzaMbs9tNibxDo+wPXHA # 4TKnguS2MgIyMHy1k8gh/TyI5mlj+O51yYvCq++6Ov3pXr+2EfG+8D3KMj5ufd4P # fpuVxBKH5xq4Tu4swd+hZegkg8kqwv25UwIDAQABo4IBrTCCAakwDgYDVR0PAQH/ # BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMBIGA1UdEwEB/wQIMAYBAf8CAQAw # HQYDVR0OBBYEFCWd0PxZCYZjxezzsRM7VxwDkjYRMB8GA1UdIwQYMBaAFB8Av0aA # Cvx4ObeltEPZVlC7zpY7MIGTBggrBgEFBQcBAQSBhjCBgzA5BggrBgEFBQcwAYYt # aHR0cDovL29jc3AuZ2xvYmFsc2lnbi5jb20vY29kZXNpZ25pbmdyb290cjQ1MEYG # CCsGAQUFBzAChjpodHRwOi8vc2VjdXJlLmdsb2JhbHNpZ24uY29tL2NhY2VydC9j # b2Rlc2lnbmluZ3Jvb3RyNDUuY3J0MEEGA1UdHwQ6MDgwNqA0oDKGMGh0dHA6Ly9j # cmwuZ2xvYmFsc2lnbi5jb20vY29kZXNpZ25pbmdyb290cjQ1LmNybDBVBgNVHSAE # TjBMMEEGCSsGAQQBoDIBAjA0MDIGCCsGAQUFBwIBFiZodHRwczovL3d3dy5nbG9i # YWxzaWduLmNvbS9yZXBvc2l0b3J5LzAHBgVngQwBAzANBgkqhkiG9w0BAQsFAAOC # AgEAJXWgCck5urehOYkvGJ+r1usdS+iUfA0HaJscne9xthdqawJPsz+GRYfMZZtM # 41gGAiJm1WECxWOP1KLxtl4lC3eW6c1xQDOIKezu86JtvE21PgZLyXMzyggULT1M # 6LC6daZ0LaRYOmwTSfilFQoUloWxamg0JUKvllb0EPokffErcsEW4Wvr5qmYxz5a # 9NAYnf10l4Z3Rio9I30oc4qu7ysbmr9sU6cUnjyHccBejsj70yqSM+pXTV4HXsrB # GKyBLRoh+m7Pl2F733F6Ospj99UwRDcy/rtDhdy6/KbKMxkrd23bywXwfl91LqK2 # vzWqNmPJzmTZvfy8LPNJVgDIEivGJ7s3r1fvxM8eKcT04i3OKmHPV+31CkDi9RjW # HumQL8rTh1+TikgaER3lN4WfLmZiml6BTpWsVVdD3FOLJX48YQ+KC7r1P6bXjvcE # Vl4hu5/XanGAv5becgPY2CIr8ycWTzjoUUAMrpLvvj1994DGTDZXhJWnhBVIMA5S # JwiNjqK9IscZyabKDqh6NttqumFfESSVpOKOaO4ZqUmZXtC0NL3W+UDHEJcxUjk1 # KRGHJNPE+6ljy3dI1fpi/CTgBHpO0ORu3s6eOFAm9CFxZdcJJdTJBwB6uMfzd+jF # 1OJV0NMe9n9S4kmNuRFyDIhEJjNmAUTf5DMOId5iiUgH2vUwggexMIIFmaADAgEC # AgwrsMr6yu5/CUgkrE4wDQYJKoZIhvcNAQELBQAwXDELMAkGA1UEBhMCQkUxGTAX # BgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExMjAwBgNVBAMTKUdsb2JhbFNpZ24gR0ND # IFI0NSBFViBDb2RlU2lnbmluZyBDQSAyMDIwMB4XDTIzMTIxNDE2NTAxNFoXDTI2 # MTIxNDE2NTAxNFowggEVMR0wGwYDVQQPDBRQcml2YXRlIE9yZ2FuaXphdGlvbjET # MBEGA1UEBRMKSFJCIDEwNzIwNzETMBEGCysGAQQBgjc8AgEDEwJERTEkMCIGCysG # AQQBgjc8AgECExNOb3JkcmhlaW4tV2VzdGZhbGVuMRYwFAYLKwYBBAGCNzwCAQET # BUtvZWxuMQswCQYDVQQGEwJERTEcMBoGA1UECBMTTm9yZHJoZWluLVdlc3RmYWxl # bjERMA8GA1UEBxMIT2RlbnRoYWwxGjAYBgNVBAkTEUVpY2hob2x6ZXIgV2VnIDM1 # MRgwFgYDVQQKEw9JVFByb0Nsb3VkIEdtYkgxGDAWBgNVBAMTD0lUUHJvQ2xvdWQg # R21iSDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANQ0Tx+Q4MOERUds # FNSUD225RWLyKxRRxkbZ8lIvuthQsGF3++pSfT+YK5WN0ORb/y+Wm4XXMqDb0dkq # Q8i8/Osvi4C1lIUtuAF7HGDhngITMBG8QoLVH0/kQrTmkok/zLedCY05XYj2Jh+I # BGRUxMqRhxGJBsNitGETeij27R/8EPsGuf7iZyAoAjRWl1bdQM3JTk2oT4b8/zBr # qoo0/6bRRFkHophl4t5E7xIQK14zD3VobesKEEA4PHlRggRAFrTKDwQILZBVXDhZ # fKQBYJS8Yqy/4CKPTGFmb5MsScV3PpKwBWl4jV8H+NLjHnwwtuOgyl2+W+lYIpHr # /YZlwAGdIgO0Pyo4SvhhDoCc7Te7e1AaQM8algItA3X/sJFZTCBCjgTGdEtE8iVM # TnXsSZaIy58JWoLuMEi0OAmtP+k3kCBBONRZdbuCmciilWdM/oXYnFMcaYHQhho7 # 0jOcW58i1ENZIin27bSc4uNOTr2sdTcLpPug8sgo20HIqpeQW6beUwH9zMSB9ai4 # JpO9yIZcRik7lxiOQMP9TQCSawjQqiCvqpEGL6bn+U+v0VAaQmMlOboX4Dcr7O6A # OWLS6uf1kaahTn8jgyMWOq5ayqYl8e/RYM1CAnwHCOyG3RiBy1jFZVrfBRC0E1T8 # BP26Xql1xwKjas/m+T2RRIL0gh7LAgMBAAGjggG2MIIBsjAOBgNVHQ8BAf8EBAMC # B4AwgZ8GCCsGAQUFBwEBBIGSMIGPMEwGCCsGAQUFBzAChkBodHRwOi8vc2VjdXJl # Lmdsb2JhbHNpZ24uY29tL2NhY2VydC9nc2djY3I0NWV2Y29kZXNpZ25jYTIwMjAu # Y3J0MD8GCCsGAQUFBzABhjNodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9nc2dj # Y3I0NWV2Y29kZXNpZ25jYTIwMjAwVQYDVR0gBE4wTDBBBgkrBgEEAaAyAQIwNDAy # BggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9y # eS8wBwYFZ4EMAQMwCQYDVR0TBAIwADBHBgNVHR8EQDA+MDygOqA4hjZodHRwOi8v # Y3JsLmdsb2JhbHNpZ24uY29tL2dzZ2NjcjQ1ZXZjb2Rlc2lnbmNhMjAyMC5jcmww # EwYDVR0lBAwwCgYIKwYBBQUHAwMwHwYDVR0jBBgwFoAUJZ3Q/FkJhmPF7POxEztX # HAOSNhEwHQYDVR0OBBYEFI4eFQIT/+F8FLMdCbLCuPhB8tV2MA0GCSqGSIb3DQEB # CwUAA4ICAQDH4zh+b37Vj/zON9/O925KJIYUH+bkY4ChLk1/0yWR8MiEasYtt3QJ # bBJ4kLlqVxP6Fg0Zzii5tFrDTukWRljtQquEzchCTZzD7Ot8I9/yMrTmKKiupk/G # i+jgx2Db9CL2M3oI3/z8D3bkPvUOIYIZwUl5qhAHrB52/QHRTKEzud0StOhsc+pm # nI9dgtm0OigJEo/Zk6czUbYKBkHxFD6xZy/Cm/KdFpPSLVZHQKqb13bLehGzioUe # BJRh3R07zWIYM7o69jEQEUP2sDKucf0ybkZ0sg6Q+kK2eiCZ3JxhEn4C9krZLAMd # nZ0joNB+Zm9hc07gBNy374DOeCstL0BpmDc2rsl9NkqbVBMS6xy0C8N4DV9X3cY5 # ao/9hQehDsSsGi0C+wMF1r5+kxyiiLvgeb6FLV6ugIHtiWISizts8NaVxyhcyiEZ # YviyJfl7FD4Lq9iLkvPYQJu70cNYhWfCPr0aXPFPJ1YJYlYmz1EqEjy3X/00+Wx3 # 2+eTcvT0SqcbvQpUzFNHEEsPsbjt2RJ0LVAZ9ZPCoiXypo0eqkgismCYF+PWcnv6 # 6wu9F2h5bsvb00m40Q+/x438wbXVwNmr65m4vOHsYaHOm5rH2NqjshR2CYU1fDvJ # mzopsEf/WA5MEefF+suI+Uy6TcsQrzQrGc23ny7vMD2Z6vcs7HEwmTGCBjEwggYt # AgEBMGwwXDELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex # MjAwBgNVBAMTKUdsb2JhbFNpZ24gR0NDIFI0NSBFViBDb2RlU2lnbmluZyBDQSAy # MDIwAgwrsMr6yu5/CUgkrE4wCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAI # oAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIB # CzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFPXnm+ks2f/MK+5QkX86 # g31n2a9mMA0GCSqGSIb3DQEBAQUABIICACep/bXUt2PdqkpikyZIalu69fOZRken # B77NkG04774/I9C/jwGGs45nGkyTNekNUkGyDroXZYgsGrnx2fYs+T49SIek/t2o # relc/n4qldRccz+IkXCBKM0CcozTWzE5SAFYDh3gwRACl2nd2R0tsKmKED0PjIdy # wSDVUsAsBnO0mvUdCEjzesazJbl6H3joiR4PQs720T60d8x/tu+N4TL4eh9FU9ZU # A9D+jEopWW8sbv+N4PDBZgMtdjnECG3hdhEPnNgKqBZGCm7MHIigAnsQxkgTskc5 # 1tLTGemd/NUYcsGVW+tA1HhdYDg87ibOt/EbZXRNaUDiyzKtkDuuynzYUU0gFWpi # 4d6JYU7nPyjcMrDvxEY7XJcK2/BQaVeHahycPkywP3T28RjtXKlyrLgdIwwYbkbZ # voBWN+R6Q9m4uqqDaVl//KqjGtk59sWBXdSjbodZQqcVPDYrPixM46+c2E/pZ77y # YtxHcetMBkOVNYyEggcL+lYTBoCFoVuXbxEsxwHDde5k7LXR7yl5qvzddjecx1Sq # nNQjAUY5FsZjXxVa8Zd/OVLClVn7dOzLaieyXeJ/FisZUUHIrtvj+gDNyQyalTl8 # +EZfySuy1/3kg5puQA+uGTBdUA93SYngcjwxTJbfkhvJhqD98I54Rrh8k8Ou7XyW # JEblP4sHu0t3oYIDIDCCAxwGCSqGSIb3DQEJBjGCAw0wggMJAgEBMHcwYzELMAkG # A1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdp # Q2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQ # BUSv85SdCDmmv9s/X+VhFjANBglghkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJAzEL # BgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTI0MDEyMzEzMTM0N1owLwYJKoZI # hvcNAQkEMSIEIG6asywKuBVgReg3FPKGfAz8Xvunudn4uzP7X30Yz9qAMA0GCSqG # SIb3DQEBAQUABIICACrZZpfFcpl+rXcgok67xu0WrR+8kHQ3ii6A7fhtgMW54VbJ # 0NdrMxrnWWt7XbTcbYzQUexGJ8fBOCAaVmsorOwV2cKKmXpYDcFsLFQtOqSMqMNO # SUATrGRvk0HIz58zVwixqjvovS3vrpdF6OHBPeHnGMLp4lwZoGXWq65S5iEMC3/Y # pMm/6/MAGzTkFCPVUQO8g5jueaYafwHy+DjDDHK0ZrsjhEFjCsQBOlLqr9rzrb5d # tfVgg/XviSwl/wEPoRpHkL5UJIvJMe8q1hknznAcr2SAvL+LcTOQoIPxLCnS40JS # mDqDzyH1P87Kv2dw3HMxTvhrhWoQPPiITJto6yk9tZT9UYf6ADplTCVS283gn4Kk # uohdwhQccY0N+hamEmczkwL3BxYuwbNh8/qbMyk8BVbpwKp27lDB+QCxY7joMHr3 # CBnp/0MBfxq8Cs5NhQ4DF7MDxSma0eHi6Jou9KLjaUwYAC2xBtOAb+w2SC4qGfSc # c0ByjUJPG+PI6qvwvDOF7q0EtmBP9pORfOJemEpKhGUrAM+tsWs5DbCseZrgzYxS # Hn4sA8Z5kp/UAL4eBj0XuHBdEYbF9EBF5GdlNKe8Es7QbLcrorHiSG5cnFs49fG5 # Vx3jD0j+EtVii23+715Q8x1k+vQSXcMJ8tlOhzjAMrWCzV4Pow0pVtn7Jmrm # SIG # End signature block