Public/Uninstall-AWSToolsModule.ps1
|
<#
.Synopsis Uninstalls AWS.Tools modules with comprehensive filtering options. .Description This cmdlet removes AWS.Tools modules by deleting their directories from the file system. This approach is significantly faster than using Uninstall-Module. The function supports filtering by module name and version. AWS.Tools.Installer is excluded and must be managed using Uninstall-AWSToolsInstaller. .Parameter Name Specifies names of the AWS.Tools modules to uninstall. All AWS.Tools modules are uninstalled by default. The names can be listed either with or without the "AWS.Tools." prefix (i.e. "AWS.Tools.Common" or simply "Common"). When this parameter is specified, you will be prompted to confirm the uninstallation of each individual module, allowing for more granular control over which modules are removed. Note: AWS.Tools.Installer cannot be specified here. Use Uninstall-AWSToolsInstaller to manage the installer module. .Parameter Version Specifies exact version number of the module to uninstall. .Parameter MinimumVersion Specifies the minimum version of the modules to uninstall. This parameter is deprecated and should no longer be used as it will be removed in the next major version. .Parameter MaximumVersion Specifies the maximum version of the modules to uninstall. This parameter is deprecated and should no longer be used as it will be removed in the next major version. .Parameter Force This parameter is deprecated and should no longer be used as it will be removed in the next major version. Use -ConfirmImpact:False to run without asking for user confirmation. .Parameter ExceptVersion Specifies that you want to uninstall all of the other available versions of AWS Tools except this one. This parameter is deprecated in favor of ExceptModules. It will be removed in a future major version. .Parameter ExceptModules Specifies an array of hashtables containing module names and versions to exclude from uninstallation. Each hashtable must contain 'Name' and 'Version' keys. This parameter provides more granular control over which specific module versions to preserve during cleanup operations. Each hashtable must contain 'Name' and 'Version' keys: @{ Name = 'AWS.Tools.Common'; Version = '5.0.8' } @{ Name = 'AWS.Tools.S3'; Version = '5.0.8' } Example: Uninstall-AWSToolsModule -ExceptModules @( @{ Name = 'AWS.Tools.Common'; Version = '5.0.8' } @{ Name = 'AWS.Tools.S3'; Version = '5.0.8' } ) .Parameter CleanUpLegacyScope Runs a separate cleanup of all instances of AWSPowerShell and AWSPowerShell.NetCore found in the specified scope. The acceptable values for this parameter are AllUsers and CurrentUser. .Parameter Scope Specifies the installation scope to target for uninstallation. The acceptable values for this parameter are AllUsers and CurrentUser. The AllUsers scope targets modules in a location that is accessible to all users of the computer. The CurrentUser targets modules in a location that is accessible only to the current user of the computer. Default value is 'CurrentUser'. Ignored if Path parameter is specified. .Parameter Path Specifies a custom path where AWS Tools modules are installed. When specified, modules will be uninstalled from this location instead of the standard scope-based paths. This is useful for testing scenarios or custom installation locations. .Notes This cmdlet uses Remove-ModuleItem to delete module directories for improved performance and consistent error handling. .Example Uninstall-AWSToolsModule -ExceptVersion 4.0.0.0 -Confirm:$false This example uninstalls all versions of all AWS.Tools modules except for version 4.0.0.0. .Example Uninstall-AWSToolsModule -ExceptModules @( @{ Name = 'AWS.Tools.Common'; Version = '5.0.8' } @{ Name = 'AWS.Tools.S3'; Version = '5.0.8' } ) -Confirm:$false This example provides granular control over cleanup, preserving specific versions of AWS.Tools.Common and AWS.Tools.S3 while uninstalling all other modules. .Example Uninstall-AWSToolsModule -Version 4.1.754 -Confirm:$false This example uninstalls only version 4.1.754 of all AWS.Tools modules. .Example Uninstall-AWSToolsModule -Name EC2,S3 -Confirm:$false This example uninstalls all versions of only the EC2 and S3 modules, with individual confirmation prompts for each module. .Example Uninstall-AWSToolsModule -CleanUpLegacyScope CurrentUser -Confirm:$false This example uninstalls all AWS.Tools modules and also removes legacy AWSPowerShell modules from the current user's scope. .Example Uninstall-AWSToolsModule -Scope AllUsers -Confirm:$false This example uninstalls AWS.Tools modules from the system-wide installation location. .Example Uninstall-AWSToolsModule -Path "C:\CustomModules" -Confirm:$false This example uninstalls AWS.Tools modules from a custom installation path. .Example Uninstall-AWSToolsModule -WhatIf This example performs a what-if analysis to preview what modules would be removed without making changes. .Example Uninstall-AWSToolsModule -Scope AllUsers This example removes AWS.Tools modules from the system-wide location with explicit confirmation prompts. #> function Uninstall-AWSToolsModule { [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High', DefaultParameterSetName = 'Default')] Param( [Parameter()] [string[]] [Alias('ModuleName')] $Name, [Parameter(ParameterSetName = 'Version')] [string] $Version, [Parameter(ParameterSetName = 'Version')] [Version] $MinimumVersion, [Parameter(ParameterSetName = 'Version')] [Version] $MaximumVersion, [Parameter(ParameterSetName = 'ExceptVersion')] [string] $ExceptVersion, [Parameter(ParameterSetName = 'ExceptModules')] [hashtable[]] $ExceptModules, [Parameter()] [ValidateSet('CurrentUser', 'AllUsers')] [string] $CleanUpLegacyScope, [Parameter()] [ValidateSet('CurrentUser', 'AllUsers')] [string] $Scope = 'CurrentUser', [Parameter()] [string] $Path, [Parameter()] [switch] $Force, [Parameter(ParameterSetName = 'Version')] [Parameter(ParameterSetName = 'ExceptVersion')] [Alias('AllowPrerelease')] [switch] $Prerelease ) Begin { # Validate prerelease parameter usage for Version and ExceptVersion if ($PSCmdlet.ParameterSetName -eq 'Version' -or $PSCmdlet.ParameterSetName -eq 'ExceptVersion') { $versionToValidate = if ($PSCmdlet.ParameterSetName -eq 'Version') { $Version } else { $ExceptVersion } if ($versionToValidate) { try { $versionFlags = Test-PrereleaseParameterValidation -Version $versionToValidate -Prerelease $Prerelease -ModuleName 'AWS.Tools' } catch { $PSCmdlet.ThrowTerminatingError($_) } } } # Reject wildcards in Version and ExceptVersion parameters if ($Version -and $Version -like '*`**') { $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( ([System.ArgumentException]"Wildcard versions are not supported for uninstall operations. Please specify an exact version (e.g., 5.0.151) or use the ExceptVersion parameter to uninstall all versions except a specific one."), 'WildcardNotSupported', [System.Management.Automation.ErrorCategory]::InvalidArgument, $Version ) ) } if ($ExceptVersion -and $ExceptVersion -like '*`**') { $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( ([System.ArgumentException]"Wildcard versions are not supported in the ExceptVersion parameter. Please specify an exact version (e.g., 5.0.151)."), 'WildcardNotSupported', [System.Management.Automation.ErrorCategory]::InvalidArgument, $ExceptVersion ) ) } # Only call Get-CleanVersion on non-semver strings (Get-CleanVersion expects [Version] type) # For semver strings (e.g., "5.0.0-preview001"), keep them as-is if ($Version -and $Version -notmatch '^\d+\.\d+\.\d+-.+$') { $Version = Get-CleanVersion $Version } $MinimumVersion = Get-CleanVersion $MinimumVersion $MaximumVersion = Get-CleanVersion $MaximumVersion if ($ExceptVersion -and $ExceptVersion -notmatch '^\d+\.\d+\.\d+-.+$') { $ExceptVersion = Get-CleanVersion $ExceptVersion } # Deprecation warnings for restored parameters if ($MinimumVersion) { Write-Warning "The MinimumVersion parameter is deprecated and should no longer be used as it will be removed in the next major version." } if ($MaximumVersion) { Write-Warning "The MaximumVersion parameter is deprecated and should no longer be used as it will be removed in the next major version." } # Deprecation warning for ExceptVersion parameter if ($ExceptVersion) { Write-Warning "The ExceptVersion parameter is deprecated in favor of ExceptModules. It will be removed in a future major version." } # Deprecation warnings for ignored legacy parameters if ($Force) { Write-Warning "The Force parameter is deprecated and should no longer be used as it will be removed in the next major version." } # Validate ExceptModules parameter if ($ExceptModules) { if ($ExceptModules.Count -eq 0) { $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( ([System.ArgumentException]"ExceptModules parameter cannot be an empty array."), 'EmptyExceptModules', [System.Management.Automation.ErrorCategory]::InvalidArgument, $ExceptModules ) ) } foreach ($moduleInfo in $ExceptModules) { # Validate hashtable structure if (-not $moduleInfo.ContainsKey('Name') -or -not $moduleInfo.ContainsKey('Version')) { $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( ([System.ArgumentException]"Invalid hashtable structure in ExceptModules. Each hashtable must contain 'Name' and 'Version' keys. Example: @{ Name = 'AWS.Tools.S3'; Version = '5.0.8' }"), 'InvalidExceptModulesStructure', [System.Management.Automation.ErrorCategory]::InvalidArgument, $moduleInfo ) ) } # Validate module name format $moduleName = $moduleInfo['Name'] if ($moduleName -notlike 'AWS.Tools*') { $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( ([System.ArgumentException]"Invalid module name '$moduleName' in ExceptModules. Module names must start with 'AWS.Tools'"), 'InvalidExceptModulesName', [System.Management.Automation.ErrorCategory]::InvalidArgument, $moduleName ) ) } # Validate version format (support both standard versions and semver with prerelease tags) $moduleVersion = $moduleInfo['Version'] try { # Check if it's a semver string with prerelease tag if ($moduleVersion -match '^(\d+\.\d+\.\d+)-.+$') { # Validate the base version part [void][Version]::Parse($Matches[1]) } else { # Standard version validation [void][Version]::Parse($moduleVersion) } } catch { $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( ([System.ArgumentException]"Invalid version '$moduleVersion' for module '$moduleName' in ExceptModules. Version must be a valid semantic version."), 'InvalidExceptModulesVersion', [System.Management.Automation.ErrorCategory]::InvalidArgument, $moduleVersion ) ) } } } # Parameter validation for version ranges if ($MinimumVersion -and $MaximumVersion -and $MinimumVersion -gt $MaximumVersion) { $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( ([System.ArgumentException]"Parameter MinimumVersion ($MinimumVersion) cannot be greater than MaximumVersion ($MaximumVersion)."), 'InvalidVersionRange', [System.Management.Automation.ErrorCategory]::InvalidArgument, $MinimumVersion ) ) } Write-Verbose ("[$($MyInvocation.MyCommand)] ConfirmPreference=$ConfirmPreference " + "WhatIfPreference=$WhatIfPreference VerbosePreference=$VerbosePreference " + "Scope=$Scope Name=($($Name -join ',')) MinimumVersion=$MinimumVersion MaximumVersion=$MaximumVersion") # Initialize progress Write-Progress -Activity "Uninstalling AWS.Tools modules" -Status "Initializing..." -PercentComplete 0 } Process { $ErrorActionPreference = 'Stop' # Check for imported modules that would prevent uninstallation. Get-Module without # -ListAvailable is fast (only loaded modules in this session). $importedModules = Get-Module -Name 'AWS.Tools*', 'AWSPowerShell*' | Where-Object { $_.Name -ne 'AWS.Tools.Installer' } # If modules are being uninstalled by name, filter imported modules to only those being uninstalled # When using ExceptVersion, we're uninstalling all modules except the specified version, so don't filter if ($Name -and -not $ExceptVersion) { $normalizedNames = $Name | ForEach-Object { if ($_.Contains('.')) { $_ } else { "AWS.Tools.$_" } } $importedModules = $importedModules | Where-Object { $moduleName = $_.Name $normalizedNames | Where-Object { $moduleName -eq $_ } } } # Check for imported modules that would prevent uninstallation $importedAWSToolsModules = $importedModules | Where-Object { $_.Name -like 'AWS.Tools*' } $importedLegacyModules = if ($CleanUpLegacyScope) { $importedModules | Where-Object { $_.Name -like 'AWSPowerShell*' } } else { @() } # Combine all imported modules that would prevent uninstallation $allImportedModules = @() if ($importedAWSToolsModules) { $allImportedModules += $importedAWSToolsModules } if ($importedLegacyModules) { $allImportedModules += $importedLegacyModules } if ($allImportedModules.Count -gt 0) { $moduleDetails = $allImportedModules | ForEach-Object { "$($_.Name) version $($_.Version)" } $errorMessage = "Cannot uninstall module(s): $($moduleDetails -join ', ') because they are currently imported in this PowerShell session. The module's DLL files are locked and cannot be removed. Close this PowerShell session and start a new PowerShell session to uninstall these modules" # If -WhatIf is specified, set a flag to show a warning after ShouldProcess if ($WhatIfPreference) { # Don't return early - allow the ShouldProcess messages to be displayed # We'll skip the actual uninstallation later and show the warning $skipUninstallation = $true $showWarningAfterShouldProcess = $true } else { $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( ([System.InvalidOperationException]$errorMessage), 'ModuleInUse', [System.Management.Automation.ErrorCategory]::InvalidOperation, $allImportedModules ) ) } } # Validate that AWS.Tools.Installer is not specified if ($Name) { $normalizedNames = $Name | ForEach-Object { if ($_.Contains('.')) { $_ } else { "AWS.Tools.$_" } } $installerNames = $normalizedNames | Where-Object { $_ -eq 'AWS.Tools.Installer' } if ($installerNames) { $PSCmdlet.ThrowTerminatingError( [System.Management.Automation.ErrorRecord]::new( ([System.InvalidOperationException]"AWS.Tools.Installer cannot be uninstalled using Uninstall-AWSToolsModule. Use Uninstall-AWSToolsInstaller instead."), 'InstallerModuleSpecified', [System.Management.Automation.ErrorCategory]::InvalidOperation, $installerNames ) ) } } Write-Progress -Activity "Uninstalling AWS.Tools modules" -Status "Checking for imported modules..." -PercentComplete 10 Write-Verbose "[$($MyInvocation.MyCommand)] Searching installed modules" # Get target path - either custom Path or scope-based path $targetPath = if ($Path) { Write-Verbose "[$($MyInvocation.MyCommand)] Using specified path: $Path" $Path } else { $scopePath = Get-PSModulePath -Scope $Scope Write-Verbose "[$($MyInvocation.MyCommand)] Using $Scope scope path: $scopePath" $scopePath } Write-Progress -Activity "Uninstalling AWS.Tools modules" -Status "Searching for installed modules..." -PercentComplete 30 # Get and filter modules (AWS.Tools.Installer is automatically excluded). This call # walks the target path on disk — typically the slowest step in uninstall. $moduleGroups = Get-ModulesToProcess -TargetPath $targetPath -Name $Name -Version $Version -ExceptVersion $ExceptVersion -ExceptModules $ExceptModules $modules = $moduleGroups.Regular # Apply MinimumVersion and MaximumVersion filtering if specified if ($MinimumVersion -and $modules) { $modules = @($modules | Where-Object { (Get-CleanVersion $_.Version) -ge $MinimumVersion }) Write-Verbose ("[$($MyInvocation.MyCommand)] Filtered modules by MinimumVersion $($MinimumVersion): $($modules.Count) modules remain") } if ($MaximumVersion -and $modules) { $modules = @($modules | Where-Object { (Get-CleanVersion $_.Version) -le $MaximumVersion }) Write-Verbose ("[$($MyInvocation.MyCommand)] Filtered modules by MaximumVersion $($MaximumVersion): $($modules.Count) modules remain") } # Process AWS.Tools modules if ($modules) { $target = Format-ModuleTarget -Modules $modules -TargetPath $targetPath -ModuleType "AWS.Tools" # Add WhatIf information message if ($WhatIfPreference) { $moduleCount = $modules.Count $versionInfo = if ($Version) { "version $Version" } elseif ($ExceptVersion) { "all versions except $ExceptVersion" } else { "all versions" } Write-Host "What if: Would remove $moduleCount AWS.Tools modules ($versionInfo) from $targetPath" } if ($PSCmdlet.ShouldProcess($target, "Uninstall AWS.Tools modules")) { # Skip actual uninstallation if modules are imported and WhatIf is specified if (-not $skipUninstallation -or -not $WhatIfPreference) { # Initialize result tracking $result = [PSCustomObject]@{ SuccessCount = 0 FailureCount = 0 RemovedModules = @() FailedModules = @() } if ($Name) { # Per-module path: -Name was specified, so the user expects per-module # ShouldProcess prompts. Keep Remove-ModuleItem (sequential, with retry). $totalModules = $modules.Count $currentModule = 0 foreach ($module in $modules) { $currentModule++ $percentComplete = [Math]::Min([Math]::Round(($currentModule / $totalModules) * 100), 100) $moduleName = $module.Name $moduleVersion = Get-ModuleVersionString -Module $module if ($PSVersionTable.PSVersion.Major -ge 6) { Write-Progress -Activity "Uninstalling AWS.Tools modules" -Status "Processing $moduleName ($moduleVersion) - Module $currentModule of $totalModules" -PercentComplete $percentComplete } Write-Verbose ("[$($MyInvocation.MyCommand)] Removing module: $moduleName " + "version $moduleVersion") $moduleTarget = "$moduleName version $moduleVersion at $($module.ModuleBase)" if ($PSCmdlet.ShouldProcess($moduleTarget, "Uninstall module")) { $moduleResult = Remove-ModuleItem -Module $module -Reason "Uninstall module" } else { $moduleResult = [PSCustomObject]@{ SuccessCount = 0 FailureCount = 0 RemovedModules = @() FailedModules = @() } } $result.SuccessCount += $moduleResult.SuccessCount $result.FailureCount += $moduleResult.FailureCount $result.RemovedModules += $moduleResult.RemovedModules $result.FailedModules += $moduleResult.FailedModules } } else { # Bulk path: no per-module ShouldProcess prompts needed (top-level # ShouldProcess already approved). Hand the full path list to the # precompiled DLL for parallel deletion. Per user direction, do not # report per-module success on this path; only failures are reported. Write-Verbose ("[$($MyInvocation.MyCommand)] Bulk parallel delete via " + "[Amazon.PowerShell.Installer.ModuleInstaller]::DeleteDirectoriesParallel") Write-Progress -Activity "Uninstalling AWS.Tools modules" -Status "Removing $($modules.Count) modules in parallel..." -PercentComplete 50 [string[]]$paths = @($modules | ForEach-Object { $_.ModuleBase }) $pathToModule = @{} foreach ($m in $modules) { $pathToModule[$m.ModuleBase] = $m } # Best-effort: PS 7.4+ exposes $PSCmdlet.StoppingToken; older shells # (notably Windows PowerShell 5.1) do not. $ct = if ($PSCmdlet.PSObject.Properties['StoppingToken']) { $PSCmdlet.StoppingToken } else { [System.Threading.CancellationToken]::None } $failedPaths = [Amazon.PowerShell.Installer.ModuleInstaller]::DeleteDirectoriesParallel($paths, $ct) $result.SuccessCount = $paths.Count - $failedPaths.Count $result.FailureCount = $failedPaths.Count $result.FailedModules = @($failedPaths | ForEach-Object { $m = $pathToModule[$_] if ($m) { "$($m.Name) ($(Get-ModuleVersionString -Module $m))" } else { $_ } }) # RemovedModules left empty on bulk path per user direction (too noisy). } if ($result.FailureCount -gt 0) { Write-Warning ("Failed to remove $($result.FailureCount) modules: " + "$($result.FailedModules -join ', ')") } else { Write-Verbose ("[$($MyInvocation.MyCommand)] Successfully removed " + "$($result.SuccessCount) AWS.Tools modules") # Provide removal summary via Write-Host if ($result.SuccessCount -gt 0) { $versionInfo = if ($Version) { "version $Version" } elseif ($ExceptVersion) { "all versions except $ExceptVersion" } else { "all versions" } Write-Host "Removed $($result.SuccessCount) AWS Tools modules ($versionInfo) from $targetPath" } } } } } else { Write-Verbose ("[$($MyInvocation.MyCommand)] No AWS.Tools modules found " + "matching the specified criteria") if ($ExceptModules -or $ExceptVersion) { Write-Host "Skipped uninstallation: No other AWS.Tools module versions found to remove in $targetPath" } else { $versionInfo = if ($Version) { "version $Version" } else { "all versions" } Write-Host "Skipped uninstallation: No AWS.Tools modules found ($versionInfo) in $targetPath" } } # Handle legacy module cleanup if requested if ($CleanUpLegacyScope) { Write-Verbose ("[$($MyInvocation.MyCommand)] Cleaning up legacy AWSPowerShell modules " + "in $CleanUpLegacyScope scope") $legacyPath = Get-PSModulePath -Scope $CleanUpLegacyScope # @(...) because return unrolls a one-element array to a scalar (no .Count on 5.1). $legacyModules = @(Get-LegacyModules -TargetPath $legacyPath) if ($legacyModules) { $legacyTarget = Format-ModuleTarget -Modules $legacyModules -TargetPath $legacyPath -ModuleType "Legacy AWSPowerShell" # Add WhatIf information message for legacy modules if ($WhatIfPreference) { $legacyModuleCount = $legacyModules.Count Write-Host "What if: Would remove $legacyModuleCount legacy AWSPowerShell modules from $legacyPath" } if ($PSCmdlet.ShouldProcess($legacyTarget, "Clean up legacy AWSPowerShell modules")) { # Skip actual uninstallation if modules are imported and WhatIf is specified if (-not $skipUninstallation -or -not $WhatIfPreference) { # Initialize result tracking for legacy modules $legacyResult = [PSCustomObject]@{ SuccessCount = 0 FailureCount = 0 RemovedModules = @() FailedModules = @() } $totalLegacyModules = $legacyModules.Count $currentLegacyModule = 0 # Process each legacy module with progress reporting foreach ($module in $legacyModules) { $currentLegacyModule++ $percentComplete = [Math]::Min([Math]::Round(($currentLegacyModule / $totalLegacyModules) * 100), 100) $moduleName = $module.Name $moduleVersion = $module.Version.ToString() # Update progress bar with current module name and progress Write-Progress -Activity "Cleaning up legacy AWSPowerShell modules" -Status "Processing $moduleName ($moduleVersion) - Module $currentLegacyModule of $totalLegacyModules" -PercentComplete $percentComplete Write-Verbose ("[$($MyInvocation.MyCommand)] Removing legacy module: $moduleName " + "version $moduleVersion") # Use Remove-ModuleItem for actual removal $moduleResult = Remove-ModuleItem -Module $module -Reason "Clean up legacy AWSPowerShell modules" # Consolidate results $legacyResult.SuccessCount += $moduleResult.SuccessCount $legacyResult.FailureCount += $moduleResult.FailureCount $legacyResult.RemovedModules += $moduleResult.RemovedModules $legacyResult.FailedModules += $moduleResult.FailedModules } if ($legacyResult.FailureCount -gt 0) { Write-Warning ("Failed to remove $($legacyResult.FailureCount) legacy modules: " + "$($legacyResult.FailedModules -join ', ')") } elseif ($legacyResult.SuccessCount -gt 0) { # Provide legacy removal summary via Write-Host Write-Host "Removed $($legacyResult.SuccessCount) legacy AWSPowerShell modules from $legacyPath" } } } } else { Write-Verbose ("[$($MyInvocation.MyCommand)] No legacy AWSPowerShell modules found " + "in $CleanUpLegacyScope scope") Write-Host "Skipped legacy cleanup: No AWSPowerShell modules found in $legacyPath" } } } End { # Show the warning after all ShouldProcess messages if ($showWarningAfterShouldProcess -and $WhatIfPreference) { $moduleDetails = $allImportedModules | ForEach-Object { "$($_.Name) version $($_.Version)" } $errorMessage = "Cannot uninstall module(s): $($moduleDetails -join ', ') because they are currently imported in this PowerShell session. The module's DLL files are locked and cannot be removed. Close this PowerShell session and start a new PowerShell session to uninstall these modules" Write-Warning $errorMessage } # Complete all progress bars Write-Progress -Activity "Uninstalling AWS.Tools modules" -Completed Write-Progress -Activity "Cleaning up legacy AWSPowerShell modules" -Completed Write-Verbose "[$($MyInvocation.MyCommand)] End" } } # SIG # Begin signature block # MIIutAYJKoZIhvcNAQcCoIIupTCCLqECAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCC2eQDfk0uXT6Se # vvoeBe6UkvkQ0IdmlyUwNvSMQ4So1aCCE+owggXAMIIEqKADAgECAhAP0bvKeWvX # +N1MguEKmpYxMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzApBgNV # BAMTIkRpZ2lDZXJ0IEhpZ2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0EwHhcNMjIwMTEz # MDAwMDAwWhcNMzExMTA5MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMM # RGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQD # ExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqGSIb3DQEBAQUAA4IC # DwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEppz1Yq3aa # za57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllV # cq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT # +CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd # 463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+ # EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmgZ92k # J7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse5w5j # rubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7 # f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJU # KSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+wh # X8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQAB # o4IBZjCCAWIwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5n # P+e6mK4cD08wHwYDVR0jBBgwFoAUsT7DaQP4v0cB1JgmGggC72NkK8MwDgYDVR0P # AQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMH8GCCsGAQUFBwEBBHMwcTAk # BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEkGCCsGAQUFBzAC # hj1odHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRIaWdoQXNzdXJh # bmNlRVZSb290Q0EuY3J0MEsGA1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwzLmRp # Z2ljZXJ0LmNvbS9EaWdpQ2VydEhpZ2hBc3N1cmFuY2VFVlJvb3RDQS5jcmwwHAYD # VR0gBBUwEzAHBgVngQwBAzAIBgZngQwBBAEwDQYJKoZIhvcNAQELBQADggEBAEHx # qRH0DxNHecllao3A7pgEpMbjDPKisedfYk/ak1k2zfIe4R7sD+EbP5HU5A/C5pg0 # /xkPZigfT2IxpCrhKhO61z7H0ZL+q93fqpgzRh9Onr3g7QdG64AupP2uU7SkwaT1 # IY1rzAGt9Rnu15ClMlIr28xzDxj4+87eg3Gn77tRWwR2L62t0+od/P1Tk+WMieNg # GbngLyOOLFxJy34riDkruQZhiPOuAnZ2dMFkkbiJUZflhX0901emWG4f7vtpYeJa # 3Cgh6GO6Ps9W7Zrk9wXqyvPsEt84zdp7PiuTUy9cUQBY3pBIowrHC/Q7bVUx8ALM # R3eWUaNetbxcyEMRoacwggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G # CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C # 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce # 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da # E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T # SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA # FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh # D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM # 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z # 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05 # huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY # mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP # /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T # AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD # VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG # A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY # aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj # ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV # HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU # cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN # BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry # sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL # IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf # Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh # OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh # dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV # 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j # wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH # Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC # XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l # /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW # eE4wggduMIIFVqADAgECAhACkbBFv37tbsDucbrJZmQsMA0GCSqGSIb3DQEBCwUA # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwHhcNMjYwNDEzMDAwMDAwWhcNMjcwNDEyMjM1OTU5WjCB9jET # MBEGCysGAQQBgjc8AgEDEwJVUzEZMBcGCysGAQQBgjc8AgECEwhEZWxhd2FyZTEd # MBsGA1UEDwwUUHJpdmF0ZSBPcmdhbml6YXRpb24xEDAOBgNVBAUTBzQxNTI5NTQx # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdTZWF0 # dGxlMSIwIAYDVQQKExlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRcwFQYDVQQL # Ew5TREtzIGFuZCBUb29sczEiMCAGA1UEAxMZQW1hem9uIFdlYiBTZXJ2aWNlcywg # SW5jLjCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKAYfPWODy5W775n # g6Qb7qn45ScvlDKKwv740oW7PjXysv4iETo57UU0QPbw1hCvKP5EbB7jGSSXvfnw # 6Zb1mhXb22f1EFgnsLdUHE3fGu1EBlkwd6lUu1G4rrsctxyYsJrrR2O044WI+WQQ # GkeRMnlxD5a9kveXWkEe5z9Dz52DetD1Z0dP/mgRsdOoT/tvKFN84LvT36oq0YFx # 8Cxn4XYe1VekrYMKZ//nk25GIswcdVTASFnWffSUPEWwPQgRyEE2EBLs1QlRDsRo # KGC4pelMzoZj+ka98JlyoWn3MFnwnO/i+XwVrdi9HgPvwI3QdmipMa6FXIIlGPhj # E73unbRwck60qHaBkh5uWkuJhJU0n6iy1aYCOONp/HUvFjrXI+U5+M3c6ZaJKneI # +z7oJI1c/ELbCMdNFNLgdZN+YbxKGBFYQAuqG4Y4KUMTkF/HD1y2JPm7aTHryrIE # TD1LT4vlwK+KPaODWpJgRSwHw6wEdjHbPgug+7kosXqqUGbC3QIDAQABo4ICAjCC # Af4wHwYDVR0jBBgwFoAUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHQYDVR0OBBYEFG/Y # ITb8e/nTXVg4U0Nrg0fSUPtVMD0GA1UdIAQ2MDQwMgYFZ4EMAQMwKTAnBggrBgEF # BQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMA4GA1UdDwEB/wQEAwIH # gDATBgNVHSUEDDAKBggrBgEFBQcDAzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRw # Oi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmlu # Z1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hB # Mzg0MjAyMUNBMS5jcmwwgZQGCCsGAQUFBwEBBIGHMIGEMCQGCCsGAQUFBzABhhho # dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUHMAKGUGh0dHA6Ly9jYWNl # cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNB # NDA5NlNIQTM4NDIwMjFDQTEuY3J0MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQAD # ggIBAIUBjjxjpjf9/pYOyXd+SkZl7jWePeWdmu6IsyuHrq26aL1ckfWVgGvoGJwt # bDzFbfcW0mRvSjdE6PyQ6zLwFgHhgSXbuuyjJZY2cfCxYYvVJ9rD8b80X3QS0RbI # C414xwTjB+D1wUMvY1GvvHFRnkixSPT4+/POuUWPtN8yELHGOwgwv3GTfrWfA2+k # t7iKGNeEVxP3SqNPsyEBWKnn2gVMsH1aGO3eqvSe5pM+Dm5uKACrbtofA7xE/7qo # WTqQ5UtxBD9hLWXMbxQkSuEh63jJGC1rL+LV2cC6iIHm/pu+V9edqCECxB2SKQ2o # Z4ObhHvmxinBYUBJ29XEHoAb8mooXYDFAxEH4o20M3yaoXkeCAYXW5m6UZR8Zpit # i9ZRYNwEvBhDlI5jJzxBdrUeOqLAXLdYk1elPp/hlLSF9t9P19iUSeWCJbdaZJkk # +hcTuxBsD4zXtUkxQYR1nbWCqjt0+H2hcXu5DcNBj7rv/hs7xMLLFY8PqL+QNFaq # 1/GamAZm07r1czJL+gHOTO6MQ01uxWlCTQ2QAkhd6yyS5jyz8LyHfKjiAxNbyLGZ # wqdVzxGI/3+ZgF+N/pcazWfL6XFiQcPJISPMDSRvAZQ0BV1Cz8C52nX0Sq8zzQ6r # 9+JNA/ti3V9KJc6vQwYMlOsjYj2T4Ph3vX/DJs3alLLwLVLRMYIaIDCCGhwCAQEw # fTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNV # BAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hB # Mzg0IDIwMjEgQ0ExAhACkbBFv37tbsDucbrJZmQsMA0GCWCGSAFlAwQCAQUAoHww # EAYKKwYBBAGCNwIBDDECMAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYK # KwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEICAdE2kQ # KMSU9DYCe3UNFRsOvawcoD7Uw2oX4HHle6y0MA0GCSqGSIb3DQEBAQUABIIBgCeN # BwQ1r7p7fcGz+BXu4WHk1LTkj6XYImJppppPBj/vp8EeEmxwy+mtlZ6wEgjN9M+5 # i6klmo/7Uc/+5q55lCeBeAmxdT41CZEtr1C/zZsvfzmyGnd0CKU1INSB2k0bvNHt # Qhi+ax1PGFqzYERKvvWFpYab9TJylrecQHZYlMbHbJNr0qFZklH1VGEXbzz9a+Xv # zj5pIk9V63Gv56kBXGB0pfPdKgDFMjT2FSp0tmcAVOQXi0HCggju+DlD9bY1qMii # daFc1uVOdRIOmNZKfhKS65TtmM7UB/r8pvi3Qd5I7Lo4+JKLrUmQulZ1c4R5rpNJ # oidYS2Qu+rZ885t26OHHDH9GvTdb7pgsdS7Iwcrc9aOOO4y3zZZa3IkjsTToHP0j # oIElTidrw+N5CCLP4/neFdxtqOtagXv/sFhnJiluZJHWW0qmAsbiTvtsxKF0scII # FAFkFZot0XfcSTjiLumuXTBqlCcke0dqdSDC5ZANc3ckOGADpugd+HeurNdtL6GC # F3YwghdyBgorBgEEAYI3AwMBMYIXYjCCF14GCSqGSIb3DQEHAqCCF08wghdLAgED # MQ8wDQYJYIZIAWUDBAIBBQAwdwYLKoZIhvcNAQkQAQSgaARmMGQCAQEGCWCGSAGG # /WwHATAxMA0GCWCGSAFlAwQCAQUABCBoc2cYudhALuihSdSV5TB8VpTUypc3y4cL # GuhD+KJ0mAIQLMhRowuEl0RimZPJnYcG6hgPMjAyNjA4MDQyMjA5MTFaoIITOjCC # Bu0wggTVoAMCAQICEAqA7xhLjfEFgtHEdqeVdGgwDQYJKoZIhvcNAQELBQAwaTEL # MAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhE # aWdpQ2VydCBUcnVzdGVkIEc0IFRpbWVTdGFtcGluZyBSU0E0MDk2IFNIQTI1NiAy # MDI1IENBMTAeFw0yNTA2MDQwMDAwMDBaFw0zNjA5MDMyMzU5NTlaMGMxCzAJBgNV # BAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNl # cnQgU0hBMjU2IFJTQTQwOTYgVGltZXN0YW1wIFJlc3BvbmRlciAyMDI1IDEwggIi # MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDQRqwtEsae0OquYFazK1e6b1H/ # hnAKAd/KN8wZQjBjMqiZ3xTWcfsLwOvRxUwXcGx8AUjni6bz52fGTfr6PHRNv6T7 # zsf1Y/E3IU8kgNkeECqVQ+3bzWYesFtkepErvUSbf+EIYLkrLKd6qJnuzK8Vcn0D # vbDMemQFoxQ2Dsw4vEjoT1FpS54dNApZfKY61HAldytxNM89PZXUP/5wWWURK+If # xiOg8W9lKMqzdIo7VA1R0V3Zp3DjjANwqAf4lEkTlCDQ0/fKJLKLkzGBTpx6EYev # vOi7XOc4zyh1uSqgr6UnbksIcFJqLbkIXIPbcNmA98Oskkkrvt6lPAw/p4oDSRZr # eiwB7x9ykrjS6GS3NR39iTTFS+ENTqW8m6THuOmHHjQNC3zbJ6nJ6SXiLSvw4Smz # 8U07hqF+8CTXaETkVWz0dVVZw7knh1WZXOLHgDvundrAtuvz0D3T+dYaNcwafsVC # GZKUhQPL1naFKBy1p6llN3QgshRta6Eq4B40h5avMcpi54wm0i2ePZD5pPIssosz # QyF4//3DoK2O65Uck5Wggn8O2klETsJ7u8xEehGifgJYi+6I03UuT1j7FnrqVrOz # aQoVJOeeStPeldYRNMmSF3voIgMFtNGh86w3ISHNm0IaadCKCkUe2LnwJKa8TIlw # CUNVwppwn4D3/Pt5pwIDAQABo4IBlTCCAZEwDAYDVR0TAQH/BAIwADAdBgNVHQ4E # FgQU5Dv88jHt/f3X85FxYxlQQ89hjOgwHwYDVR0jBBgwFoAU729TSunkBnx6yuKQ # VvYv1Ensy04wDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMI # MIGVBggrBgEFBQcBAQSBiDCBhTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln # aWNlcnQuY29tMF0GCCsGAQUFBzAChlFodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5j # b20vRGlnaUNlcnRUcnVzdGVkRzRUaW1lU3RhbXBpbmdSU0E0MDk2U0hBMjU2MjAy # NUNBMS5jcnQwXwYDVR0fBFgwVjBUoFKgUIZOaHR0cDovL2NybDMuZGlnaWNlcnQu # Y29tL0RpZ2lDZXJ0VHJ1c3RlZEc0VGltZVN0YW1waW5nUlNBNDA5NlNIQTI1NjIw # MjVDQTEuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwHATANBgkq # hkiG9w0BAQsFAAOCAgEAZSqt8RwnBLmuYEHs0QhEnmNAciH45PYiT9s1i6UKtW+F # ERp8FgXRGQ/YAavXzWjZhY+hIfP2JkQ38U+wtJPBVBajYfrbIYG+Dui4I4PCvHpQ # uPqFgqp1PzC/ZRX4pvP/ciZmUnthfAEP1HShTrY+2DE5qjzvZs7JIIgt0GCFD9kt # x0LxxtRQ7vllKluHWiKk6FxRPyUPxAAYH2Vy1lNM4kzekd8oEARzFAWgeW3az2xe # jEWLNN4eKGxDJ8WDl/FQUSntbjZ80FU3i54tpx5F/0Kr15zW/mJAxZMVBrTE2oi0 # fcI8VMbtoRAmaaslNXdCG1+lqvP4FbrQ6IwSBXkZagHLhFU9HCrG/syTRLLhAezu # /3Lr00GrJzPQFnCEH1Y58678IgmfORBPC1JKkYaEt2OdDh4GmO0/5cHelAK2/gTl # QJINqDr6JfwyYHXSd+V08X1JUPvB4ILfJdmL+66Gp3CSBXG6IwXMZUXBhtCyIaeh # r0XkBoDIGMUG1dUtwq1qmcwbdUfcSYCn+OwncVUXf53VJUNOaMWMts0VlRYxe5nK # +At+DI96HAlXHAL5SlfYxJ7La54i71McVWRP66bW+yERNpbJCjyCYG2j+bdpxo/1 # Cy4uPcU3AWVPGrbn5PhDBf3Froguzzhk++ami+r3Qrx5bIbY3TVzgiFI7Gq3zWcw # gga0MIIEnKADAgECAhANx6xXBf8hmS5AQyIMOkmGMA0GCSqGSIb3DQEBCwUAMGIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBH # NDAeFw0yNTA1MDcwMDAwMDBaFw0zODAxMTQyMzU5NTlaMGkxCzAJBgNVBAYTAlVT # MRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1 # c3RlZCBHNCBUaW1lU3RhbXBpbmcgUlNBNDA5NiBTSEEyNTYgMjAyNSBDQTEwggIi # MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC0eDHTCphBcr48RsAcrHXbo0Zo # dLRRF51NrY0NlLWZloMsVO1DahGPNRcybEKq+RuwOnPhof6pvF4uGjwjqNjfEvUi # 6wuim5bap+0lgloM2zX4kftn5B1IpYzTqpyFQ/4Bt0mAxAHeHYNnQxqXmRinvuNg # xVBdJkf77S2uPoCj7GH8BLuxBG5AvftBdsOECS1UkxBvMgEdgkFiDNYiOTx4OtiF # cMSkqTtF2hfQz3zQSku2Ws3IfDReb6e3mmdglTcaarps0wjUjsZvkgFkriK9tUKJ # m/s80FiocSk1VYLZlDwFt+cVFBURJg6zMUjZa/zbCclF83bRVFLeGkuAhHiGPMvS # GmhgaTzVyhYn4p0+8y9oHRaQT/aofEnS5xLrfxnGpTXiUOeSLsJygoLPp66bkDX1 # ZlAeSpQl92QOMeRxykvq6gbylsXQskBBBnGy3tW/AMOMCZIVNSaz7BX8VtYGqLt9 # MmeOreGPRdtBx3yGOP+rx3rKWDEJlIqLXvJWnY0v5ydPpOjL6s36czwzsucuoKs7 # Yk/ehb//Wx+5kMqIMRvUBDx6z1ev+7psNOdgJMoiwOrUG2ZdSoQbU2rMkpLiQ6bG # RinZbI4OLu9BMIFm1UUl9VnePs6BaaeEWvjJSjNm2qA+sdFUeEY0qVjPKOWug/G6 # X5uAiynM7Bu2ayBjUwIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAd # BgNVHQ4EFgQU729TSunkBnx6yuKQVvYv1Ensy04wHwYDVR0jBBgwFoAU7NfjgtJx # XWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUF # BwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln # aWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5j # b20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJo # dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNy # bDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQEL # BQADggIBABfO+xaAHP4HPRF2cTC9vgvItTSmf83Qh8WIGjB/T8ObXAZz8OjuhUxj # aaFdleMM0lBryPTQM2qEJPe36zwbSI/mS83afsl3YTj+IQhQE7jU/kXjjytJgnn0 # hvrV6hqWGd3rLAUt6vJy9lMDPjTLxLgXf9r5nWMQwr8Myb9rEVKChHyfpzee5kH0 # F8HABBgr0UdqirZ7bowe9Vj2AIMD8liyrukZ2iA/wdG2th9y1IsA0QF8dTXqvcnT # mpfeQh35k5zOCPmSNq1UH410ANVko43+Cdmu4y81hjajV/gxdEkMx1NKU4uHQcKf # ZxAvBAKqMVuqte69M9J6A47OvgRaPs+2ykgcGV00TYr2Lr3ty9qIijanrUR3anzE # wlvzZiiyfTPjLbnFRsjsYg39OlV8cipDoq7+qNNjqFzeGxcytL5TTLL4ZaoBdqbh # OhZ3ZRDUphPvSRmMThi0vw9vODRzW6AxnJll38F0cuJG7uEBYTptMSbhdhGQDpOX # gpIUsWTjd6xpR6oaQf/DJbg3s6KCLPAlZ66RzIg9sC+NJpud/v4+7RWsWCiKi9EO # LLHfMR2ZyJ/+xhCx9yHbxtl5TPau1j/1MIDpMPx0LckTetiSuEtQvLsNz3Qbp7wG # WqbIiOWCnb5WqxL3/BAPvIXKUjPSxyZsq8WhbaM2tszWkPZPubdcMIIFjTCCBHWg # AwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkqhkiG9w0BAQwFADBlMQswCQYDVQQG # EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl # cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcN # MjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEVMBMG # A1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw # HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqGSIb3DQEB # AQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp # pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+ # n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYykt # zuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw # 2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQjdjUN6Qu # BX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/CNdaSaTC # 5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtmmnTK # 3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3 # IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEP # lAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98 # THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t9dmpsh3l # GwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7NfjgtJx # XWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8w # DgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0 # cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0 # cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3J0MEUGA1Ud # HwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFz # c3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAowCDAGBgRVHSAAMA0GCSqGSIb3DQEB # DAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/Vwe9mqyhhyzshV6pGrsi+IcaaVQi # 7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLeJLxSA8hO0Cre+i1Wz/n096wwepqL # sl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE1Od/6Fmo8L8vC6bp8jQ87PcDx4eo # 0kxAGTVGamlUsLihVo7spNU96LHc/RzY9HdaXFSMb++hUD38dglohJ9vytsgjTVg # HAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbObyMt9H5xaiNrIv8SuFQtJ37YOtnw # toeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMYIDfDCCA3gCAQEwfTBpMQswCQYDVQQG # EwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0 # IFRydXN0ZWQgRzQgVGltZVN0YW1waW5nIFJTQTQwOTYgU0hBMjU2IDIwMjUgQ0Ex # AhAKgO8YS43xBYLRxHanlXRoMA0GCWCGSAFlAwQCAQUAoIHRMBoGCSqGSIb3DQEJ # AzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcNMjYwODA0MjIwOTExWjAr # BgsqhkiG9w0BCRACDDEcMBowGDAWBBTdYjCshgotMGvaOLFoeVIwB/tBfjAvBgkq # hkiG9w0BCQQxIgQgofOBXdjSM1M2Df5wqqAEQLixQyqqClx5w4olePvIUN4wNwYL # KoZIhvcNAQkQAi8xKDAmMCQwIgQgSqA/oizXXITFXJOPgo5na5yuyrM/420mmqM0 # 8UYRCjMwDQYJKoZIhvcNAQEBBQAEggIAPU6Ek09DhuBp3an4ieLjZOiPcCYhzw65 # cjYtNsnNHNcGVSHzIP0VcPEVBwJq37Lmx51m3iQpg6SNL5/4/FoUSjxVWc3xJorK # SbTxYYlO34ke5/1WYP9FMs+hekYbLTGZqJRSvdC8I9hwjVyhXlJCDLv2ZUHLYPe6 # 6gRpPvYkoyjXU8aaQ+MI8/y7G16oTCETyQ4oeBVormdt0ntJguf9+zFEUFjXexOR # 6rDWfWuv9tzXkTYL29AgQVaiCITteNPpMECoMus+AmBIfsDwWrhdtbWrrz45hv2l # /PtRVMjVaX3h8VbDom+DujfgCJ6Dd0VktbygQBNEOXCVVTPxmwG7sUC/VxcHm8eh # XOxcAbaqP0K7TGDKaxM/Z2Xno5uDiz50jOmxp0D/HvQfef7Yr6fwSJfupOgdN8g6 # t9M/yK6+JKLvBnhyC3R1pdIjE0OfxXRHLMAMrssJyh6fu+Gz/y5/dd47FZSBHZLM # Wgvye3wLD7/NSD9TicYkHdxe3Fzlbb9QAhbMZvgLqBrS40IhkQU0tZjk71LXmtvG # zFCojBeGdsrH04MeV+LWMQwa51dTFckCBSQLWku6l/lclSt0A+tT3myEvQwHGesy # FIP0g8jqKID5gS7+LmiJhNPZFap7ateM3rS6RF9uYR/1LYNCk+ir1tUPUBXQ3SgS # EmuDCUforBU= # SIG # End signature block |