mirror of
https://github.com/kiwix/kiwix-js-pwa.git
synced 2025-09-12 05:48:25 -04:00
794 lines
34 KiB
PowerShell
794 lines
34 KiB
PowerShell
#
|
|
# Add-AppxDevPackage.ps1 is a PowerShell script designed to install app
|
|
# packages created by Visual Studio for developers. To run this script from
|
|
# Explorer, right-click on its icon and choose "Run with PowerShell".
|
|
#
|
|
# Visual Studio supplies this script in the folder generated with its
|
|
# "Prepare Package" command. The same folder will also contain the app
|
|
# package (a .appx file), the signing certificate (a .cer file), and a
|
|
# "Dependencies" subfolder containing all the framework packages used by the
|
|
# app.
|
|
#
|
|
# This script simplifies installing these packages by automating the
|
|
# following functions:
|
|
# 1. Find the app package and signing certificate in the script directory
|
|
# 2. Prompt the user to acquire a developer license and to install the
|
|
# certificate if necessary
|
|
# 3. Find dependency packages that are applicable to the operating system's
|
|
# CPU architecture
|
|
# 4. Install the package along with all applicable dependencies
|
|
#
|
|
# All command line parameters are reserved for use internally by the script.
|
|
# Users should launch this script from Explorer.
|
|
#
|
|
|
|
# .Link
|
|
# http://go.microsoft.com/fwlink/?LinkId=243053
|
|
|
|
param(
|
|
[switch]$Force = $false,
|
|
[switch]$GetDeveloperLicense = $false,
|
|
[string]$CertificatePath = $null
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
# The language resources for this script are placed in the
|
|
# "Add-AppDevPackage.resources" subfolder alongside the script. Since the
|
|
# current working directory might not be the directory that contains the
|
|
# script, we need to create the full path of the resources directory to
|
|
# pass into Import-LocalizedData
|
|
$ScriptPath = $null
|
|
try
|
|
{
|
|
$ScriptPath = (Get-Variable MyInvocation).Value.MyCommand.Path
|
|
$ScriptDir = Split-Path -Parent $ScriptPath
|
|
}
|
|
catch {}
|
|
|
|
if (!$ScriptPath)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorNoScriptPath $ErrorCodes.NoScriptPath
|
|
}
|
|
|
|
$LocalizedResourcePath = Join-Path $ScriptDir "Add-AppDevPackage.resources"
|
|
Import-LocalizedData -BindingVariable UiStrings -BaseDirectory $LocalizedResourcePath
|
|
|
|
$ErrorCodes = Data {
|
|
ConvertFrom-StringData @'
|
|
Success = 0
|
|
NoScriptPath = 1
|
|
NoPackageFound = 2
|
|
ManyPackagesFound = 3
|
|
NoCertificateFound = 4
|
|
ManyCertificatesFound = 5
|
|
BadCertificate = 6
|
|
PackageUnsigned = 7
|
|
CertificateMismatch = 8
|
|
ForceElevate = 9
|
|
LaunchAdminFailed = 10
|
|
GetDeveloperLicenseFailed = 11
|
|
InstallCertificateFailed = 12
|
|
AddPackageFailed = 13
|
|
ForceDeveloperLicense = 14
|
|
CertUtilInstallFailed = 17
|
|
CertIsCA = 18
|
|
BannedEKU = 19
|
|
NoBasicConstraints = 20
|
|
NoCodeSigningEku = 21
|
|
InstallCertificateCancelled = 22
|
|
BannedKeyUsage = 23
|
|
ExpiredCertificate = 24
|
|
'@
|
|
}
|
|
|
|
function PrintMessageAndExit($ErrorMessage, $ReturnCode)
|
|
{
|
|
Write-Host $ErrorMessage
|
|
if (!$Force)
|
|
{
|
|
Pause
|
|
}
|
|
exit $ReturnCode
|
|
}
|
|
|
|
#
|
|
# Warns the user about installing certificates, and presents a Yes/No prompt
|
|
# to confirm the action. The default is set to No.
|
|
#
|
|
function ConfirmCertificateInstall
|
|
{
|
|
$Answer = $host.UI.PromptForChoice(
|
|
"",
|
|
$UiStrings.WarningInstallCert,
|
|
[System.Management.Automation.Host.ChoiceDescription[]]@($UiStrings.PromptYesString, $UiStrings.PromptNoString),
|
|
1)
|
|
|
|
return $Answer -eq 0
|
|
}
|
|
|
|
#
|
|
# Validates whether a file is a valid certificate using CertUtil.
|
|
# This needs to be done before calling Get-PfxCertificate on the file, otherwise
|
|
# the user will get a cryptic "Password: " prompt for invalid certs.
|
|
#
|
|
function ValidateCertificateFormat($FilePath)
|
|
{
|
|
# certutil -verify prints a lot of text that we don't need, so it's redirected to $null here
|
|
certutil.exe -verify $FilePath > $null
|
|
if ($LastExitCode -lt 0)
|
|
{
|
|
PrintMessageAndExit ($UiStrings.ErrorBadCertificate -f $FilePath, $LastExitCode) $ErrorCodes.BadCertificate
|
|
}
|
|
|
|
# Check if certificate is expired
|
|
$cert = Get-PfxCertificate $FilePath
|
|
if (($cert.NotBefore -gt (Get-Date)) -or ($cert.NotAfter -lt (Get-Date)))
|
|
{
|
|
PrintMessageAndExit ($UiStrings.ErrorExpiredCertificate -f $FilePath) $ErrorCodes.ExpiredCertificate
|
|
}
|
|
}
|
|
|
|
#
|
|
# Verify that the developer certificate meets the following restrictions:
|
|
# - The certificate must contain a Basic Constraints extension, and its
|
|
# Certificate Authority (CA) property must be false.
|
|
# - The certificate's Key Usage extension must be either absent, or set to
|
|
# only DigitalSignature.
|
|
# - The certificate must contain an Extended Key Usage (EKU) extension with
|
|
# Code Signing usage.
|
|
# - The certificate must NOT contain any other EKU except Code Signing and
|
|
# Lifetime Signing.
|
|
#
|
|
# These restrictions are enforced to decrease security risks that arise from
|
|
# trusting digital certificates.
|
|
#
|
|
function CheckCertificateRestrictions
|
|
{
|
|
Set-Variable -Name BasicConstraintsExtensionOid -Value "2.5.29.19" -Option Constant
|
|
Set-Variable -Name KeyUsageExtensionOid -Value "2.5.29.15" -Option Constant
|
|
Set-Variable -Name EkuExtensionOid -Value "2.5.29.37" -Option Constant
|
|
Set-Variable -Name CodeSigningEkuOid -Value "1.3.6.1.5.5.7.3.3" -Option Constant
|
|
Set-Variable -Name LifetimeSigningEkuOid -Value "1.3.6.1.4.1.311.10.3.13" -Option Constant
|
|
|
|
$CertificateExtensions = (Get-PfxCertificate $CertificatePath).Extensions
|
|
$HasBasicConstraints = $false
|
|
$HasCodeSigningEku = $false
|
|
|
|
foreach ($Extension in $CertificateExtensions)
|
|
{
|
|
# Certificate must contain the Basic Constraints extension
|
|
if ($Extension.oid.value -eq $BasicConstraintsExtensionOid)
|
|
{
|
|
# CA property must be false
|
|
if ($Extension.CertificateAuthority)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorCertIsCA $ErrorCodes.CertIsCA
|
|
}
|
|
$HasBasicConstraints = $true
|
|
}
|
|
|
|
# If key usage is present, it must be set to digital signature
|
|
elseif ($Extension.oid.value -eq $KeyUsageExtensionOid)
|
|
{
|
|
if ($Extension.KeyUsages -ne "DigitalSignature")
|
|
{
|
|
PrintMessageAndExit ($UiStrings.ErrorBannedKeyUsage -f $Extension.KeyUsages) $ErrorCodes.BannedKeyUsage
|
|
}
|
|
}
|
|
|
|
elseif ($Extension.oid.value -eq $EkuExtensionOid)
|
|
{
|
|
# Certificate must contain the Code Signing EKU
|
|
$EKUs = $Extension.EnhancedKeyUsages.Value
|
|
if ($EKUs -contains $CodeSigningEkuOid)
|
|
{
|
|
$HasCodeSigningEKU = $True
|
|
}
|
|
|
|
# EKUs other than code signing and lifetime signing are not allowed
|
|
foreach ($EKU in $EKUs)
|
|
{
|
|
if ($EKU -ne $CodeSigningEkuOid -and $EKU -ne $LifetimeSigningEkuOid)
|
|
{
|
|
PrintMessageAndExit ($UiStrings.ErrorBannedEKU -f $EKU) $ErrorCodes.BannedEKU
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$HasBasicConstraints)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorNoBasicConstraints $ErrorCodes.NoBasicConstraints
|
|
}
|
|
if (!$HasCodeSigningEKU)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorNoCodeSigningEku $ErrorCodes.NoCodeSigningEku
|
|
}
|
|
}
|
|
|
|
#
|
|
# Performs operations that require administrative privileges:
|
|
# - Prompt the user to obtain a developer license
|
|
# - Install the developer certificate (if -Force is not specified, also prompts the user to confirm)
|
|
#
|
|
function DoElevatedOperations
|
|
{
|
|
if ($GetDeveloperLicense)
|
|
{
|
|
Write-Host $UiStrings.GettingDeveloperLicense
|
|
|
|
if ($Force)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorForceDeveloperLicense $ErrorCodes.ForceDeveloperLicense
|
|
}
|
|
try
|
|
{
|
|
Show-WindowsDeveloperLicenseRegistration
|
|
}
|
|
catch
|
|
{
|
|
$Error[0] # Dump details about the last error
|
|
PrintMessageAndExit $UiStrings.ErrorGetDeveloperLicenseFailed $ErrorCodes.GetDeveloperLicenseFailed
|
|
}
|
|
}
|
|
|
|
if ($CertificatePath)
|
|
{
|
|
Write-Host $UiStrings.InstallingCertificate
|
|
|
|
# Make sure certificate format is valid and usage constraints are followed
|
|
ValidateCertificateFormat $CertificatePath
|
|
CheckCertificateRestrictions
|
|
|
|
# If -Force is not specified, warn the user and get consent
|
|
if ($Force -or (ConfirmCertificateInstall))
|
|
{
|
|
# Add cert to store
|
|
certutil.exe -addstore TrustedPeople $CertificatePath
|
|
if ($LastExitCode -lt 0)
|
|
{
|
|
PrintMessageAndExit ($UiStrings.ErrorCertUtilInstallFailed -f $LastExitCode) $ErrorCodes.CertUtilInstallFailed
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorInstallCertificateCancelled $ErrorCodes.InstallCertificateCancelled
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Checks whether the machine is missing a valid developer license.
|
|
#
|
|
function CheckIfNeedDeveloperLicense
|
|
{
|
|
$Result = $true
|
|
try
|
|
{
|
|
$Result = (Get-WindowsDeveloperLicense | Where-Object { $_.IsValid } | Measure-Object).Count -eq 0
|
|
}
|
|
catch {}
|
|
|
|
return $Result
|
|
}
|
|
|
|
#
|
|
# Launches an elevated process running the current script to perform tasks
|
|
# that require administrative privileges. This function waits until the
|
|
# elevated process terminates, and checks whether those tasks were successful.
|
|
#
|
|
function LaunchElevated
|
|
{
|
|
# Set up command line arguments to the elevated process
|
|
$RelaunchArgs = '-ExecutionPolicy Unrestricted -file "' + $ScriptPath + '"'
|
|
|
|
if ($Force)
|
|
{
|
|
$RelaunchArgs += ' -Force'
|
|
}
|
|
if ($NeedDeveloperLicense)
|
|
{
|
|
$RelaunchArgs += ' -GetDeveloperLicense'
|
|
}
|
|
if ($NeedInstallCertificate)
|
|
{
|
|
$RelaunchArgs += ' -CertificatePath "' + $DeveloperCertificatePath.FullName + '"'
|
|
}
|
|
|
|
# Launch the process and wait for it to finish
|
|
try
|
|
{
|
|
$AdminProcess = Start-Process "$PsHome\PowerShell.exe" -Verb RunAs -ArgumentList $RelaunchArgs -PassThru
|
|
}
|
|
catch
|
|
{
|
|
$Error[0] # Dump details about the last error
|
|
PrintMessageAndExit $UiStrings.ErrorLaunchAdminFailed $ErrorCodes.LaunchAdminFailed
|
|
}
|
|
|
|
while (!($AdminProcess.HasExited))
|
|
{
|
|
Start-Sleep -Seconds 2
|
|
}
|
|
|
|
# Check if all elevated operations were successful
|
|
if ($NeedDeveloperLicense)
|
|
{
|
|
if (CheckIfNeedDeveloperLicense)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorGetDeveloperLicenseFailed $ErrorCodes.GetDeveloperLicenseFailed
|
|
}
|
|
else
|
|
{
|
|
Write-Host $UiStrings.AcquireLicenseSuccessful
|
|
}
|
|
}
|
|
if ($NeedInstallCertificate)
|
|
{
|
|
$Signature = Get-AuthenticodeSignature $DeveloperPackagePath -Verbose
|
|
if ($Signature.Status -ne "Valid")
|
|
{
|
|
PrintMessageAndExit ($UiStrings.ErrorInstallCertificateFailed -f $Signature.Status) $ErrorCodes.InstallCertificateFailed
|
|
}
|
|
else
|
|
{
|
|
Write-Host $UiStrings.InstallCertificateSuccessful
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Finds all applicable dependency packages according to OS architecture, and
|
|
# installs the developer package with its dependencies. The expected layout
|
|
# of dependencies is:
|
|
#
|
|
# <current dir>
|
|
# \Dependencies
|
|
# <Architecture neutral dependencies>.appx\.msix
|
|
# \x86
|
|
# <x86 dependencies>.appx\.msix
|
|
# \x64
|
|
# <x64 dependencies>.appx\.msix
|
|
# \arm
|
|
# <arm dependencies>.appx\.msix
|
|
#
|
|
function InstallPackageWithDependencies
|
|
{
|
|
$DependencyPackagesDir = (Join-Path $ScriptDir "Dependencies")
|
|
$DependencyPackages = @()
|
|
if (Test-Path $DependencyPackagesDir)
|
|
{
|
|
# Get architecture-neutral dependencies
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "*.appx") | Where-Object { $_.Mode -NotMatch "d" }
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "*.msix") | Where-Object { $_.Mode -NotMatch "d" }
|
|
|
|
# Get architecture-specific dependencies
|
|
if (($Env:Processor_Architecture -eq "x86" -or $Env:Processor_Architecture -eq "amd64") -and (Test-Path (Join-Path $DependencyPackagesDir "x86")))
|
|
{
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "x86\*.appx") | Where-Object { $_.Mode -NotMatch "d" }
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "x86\*.msix") | Where-Object { $_.Mode -NotMatch "d" }
|
|
}
|
|
if (($Env:Processor_Architecture -eq "amd64") -and (Test-Path (Join-Path $DependencyPackagesDir "x64")))
|
|
{
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "x64\*.appx") | Where-Object { $_.Mode -NotMatch "d" }
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "x64\*.msix") | Where-Object { $_.Mode -NotMatch "d" }
|
|
}
|
|
if (($Env:Processor_Architecture -eq "arm") -and (Test-Path (Join-Path $DependencyPackagesDir "arm")))
|
|
{
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "arm\*.appx") | Where-Object { $_.Mode -NotMatch "d" }
|
|
$DependencyPackages += Get-ChildItem (Join-Path $DependencyPackagesDir "arm\*.msix") | Where-Object { $_.Mode -NotMatch "d" }
|
|
}
|
|
}
|
|
Write-Host $UiStrings.InstallingPackage
|
|
|
|
$AddPackageSucceeded = $False
|
|
try
|
|
{
|
|
if ($DependencyPackages.FullName.Count -gt 0)
|
|
{
|
|
Write-Host $UiStrings.DependenciesFound
|
|
$DependencyPackages.FullName
|
|
Add-AppxPackage -Path $DeveloperPackagePath.FullName -DependencyPath $DependencyPackages.FullName -ForceApplicationShutdown
|
|
}
|
|
else
|
|
{
|
|
Add-AppxPackage -Path $DeveloperPackagePath.FullName -ForceApplicationShutdown
|
|
}
|
|
$AddPackageSucceeded = $?
|
|
}
|
|
catch
|
|
{
|
|
$Error[0] # Dump details about the last error
|
|
}
|
|
|
|
if (!$AddPackageSucceeded)
|
|
{
|
|
if ($NeedInstallCertificate)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorAddPackageFailedWithCert $ErrorCodes.AddPackageFailed
|
|
}
|
|
else
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorAddPackageFailed $ErrorCodes.AddPackageFailed
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Main script logic when the user launches the script without parameters.
|
|
#
|
|
function DoStandardOperations
|
|
{
|
|
# Check for an .appx or .msix file in the script directory
|
|
$PackagePath = Get-ChildItem (Join-Path $ScriptDir "*.appx") | Where-Object { $_.Mode -NotMatch "d" }
|
|
if ($PackagePath -eq $null)
|
|
{
|
|
$PackagePath = Get-ChildItem (Join-Path $ScriptDir "*.msix") | Where-Object { $_.Mode -NotMatch "d" }
|
|
}
|
|
$PackageCount = ($PackagePath | Measure-Object).Count
|
|
|
|
# Check for an .appxbundle or .msixbundle file in the script directory
|
|
$BundlePath = Get-ChildItem (Join-Path $ScriptDir "*.appxbundle") | Where-Object { $_.Mode -NotMatch "d" }
|
|
if ($BundlePath -eq $null)
|
|
{
|
|
$BundlePath = Get-ChildItem (Join-Path $ScriptDir "*.msixbundle") | Where-Object { $_.Mode -NotMatch "d" }
|
|
}
|
|
$BundleCount = ($BundlePath | Measure-Object).Count
|
|
|
|
# Check for an .eappx or .emsix file in the script directory
|
|
$EncryptedPackagePath = Get-ChildItem (Join-Path $ScriptDir "*.eappx") | Where-Object { $_.Mode -NotMatch "d" }
|
|
if ($EncryptedPackagePath -eq $null)
|
|
{
|
|
$EncryptedPackagePath = Get-ChildItem (Join-Path $ScriptDir "*.emsix") | Where-Object { $_.Mode -NotMatch "d" }
|
|
}
|
|
$EncryptedPackageCount = ($EncryptedPackagePath | Measure-Object).Count
|
|
|
|
# Check for an .eappxbundle or .emsixbundle file in the script directory
|
|
$EncryptedBundlePath = Get-ChildItem (Join-Path $ScriptDir "*.eappxbundle") | Where-Object { $_.Mode -NotMatch "d" }
|
|
if ($EncryptedBundlePath -eq $null)
|
|
{
|
|
$EncryptedBundlePath = Get-ChildItem (Join-Path $ScriptDir "*.emsixbundle") | Where-Object { $_.Mode -NotMatch "d" }
|
|
}
|
|
$EncryptedBundleCount = ($EncryptedBundlePath | Measure-Object).Count
|
|
|
|
$NumberOfPackages = $PackageCount + $EncryptedPackageCount
|
|
$NumberOfBundles = $BundleCount + $EncryptedBundleCount
|
|
|
|
# There must be at least one package or bundle
|
|
if ($NumberOfPackages + $NumberOfBundles -lt 1)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorNoPackageFound $ErrorCodes.NoPackageFound
|
|
}
|
|
# We must have exactly one bundle OR no bundle and exactly one package
|
|
elseif ($NumberOfBundles -gt 1 -or
|
|
($NumberOfBundles -eq 0 -and $NumberOfpackages -gt 1))
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorManyPackagesFound $ErrorCodes.ManyPackagesFound
|
|
}
|
|
|
|
# First attempt to install a bundle or encrypted bundle. If neither exists, fall back to packages and then encrypted packages
|
|
if ($BundleCount -eq 1)
|
|
{
|
|
$DeveloperPackagePath = $BundlePath
|
|
Write-Host ($UiStrings.BundleFound -f $DeveloperPackagePath.FullName)
|
|
}
|
|
elseif ($EncryptedBundleCount -eq 1)
|
|
{
|
|
$DeveloperPackagePath = $EncryptedBundlePath
|
|
Write-Host ($UiStrings.EncryptedBundleFound -f $DeveloperPackagePath.FullName)
|
|
}
|
|
elseif ($PackageCount -eq 1)
|
|
{
|
|
$DeveloperPackagePath = $PackagePath
|
|
Write-Host ($UiStrings.PackageFound -f $DeveloperPackagePath.FullName)
|
|
}
|
|
elseif ($EncryptedPackageCount -eq 1)
|
|
{
|
|
$DeveloperPackagePath = $EncryptedPackagePath
|
|
Write-Host ($UiStrings.EncryptedPackageFound -f $DeveloperPackagePath.FullName)
|
|
}
|
|
|
|
# The package must be signed
|
|
$PackageSignature = Get-AuthenticodeSignature $DeveloperPackagePath
|
|
$PackageCertificate = $PackageSignature.SignerCertificate
|
|
if (!$PackageCertificate)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorPackageUnsigned $ErrorCodes.PackageUnsigned
|
|
}
|
|
|
|
# Test if the package signature is trusted. If not, the corresponding certificate
|
|
# needs to be present in the current directory and needs to be installed.
|
|
$NeedInstallCertificate = ($PackageSignature.Status -ne "Valid")
|
|
|
|
if ($NeedInstallCertificate)
|
|
{
|
|
# List all .cer files in the script directory
|
|
$DeveloperCertificatePath = Get-ChildItem (Join-Path $ScriptDir "*.cer") | Where-Object { $_.Mode -NotMatch "d" }
|
|
$DeveloperCertificateCount = ($DeveloperCertificatePath | Measure-Object).Count
|
|
|
|
# There must be exactly 1 certificate
|
|
if ($DeveloperCertificateCount -lt 1)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorNoCertificateFound $ErrorCodes.NoCertificateFound
|
|
}
|
|
elseif ($DeveloperCertificateCount -gt 1)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorManyCertificatesFound $ErrorCodes.ManyCertificatesFound
|
|
}
|
|
|
|
Write-Host ($UiStrings.CertificateFound -f $DeveloperCertificatePath.FullName)
|
|
|
|
# The .cer file must have the format of a valid certificate
|
|
ValidateCertificateFormat $DeveloperCertificatePath
|
|
|
|
# The package signature must match the certificate file
|
|
if ($PackageCertificate -ne (Get-PfxCertificate $DeveloperCertificatePath))
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorCertificateMismatch $ErrorCodes.CertificateMismatch
|
|
}
|
|
}
|
|
|
|
$NeedDeveloperLicense = CheckIfNeedDeveloperLicense
|
|
|
|
# Relaunch the script elevated with the necessary parameters if needed
|
|
if ($NeedDeveloperLicense -or $NeedInstallCertificate)
|
|
{
|
|
Write-Host $UiStrings.ElevateActions
|
|
if ($NeedDeveloperLicense)
|
|
{
|
|
Write-Host $UiStrings.ElevateActionDevLicense
|
|
}
|
|
if ($NeedInstallCertificate)
|
|
{
|
|
Write-Host $UiStrings.ElevateActionCertificate
|
|
}
|
|
|
|
$IsAlreadyElevated = ([Security.Principal.WindowsIdentity]::GetCurrent().Groups.Value -contains "S-1-5-32-544")
|
|
if ($IsAlreadyElevated)
|
|
{
|
|
if ($Force -and $NeedDeveloperLicense)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorForceDeveloperLicense $ErrorCodes.ForceDeveloperLicense
|
|
}
|
|
if ($Force -and $NeedInstallCertificate)
|
|
{
|
|
Write-Warning $UiStrings.WarningInstallCert
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ($Force)
|
|
{
|
|
PrintMessageAndExit $UiStrings.ErrorForceElevate $ErrorCodes.ForceElevate
|
|
}
|
|
else
|
|
{
|
|
Write-Host $UiStrings.ElevateActionsContinue
|
|
Pause
|
|
}
|
|
}
|
|
|
|
LaunchElevated
|
|
}
|
|
|
|
InstallPackageWithDependencies
|
|
}
|
|
|
|
#
|
|
# Main script entry point
|
|
#
|
|
if ($GetDeveloperLicense -or $CertificatePath)
|
|
{
|
|
DoElevatedOperations
|
|
}
|
|
else
|
|
{
|
|
DoStandardOperations
|
|
PrintMessageAndExit $UiStrings.Success $ErrorCodes.Success
|
|
}
|
|
|
|
# SIG # Begin signature block
|
|
# MIIlqwYJKoZIhvcNAQcCoIIlnDCCJZgCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
|
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
|
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD5BdpRggDM/3NT
|
|
# wBDQFaER9aOD9SdM3CUzPDQe6F3dFqCCC3IwggT6MIID4qADAgECAhMzAAAEOfYf
|
|
# emdtoACvAAAAAAQ5MA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
|
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
|
# bmcgUENBIDIwMTAwHhcNMjEwOTAyMTgyNTU4WhcNMjIwOTAxMTgyNTU4WjB0MQsw
|
|
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
|
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
|
|
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
|
# AQDYxnPFVXLjCNZotpu2pA/klQnh61TVmOwkp46L2lhfjh3H1JisbpZfdR7PSIOy
|
|
# thfERueQRQM4cYwlCHxZs2PJgVAWT1A09MgvyOnUu8+TP3rMJux8XpgfjbT1QY9W
|
|
# NvAV+9T/3+JaRgW+L/IarOJQ+fQx6fwoO8U1UDJykFo5fQIbgCGXO/uz69B0z6LE
|
|
# VrJP+qibVhromVIQ0vaip2Rh+EMlHNN3jDpuYJOfcI9iClLffv30NDVa7LNdr5S8
|
|
# 5uFW7WD6aVLd5Y4vytrD477um9drb3Xe/gXmBKUZ2JLMv+xZG39Xw/UbA1lQTN/t
|
|
# bof2MgifNoRRRRELlcOForTtAgMBAAGjggF5MIIBdTAfBgNVHSUEGDAWBgorBgEE
|
|
# AYI3PQYBBggrBgEFBQcDAzAdBgNVHQ4EFgQUxfAmBmr7eiyHypaAy6/f8G8lQsUw
|
|
# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1
|
|
# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzA4NjUrNDY3Mzk4MB8GA1UdIwQYMBaAFOb8
|
|
# X3u7IgBY5HJOtfQhdCMy5u+sMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwu
|
|
# bWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY0NvZFNpZ1BDQV8yMDEw
|
|
# LTA3LTA2LmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93
|
|
# d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljQ29kU2lnUENBXzIwMTAtMDct
|
|
# MDYuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggEBAGaOsNHOxecF
|
|
# hmUQiipJkW1uEeTTuKdpftxfnqFzxAqNngYLPDHQb3Ja8CnFNwCN5BFh21p4TM15
|
|
# Pv1aO+HCA3mYRAexP5LM9mTTBEoC5WFMNVG+6x138G/BnafTHRIj5UjgZHWR3t2s
|
|
# /uWoNBRtTYVUKTdwuvh+2bCeJrEebuWi4cOOkHd3eBwaD+Dh/iJinmdUoYoAA8cN
|
|
# AnZ+4jsirVYsvnfHeYtzEPVUPFtRVsHSRhs+zMpm+66oju2d8z2HHS3Q+OVgbCXq
|
|
# BAg1c+BTzV9+9oaMXuq7klKeRNj1quZae0jisxP+fxQx3iWB7I8YVx0EmGg67aQS
|
|
# pjH84cst2PswggZwMIIEWKADAgECAgphDFJMAAAAAAADMA0GCSqGSIb3DQEBCwUA
|
|
# MIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
|
|
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQD
|
|
# EylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0x
|
|
# MDA3MDYyMDQwMTdaFw0yNTA3MDYyMDUwMTdaMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
|
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
|
# bmcgUENBIDIwMTAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDpDmRQ
|
|
# eWe1xOP9CQBMnpSs91Zo6kTYz8VYT6mldnxtRbrTOZK0pB75+WWC5BfSj/1EnAjo
|
|
# ZZPOLFWEv30I4y4rqEErGLeiS25JTGsVB97R0sKJHnGUzbV/S7SvCNjMiNZrF5Q6
|
|
# k84mP+zm/jSYV9UdXUn2siou1YW7WT/4kLQrg3TKK7M7RuPwRknBF2ZUyRy9HcRV
|
|
# Yldy+Ge5JSA03l2mpZVeqyiAzdWynuUDtWPTshTIwciKJgpZfwfs/w7tgBI1TBKm
|
|
# vlJb9aba4IsLSHfWhUfVELnG6Krui2otBVxgxrQqW5wjHF9F4xoUHm83yxkzgGqJ
|
|
# TaNqZmN4k9Uwz5UfAgMBAAGjggHjMIIB3zAQBgkrBgEEAYI3FQEEAwIBADAdBgNV
|
|
# HQ4EFgQU5vxfe7siAFjkck619CF0IzLm76wwGQYJKwYBBAGCNxQCBAweCgBTAHUA
|
|
# YgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU
|
|
# 1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2Ny
|
|
# bC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIw
|
|
# MTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDov
|
|
# L3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0w
|
|
# Ni0yMy5jcnQwgZ0GA1UdIASBlTCBkjCBjwYJKwYBBAGCNy4DMIGBMD0GCCsGAQUF
|
|
# BwIBFjFodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vUEtJL2RvY3MvQ1BTL2RlZmF1
|
|
# bHQuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAFAAbwBsAGkAYwB5
|
|
# AF8AUwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQAadO9X
|
|
# Tyl7xBaFeLhQ0yL8CZ2sgpf4NP8qLJeVEuXkv8+/k8jjNKnbgbjcHgC+0jVvr+V/
|
|
# eZV35QLU8evYzU4eG2GiwlojGvCMqGJRRWcI4z88HpP4MIUXyDlAptcOsyEp5aWh
|
|
# aYwik8x0mOehR0PyU6zADzBpf/7SJSBtb2HT3wfV2XIALGmGdj1R26Y5SMk3YW0H
|
|
# 3VMZy6fWYcK/4oOrD+Brm5XWfShRsIlKUaSabMi3H0oaDmmp19zBftFJcKq2rbty
|
|
# R2MX+qbWoqaG7KgQRJtjtrJpiQbHRoZ6GD/oxR0h1Xv5AiMtxUHLvx1MyBbvsZx/
|
|
# /CJLSYpuFeOmf3Zb0VN5kYWd1dLbPXM18zyuVLJSR2rAqhOV0o4R2plnXjKM+zeF
|
|
# 0dx1hZyHxlpXhcK/3Q2PjJst67TuzyfTtV5p+qQWBAGnJGdzz01Ptt4FVpd69+lS
|
|
# TfR3BU+FxtgL8Y7tQgnRDXbjI1Z4IiY2vsqxjG6qHeSF2kczYo+kyZEzX3EeQK+Y
|
|
# Zcki6EIhJYocLWDZN4lBiSoWD9dhPJRoYFLv1keZoIBA7hWBdz6c4FMYGlAdOJWb
|
|
# HmYzEyc5F3iHNs5Ow1+y9T1HU7bg5dsLYT0q15IszjdaPkBCMaQfEAjCVpy/JF1R
|
|
# Ap1qedIX09rBlI4HeyVxRKsGaubUxt8jmpZ1xTGCGY8wghmLAgEBMIGVMH4xCzAJ
|
|
# BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
|
|
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jv
|
|
# c29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTACEzMAAAQ59h96Z22gAK8AAAAABDkw
|
|
# DQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYK
|
|
# KwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIEMB6sh3
|
|
# 0od0djZhSjYmDFfgME5hmf84vbeilDhjyyYCMEIGCisGAQQBgjcCAQwxNDAyoBSA
|
|
# EgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20w
|
|
# DQYJKoZIhvcNAQEBBQAEggEA1bK1LEyaLO54Y+b9vTXXest5Q5wkeB8/7oc9KI76
|
|
# AjOvVdSHXlY9t/MjzQbdAq74y0RSl0kyZyAa+p5GaLo9CWLPQRXLTxMxXHluqXhJ
|
|
# WvOYiJf+Vn4RnC15NMbVSszOxNXmb06yg+PPxnJkEzCI3fYpNcFjhMoD0Pi6gdnf
|
|
# 4B/HO4+clhdgi5ymjcwPmwEF5h/r/LX3wxqudCJ6k5IQ/VwgL+bOeGrPzW5sHWYX
|
|
# 5na7OWdRLNJ1LpE17Jwqf+FLCPjUeHwEMbywsKuxtZADwDV2Ao45pMaBvTJZ68ED
|
|
# B14ubOpND4DzzH/lDTNE1gZXWrdeeQl8bSU9DGVe9bb4/6GCFxkwghcVBgorBgEE
|
|
# AYI3AwMBMYIXBTCCFwEGCSqGSIb3DQEHAqCCFvIwghbuAgEDMQ8wDQYJYIZIAWUD
|
|
# BAIBBQAwggFZBgsqhkiG9w0BCRABBKCCAUgEggFEMIIBQAIBAQYKKwYBBAGEWQoD
|
|
# ATAxMA0GCWCGSAFlAwQCAQUABCCdWLvdpm26AY4dte05VMulpazCHWPb404X6TRR
|
|
# ryYWfwIGYhe2c+qrGBMyMDIyMDQwNjAxMDYwNy40MjRaMASAAgH0oIHYpIHVMIHS
|
|
# MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
|
|
# bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRN
|
|
# aWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsTHVRo
|
|
# YWxlcyBUU1MgRVNOOjhENDEtNEJGNy1CM0I3MSUwIwYDVQQDExxNaWNyb3NvZnQg
|
|
# VGltZS1TdGFtcCBTZXJ2aWNloIIRaDCCBxQwggT8oAMCAQICEzMAAAGILs3GgUHh
|
|
# vCoAAQAAAYgwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
|
|
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
|
|
# dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB
|
|
# IDIwMTAwHhcNMjExMDI4MTkyNzQwWhcNMjMwMTI2MTkyNzQwWjCB0jELMAkGA1UE
|
|
# BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
|
|
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0
|
|
# IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNT
|
|
# IEVTTjo4RDQxLTRCRjctQjNCNzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3Rh
|
|
# bXAgU2VydmljZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJrnEAgE
|
|
# JpHFx8g61eEvPFXiYNlxqjSnFqbK2qUShVnIYYy7H/zPVzfW4M5yzePAVzwLTpcK
|
|
# HnQdpDeG2XTz9ynUTW2KtbTRVIfFJ5owgq/goy5a4oB3JktEfq7DdoATF5SxGYdl
|
|
# vwjrg/VTi7G9j9ow6eN91eK1AAFFvNjO64PNXdznHLTvtV1tYdxLW0LUukBJMOg2
|
|
# CLr31+wMPI1x2Z7DLoD/GQNaLaa6UzVIf80Vguwicgc8pkCA0gnVoVXw+LIcXvkb
|
|
# OtWsX9u204OR/1f0pDXfYczOjav8tjowyqy7bjfYUud+evboUzUHgIQFQ33h6RM5
|
|
# TL7Vzsl+jE5nt45x3Rz4+hi0/QDESKwH/eoT2DojxAbx7a4OjKYiN/pejZW0jrNe
|
|
# vxU3pY09frHbFhrRU2b3mvaQKldWge/eWg5JmerEZuY7XZ1Ws36Fqx3d7w3od+Vl
|
|
# dPL1uE5TnxHFdvim2oqz8WhZCePrZbCfjH7FTok6/2Zw4GjGh5886IHpSNwKHw1P
|
|
# SE2zJE7U8ayz8oE20XbW6ba5y8wZ9o80eEyX5EKPoc1rmjLuTrTGYildiOTDtJtZ
|
|
# irlAIKKvuONi8PAkLo/RAthfJ02yW9jXFA4Pu+HYCYrPz/AWvzq5cVvk64HOkzxs
|
|
# QjrU+9/VKnrJb1g+qzUOlBDvX+71g5IXdr7bAgMBAAGjggE2MIIBMjAdBgNVHQ4E
|
|
# FgQUZHm1UMSju867vfqNuxoz5YzJSkowHwYDVR0jBBgwFoAUn6cVXQBeYl2D9OXS
|
|
# ZacbUzUZ6XIwXwYDVR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNyb3NvZnQu
|
|
# Y29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIw
|
|
# MTAoMSkuY3JsMGwGCCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0cDovL3d3
|
|
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1lLVN0
|
|
# YW1wJTIwUENBJTIwMjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAK
|
|
# BggrBgEFBQcDCDANBgkqhkiG9w0BAQsFAAOCAgEAQBBa2/tYCCbL/xii0ts2r5tn
|
|
# pNe+5pOMrugbkulYiLi9HttGDdnXV3olIRHYZNxUbaPxg/d5OUiMjSel/qfLkDDs
|
|
# SNt2DknchMyycIe/n7btCH/Mt8egCdEtXddjme37GKpYx1HnHJ3kvQ1qoqR5PLjP
|
|
# JtmWwYUZ1DfDOIqoOK6CRpmSmfRXPGe2RyYDPe4u3yMgPYSR9Ne89uVqwyZcWqQ+
|
|
# XZjMjcs83wFamgcnpgqAZ+FZEQhjSEsdMUZXG/d1uhDYSRdTQYzJd3ClRB1uHfGN
|
|
# DWYaXVw7Xi5PR4GycngiNnzfRgawktQdWpPtfeDxomSi/PoLSuzaKwKADELxZGIK
|
|
# x61gmH41ej6LgtzfgOsDga3JFTh0/T1CAyuQAwh+Ga2kInXkvSw/4pihzNyOImsz
|
|
# 5KHB3BRwfcqOXfZTCWfqZwAFoJUEIzFoVKpxP5ZQPhKo2ztJQMZZlLVYqFVLMIU9
|
|
# 6Sug4xUVzPy1McE7bbn89cwYxC5ESGfLgstWJDMXwRcBKLP0BSJQ2hUr1J+CIlmQ
|
|
# N1S3wBI8udYicCto0iB8PtW4wiPhQR3Ak0R9qT9/oeQ5UOQGf3b3HzawEz9cMM9u
|
|
# SK/CoCjmx0QiGB+FSNla5jm6EhxRu/SWx3ZD1Uo3y8U7k7KIeRc6FNbebqxtK8Lp
|
|
# aGWRWcU5K8X8k5Ib5owwggdxMIIFWaADAgECAhMzAAAAFcXna54Cm0mZAAAAAAAV
|
|
# MA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
|
|
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
|
|
# cmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRo
|
|
# b3JpdHkgMjAxMDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMyMjVaMHwxCzAJ
|
|
# BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
|
|
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jv
|
|
# c29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
|
|
# MIICCgKCAgEA5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51yMo1V/YBf2xK
|
|
# 4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY6GB9alKDRLem
|
|
# jkZrBxTzxXb1hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9cmmvHaus9ja+
|
|
# NSZk2pg7uhp7M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN7928jaTjkY+y
|
|
# OSxRnOlwaQ3KNi1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDuaRr3tpK56KTes
|
|
# y+uDRedGbsoy1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74kpEeHT39IM9z
|
|
# fUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2K26oElHovwUD
|
|
# o9Fzpk03dJQcNIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5TI4CvEJoLhDq
|
|
# hFFG4tG9ahhaYQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZki1ugpoMhXV8w
|
|
# dJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9QBXpsxREdcu+N
|
|
# +VLEhReTwDwV2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3PmriLq0CAwEAAaOC
|
|
# Ad0wggHZMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYEFCqnUv5k
|
|
# xJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJlpxtTNRnpcjBc
|
|
# BgNVHSAEVTBTMFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNodHRwOi8v
|
|
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wEwYD
|
|
# VR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYD
|
|
# VR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxi
|
|
# aNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3Nv
|
|
# ZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMu
|
|
# Y3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNy
|
|
# b3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQw
|
|
# DQYJKoZIhvcNAQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/ypb+pcFLY+Tkdk
|
|
# eLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulmZzpTTd2YurYe
|
|
# eNg2LpypglYAA7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM9W0jVOR4U3Uk
|
|
# V7ndn/OOPcbzaN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECWOKz3+SmJw7wX
|
|
# sFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4FOmRsqlb30mj
|
|
# dAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3UwxTSwethQ/gpY
|
|
# 3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPXfx5bRAGOWhmR
|
|
# aw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVXVAmxaQFEfnyh
|
|
# YWxz/gq77EFmPWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGConsXHRWJjXD+
|
|
# 57XQKBqJC4822rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU5nR0W2rRnj7t
|
|
# fqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEGahC0HVUzWLOh
|
|
# cGbyoYIC1zCCAkACAQEwggEAoYHYpIHVMIHSMQswCQYDVQQGEwJVUzETMBEGA1UE
|
|
# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
|
|
# b2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVy
|
|
# YXRpb25zIExpbWl0ZWQxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjhENDEtNEJG
|
|
# Ny1CM0I3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMK
|
|
# AQEwBwYFKw4DAhoDFQDhPIrMfCAXlT0sHg/NOZeUHXoOQqCBgzCBgKR+MHwxCzAJ
|
|
# BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
|
|
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jv
|
|
# c29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBBQUAAgUA5fbvvzAi
|
|
# GA8yMDIyMDQwNjAwNDEzNVoYDzIwMjIwNDA3MDA0MTM1WjB3MD0GCisGAQQBhFkK
|
|
# BAExLzAtMAoCBQDl9u+/AgEAMAoCAQACAgXaAgH/MAcCAQACAhE0MAoCBQDl+EE/
|
|
# AgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSCh
|
|
# CjAIAgEAAgMBhqAwDQYJKoZIhvcNAQEFBQADgYEAW1J5eEMYfXtkrKOyiWqaFA4R
|
|
# x3RqsLVl75o4q9FJxFP7PPk6m8Qaj3ESciGapxXCv4Nv1MD7PIDpn6bKST40F6tH
|
|
# sznFFom9WNjwplWtKNzbKaYa4kXQK3ukxPGuV2Yw/novhKINInuVm8P0X/EJVKqP
|
|
# EL69eT7TX4RlPIagR/wxggQNMIIECQIBATCBkzB8MQswCQYDVQQGEwJVUzETMBEG
|
|
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
|
|
# cm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFt
|
|
# cCBQQ0EgMjAxMAITMwAAAYguzcaBQeG8KgABAAABiDANBglghkgBZQMEAgEFAKCC
|
|
# AUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEiBCBL
|
|
# vuSd2Mx1iL1sjaVOqM8qabl4AW7nM2zwRy41rWQ6WDCB+gYLKoZIhvcNAQkQAi8x
|
|
# geowgecwgeQwgb0EIGbp3u2sBjdGhIL4z+ycjtzSpe4bLV/AoYaypl7SSUClMIGY
|
|
# MIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV
|
|
# BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQG
|
|
# A1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAGILs3GgUHh
|
|
# vCoAAQAAAYgwIgQgKV07MmZcr+UzefVb+VjcB4hQAcjmV7CgmGfP12IKnggwDQYJ
|
|
# KoZIhvcNAQELBQAEggIAAXe2ksrmocLIrH+I/lKdAuE0jlbAHiUoRWW675PnesZ7
|
|
# YevQsri4WoZN7rUDEXvnTXdTm5ShGMD/DLK8ctZkpBeDYgHEf/fNYkxnN6wx2A/I
|
|
# VzBk9V4HmUCP8285btTtZXF4jw4Trk7WS+zZZKXtMtZswkSAvahOHinwhS/W7SP7
|
|
# 0xT9RNU40b+5sd9O+hHLXZIicMLO4rD0dgwXT44b94aTYZyQmDzBS1QITA3zEuy8
|
|
# dtUuZDuRYxlNhaUzJQyKq3p8RtwQC3Ad//CtxZ4Q6IseIG4IwjlRajYuUi6n+YGK
|
|
# wCzewOl0bn+P2oL9CjDgsvmO1EdRxeIK4f6rfq8IAFIXetZMIi4ei7WT19MS+1hF
|
|
# nZ7VM9L2lSIUkmI+Sxgmp5dnz0jS213UC8eq3kudI96BO3V6leiHXZf1GD0LsPoS
|
|
# xs7NilsAtbVq30Bi8foKMW99JosWFG9tqUDSCBSAvMC0jaXj0oZA772TMtk9zyhJ
|
|
# 7F7c3DxjXDmUqIpGcMjyIDteyyZNCVC4O7/DmB+t0Vcwj44gseQdCqpJbWCc8IZ6
|
|
# +8gxWBekvUzzY8rCoYu0fIFWCtq6TfkrrwCJ7TY+6fhmGko7Z/Bfw+5AMiL0/0u5
|
|
# VVWMrCrJIuN44/1LWJyhMHN0b/6g4THgPcV5GHB2dbJ6xpi8ideoTGqCOWu5JAQ=
|
|
# SIG # End signature block
|