functions/Publish-DosWebApplication.ps1
<#
.SYNOPSIS Publishes the target DOS web application with the specified options .DESCRIPTION Publishes the target DOS web application with the specified options. Either uses WebDeploy (for older apps), or internal logic for new .Net Core applicaitons. .PARAMETER WebAppPackagePath File path to web application zip to publish .PARAMETER SettingsXmlPath ONLY USED in WebDeploy Applications - File path to xml settings .PARAMETER AppPoolName IIS Application Pool name .PARAMETER AppPoolCredential Credential object used to configure the built-in account the IIS Application Pool runs as .PARAMETER AuthenticationType ONLY USED in WebDeploy Applications - Windows or Anonymous authentication .PARAMETER WebDeploy A toggle for the web application to be deployed via WebDeploy or by other means .PARAMETER AppName ONLY USED in NON-Webdeploy applications. Specifies both the application's name AND the folder name where the application will be placed underneath the IIS site's root folder. .PARAMETER IISWebSite ONLY USED in NON-WebDeploy applications. Specifies the IIS site to publish the application to. Defaults to "Default Web Site" .PARAMETER WebDeployParameters ONLY USED in WebDeploy Applications - Arraylist object containing site settings .EXAMPLE Publish-DosWebApplication -WebAppPackagePath "testapp.zip" -SettingsXmlPath "testapp.settings.xml" -AppPoolName "x" -AppPoolCredential $creds -AuthenticationType "Windows" -WebDeploy -WebDeployParameters $webDeployParams #> function Publish-DosWebApplication { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [ValidateNotNullorEmpty()] [ValidateScript({ if (!(Test-Path $_)) { Write-DosMessage -Level "Error" -Message "$_ does not exist. Please enter valid path." -ErrorAction Stop } else { $true } })] [string] $WebAppPackagePath, [string] $SettingsXmlPath, [Parameter(Mandatory=$true)] [ValidateNotNullorEmpty()] [ValidateLength(1,64)] [ValidateScript({ if ($_ -match '[^a-zA-Z0-9]') { Write-DosMessage -Level "Error" -Message "$_ must only contain alphanumeric values. Please remove special characters." -ErrorAction Stop } else { $true } })] [string] $AppPoolName, [PSCredential] $AppPoolCredential, [ValidateSet("Windows", "Anonymous")] [string[]] $AuthenticationType, [switch] $WebDeploy, [string] $AppName, [string] $IISWebSite = "Default Web Site", [System.Collections.ArrayList] $WebDeployParameters, [switch] $NoCredential ) Test-ElevatedPermission Import-Module WebAdministration -Force ###Only allow one source of input for webdeploy args try { if ($NoCredential.IsPresent) { Write-DosMessage -Level "Information" -Message "The NoCredential parameter was provided. Proceeding to application pool validation." if(!(Test-Path "IIS:\AppPools\$AppPoolName" -PathType Container)){ New-AppPool -IISAppPoolName $AppPoolName } else { Set-AppPoolSettings -IISAppPoolName $AppPoolName -NoCredential $NoCredential.IsPresent } } else { if(!(Test-Path "IIS:\AppPools\$AppPoolName" -PathType Container)){ if($AppPoolCredential -eq $null){ Write-DosMessage -Level "Fatal" -Message "No app pool found named $AppPoolName and no credentials specified. Please specify credentials -AppPoolCredential if you want to create a new application pool" return } New-AppPool -IISAppPoolName $AppPoolName -IdentityCredential $AppPoolCredential } else { $existingAppPool = Get-Item -Path "IIS:\AppPools\$AppPoolName" # if app pool exists and credential is passed in / checks if the existing credential is the same / if it differs we fail out if ($null -ne $AppPoolCredential) { if ($existingAppPool.processModel.userName -ne $AppPoolCredential.UserName -or $existingAppPool.processModel.password -ne $AppPoolCredential.GetNetworkCredential().Password) { Write-DosMessage -Level "Fatal" -Message "The '$AppPoolName' app pool has an identity configured that differs from the identity credential provided. Halting deployment." } } Set-AppPoolSettings -IISAppPoolName $AppPoolName -IdentityCredential $AppPoolCredential Write-DosMessage -Level "Information" -Message "Application Pool: $AppPoolName already exists. Deploying '$WebAppPackagePath' to $AppPoolName" } } $appPool = Get-Item "IIS:\AppPools\$AppPoolName" $appPool.Start() } catch { Write-DosMessage -Level "Error" -Message "Error occured getting, creating, or updating a IIS application pool. Exception: $($_.Exception)" return } #Deploy Website to IIS if ($WebDeploy.IsPresent){ if([String]::IsNullOrEmpty($SettingsXmlPath) -and ($null -eq $WebDeployParameters)){ Write-DosMessage -Level "Error" -Message "Must provide parameters through a settings xml file or webdeployparameters when deploying a web deploy application" return } if($SettingsXmlPath) { try { [xml] $parsedXml = Get-Content $SettingsXmlPath } catch { Write-DosMessage -Level "Error" -Message "Error occured parsing xml settings file. Exception: $($_.Exception)" return } } try { Write-DosMessage -Level "Information" -Message "Attempting to retrieve the IIS web application information." $siteName,$appNameFromSettings = Get-IisWebAppInfo -SettingsXmlPath $SettingsXmlPath -WebDeployParameters $WebDeployParameters -ParsedXml $parsedXml Write-DosMessage -Level "Information" -Message "Successfully retrieved the IIS web application information." Write-DosMessage -Level "Information" -Message "Deploying '$appNameFromSettings' through WebDeploy." } catch { Write-DosMessage -Level "Error" -Message "Unable to find node containing IIS Web Application Name values" return } Publish-WebDeployWebApp -WebDeployPackageFilePath $WebAppPackagePath -WebDeployParameterFilePath $SettingsXmlPath -WebParameters $WebDeployParameters -AppName $appNameFromSettings -IISWebSite $IISWebSite -AppPoolName $AppPoolName Set-ApplicationPool -SiteName $siteName -AppName $appNameFromSettings -AppPoolName $AppPoolName Set-AuthenticationType -SiteName $siteName -AppName $appNameFromSettings -AuthenticationType $AuthenticationType Write-DosTelemetry -Message "Publish-DosWebApplication called and published using Publish-WebDeployWebApp." } else { if([string]::IsNullOrEmpty($AppName)){ Write-DosMessage -Level "Fatal" -Message "AppName must be non-null and non empty" } Publish-DotNetCoreWebApp -WebApplicationPackagePath $WebAppPackagePath -AppName $AppName -IISWebSite $IISWebSite -AppPoolName $AppPoolName Set-ApplicationPool -SiteName $IISWebSite -AppName $AppName -AppPoolName $AppPoolName if (-Not ([string]::IsNullOrEmpty($AuthenticationType))) { Install-UrlRewrite Set-AuthenticationType -SiteName $IISWebSite -AppName $AppName -AuthenticationType $AuthenticationType } Write-DosTelemetry -Message "Publish-DosWebApplication called and published using Publish-DotNetCoreWebApp." } } function Get-IisWebAppInfo { param ( [string] $SettingsXmlPath, [System.Collections.ArrayList] $WebDeployParameters, [xml] $ParsedXml ) if($SettingsXmlPath){ # Parameter childnodes can be different $iisParameter = $ParsedXml.parameters.ChildNodes | Where-Object { $_.name -eq "IIS Web Application Name" } # Parameter attribute names differ (eg. defaultValue and value) $iisAppPath = $iisParameter.Attributes | Where-Object { $_ -like "*value" } $siteName,$appNameFromSettings = $iisAppPath.'#text'.split('/') }else{ # Parameter attribute names differ (eg. defaultValue and value) foreach ($param in $WebDeployParameters) { if($param.Name -eq "IIS Web Application Name"){ $iisAppPath = $param.Value } } $siteName,$appNameFromSettings = $iisAppPath.split('/') } return $siteName,$appNameFromSettings } function Set-ApplicationPool { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Justification="WhatIf support not implemented.")] param ( [string] $SiteName, [string] $AppName, [string] $AppPoolName ) try { # Set-Application Pool with specific app Push-Location -Path IIS:\Sites\$SiteName\ Set-ItemProperty -Path $AppName -Name applicationPool -Value $AppPoolName } catch { Write-DosMessage -Level "Error" -Message "Error occured associating application to the app pool. Exception: $($_.Exception)" return } finally { Pop-Location } } function Set-AuthenticationType { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Justification="WhatIf support not implemented.")] param ( [string] $SiteName, [string] $AppName, [string[]] $AuthenticationType ) try{ Push-Location -Path IIS:\Sites\$SiteName\$AppName # Set-Authentication and transform the web config Set-IISAuthentication -AuthenticationType $AuthenticationType -SiteName $SiteName -ApplicationName $AppName } catch { Write-DosMessage -Level "Error" -Message "Error occured altering authentication types. Exception: $($_.Exception)" return } finally { Pop-Location } } function Install-UrlRewrite { # Check if URL Rewrite is installed before setting authentication $urlRewriteRegistry = "HKLM:\SOFTWARE\Microsoft\IIS Extensions\URL Rewrite" if (-Not (Test-Path $urlRewriteRegistry)) { Write-DosMessage -Level "Information" -Message "UrlRewrite not installed" # Install Web Platform Installer if not present if (-Not (Test-Path "$($env:ProgramFiles)\Microsoft\Web Platform Installer")) { Write-DosMessage -Level "Information" -Message "Web Platform Installer not found" Get-WebRequestDownload "https://go.microsoft.com/fwlink/?LinkId=287166" -OutFile "$PSScriptRoot\Web-Platform-Install.msi" Write-DosMessage -Level "Information" -Message "Installing Web Platform Installer" Start-Process "$PSScriptRoot\Web-Platform-Install.msi" '/qn' -PassThru | Wait-Process Remove-Item "$PSScriptRoot\Web-Platform-Install.msi" } # Install UrlRewrite using Web Platform Installer if (Test-Path "$($env:ProgramFiles)\Microsoft\Web Platform Installer\WebpiCmd.exe") { Write-DosMessage -Level "Information" -Message "Installing UrlRewrite" Start-Process "$($env:ProgramFiles)\Microsoft\Web Platform Installer\WebpiCmd.exe" "/Install /Products:'UrlRewrite2' /AcceptEULA" -PassThru | Wait-Process if (-Not (Test-Path $urlRewriteRegistry)) { Write-DosMessage -Level "Warning" -Message "UrlRewrite did not install correctly" } } else { Write-DosMessage -Level "Warning" -Message "Unable to install UrlRewrite, WebpiCmd.exe not found at $($env:ProgramFiles)\Microsoft\Web Platform Installer\WebpiCmd.exe" } } } # SIG # Begin signature block # MIIcRgYJKoZIhvcNAQcCoIIcNzCCHDMCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCHmyaJewPx+iRt # kApQvkOZLCYovzlRyfTKArY0r1YiwqCCCqAwggUwMIIEGKADAgECAhAECRgbX9W7 # ZnVTQ7VvlVAIMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV # BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBa # Fw0yODEwMjIxMjAwMDBaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lD # ZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3 # DQEBAQUAA4IBDwAwggEKAoIBAQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/l # qJ3bMtdx6nadBS63j/qSQ8Cl+YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fT # eyOU5JEjlpB3gvmhhCNmElQzUHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqH # CN8M9eJNYBi+qsSyrnAxZjNxPqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+ # bMt+dDk2DZDv5LVOpKnqagqrhPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLo # LFH3c7y9hbFig3NBggfkOItqcyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIB # yTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAK # BggrBgEFBQcDAzB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9v # Y3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHow # eDA6oDigNoY0aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJl # ZElEUm9vdENBLmNybDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp # Z2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwA # AgQwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAK # BghghkgBhv1sAzAdBgNVHQ4EFgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0j # BBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7s # DVoks/Mi0RXILHwlKXaoHV0cLToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGS # dQ9RtG6ljlriXiSBThCk7j9xjmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6 # r7VRwo0kriTGxycqoSkoGjpxKAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo # +MUSaJ/PQMtARKUT8OZkDCUIQjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qz # sIzV6Q3d9gEgzpkxYz0IGhizgZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHq # aGxEMrJmoecYpJpkUe8wggVoMIIEUKADAgECAhAKRecO+XBAYPQ5XoaaebXrMA0G # CSqGSIb3DQEBCwUAMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0 # IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwHhcNMTcwNDEzMDAwMDAw # WhcNMjAwNDE1MTIwMDAwWjCBpDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcw # FQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVSGVhbHRoIENhdGFseXN0 # LCBJbmMuMR4wHAYDVQQDExVIZWFsdGggQ2F0YWx5c3QsIEluYy4xLzAtBgkqhkiG # 9w0BCQEWIGFkbWluaXN0cmF0b3JAaGVhbHRoY2F0YWx5c3QuY29tMIIBIjANBgkq # hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv8AEfB5imOv8J17fvW8w+WKuE0keRub9 # 1+QzkiI+nSa9y2yADr/ZCEXqxGqDKdg47CjlvpOmKg8K88NPaTPvGN5fm7p7avmn # Cfp7IGXLGtutZ1RnFW2fYC8+kl86WinKVQ7eHLe7Rsvn9CyurIzttJpJcTikxqrr # U45yE8Iw/H9ziiwP+grfm8AiGN3C2vuxbhs8YwG2pbbn2aa5hN5q4bbFzoQ4xHGO # kFiqhRYVyGbVZNeoGTpkf/DNXJh07RuSDdcFXoh7whwwvfXhrk9Z5YzE6GEk2CUF # adTjqWHuGyfpBpY7bYZ8/mbDTmUqLNeGsTQrVmowv4r+usyK6lz6LwIDAQABo4IB # xTCCAcEwHwYDVR0jBBgwFoAUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHQYDVR0OBBYE # FDCXth9LjWUWNRWEPkEw5VZAVdBSMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAK # BggrBgEFBQcDAzB3BgNVHR8EcDBuMDWgM6Axhi9odHRwOi8vY3JsMy5kaWdpY2Vy # dC5jb20vc2hhMi1hc3N1cmVkLWNzLWcxLmNybDA1oDOgMYYvaHR0cDovL2NybDQu # ZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwTAYDVR0gBEUwQzA3 # BglghkgBhv1sAwEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQu # Y29tL0NQUzAIBgZngQwBBAEwgYQGCCsGAQUFBwEBBHgwdjAkBggrBgEFBQcwAYYY # aHR0cDovL29jc3AuZGlnaWNlcnQuY29tME4GCCsGAQUFBzAChkJodHRwOi8vY2Fj # ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyQXNzdXJlZElEQ29kZVNpZ25p # bmdDQS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAkIewxl/k # WdhH2w7hIW0jT2WXhasjLk/UVeJtON2V7uj6J5/geg9huBlF9UDASBN9Po3sULeE # /WQ+Lxbd3BDLq+jcENPKdEE7v9NFOCzs142tBJ+tng5uSD4KCG7wStTggI8XElpu # 0uraecK21bq4T4A2uGXpruEVNdS8DkANh34AwLJWanhaavbqunHZMkjQU0oluktS # ikJ1BVeyROM0Xh11VBnM5nSftS4c8eC66ZXhsuc268wwzwb3eD81jKwXdli3SrvT # zFKtAFqzh2/1bVIceq+iT7zketpGuFTg3BOkhbiJhIEjAS9pA3v+tVKrWcdTp/HC # mT2XH0Xyeg2GhzGCEPwwghD4AgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNV # BAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0ECEApF # 5w75cEBg9Dlehpp5teswDQYJYIZIAWUDBAIBBQCgfDAQBgorBgEEAYI3AgEMMQIw # ADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYK # KwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgeccMmZVXc2VNCLghWE6MLJuaEmPQ # pLjPKo/wht3VPVQwDQYJKoZIhvcNAQEBBQAEggEAv45iHaSHWrjOhiPnyTtEaNIu # vFqkhQObCInB97IcquM+onzh+sRSDrfoflOPG7JpLMlqxBY3/uNUDYt7L4Ar2S4M # ksrJMS9JN3Vupk/bpTXtCxn+ngG1ugO4gtsKll7GhuU02/LMlL0ncspDvzd2fpaJ # GysFga2qbPEyHt+VSTnIIZR/e77sIDypukyLnk8sxRYI5d6ORF911ZPrLjXjPSbz # M4LZx0C62P5prJMdy9TngzPtbJHW38V5/RxwRorcVSsz92J5GcdvNa+a8i9K6TCP # jprTduA08Mrn2mxAogQAeAlHAKnhQk5LLa1fPyGwlyCTILq/uLZqQphKOGaiWaGC # Dsgwgg7EBgorBgEEAYI3AwMBMYIOtDCCDrAGCSqGSIb3DQEHAqCCDqEwgg6dAgED # MQ8wDQYJYIZIAWUDBAIBBQAwdwYLKoZIhvcNAQkQAQSgaARmMGQCAQEGCWCGSAGG # /WwHATAxMA0GCWCGSAFlAwQCAQUABCBPGmQEMco1W6wcrGrpz9q9zdbpVcl2xuZv # jpOYDuqtvAIQYp2EJDF4bvivtYtXoZCNNBgPMjAyMDAyMjgxNzI2MzFaoIILuzCC # BoIwggVqoAMCAQICEATNP4VornbGG7D+cWDMp20wDQYJKoZIhvcNAQELBQAwcjEL # MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 # LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElE # IFRpbWVzdGFtcGluZyBDQTAeFw0xOTEwMDEwMDAwMDBaFw0zMDEwMTcwMDAwMDBa # MEwxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEkMCIGA1UE # AxMbVElNRVNUQU1QLVNIQTI1Ni0yMDE5LTEwLTE1MIIBIjANBgkqhkiG9w0BAQEF # AAOCAQ8AMIIBCgKCAQEA6WQ1nPqpmGVkG+QX3LgpNsxnCViFTTDgyf/lOzwRKFCv # BzHiXQkYwvaJjGkIBCPgdy2dFeW46KFqjv/UrtJ6Fu/4QbUdOXXBzy+nrEV+lG2s # AwGZPGI+fnr9RZcxtPq32UI+p1Wb31pPWAKoMmkiE76Lgi3GmKtrm7TJ8mURDHQN # svAIlnTE6LJIoqEUpfj64YlwRDuN7/uk9MO5vRQs6wwoJyWAqxBLFhJgC2kijE7N # xtWyZVkh4HwsEo1wDo+KyuDT17M5d1DQQiwues6cZ3o4d1RA/0+VBCDU68jOhxQI # /h2A3dDnK3jqvx9wxu5CFlM2RZtTGUlinXoCm5UUowIDAQABo4IDODCCAzQwDgYD # VR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUH # AwgwggG/BgNVHSAEggG2MIIBsjCCAaEGCWCGSAGG/WwHATCCAZIwKAYIKwYBBQUH # AgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwggFkBggrBgEFBQcCAjCC # AVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgAaQBzACAAQwBlAHIAdABp # AGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQAZQBzACAAYQBjAGMAZQBw # AHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcAaQBDAGUAcgB0ACAAQwBQ # AC8AQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwAeQBpAG4AZwAgAFAAYQBy # AHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkAYwBoACAAbABpAG0AaQB0 # ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEAcgBlACAAaQBuAGMAbwBy # AHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIAeQAgAHIAZQBmAGUAcgBl # AG4AYwBlAC4wCwYJYIZIAYb9bAMVMB8GA1UdIwQYMBaAFPS24SAd/imu0uRhpbKi # JbLIFzVuMB0GA1UdDgQWBBRWUw/BxgenTdfYbldygFBM5OyewTBxBgNVHR8EajBo # MDKgMKAuhixodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLXRz # LmNybDAyoDCgLoYsaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJl # ZC10cy5jcmwwgYUGCCsGAQUFBwEBBHkwdzAkBggrBgEFBQcwAYYYaHR0cDovL29j # c3AuZGlnaWNlcnQuY29tME8GCCsGAQUFBzAChkNodHRwOi8vY2FjZXJ0cy5kaWdp # Y2VydC5jb20vRGlnaUNlcnRTSEEyQXNzdXJlZElEVGltZXN0YW1waW5nQ0EuY3J0 # MA0GCSqGSIb3DQEBCwUAA4IBAQAug6FEBUoE47kyUvrZgfAau/gJjSO5PdiSoeZG # HEovbno8Y243F6Mav1gjskOclINOOQmwLOjH4eLM7ct5a87eIwFH7ZVUgeCAexKx # rwKGqTpzav74n8GN0SGM5CmCw4oLYAACnR9HxJ+0CmhTf1oQpvgi5vhTkjFf2IKD # LW0TQq6DwRBOpCT0R5zeDyJyd1x/T+k5mCtXkkTX726T2UPHBDNjUTdWnkcEEcOj # WFQh2OKOVtdJP1f8Cp8jXnv0lI3dnRq733oqptJFplUMj/ZMivKWz4lG3DGykZCj # XzMwYFX1/GswrKHt5EdOM55naii1TcLtW5eC+MupCGxTCbT3MIIFMTCCBBmgAwIB # AgIQCqEl1tYyG35B5AXaNpfCFTANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQGEwJV # UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu # Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMTYw # MTA3MTIwMDAwWhcNMzEwMTA3MTIwMDAwWjByMQswCQYDVQQGEwJVUzEVMBMGA1UE # ChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYD # VQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQgSUQgVGltZXN0YW1waW5nIENBMIIB # IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvdAy7kvNj3/dqbqCmcU5VChX # tiNKxA4HRTNREH3Q+X1NaH7ntqD0jbOI5Je/YyGQmL8TvFfTw+F+CNZqFAA49y4e # O+7MpvYyWf5fZT/gm+vjRkcGGlV+Cyd+wKL1oODeIj8O/36V+/OjuiI+GKwR5PCZ # A207hXwJ0+5dyJoLVOOoCXFr4M8iEA91z3FyTgqt30A6XLdR4aF5FMZNJCMwXbzs # PGBqrC8HzP3w6kfZiFBe/WZuVmEnKYmEUeaC50ZQ/ZQqLKfkdT66mA+Ef58xFNat # 1fJky3seBdCEGXIX8RcG7z3N1k3vBkL9olMqT4UdxB08r8/arBD13ays6Vb/kwID # AQABo4IBzjCCAcowHQYDVR0OBBYEFPS24SAd/imu0uRhpbKiJbLIFzVuMB8GA1Ud # IwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMBIGA1UdEwEB/wQIMAYBAf8CAQAw # DgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHkGCCsGAQUFBwEB # BG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsG # AQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1 # cmVkSURSb290Q0EuY3J0MIGBBgNVHR8EejB4MDqgOKA2hjRodHRwOi8vY3JsNC5k # aWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMDqgOKA2hjRo # dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0Eu # Y3JsMFAGA1UdIARJMEcwOAYKYIZIAYb9bAACBDAqMCgGCCsGAQUFBwIBFhxodHRw # czovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAsGCWCGSAGG/WwHATANBgkqhkiG9w0B # AQsFAAOCAQEAcZUS6VGHVmnN793afKpjerN4zwY3QITvS4S/ys8DAv3Fp8MOIEIs # r3fzKx8MIVoqtwU0HWqumfgnoma/Capg33akOpMP+LLR2HwZYuhegiUexLoceywh # 4tZbLBQ1QwRostt1AuByx5jWPGTlH0gQGF+JOGFNYkYkh2OMkVIsrymJ5Xgf1gsU # pYDXEkdws3XVk4WTfraSZ/tTYYmo9WuWwPRYaQ18yAGxuSh1t5ljhSKMYcp5lH5Z # /IwP42+1ASa2bKXuh1Eh5Fhgm7oMLSttosR+u8QlK0cCCHxJrhO24XxCQijGGFbP # QTS2Zl22dHv1VjMiLyI2skuiSpXY9aaOUjGCAk0wggJJAgEBMIGGMHIxCzAJBgNV # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp # Y2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBUaW1l # c3RhbXBpbmcgQ0ECEATNP4VornbGG7D+cWDMp20wDQYJYIZIAWUDBAIBBQCggZgw # GgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yMDAy # MjgxNzI2MzFaMCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFAMlvVBe2pYwLcIvT6Ae # TCi+KDTFMC8GCSqGSIb3DQEJBDEiBCBVP6+fzDZm0IuO21kI6hYwlrPuuNJIAhBz # xgAfAJOt6jANBgkqhkiG9w0BAQEFAASCAQBy+AtNfz9hl+wRkjqefDlMYM9g5MBz # cR1RC6gtN6ylN8s3ZI1rN0uQBBIuoDASbjG1XV2IennBb0R6gscSx53UMU0ikNZu # aEIu3AeFJ48uaLq0Ulcjm9H4xZ9NuOxZ7I8Q1M3lLExfFHCTc8PS7D7or2wGXNdl # znyizI4EawVlaI8VzicF3VaNjj9vRUcrB8pN+efxOWpdnD0ec5uOH5NoPJJLow1M # MGT+qzjoU2bz4h654e3tu5Zd1uf/ohNXN5nUacFC61XcDhJtNj9BeatBp+IltB+s # ByxQtzYfjsQttuYYhBdguIVRSPGzxPQHz4F3NpVPOFMwgvy//G2h1UvJ # SIG # End signature block |