(C) Ondrej Sevecek, 2019 - www.sevecek.com, ondrej@sevecek.com
# # Note: This code may be run without $vmConfig and $vmName because of the obsolette Hyper-V IC (HVIC) # so this phase may run twice, first to update basic $commonVM settings and # mainly install newest Hyper-V IC (HVIC) # # #===================== # Common machine config DBG ("Build step: {0}" -f $MyInvocation.MyCommand.Definition) DBG "First stage with Hyper-V IC (HVIC) installation..." DBGIF ('Weird system drive letter not tested: {0}' -f $env:SystemDrive) { $env:SystemDrive -ne 'C:' } DBG ('Should we stop on BSOD instead of restarting: {0}' -f (Parse-BoolSafe $vmConfig.bsodStop)) if (Parse-BoolSafe $vmConfig.bsodStop) { Set-RegistryValue 'HKLM:\SYSTEM\ControlSet001\Control\CrashControl' AutoReboot 0 DWord } if ($global:phaseRetrial -eq 1) { #=============== DBGIF 'SYSPREP myself' { (Is-ValidString $vmConfig.sysprep.unatt) } if (Is-ValidString $vmConfig.sysprep.unatt) { DBG ('Determine currently running admin account') DBGSTART $currentRunningAdmin = [Security.Principal.WindowsIdentity]::GetCurrent($false) DBGER $MyInvocation.MyCommand.Name $error DBGEND DBG ('Currently running admin account: {0} | {1}' -f $currentRunningAdmin.Name, $currentRunningAdmin.User.Value) DBGIF $MyInvocation.MyCommand.Name { $currentRunningAdmin.User.Value -ne "$($global:thisComputerSID)-500" } DBGIF $MyInvocation.MyCommand.Name { $currentRunningAdmin.Name -ne "$global:thisComputerNetBIOS\Administrator" } DBG ('Build SYSPREP unattended file with the following params: {0} | {1}' -f $vmConfig.sysprep.pk, $vmConfig.sysprep.org) if ($global:thisOSVersionNumber -ge 6) { $sysprepPK = Get-SysprepUnattendedXmlPKElement $vmConfig.sysprep.pk $sysprepUnattendedSource = Resolve-PathSafe $vmConfig.sysprep.unatt $sysprepPath = Join-Path $env:SystemRoot 'System32\sysprep\sysprep.exe' $sysprepUnattended = Get-DataFileApp "sysprep-unattended-replaced" $null ([System.IO.Path]::GetExtension($sysprepUnattendedSource)) $true Replace-ArgumentsInFile $sysprepUnattendedSource ('defaultAdminPassword${0}|productKey${1}|organization${2}|installFromImage${3}|configId${4}|buildupMainBAT${5}' -f (Escape-ForMultiValue $global:phaseCfg.sevecekBuildup.login.pwd, $sysprepPK, $vmConfig.sysprep.org, '', $global:configScheme, $global:buildupMainBAT)) $sysprepUnattended ASCII DBG ('Going to run SYSPREP on Windows 6+: {0} | {1} | {2} | {3}' -f $vmConfig.sysprep.unatt, $sysprepUnattendedSource, $sysprepUnattended, $sysprepPath) } else { DBGIF ('SYSPREP not implemented for Windows 5.x') { $true } } DBGIF $MyInvocation.MyCommand.Name { -not (Test-Path $sysprepPath) } DBGIF $MyInvocation.MyCommand.Name { -not (Test-Path $sysprepUnattended) } if ((Test-Path $sysprepPath) -and (Test-Path $sysprepUnattended)) { Run-Process $sysprepPath ('/generalize /oobe /quiet /quit /unattend:"{0}"' -f $sysprepUnattended) } $currentRunningAdminLogin = $currentRunningAdmin.Name.SubString("$global:thisComputerNetBIOS\".Length) # Note: I do not like [Environment]::UserName so this goes only to ensure some basics DBGIF $MyInvocation.MyCommand.Name { [Environment]::UserName -ne $currentRunningAdminLogin } if ($global:thisOSRole -like '*workstation') { DBG ('Workstation OS built-in Administrator behavior') # Note: seems like SYSPREP disables the built-in Administrator account during its pre-restart Generalize phase # and again during some of the post-restart phases (most probably the Specialize phase) # Here we enable the account to let our script finish in a normal manner undisturbed by the fact # it might run under a disabled account. # Later, during the post-restart oobeSystem, we enable the account again using theelement # of the answer file DBG ('Verify that the generalize phase of sysprep really disabled the admin account and enable it again: {0}' -f $currentRunningAdminLogin) # Note: here we might be running under a different login because, as documentation says # the -500 account will get renamed back to Administrator during oobeSystem # (not verified by me, just as documentation states) Enable-LocalUser $currentRunningAdminLogin -assertIfNotDisabled $true } else { DBG ('Server OS built-in Administrator behavior') # Note: the server OS editions do not disable the built-in Administrator account during the Generalize phase # nor later during post-restart phases, so we just make sure it stays that way DBGIF $MyInvocation.MyCommand.Name { -not (Is-LocalUserEnabled $currentRunningAdminLogin) } } $global:restartCurrentPhase = $true DBG ('Exiting SYSPREP phase to restart') exit } } DBG ('Should we install any root CA certificates: {0} | {1}' -f $vmConfig.wks.rootCAs.search, (Is-ValidString $vmConfig.wks.rootCAs.search)) if (Is-ValidString $vmConfig.wks.rootCAs.search) { $rootCaSearches = Split-MultiValue $vmConfig.wks.rootCAs.search DBG ('Will import root CAs from the following search locations: {0}' -f (Get-CountSafe $rootCaSearches), ($rootCaSearches -join ',')) foreach ($oneRootCaSearch in $rootCaSearches) { $rootCaWildcard = Join-Path (Join-Path $global:libCommonParentDir 'AD-CS') $oneRootCaSearch DBG ('Searching in the following root CA location: {0}' -f $rootCaWildcard) DBGSTART $oneRootCAs = $null $oneRootCAs = Get-ChildItem $rootCaWildcard | Select -Expand FullName DBGER $MyInvocation.MyCommand.Name $error DBGEND DBG ('Found the root CA certificates: #{0} | {1}' -f (Get-CountSafe $oneRootCAs), ($oneRootCAs -join ',')) DBGIF ('Didnt find any root CA certificate as specified: {0}' -f $rootCaWildcard) { (Get-CountSafe $oneRootCAs) -lt 1 } if ((Get-CountSafe $oneRootCAs) -gt 0) { foreach ($oneRootCaCertificate in $oneRootCAs) { DBG ('Install one root CA certificate: {0}' -f $oneRootCaCertificate) DBGSTART $oneCertLoaded = $true $oneCertLoaded = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $oneRootCaCertificate $targetCertStore = Get-Item 'Cert:\LocalMachine\Root' $targetCertStore.Open('ReadWrite') $targetCertStore.Add($oneCertLoaded) DBGER $MyInvocation.MyCommand.Name $error DBGEND } } } } #=============== # Hyper-V IC (HVIC) update if necessary $wasICUpdated = Update-HyperVIntegration DBG ('HVIC was updated and restart is needed to update vmConfig? {0} | {1}' -f $wasICUpdated, (Is-EmptyString $global:vmName)) if ($wasICUpdated -and (Is-EmptyString $global:vmName)) { DBG ('Will restart current phase to allow for valid $vmConfig next time') $global:restartCurrentPhase = $true exit } #=============== DBG ("All local user passwords except for GUEST") $users = Get-WMIQueryArray '.' "SELECT * FROM Win32_UserAccount WHERE Domain='$thisComputerNetBIOS' AND SID <> '$thisComputerSID-501'" DBGIF $MyInvocation.MyCommand.Name { $users.Count -lt 1 } if (Is-ValidString $vmConfig.commonVM.builtinUserPwd) { if ($users.Count -ge 1) { DBG ("Resetting passwords for local {0} user accounts." -f $users.Count) foreach ($wmiUsr in $users) { Reset-UserPassword $wmiUsr.Domain $wmiUsr.Name $vmConfig.commonVM.builtinUserPwd -nonExpirePassword (Parse-BoolSafe($vmConfig.commonVM.nonExpirePwd)) } } } #=============== # Note: we MUST disable UAC for the duration of the buildup process as it was designed in such a way # from the very start. So this code has been moved to DTR as the very final task and changed to # actually re-enable UAC if requested #DBG ("Disable UAC: {0}" -f (Parse-BoolSafe $vmConfig.commonVM.uacOff)) # #if (Parse-BoolSafe($vmConfig.commonVM.uacOff)) #{ DBG ('We must disable UAC for the duration of the buildup process on Windows 6.0+: {0}' -f ($global:thisOSVersionNumber -ge 6)) if ($global:thisOSVersionNumber -ge 6) { [string] $luaRegKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' DBG ('Verify the value existance: {0}' -f $luaRegKey) DBGIF $MyInvocation.MyCommand.Name { -not (Test-Path -Literal $luaRegKey) } DBGSTART $luaRegValues = Get-ItemProperty $luaRegKey DBGER $MyInvocation.MyCommand.Name $error DBGEND DBG ('LUA settings: {0} | {1} | {2}' -f $luaRegValues.EnableLUA, $luaRegValues.PromptOnSecureDesktop, $luaRegValues.ConsentPromptBehaviorAdmin) DBGIF ('Weird LUA settings: {0},{1},{2} should be either 0,0,0 or 1,1,5' -f $luaRegValues.EnableLUA, $luaRegValues.PromptOnSecureDesktop, $luaRegValues.ConsentPromptBehaviorAdmin) { (-not (($luaRegValues.EnableLUA -eq 0) -and ($luaRegValues.PromptOnSecureDesktop -eq 0) -and ($luaRegValues.ConsentPromptBehaviorAdmin -eq 0))) -and (-not (($luaRegValues.EnableLUA -eq 1) -and ($luaRegValues.PromptOnSecureDesktop -eq 1) -and ($luaRegValues.ConsentPromptBehaviorAdmin -eq 5))) } Set-RegistryValue 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' EnableLUA 0 DWord Set-RegistryValue 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' PromptOnSecureDesktop 0 DWord Set-RegistryValue 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' ConsentPromptBehaviorAdmin 0 DWord } #} #=============== DBG ("Disable System Restore (System Protection): {0}" -f (Parse-BoolSafe($vmConfig.commonVM.systemRestoreOff))) if (Parse-BoolSafe($vmConfig.commonVM.systemRestoreOff)) { Disable-SystemRestore } ReDisable-Updates #=============== DBG ('Disable "Take a tour" on Windows XP: {0}' -f (Parse-BoolSafe($vmConfig.commonVM.tourOff))) if ((Parse-BoolSafe($vmConfig.commonVM.tourOff)) -and ($thisOSVersionNumber -eq 5.1)) { Set-RegistryValue 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Applets\Tour' RunCount 0 DWord } #=============== DBG ("Disable security center notifications: {0}" -f (Parse-BoolSafe($vmConfig.commonVM.scNotifyOff))) if (Parse-BoolSafe($vmConfig.commonVM.scNotifyOff)) { if ($thisOSVersion -like '5.*') { Set-RegistryValue 'HKLM:\SOFTWARE\Microsoft\Security Center' AntiVirusDisableNotify 1 DWord Set-RegistryValue 'HKLM:\SOFTWARE\Microsoft\Security Center' FirewallDisableNotify 1 DWord Set-RegistryValue 'HKLM:\SOFTWARE\Microsoft\Security Center' UpdatesDisableNotify 1 DWord } } #=============== DBG ("Configure firewall to Allow/Allow: {0}" -f (Parse-BoolSafe($vmConfig.commonVM.firewallAllow))) if (Parse-BoolSafe($vmConfig.commonVM.firewallAllow)) { if ($thisOSVersion -like '5.*') { DBG ("Firewall config on Windows 5.x: Disable") $fwBackupFile = Get-DataFileApp 'firewall-backup-win50' $null '.ini' -doNotPrefixWithOutFile $true if ($global:thisOSRole -like '*workstation*') { DBG ('Configure Windows Firewall on Windows XP') Set-AdvFirewallWithBackup $fwBackupFile -state5x 'disable' -state5xSvc 'Disabled' -expectedState5x 'enable' -expectedState5xSvc 'auto' } else { if ($global:phaseCfg.sevecekBuildup.media.source -eq 'iso') { # Note: on 5.x we must ensure the Windows Firewall/Internet Connection Sharing service # (SharedAccess) is disabled. When installing from ISO, the service is not # disabled by default not even on Windows 2003. # On Windows 5.x, after disabling it with NETSH, the service is left in Automatic # start mode and just stops immediatelly after started automatically. This prevents # later installation of IP NAT and also displays GUI error of a service not started. DBG ('Configure Windows Firewall on Windows 2003 when built from ISO') Set-AdvFirewallWithBackup $fwBackupFile -state5x 'disable' -state5xSvc 'Disabled' -expectedState5x 'enable' -expectedState5xSvc 'auto' } else { DBG ('Configure Windows Firewall on Windows 2003 when built from VHD') Set-AdvFirewallWithBackup $fwBackupFile -state5x 'disable' -state5xSvc 'Disabled' -expectedState5x 'disable' -expectedState5xSvc 'disabled' } } } else { DBG ("Firewall config on Windows 6.0+: Allow/Allow") $fwBackupFile = Get-DataFileApp 'firewall-backup-win60' $null '.ini' -doNotPrefixWithOutFile $true Set-AdvFirewallWithBackup $fwBackupFile -group domainprofile -what state -value on -expectedWhat State -expectedCurrentValue on Set-AdvFirewallWithBackup $fwBackupFile -group privateprofile -what state -value on -expectedWhat State -expectedCurrentValue on Set-AdvFirewallWithBackup $fwBackupFile -group publicprofile -what state -value on -expectedWhat State -expectedCurrentValue on Set-AdvFirewallWithBackup $fwBackupFile -group domainprofile -what firewallpolicy -value 'allowinbound,allowoutbound' -expectedWhat 'Firewall Policy' -expectedCurrentValue 'BlockInbound,AllowOutbound' Set-AdvFirewallWithBackup $fwBackupFile -group privateprofile -what firewallpolicy -value 'allowinbound,allowoutbound' -expectedWhat 'Firewall Policy' -expectedCurrentValue 'BlockInbound,AllowOutbound' Set-AdvFirewallWithBackup $fwBackupFile -group publicprofile -what firewallpolicy -value 'allowinbound,allowoutbound' -expectedWhat 'Firewall Policy' -expectedCurrentValue 'BlockInbound,AllowOutbound' if ($global:thisOSRole -like '*workstation*') { Set-AdvFirewallWithBackup $fwBackupFile -group global -what statefulftp -value enable -expectedWhat 'StatefulFTP' -expectedCurrentValue 'Enable' Set-AdvFirewallWithBackup $fwBackupFile -group global -what statefulpptp -value enable -expectedWhat 'StatefulPPTP' -expectedCurrentValue 'Enable' } else { Set-AdvFirewallWithBackup $fwBackupFile -group global -what statefulftp -value enable -expectedWhat 'StatefulFTP' -expectedCurrentValue 'Disable' Set-AdvFirewallWithBackup $fwBackupFile -group global -what statefulpptp -value enable -expectedWhat 'StatefulPPTP' -expectedCurrentValue 'Disable' } # other firewall states are: blockinboundalways, blockinbound, blockoutbound <#$cmdRs = & { netsh advfirewall set allprofiles state on netsh advfirewall set allprofiles firewallpolicy "allowinbound,allowoutbound" netsh advfirewall set global statefulftp enable netsh advfirewall set global statefulpptp enable } | Out-String DBG ("CMD output: {0}" -f $cmdRs)#> } } #=============== DBG ("Should disable WinRE: {0}" -f (($thisOSVersionNumber -ge 6.1) -and (Parse-BoolSafe($vmConfig.commonVM.winreOff)))) if (($thisOSVersionNumber -ge 6.1) -and (Parse-BoolSafe($vmConfig.commonVM.winreOff))) { Run-Process 'ReAgentC' '/disable' } #================ DBG ('Should we change time zone: {0} | {1}' -f (Is-ValidString $vmConfig.commonVM.timeZone), $vmConfig.commonVM.timeZone) if (Is-ValidString $vmConfig.commonVM.timeZone) { Set-TimeZone $vmConfig.commonVM.timeZone } #================ DBG ("Fixing WMI Error 10 on Windows 6.0/6.1") if (($thisOSVersion -like '6.0.*') -or ($thisOSVersion -like '6.1.*')) { DBG ("Going to obtain the BVTFilter and its associates.") $evFilter = Get-WMIQueryArray '.' "SELECT * FROM __EventFilter WHERE Name='BVTFilter'" 'root\subscription' DBG ('Must delete the EventFilter = BVTFilter? Exists = {0}' -f ((Get-CountSafe $evFilter) -gt 0)) if ((Get-CountSafe $evFilter) -gt 0) { # this is the list of real objects the are associated with the filter $assocs = Get-WMIQueryArray '.' "Associators Of {__EventFilter.Name='BVTFilter'} WHERE AssocClass=__FilterToConsumerBinding" 'root\subscription' # this is the list of binding classes that connect the two real objects $refers = Get-WMIQueryArray '.' "References Of {__EventFilter.Name='BVTFilter'} WHERE ResultClass=__FilterToConsumerBinding" 'root\subscription' DBG ("Going to delete the objects...") DBGSTART $assocs | Remove-WmiObject $refers | Remove-WmiObject $evFilter | Remove-WmiObject DBGER $MyInvocation.MyCommand.Name $error DBGEND } } #=============== DBG ('Should we configure static w32time/w32tm settings: {0}' -f (Is-NonNull $vmConfig.w32time)) if (Is-NonNull $vmConfig.w32time) { Set-W32timeConfig -maxPosCorrection $vmConfig.w32time.maxPosCorrection -maxNegCorrection $vmConfig.w32time.maxNegCorrection -specialPoll $vmConfig.w32time.specialPoll -manualPeers $vmConfig.w32time.manualPeers -clientType $vmConfig.w32time.clientType -triggerW32TimeOnNetwork (Parse-BoolSafe $vmConfig.w32time.triggerOnNetwork) } #=============== DBG ('Local/builtin admin (-500) rename: {0}' -f $vmConfig.commonVM.builtinAdmin) if (Is-ValidString $vmConfig.commonVM.builtinAdmin) { $currentAutoLogin = $global:phaseCfg.sevecekBuildup.login DBG ('Current autologon parameters: {0}\{1}' -f $currentAutoLogin.domain, $currentAutoLogin.autoLogin) DBG ('Get the current -500 builtin Administrator account name') [string] $builtinAdminSAM = Get-SAMLogin ('{0}{1}' -f $global:thisComputerSID, $global:wellKnownSIDs['Administrator']) [string] $builtinAdminLogin = $builtinAdminSAM.SubString(($builtinAdminSAM.IndexOf('\') + 1)) DBG ('Current builtin Administrator (-500) account login name: {0}' -f $builtinAdminLogin) DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $builtinAdminLogin } DBGIF ('We are not adapting and the current autologon identity is not the same as builtin admin: auto = {0} | builtin = {1}' -f $currentAutoLogin.autoLogin, $builtinAdminLogin) { (-not $global:adaptingExistingEnv) -and (($builtinAdminLogin -ne $currentAutoLogin.autoLogin) -or ($currentAutoLogin.domain -ne '.')) } # # DBG ('Should we rename the builtin admin to a new value: currentBuiltin = {0} | newBuiltin = {1}' -f $builtinAdminLogin, $vmConfig.commonVM.builtinAdmin) if ($builtinAdminLogin -ne $vmConfig.commonVM.builtinAdmin) { Rename-LocalObj 'user' $builtinAdminLogin $vmConfig.commonVM.builtinAdmin } # Note: we are changing to ensure some control over the input/state parameters but when adapting # the password change may not succeed as there might alread be some domain/local policies in place such as # MinimumPasswordAge or PasswordHistory which require SetPassword() to work # If we are adapting, we may also hit the problem with current password being unknown Change-LocalUserPassword $vmConfig.commonVM.builtinAdmin $currentAutoLogin.pwd $vmConfig.commonVM.builtinAdminPwd -resetIfComplexityOrCurrentFails $true $newAutoLogonLogin = $vmConfig.commonVM.builtinAdmin $newAutoLogonDomain = '.' $newAutoLogonPwd = $vmConfig.commonVM.builtinAdminPwd DBG ('Changing autologon identity to the renamed local admin: current = {0}\{1} | new = {2}\{3}' -f $currentAutoLogin.domain, $currentAutoLogin.autoLogin, $newAutoLogonDomain, $newAutoLogonLogin) $global:phaseCfg.sevecekBuildup.login.autoLogin = $newAutoLogonLogin $global:phaseCfg.sevecekBuildup.login.pwd = $newAutoLogonPwd $global:phaseCfg.sevecekBuildup.login.domain = $newAutoLogonDomain $global:phaseCfg.sevecekBuildup.originalAdmin.login = $vmConfig.commonVM.builtinAdmin } else { DBGIF ('Inconsistent autologin and current user: autologin = {0} | current = {1}' -f $global:phaseCfg.sevecekBuildup.login.autoLogin, ([Environment]::UserName)) { $global:phaseCfg.sevecekBuildup.login.autoLogin -ne ([Environment]::UserName) } DBGIF ('Current user is not -500 admin: {0}' -f ([Environment]::UserName)) { (New-Object Security.Principal.NTAccount ([Environment]::UserName)).Translate([Security.Principal.SecurityIdentifier]).Value -notlike 'S-1-5-21-?*-500' } $global:phaseCfg.sevecekBuildup.login.autoLogin = [Environment]::UserName $global:phaseCfg.sevecekBuildup.login.domain = '.' $global:phaseCfg.sevecekBuildup.originalAdmin.login = [Environment]::UserName DBG ('We are not renaming the admin-500 so we just keep the original admin name: {0}' -f $global:phaseCfg.sevecekBuildup.originalAdmin.login) } # SIG # Begin signature block # MIIYMAYJKoZIhvcNAQcCoIIYITCCGB0CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCjzjO4XAlopVeo # gaMfcZqNMxYuyjxSyNscbcV81qALu6CCE0cwggYEMIID7KADAgECAgoqHIRwAAEA # AAB/MA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYTAkNaMRcwFQYDVQQIEw5DemVj # aCBSZXB1YmxpYzENMAsGA1UEBxMEQnJubzEQMA4GA1UEChMHU2V2ZWNlazEjMCEG # A1UEAxMaU2V2ZWNlayBFbnRlcnByaXNlIFJvb3QgQ0EwHhcNMTkwNjExMTkyMzMy # WhcNMjQwNjA5MTkyMzMyWjCBjzELMAkGA1UEBhMCQ1oxFzAVBgNVBAgTDkN6ZWNo # IFJlcHVibGljMQ0wCwYDVQQHEwRCcm5vMRwwGgYDVQQKExNJbmcuIE9uZHJlaiBT # ZXZlY2VrMRcwFQYDVQQDEw5PbmRyZWogU2V2ZWNlazEhMB8GCSqGSIb3DQEJARYS # b25kcmVqQHNldmVjZWsuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC # AQEAnkjWNkK4FfUUN8iAN91ry+wsSn8cFKJbMnROAqTrx8t3H315p2/bUG2DosCF # Odu0WcaTOLdm5obhT+/3O7BqpdcnlWKlSEz4AL9zQeCbe4++NObBVPBbPE16j9C4 # xELoXW/Ti86C2PEkN5azGUvxGxzQQ45g32OsEI+Bh05qHMkk3oQ6L8O0Fpd5W4e+ # L4HuKS3JOikNhhryTNPD9grF/0wXTzn94TrL1GohuaCPh8g9HOtMoDCd+ExnqV8q # 4k60D37BOK1I81hYFIBn8MvCsjMRC5TK87MtI7aUUIeve5kopc8ZpxNti3F/+Puh # 4UUxL3nKjfAM6HE0b7FqkfkRpwIDAQABo4IBgjCCAX4wEwYDVR0lBAwwCgYIKwYB # BQUHAwMwDgYDVR0PAQH/BAQDAgbAMBsGCSsGAQQBgjcVCgQOMAwwCgYIKwYBBQUH # AwMwHQYDVR0OBBYEFOKbNkkiAht2GxCISJMJxLg4gOC9MB0GA1UdEQQWMBSBEm9u # ZHJlakBzZXZlY2VrLmNvbTAfBgNVHSMEGDAWgBQNnMgyfdUi8l9UfithS4FQ88Vs # wDBSBgNVHR8ESzBJMEegRaBDhkFodHRwOi8vcGtpLnNldmVjZWsuY29tL0NBL1Nl # dmVjZWslMjBFbnRlcnByaXNlJTIwUm9vdCUyMENBKDEpLmNybDCBhgYIKwYBBQUH # AQEEejB4ME0GCCsGAQUFBzAChkFodHRwOi8vcGtpLnNldmVjZWsuY29tL0NBL1Nl # dmVjZWslMjBFbnRlcnByaXNlJTIwUm9vdCUyMENBKDEpLmNydDAnBggrBgEFBQcw # AYYbaHR0cDovL3BraS5zZXZlY2VrLmNvbS9vY3NwMA0GCSqGSIb3DQEBCwUAA4IC # AQCfr6XDtt/O8OBr+X5l49UBLaJrjUXHkAHofdC7p7BLCXIs4GYIti1lf6pas5yB # Q428aKITITq/vEHUTyiiyKtzVkafILWXXKPxy+zmmuw9odB3Hea4ECNpcaG8UNtz # vMm1Dr0ZrkENhcv6I3tNhRr2AOE9AKOfnVEullFD/mZqfmaNkhpnl31jk7OMSUQc # oY8qD6BDQP9371C10gJOmp57sHfPa4Vn5E4aNzn8+o9C9HI7nNagZF5BamKOFdR2 # ui7K3krMbTuDHo+ZcA9nHnzZqiVKpEBFu8lGv9Mf+GDb9yxz6EjV3xS2RcnywX2v # z0VUt2NGno8LudrnWpgrRy4Sl7x6FwVVKtS/o7zFSIiHgntIKFv8urSKSTukCLFK # Y9fBIDDlWFV1ZV1DNpNWxnexWIRv2AH7YlzKQCA4Rysn01hVeBGsWFkCr9J33LmV # enQYpk9eoYMPRwAYg48r65wOOOzLvmyLSGllH88BMvmTQ9myXqwp6NDH1psljXTl # PUbpf7w6IZwsY0dhGhP9iyqbcrGdK0Bnf8Za6Qdj3iXtwd1VgpatFZrxOM5KawCL # pkYl1ABupbzNpWzmC+nfymqwbYiCogPt1vHOyF4EJ73ExVDCqXkpiNvFRqmu1eaZ # IOdbPCdl00a9rk52NKqo/BUsw16TKsDEYTA/7ACbEsnERzCCBmowggVSoAMCAQIC # EAMBmgI6/1ixa9bV6uYX8GYwDQYJKoZIhvcNAQEFBQAwYjELMAkGA1UEBhMCVVMx # FTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNv # bTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBDQS0xMB4XDTE0MTAyMjAw # MDAwMFoXDTI0MTAyMjAwMDAwMFowRzELMAkGA1UEBhMCVVMxETAPBgNVBAoTCERp # Z2lDZXJ0MSUwIwYDVQQDExxEaWdpQ2VydCBUaW1lc3RhbXAgUmVzcG9uZGVyMIIB # IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo2Rd/Hyz4II14OD2xirmSXU7 # zG7gU6mfH2RZ5nxrf2uMnVX4kuOe1VpjWwJJUNmDzm9m7t3LhelfpfnUh3SIRDsZ # yeX1kZ/GFDmsJOqoSyyRicxeKPRktlC39RKzc5YKZ6O+YZ+u8/0SeHUOplsU/UUj # joZEVX0YhgWMVYd5SEb3yg6Np95OX+Koti1ZAmGIYXIYaLm4fO7m5zQvMXeBMB+7 # NgGN7yfj95rwTDFkjePr+hmHqH7P7IwMNlt6wXq4eMfJBi5GEMiN6ARg27xzdPpO # 2P6qQPGyznBGg+naQKFZOtkVCVeZVjCT88lhzNAIzGvsYkKRrALA76TwiRGPdwID # AQABo4IDNTCCAzEwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0l # AQH/BAwwCgYIKwYBBQUHAwgwggG/BgNVHSAEggG2MIIBsjCCAaEGCWCGSAGG/WwH # ATCCAZIwKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMw # ggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgA # aQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQA # ZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcA # aQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwA # eQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkA # YwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEA # cgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIA # eQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMB8GA1UdIwQYMBaA # FBUAEisTmLKZB+0e36K+Vw0rZwLNMB0GA1UdDgQWBBRhWk0ktkkynUoqeRqDS/Qe # icHKfTB9BgNVHR8EdjB0MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20v # RGlnaUNlcnRBc3N1cmVkSURDQS0xLmNybDA4oDagNIYyaHR0cDovL2NybDQuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwdwYIKwYBBQUHAQEE # azBpMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQQYIKwYB # BQUHMAKGNWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3Vy # ZWRJRENBLTEuY3J0MA0GCSqGSIb3DQEBBQUAA4IBAQCdJX4bM02yJoFcm4bOIyAP # gIfliP//sdRqLDHtOhcZcRfNqRu8WhY5AJ3jbITkWkD73gYBjDf6m7GdJH7+IKRX # rVu3mrBgJuppVyFdNC8fcbCDlBkFazWQEKB7l8f2P+fiEUGmvWLZ8Cc9OB0obzpS # CfDscGLTYkuw4HOmksDTjjHYL+NtFxMG7uQDthSr849Dp3GdId0UyhVdkkHa+Q+B # 0Zl0DSbEDn8btfWg8cZ3BigV6diT5VUW8LsKqxzbXEgnZsijiwoc5ZXarsQuWaBh # 3drzbaJh6YoLbewSGL33VVRAA5Ira8JRwgpIr7DUbuD0FAo6G+OPPcqvao173NhE # MIIGzTCCBbWgAwIBAgIQBv35A5YDreoACus/J7u6GzANBgkqhkiG9w0BAQUFADBl # MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 # d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv # b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMjExMTEwMDAwMDAwWjBiMQswCQYDVQQG # EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl # cnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBBc3N1cmVkIElEIENBLTEwggEiMA0G # CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDogi2Z+crCQpWlgHNAcNKeVlRcqcTS # QQaPyTP8TUWRXIGf7Syc+BZZ3561JBXCmLm0d0ncicQK2q/LXmvtrbBxMevPOkAM # Rk2T7It6NggDqww0/hhJgv7HxzFIgHweog+SDlDJxofrNj/YMMP/pvf7os1vcyP+ # rFYFkPAyIRaJxnCI+QWXfaPHQ90C6Ds97bFBo+0/vtuVSMTuHrPyvAwrmdDGXRJC # geGDboJzPyZLFJCuWWYKxI2+0s4Grq2Eb0iEm09AufFM8q+Y+/bOQF1c9qjxL6/s # iSLyaxhlscFzrdfx2M8eCnRcQrhofrfVdwonVnwPYqQ/MhRglf0HBKIJAgMBAAGj # ggN6MIIDdjAOBgNVHQ8BAf8EBAMCAYYwOwYDVR0lBDQwMgYIKwYBBQUHAwEGCCsG # AQUFBwMCBggrBgEFBQcDAwYIKwYBBQUHAwQGCCsGAQUFBwMIMIIB0gYDVR0gBIIB # yTCCAcUwggG0BgpghkgBhv1sAAEEMIIBpDA6BggrBgEFBQcCARYuaHR0cDovL3d3 # dy5kaWdpY2VydC5jb20vc3NsLWNwcy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsGAQUF # BwICMIIBVh6CAVIAQQBuAHkAIAB1AHMAZQAgAG8AZgAgAHQAaABpAHMAIABDAGUA # cgB0AGkAZgBpAGMAYQB0AGUAIABjAG8AbgBzAHQAaQB0AHUAdABlAHMAIABhAGMA # YwBlAHAAdABhAG4AYwBlACAAbwBmACAAdABoAGUAIABEAGkAZwBpAEMAZQByAHQA # IABDAFAALwBDAFAAUwAgAGEAbgBkACAAdABoAGUAIABSAGUAbAB5AGkAbgBnACAA # UABhAHIAdAB5ACAAQQBnAHIAZQBlAG0AZQBuAHQAIAB3AGgAaQBjAGgAIABsAGkA # bQBpAHQAIABsAGkAYQBiAGkAbABpAHQAeQAgAGEAbgBkACAAYQByAGUAIABpAG4A # YwBvAHIAcABvAHIAYQB0AGUAZAAgAGgAZQByAGUAaQBuACAAYgB5ACAAcgBlAGYA # ZQByAGUAbgBjAGUALjALBglghkgBhv1sAxUwEgYDVR0TAQH/BAgwBgEB/wIBADB5 # BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0 # LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp # Z2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0 # cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNy # bDA6oDigNoY0aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJl # ZElEUm9vdENBLmNybDAdBgNVHQ4EFgQUFQASKxOYspkH7R7for5XDStnAs0wHwYD # VR0jBBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wDQYJKoZIhvcNAQEFBQADggEB # AEZQPsm3KCSnOB22WymvUs9S6TFHq1Zce9UNC0Gz7+x1H3Q48rJcYaKclcNQ5IK5 # I9G6OoZyrTh4rHVdFxc0ckeFlFbR67s2hHfMJKXzBBlVqefj56tizfuLLZDCwNK1 # lL1eT7EF0g49GqkUW6aGMWKoqDPkmzmnxPXOHXh2lCVz5Cqrz5x2S+1fwksW5Etw # TACJHvzFebxMElf+X+EevAJdqP77BzhPDcZdkbkPZ0XN1oPt55INjbFpjE/7WeAj # D9KqrgB87pxCDs+R1ye3Fu4Pw718CqDuLAhVhSK46xgaTfwqIa1JMYNHlXdx3LEb # S0scEJx3FMGdTy9alQgpECYxggQ/MIIEOwIBATB6MGwxCzAJBgNVBAYTAkNaMRcw # FQYDVQQIEw5DemVjaCBSZXB1YmxpYzENMAsGA1UEBxMEQnJubzEQMA4GA1UEChMH # U2V2ZWNlazEjMCEGA1UEAxMaU2V2ZWNlayBFbnRlcnByaXNlIFJvb3QgQ0ECCioc # hHAAAQAAAH8wDQYJYIZIAWUDBAIBBQCggYQwGAYKKwYBBAGCNwIBDDEKMAigAoAA # oQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4w # DAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgK2n96QiNoFvCFBC58grIKtKq # ysUF9oRjFFzYV0Ffwu0wDQYJKoZIhvcNAQEBBQAEggEAaCQK1Bg5jB+TgyfOeauR # 4pSXfbOnoNWuWvMp+nAARhWglN0/0414KHK+lEpfaB4TZJpMqBrSwnyp6AG93cdX # 9ljdWzE1cqIP3SFnf0h9GiVnJq5ZBbBxBqlj8PfbZzF24fBB1pTg/WXI/wlT8cKY # mFFb4TnbMTmfjlyIPNxbcPaVPcFBJ6vJ1paj+aTkU+PLYLC0dSVg04GsZ2IIF53X # 2N6NkoEVW4/lghh56G6FdijfC/0FvGTIWVlOnVwxR67W73Fhm5Q+n31EuA2J6Tlr # owlUOOYTIpd5oxTXSj2mywRJH9y2c9GArQFFxtZQx4kxqGbgto2SuU3szRBcSGsU # YKGCAg8wggILBgkqhkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNVBAYTAlVT # MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j # b20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGaAjr/WLFr # 1tXq5hfwZjAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAc # BgkqhkiG9w0BCQUxDxcNMTkwNjEyMTYxOTM1WjAjBgkqhkiG9w0BCQQxFgQUVFut # hvA/djLzl7ubhWZstUxQ9I0wDQYJKoZIhvcNAQEBBQAEggEAR165mv0z2c4WJe4y # kkUexgOfHfF3aY0V1TXbBils/BzJ76P9Z0YyIMjhs8UoxnNpUlYycT2j74QdhTcN # FhX1ZGcOJtJO6nAAFC5V8HHT6B3zWHTt7MINJhmr6n/yp7rvoe+sRMKJ7/NQfd7L # qIEFEY4QlWwobzVlhDsDkq9nD0izE2ETRvdIY+FslrdS/ekBkCYkHNf9GpCgiQD6 # Li9RU+JIJtb6oM8yA+Lm5Sp1Rt578xaYa5NR/KP6P7bQsq6OdEkvY/xAD5YmKVtJ # FGVC69+kx/DxZMIFuid/glS6A5f4L4d4zV445boGtAXpd3BoW6wkD89gDvGiRpBR # UNyteA== # SIG # End signature block