(C) Ondrej Sevecek, 2019 - www.sevecek.com, ondrej@sevecek.com
$libDir = Split-Path -parent $MyInvocation.MyCommand.Definition & "$libDir\lib-common.ps1" -defaultConfig -rootDir $libDir -outFile mimLib & "$libDir\lib-modifyActions.ps1" & "$libDir\lib-buildup.ps1" $vmName = $args[0] DBG ('MIM/FIM installation library') Redirect-TempToOutput Load-VMConfig Find-MarkedVolumes $installSourceMediaMIM = '!sevecek-installation-source-media-ExchangeSharePoint.txt' $installMediaVolumeMIM = Find-MarkedVolume $installSourceMediaMIM 3 DBG ('FIM/MIM install media volume: {0}' -f $installMediaVolumeMIM) $appTag = 'mim' $appConfig = $vmConfig.$appTag $firstAppHost = Get-FirstAppHostInInstance $appTag $appConfig.instance 'waitParams' $firstAppConfig = (Get-FirstAppHostInInstance $appTag $appConfig.instance 'vmConfig').$appTag $firstAppHostInInstance = Check-FirstAppHostInInstance $appTag $appConfig.instance $firstAppHostFQDN = Get-FirstAppHostInInstance $appTag $appConfig.instance 'fqdn' if (-not $firstAppHostInInstance) { $allPreviousAppHosts = Get-AllAppHostsOfInstance $appTag $appConfig.instance 'waitParams' -onlyBeforeMyHostName $vmConfig.hostName } if (Is-Null $appConfig) { DBG ('Invalid appCofnig, exiting'); exit } #==================== #==================== # # DBG ('Backup IIS site/apppool state before buildup') $iisSitesBackup = Get-IISSites -structured $true $iisAppPoolBackup = Get-IISAppPools -structured $true # # ################ # # Note: Main code # if ($global:thisOSVersionNumber -lt 6.1) { DBGIF $MyInvocation.MyCommand.Name { $global:thisOSVersionNumber -lt 6.3 } exit } DBG ('Get the roles required') $roleSyncNode = $firstAppConfig.SelectSingleNode('./svc[@appTag="sync"]') DBG ('We should install synchronization service: {0}' -f (Is-NonNull $roleSyncNode)) $roleServiceNode = $firstAppConfig.SelectSingleNode('./svc[@appTag="service"]') DBG ('We should install service and portal service: {0}' -f (Is-NonNull $roleServiceNode)) $roleMANode = $firstAppConfig.SelectSingleNode('./svc[@appTag="ma"]') DBG ('We should counfigure MIM MA: {0}' -f (Is-NonNull $roleMANode)) $rolePwdRegNode = $firstAppConfig.SelectSingleNode('./svc[@appTag="pwdreg"]') DBG ('We should install password registration (pwdreg) portal: {0}' -f (Is-NonNull $rolePwdRegNode)) $rolePwdRstNode = $firstAppConfig.SelectSingleNode('./svc[@appTag="pwdrst"]') DBG ('We should install password reset (pwdrst) portal: {0}' -f (Is-NonNull $rolePwdRstNode)) DBG ('Determine the DB server') $dbInstance = $firstAppConfig.sql.instance DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $dbInstance } $dbServerFQDN = Get-FirstAppHostInInstance 'sql' $dbInstance 'fqdn' $dbServer = '{0}\{1}' -f $dbServerFQDN, $dbInstance DBG ('DB server determined as: {0}' -f $dbServer) DBG ('Determine already installed services') $isInstalledSyncSvc = Get-WmiQuerySingleObject '.' 'SELECT * FROM Win32_Product WHERE Name = "Microsoft Identity Manager Synchronization Service"' $isInstalledServiceSvc = Get-WmiQuerySingleObject '.' 'SELECT * FROM Win32_Product WHERE Name = "Microsoft Identity Manager Service"' DBG ('Installed services: sync = {0} | svc = {1}' -f (Is-NonNull $isInstalledSyncSvc), (Is-NonNull $isInstalledServiceSvc)) # # if ((Is-NonNull $roleSyncNode) -and (Is-Null $isInstalledSyncSvc)) { DBG ('Going to prepare sync service installation') $syncSvcMSI = Join-Path $installMediaVolumeMIM 'MIM2016-SP1\Synchronization Service\Synchronization Service.msi' DBG ('Sync service MSI path determined: {0}' -f $syncSvcMSI) DBGIF $MyInvocation.MyCommand.Name { -not (Test-Path $syncSvcMSI) } if (Test-Path $syncSvcMSI) { $syncSvcLog = Get-DataFileApp 'mim-sync-service-install' $null '.log' $syncSvcSAM = Get-SAMLogin $roleSyncNode.login $roleSyncNode.domain $syncGroupAdmSAM = Get-SAMLogin $firstAppConfig.app.aGroup $firstAppConfig.app.iDomain $syncGroupOp = $firstAppConfig.SelectSingleNode('./group[@appTag="op"]') DBGIF $MyInvocation.MyCommand.Name { Is-Null $syncGroupOp } $syncGroupOpSAM = Get-SAMLogin $syncGroupOp.login $syncGroupOp.domain $syncGroupJoin = $firstAppConfig.SelectSingleNode('./group[@appTag="join"]') DBGIF $MyInvocation.MyCommand.Name { Is-Null $syncGroupJoin } $syncGroupJoinSAM = Get-SAMLogin $syncGroupJoin.login $syncGroupJoin.domain $syncGroupBwse = $firstAppConfig.SelectSingleNode('./group[@appTag="bwse"]') DBGIF $MyInvocation.MyCommand.Name { Is-Null $syncGroupBwse } $syncGroupBwseSAM = Get-SAMLogin $syncGroupBwse.login $syncGroupBwse.domain $syncGroupPwd = $firstAppConfig.SelectSingleNode('./group[@appTag="pwd"]') DBGIF $MyInvocation.MyCommand.Name { Is-Null $syncGroupPwd } $syncGroupPwdSAM = Get-SAMLogin $syncGroupPwd.login $syncGroupPwd.domain DBG ('We are going to install the sync service MSI') Run-Process msiexec ('/i "{0}" /qn /norestart /l*v "{1}" STORESERVER="{2}" SQLINSTANCE="{3}" SQLDB="MIM_Sync_{4}" SERVICEACCOUNT="{5}" SERVICEDOMAIN="{6}" SERVICEPASSWORD="{7}" GROUPADMINS="{8}" GROUPOPERATORS="{9}" GROUPACCOUNTJOINERS="{10}" GROUPBROWSE="{11}" GROUPPASSWORDSET="{12}" FIREWALL_CONF=1' -f $syncSvcMSI, $syncSvcLog, $dbServerFQDN, $dbInstance, $appConfig.instance, $syncSvcSAM.Split('\')[1], $syncSvcSAM.Split('\')[0], $roleSyncNode.pwd, $syncGroupAdmSAM, $syncGroupOpSAM, $syncGroupJoinSAM, $syncGroupBwseSAM, $syncGroupPwdSAM) $fimSyncService = Get-WmiQuerySingleObject '.' 'SELECT * FROM Win32_Service WHERE Name = "FIMSynchronizationService"' DBGIF $MyInvocation.MyCommand.Name { Is-Null $fimSyncService } if (Is-NonNull $fimSyncService) { DBGIF ('Weird service start mode: {0}' -f $fimSyncService.StartMode) { $fimSyncService.StartMode -ne 'Auto' } DBGIF ('Weird service state: {0}' -f $fimSyncService.State) { $fimSyncService.State -ne 'Running' } DBGIF ('Weird service path: {0}' -f $fimSyncService.PathName) { $fimSyncService.PathName -ne ('"{0}"' -f (Join-Path $env:ProgramFiles 'Microsoft Forefront Identity Manager\2010\Synchronization Service\Bin\miiserver.exe')) } $miisClientEXE = Join-Path $env:ProgramFiles 'Microsoft Forefront Identity Manager\2010\Synchronization Service\UIShell\miisclient.exe' DBG ('Create links to the sync service: {0}' -f $miisClientEXE) DBGIF ('The sync UI exe does not exist: {0}' -f $miisClientEXE) { -not (Test-Path -Literal $miisClientEXE) } if (Test-Path -Literal $miisClientEXE) { $miisClientLINK = Join-Path $env:PUBLIC 'Desktop\MIM Sync.lnk' DBG ('Create the sync UI link: {0} | {1}' -f $miisClientEXE, $miisClientLINK) DBGSTART $shell = New-Object -Com WScript.Shell $shortcut = $shell.CreateShortcut($miisClientLINK) $shortcut.TargetPath = $miisClientEXE $shortcut.Save() DBGER $MyInvocation.MyCommand.Name $error DBGEND } $miisKeyMgmtUtility = Join-Path $env:ProgramFiles 'Microsoft Forefront Identity Manager\2010\Synchronization Service\Bin\miiskmu.exe' DBG ('Backup the database encryption key: {0}' -f $miisKeyMgmtUtility) DBGIF $MyInvocation.MyCommand.Name { -not (Test-Path $miisKeyMgmtUtility) } if (Test-Path $miisKeyMgmtUtility) { $miisKeyMgmtUtilityBackup = Get-DataFileApp 'miis-sync-service-encryption-key-backup' $null '.bin' Run-Process $miisKeyMgmtUtility ('/e "{0}" "/u:{1}" "{2}" /q' -f $miisKeyMgmtUtilityBackup, $syncSvcSAM, $roleSyncNode.pwd) } } } } # # $msiPwdRegAddLocal = '' $msiPwdRegParams = 'REQUIRE_REGISTRATION_INFO=0' if (Is-NonNull $rolePwdRegNode) { DBG ('Preparing installation for the Password Reset Registration Portal') DBGIF $MyInvocation.MyCommand.Name { Is-Null $rolePwdRegNode.mimSvc } DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $rolePwdRegNode.mimSvc.addr } DBGIF $MyInvocation.MyCommand.Name { Is-Null $roleServiceNode.mimSvc } DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $roleServiceNode.mimSvc.addr } $msiPwdRegAddLocal = ',RegistrationPortal' $msiPwdRegSAM = Get-SAMLogin $rolePwdRegNode.login $rolePwdRegNode.domain $msiPwdRegParams = 'REQUIRE_REGISTRATION_INFO=1 REGISTRATION_HOSTNAME="{0}" REGISTRATION_PORTAL_URL="https://{0}" REGISTRATION_PORT=80 IS_REGISTRATION_EXTRANET=Extranet REGISTRATION_FIREWALL_CONF=0 REGISTRATION_ACCOUNT="{1}" REGISTRATION_ACCOUNT_PASSWORD="{2}" REGISTRATION_SERVERNAME="{3}"' -f $rolePwdRegNode.mimSvc.addr, $msiPwdRegSAM, $rolePwdRegNode.pwd, $roleServiceNode.mimSvc.addr DBG ('PWD REG params defined: {0}' -f $msiPwdRegAddLocal) } # # $msiPwdRstAddLocal = '' $msiPwdRstParams = 'REQUIRE_RESET_INFO=0' if ((Is-NonNull $rolePwdRstNode) -and (Is-Null $isInstalledServiceSvc)) { DBG ('Preparing installation for the Password Reset Portal') DBGIF $MyInvocation.MyCommand.Name { Is-Null $rolePwdRstNode.mimSvc } DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $rolePwdRstNode.mimSvc.addr } DBGIF $MyInvocation.MyCommand.Name { Is-Null $roleServiceNode.mimSvc } DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $roleServiceNode.mimSvc.addr } $msiPwdRstAddLocal = ',ResetPortal' $msiPwdRstSAM = Get-SAMLogin $rolePwdRstNode.login $rolePwdRstNode.domain $msiPwdRstParams = 'REQUIRE_RESET_INFO=1 IS_RESET_EXTRANET=Extranet RESET_FIREWALL_CONF=0 RESET_HOSTNAME="{0}" RESET_PORT=80 RESET_ACCOUNT="{1}" RESET_ACCOUNT_PASSWORD="{2}" RESET_SERVERNAME="{3}"' -f $rolePwdRstNode.mimSvc.addr, $msiPwdRstSAM, $rolePwdRstNode.pwd, $roleServiceNode.mimSvc.addr DBG ('PWD RST params defined: {0}' -f $msiPwdRstParams) } # # if (Is-NonNull $roleServiceNode) { DBG ('Going to prepare MIM service installation') DBGIF $MyInvocation.MyCommand.Name { Is-Null $roleServiceNode.mimSvc } DBGIF $MyInvocation.MyCommand.Name { Is-Null $roleMANode } $serviceSvcMSI = Join-Path $installMediaVolumeMIM 'MIM2016-SP1\Service and Portal\Service and Portal.msi' DBG ('MIM Service MSI path determined: {0}' -f $serviceSvcMSI) DBGIF $MyInvocation.MyCommand.Name { -not (Test-Path $serviceSvcMSI) } if (Test-Path $serviceSvcMSI) { $serviceSvcLog = Get-DataFileApp 'mim-service-install' $null '.log' $serviceSvcSAM = Get-SAMLogin $roleServiceNode.login $roleServiceNode.domain $serviceSvcMASAM = Get-SAMLogin $roleMANode.login $roleMANode.domain DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $roleServiceNode.mimSvc.addr } DBGIF $MyInvocation.MyCommand.Name { Is-EmptyString $roleServiceNode.mimSvc.spSite } Define-DnsHostAliases -dnsAliases $roleServiceNode.mimSvc.addr -addHosts $true -disableLoopbackCheck $true if (Is-ValidString $rolePwdRegNode.mimSvc.addr) { Define-DnsHostAliases -dnsAliases $rolePwdRegNode.mimSvc.addr -addHosts $true -disableLoopbackCheck $true } if (Is-ValidString $rolePwdRstNode.mimSvc.addr) { Define-DnsHostAliases -dnsAliases $rolePwdRstNode.mimSvc.addr -addHosts $true -disableLoopbackCheck $false } DBG ('Ensure the SP Timer service is running') DBGSTART Get-Service sptimer* | ? { $_.Status -ne 'Running' } | % { DBGIF ('The SharePoint Timer service is not running before going to install MIM Service and Portal: {0} | {1}' -f $_.Name, $_.Status) { $true } ; Start-Service $_.Name -Confirm:$false } DBGER $MyInvocation.MyCommand.Name $error DBGEND DBG ('We are going to install the Service MSI') DBGIF ('As it seems the certificate subject must be ForefrontIdentityManager even for MIM 2016 SP1') { $roleServiceNode.mimSvc.certSubject -ne 'ForefrontIdentityManager' } Run-Process msiexec ('/i "{0}" /qb /norestart /l*v "{1}" ADDLOCAL="ConfigurationBackup,CommonServices,WebPortals{13}{14}" SQLSERVER_SERVER="{2}" SQLSERVER_DATABASE="MIM_Service_{3}" EXISTINGDATABASE=0 SERVICE_ACCOUNT_NAME="{4}" SERVICE_ACCOUNT_DOMAIN="{5}" SERVICE_ACCOUNT_PASSWORD="{6}" SERVICE_ACCOUNT_EMAIL="{7}" CERTIFICATE_NAME="{8}" SERVICEADDRESS="{9}" SYNCHRONIZATION_SERVER="{10}" SYNCHRONIZATION_SERVER_ACCOUNT="{11}" SHAREPOINT_URL="{12}" SHAREPOINTUSERS_CONF=1 SHAREPOINTTIMEOUT=660 FIREWALL_CONF=1 SQMOPTINSETTING=0 MAIL_SERVER=localhost MAIL_SERVER_IS_EXCHANGE=0 MAIL_SERVER_USE_SSL=0 POLL_EXCHANGE_ENABLED=0 {15} {16}' -f $serviceSvcMSI, $serviceSvcLog, $dbServer, $appConfig.instance, $serviceSvcSAM.Split('\')[1], $serviceSvcSAM.Split('\')[0], $roleServiceNode.pwd, $roleServiceNode.mail, $roleServiceNode.mimSvc.certSubject, $roleServiceNode.mimSvc.addr, $global:thisComputerFQDN, $serviceSvcMASAM, $roleServiceNode.mimSvc.spSite, $msiPwdRegAddLocal, $msiPwdRstAddLocal, $msiPwdRegParams, $msiPwdRstParams) $fimService = Get-WmiQuerySingleObject '.' 'SELECT * FROM Win32_Service WHERE Name = "FIMService"' DBGIF $MyInvocation.MyCommand.Name { Is-Null $fimService } if (Is-NonNull $fimService) { DBGIF ('Weird service start mode: {0}' -f $fimService.StartMode) { $fimService.StartMode -ne 'Auto' } DBGIF ('Weird service state: {0}' -f $fimService.State) { $fimService.State -ne 'Running' } DBGIF ('Weird service path: {0}' -f $fimService.PathName) { $fimService.PathName -ne ('"{0}"' -f (Join-Path $env:ProgramFiles 'Microsoft Forefront Identity Manager\2010\Service\Microsoft.ResourceManagement.Service.exe')) } $mimPortalIcon = Join-Path $env:SystemRoot 'System32\shell32.dll,17' $mimPortalURL = '{0}/IdentityManagement' -f $roleServiceNode.mimSvc.spSite.Trim('/') $mimPortalLINK = Join-Path $env:PUBLIC 'Desktop\MIM Portal.lnk' DBG ('Create the MIM Portal link: {0} | {1} | {2}' -f $mimPortalURL, $mimPortalLINK, $mimPortalIcon) DBGSTART $shell = New-Object -Com WScript.Shell $shortcut = $shell.CreateShortcut($mimPortalLINK) $shortcut.TargetPath = $mimPortalURL $shortcut.IconLocation = $mimPortalIcon $shortcut.Save() DBGER $MyInvocation.MyCommand.Name $error DBGEND } if (Is-NonNull $rolePwdRegNode) { DBG ('Disabling Kernel Mode authentication for the PWD REG web site') Run-Process (Join-Path $env:SystemRoot 'System32\inetsrv\appcmd') 'set config "MIM Password Registration Site" /section:windowsAuthentication /useKernelMode:false /commit:appHost' } } } # # Restore-IISSiteAndPoolState -iisSitesBackup $iisSitesBackup -iisAppPoolBackup $iisAppPoolBackup # # DBG ('Throw up any remaining errors') DBGSTART; DBGEND # SIG # Begin signature block # MIIc/QYJKoZIhvcNAQcCoIIc7jCCHOoCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDHDyo/DHbHI+zu # g1HH2wC3b3hvLmMvWurGP+hFcyGK3aCCGAQwggTlMIIDzaADAgECAhA5vUKe0oFu # utW8yQO0umXnMA0GCSqGSIb3DQEBCwUAMHUxCzAJBgNVBAYTAklMMRYwFAYDVQQK # Ew1TdGFydENvbSBMdGQuMSkwJwYDVQQLEyBTdGFydENvbSBDZXJ0aWZpY2F0aW9u # IEF1dGhvcml0eTEjMCEGA1UEAxMaU3RhcnRDb20gQ2xhc3MgMiBPYmplY3QgQ0Ew # HhcNMTYxMjAxMTU1MTEzWhcNMTgxMjAxMTU1MTEzWjBRMQswCQYDVQQGEwJDWjEa # MBgGA1UECAwRSmlob21vcmF2c2t5IEtyYWoxDTALBgNVBAcMBEJybm8xFzAVBgNV # BAMMDk9uZHJlaiBTZXZlY2VrMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC # AQEAr9E9hNj06bash9JX97kpsqK9Z/ciOBC6trI4nvlW9CPwhKBTb5wArhxLYZBG # 9jWPWrdy1nL/cm5qMqBb/mogYwMwvEYWMvsIOOVn6HD9lVhNAovD6PHz0ziBBKIs # zXTjyUPQaoIlIELovz967m78HJdUZJGxqhluAsS9o9/fEzA7XXUhUuqRKsetuZV/ # Asfh5sOveeoRsbeW4daTWvtz3TJuULL0w43LNVYJkd6LL8cegvLPVZUe1N7skvid # EvntdlowQsJlqFdrH3SGKIPKA6ObcY8SZWkEQSbVBF8Kum1UT+jN0gm+84FwOg5W # qKx+VvTK2ljVWnPrCD0Zzu2oIQIDAQABo4IBkzCCAY8wDgYDVR0PAQH/BAQDAgeA # MBMGA1UdJQQMMAoGCCsGAQUFBwMDMAkGA1UdEwQCMAAwHQYDVR0OBBYEFG2vSo3N # hQWILeUs0oN9XzHTejcfMB8GA1UdIwQYMBaAFD5ik5rXxxnuPo9JEIVVFSDjlIQc # MG0GCCsGAQUFBwEBBGEwXzAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Auc3RhcnRz # c2wuY29tMDcGCCsGAQUFBzAChitodHRwOi8vYWlhLnN0YXJ0c3NsLmNvbS9jZXJ0 # cy9zY2EuY29kZTIuY3J0MDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwuc3Rh # cnRzc2wuY29tL3NjYS1jb2RlMi5jcmwwIwYDVR0SBBwwGoYYaHR0cDovL3d3dy5z # dGFydHNzbC5jb20vMFEGA1UdIARKMEgwCAYGZ4EMAQQBMDwGCysGAQQBgbU3AQIF # MC0wKwYIKwYBBQUHAgEWH2h0dHBzOi8vd3d3LnN0YXJ0c3NsLmNvbS9wb2xpY3kw # DQYJKoZIhvcNAQELBQADggEBAJuRiEvHtIYSpsmMkPhTz4QOOShN3p5KWdf8vm71 # A33CR9fds10d8D2B2aE+vjmHJ69GY0bbfg5oZY2Lsq2euL7Da5/hS8+6T3MEtD4h # njfHV7mxmoSfFuy/KDipoV6uwhI+ksqchXYdUH+5uCQO0MOO8ITjAgzUQsnZ4UIB # HBGeP+e+3ljxSYSXWdPIrgxdR971P/HhWSVfKNlmBgEKMQM5Jy0aAd4jxSl/AzdY # t0+6pliFJ1peGhdFni2Fm8fu5oN68aTIrNtc5WY7Lzgf+sRTVeWORWS37+1zAD0m # jzd8gyfBLxRuaRSfjYxny0rLXelAwfiA3ze2DU2Bfg9/rfcwggXYMIIDwKADAgEC # AhBsO9J+3TyUnpWOKKmzx1egMA0GCSqGSIb3DQEBCwUAMH0xCzAJBgNVBAYTAklM # MRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSswKQYDVQQLEyJTZWN1cmUgRGlnaXRh # bCBDZXJ0aWZpY2F0ZSBTaWduaW5nMSkwJwYDVQQDEyBTdGFydENvbSBDZXJ0aWZp # Y2F0aW9uIEF1dGhvcml0eTAeFw0xNTEyMTYwMTAwMDVaFw0zMDEyMTYwMTAwMDVa # MHUxCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSkwJwYDVQQL # EyBTdGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEjMCEGA1UEAxMaU3Rh # cnRDb20gQ2xhc3MgMiBPYmplY3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw # ggEKAoIBAQC5FARY97LFhiwIMmCtCCbAgXe5aBnZFSsdGGnk2hqWBZcuZHkaqT1R # M1rQd2r0ApNBw466cBur2Ht0b5jo17mpPmh2pImgIqwX1in4u7hhn9IH0GYOMEcg # K3ACHv5zCRxxNLXifqmsqKfxjjpABnaSyvd4bO9YBXN9f4NQ6aJVAuMArpanxsJk # e+P4WECVLk17v92CAN5JVaczI+baT/lgo5NVcTEkloCViSbIfU6ILeyhOSQZvpom # MYk8eJqI0nimOTJJfmXangNDsrX8np+3lXD0+6rCZisXRWIaeffyTMHZ31Qj1D50 # WYdRtX5yev4WgaXoKJQN3lkgXUcytvyHAgMBAAGjggFaMIIBVjAOBgNVHQ8BAf8E # BAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAy # BgNVHR8EKzApMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0c3NsLmNvbS9zZnNjYS5j # cmwwZgYIKwYBBQUHAQEEWjBYMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5zdGFy # dHNzbC5jb20wMAYIKwYBBQUHMAKGJGh0dHA6Ly9haWEuc3RhcnRzc2wuY29tL2Nl # cnRzL2NhLmNydDAdBgNVHQ4EFgQUPmKTmtfHGe4+j0kQhVUVIOOUhBwwHwYDVR0j # BBgwFoAUTgvvGqRAW6UXaYcwyjRoQ9BBrvIwPwYDVR0gBDgwNjA0BgRVHSAAMCww # KgYIKwYBBQUHAgEWHmh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeTANBgkq # hkiG9w0BAQsFAAOCAgEAY6U81bNtJyjY67pTrzAL6kpdEtX5mspw+kxjjNdNVH5G # 6lLnhaEkIxqdpvY/Wdw+UdNtExs+N8efKPSwh2m/BxXj2fSeLMwXcwHFookScEER # 8ez0quCNzioqNHac7LCXPEnQzbtG2FHlePKNDWh8eU6KxiAzNzIrIxPthinHGgLT # BOACHQM2YTlD8YoU5oN3dLmBOqtH0BDMZoLcjEIoEW1zC+TnVb3yU1G0xub6gnN7 # lP50vbAiHJYrnywQiXaloBV8B9YYfe6ZgvjqxwufwFcMVyE3UmCuDTsOpjqDEKpJ # 25s+FUdkie5VqCS1aaudLo31X+9UvP45pfgyRqzyfUnVEhH4ZXxlBWZMzj2Xov5+ # m/+H3kxYuFA5xdqdshj/Zx00S7PkCSF+8M1NCcvFgQwjIw61bZAjDBl3P3a8xNTX # sb2CjFdiNKbT3LD6IGeIf0b/EbPf0FXdvBrxm0ofMOhnngdPolPYCtoOGtZPAVe/ # xeu+/ZyKv6TSHlshaUO0iYfsmbXnZ51vvt/kkjwms9/qPFxSuE0fjEfF7aQazwRE # Df2hiVPR0pAhvShtM3oU4XreEFEUWEYHs25fYV4WMmxkUKSgmSmwRq45tvtGH4LT # b5+cd+iLqK8rBQL0E6xaUjjGfsYx7bueIvqTvCkrQvoxMbn/qDHCiypowDVq6TAw # ggZqMIIFUqADAgECAhADAZoCOv9YsWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0Et # MTAeFw0xNDEwMjIwMDAwMDBaFw0yNDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVT # MREwDwYDVQQKEwhEaWdpQ2VydDElMCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1w # IFJlc3BvbmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8 # s+CCNeDg9sYq5kl1O8xu4FOpnx9kWeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7d # y4XpX6X51Id0iEQ7Gcnl9ZGfxhQ5rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGf # rvP9Enh1DqZbFP1FI46GRFV9GIYFjFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5 # uHzu5uc0LzF3gTAfuzYBje8n4/ea8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYu # RhDIjegEYNu8c3T6Ttj+qkDxss5wRoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJC # kawCwO+k8IkRj3cCAwEAAaOCAzUwggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMB # Af8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIw # ggGhBglghkgBhv1sBwEwggGSMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdp # Y2VydC5jb20vQ1BTMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBl # ACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBu # AHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0 # AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0 # AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBl # AG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5 # ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABl # AHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwD # FTAfBgNVHSMEGDAWgBQVABIrE5iymQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpN # JLZJMp1KKnkag0v0HonByn0wfQYDVR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMu # ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0 # dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3Js # MHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNl # cnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20v # RGlnaUNlcnRBc3N1cmVkSURDQS0xLmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+ # GzNNsiaBXJuGziMgD4CH5Yj//7HUaiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94G # AYw3+puxnSR+/iCkV61bt5qwYCbqaVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFB # pr1i2fAnPTgdKG86Ugnw7HBi02JLsOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dx # nSHdFMoVXZJB2vkPgdGZdA0mxA5/G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bI # o4sKHOWV2q7ELlmgYd3a822iYemKC23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQK # Ohvjjz3Kr2qNe9zYRDCCBs0wggW1oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJ # KoZIhvcNAQEFBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IElu # YzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQg # QXNzdXJlZCBJRCBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAw # MFowYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UE # CxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJ # RCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKV # pYBzQHDSnlZUXKnE0kEGj8kz/E1FkVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqv # y15r7a2wcTHrzzpADEZNk+yLejYIA6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/ # 2DDD/6b3+6LNb3Mj/qxWBZDwMiEWicZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE # 7h6z8rwMK5nQxl0SQoHhg26Ccz8mSxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKv # mPv2zkBdXPao8S+v7Iki8msYZbHBc63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIU # YJX9BwSiCQIDAQABo4IDejCCA3YwDgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIG # CCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcD # CDCCAdIGA1UdIASCAckwggHFMIIBtAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUH # AgEWLmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5o # dG0wggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0 # AGgAaQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1 # AHQAZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABp # AGcAaQBDAGUAcgB0ACAAQwBQAC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBl # AGwAeQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBo # AGkAYwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAg # AGEAcgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAg # AGIAeQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB # /wQIMAYBAf8CAQAweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8v # b2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRp # Z2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6 # MHgwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3Vy # ZWRJRFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9E # aWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e # 36K+Vw0rZwLNMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqG # SIb3DQEBBQUAA4IBAQBGUD7Jtygkpzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90 # OPKyXGGinJXDUOSCuSPRujqGcq04eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann # 4+erYs37iy2QwsDStZS9Xk+xBdIOPRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qq # q8+cdkvtX8JLFuRLcEwAiR78xXm8TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD # 7eeSDY2xaYxP+1ngIw/Sqq4AfO6cQg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38 # KiGtSTGDR5V3cdyxG0tLHBCcdxTBnU8vWpUIKRAmMYIETzCCBEsCAQEwgYkwdTEL # MAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKTAnBgNVBAsTIFN0 # YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSMwIQYDVQQDExpTdGFydENv # bSBDbGFzcyAyIE9iamVjdCBDQQIQOb1CntKBbrrVvMkDtLpl5zANBglghkgBZQME # AgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEM # BgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqG # SIb3DQEJBDEiBCDbmnZ2E5UpBrsLZw4zEUjjhtMjugvpyEpUYUk+9XfkRTANBgkq # hkiG9w0BAQEFAASCAQADqC5WeKT0c/snqlFVHre0jFfaWTP484eJXXvw5aKtrGOE # kW1iXS9WDT2bWuNMxZsZeLKaYz6QulqXurU2THV5zz3V5g9J1ZBvor3df9nSJjOC # wb54+znOyUfO0Jg/UYxFWYKl6WISBRllkJdPzQvxNxWQ29gxdcpJ7IEdvdsoBlCQ # JIFFl5ZA1x1jRP2ObxqbVG9ffumtFQbJSW477AnVm5f+dFOzAmNQSnTlbaQWYRCB # oo38Cu++p29N/mP19t4Kxo13IFvrdvDLdvo0qaHpcICim0ELBL5R6NG5wmNI6VGW # GsEgvBjSGwGzTXV2Z5JHIRF6el9sPOoXWk9itONToYICDzCCAgsGCSqGSIb3DQEJ # BjGCAfwwggH4AgEBMHYwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0 # IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNl # cnQgQXNzdXJlZCBJRCBDQS0xAhADAZoCOv9YsWvW1ermF/BmMAkGBSsOAwIaBQCg # XTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xODA4 # MDIxNTE3MTZaMCMGCSqGSIb3DQEJBDEWBBTyVKKGf9nrBkhJuE9+zOrKSQ1nGTAN # BgkqhkiG9w0BAQEFAASCAQCLMjbTPVhKAhir+uIQtovIJ67aGVg0+hpQfELFuYbu # WppawdlwKOdIyxLuOPbryDQFs1Gbhljan0wh8+MX8ybk9wgD3hbZDrYErJ4R9Q5x # Cy/oJE1+ohHR39mTH6Kelj0n7nrjxK97mY6GNoX+I535Nzty7izAShfAyFXx79v3 # F6QHdVo/Yd2qhOGya1gUpwelt9dhZv+qHkmVC6fFO7K1yQtajtcizB5RDPjJU+M5 # aWtV2vaR6fi/uj2w3yaTbDYRuXCUEjaPidwhjCQCo1DqYrRFdj2ivnRF3N4uklVW # dWC9nGKvxvXrbJlo1aHevClXx9xSMxdxJMXtKCy1l11x # SIG # End signature block