public/Import-AppVManagementPackage.ps1
|
<#
.SYNOPSIS Imports App-V Management packages into AppVentiX as publishing tasks. .DESCRIPTION Import-AppVManagementPackage retrieves packages from an App-V Management SQL database and converts them into AppVentiX publishing tasks. The function matches package URLs against the configured AppVentiX Content Stores and optionally associates packages with the appropriate Machine Groups based on Content Store location. The target Machine Group can be resolved automatically (-MatchPackageWithMachineGroup) or pinned to a specific group (-MachineGroupFriendlyName), and the group(s) a package is published to can be set independently with -PublishingMachineGroupFriendlyName. If a Deployment Configuration XML is present in the database, it is saved as an .appd file alongside the package. .PARAMETER SQLServer The name or IP address of the SQL Server hosting the App-V Management database. Default: 'localhost'. .PARAMETER SQLInstance The SQL Server instance name (optional). Leave empty for the default instance. .PARAMETER SQLDatabase The name of the App-V Management database. Default: 'AppVManagement'. .PARAMETER SQLCredential A PSCredential object for SQL Server authentication. Use [System.Management.Automation.PSCredential]::Empty for Windows authentication (default). .PARAMETER MatchPackageWithMachineGroup When specified, attempts to match each package to the appropriate AppVentiX Machine Group based on its Content Store location. If no match is found, the package is published to all Machine Groups. .PARAMETER GUI When specified, displays a graphical selection window allowing the user to manually choose which packages to import. .PARAMETER CachePackages When specified, package manifest identity fields read from the Content Stores are cached in memory for the duration of the PowerShell session and reused on subsequent runs, so unchanged packages are not re-read. The cache is keyed on file path, last write time and size (a repackaged file is always re-read), is module-scoped, and is cleared when the module is reimported. Off by default. .PARAMETER ThrottleLimit The maximum number of package manifests to read concurrently from the Content Stores when retrieving AppVentiX Content Store packages. Reading manifests over a (usually remote) share is network-latency bound and benefits from parallelism. Default: 16. Increase on high-latency shares; decrease to reduce load on the file server. .PARAMETER MachineGroupFriendlyName The friendly name of the AppVentiX Machine Group the packages are matched to. If not specified, packages are matched to All Machine Groups. .PARAMETER PublishingMachineGroupFriendlyName The friendly name(s) of the AppVentiX Machine Group(s) to which the packages are published. If not specified, packages are published to the same Machine Group as matched by the Content Store location. .PARAMETER ConfigShare Internal parameter. Points to the AppVentiX configuration share path. Automatically populated from the module configuration and does not normally need to be specified manually. .EXAMPLE Import-AppVManagementPackage Imports all enabled App-V packages from the local SQL Server ('localhost', database 'AppVManagement') and publishes them to All Machine Groups. .EXAMPLE Import-AppVManagementPackage -SQLServer 'sql01' -SQLDatabase 'AppVManagement' -MatchPackageWithMachineGroup Imports all enabled App-V packages from SQL Server 'sql01' and associates each package with the corresponding AppVentiX Machine Group based on its Content Store location. .EXAMPLE Import-AppVManagementPackage -SQLServer 'sql01' -GUI -MatchPackageWithMachineGroup Displays a selection window listing all available packages so the user can choose which ones to import, then associates them with the appropriate Machine Group. .LINK Test-AppVManagementSQLConnection .LINK Get-AppVManagementPackage .LINK Get-AppVManagementConnectionGroup .LINK Import-AppVManagementConnectionGroup .LINK New-AppVentiXPublishingTask .LINK New-AppVentiXConnectionGroup .NOTES Function : Import-AppVManagementPackage Author : John Billekens Copyright : (c) John Billekens Consultancy & AppVentiX Version : 2026.721.2230 Requires : SqlServer PowerShell module #> function Import-AppVManagementPackage { [CmdletBinding(DefaultParameterSetName = 'MatchWithMachineGroup')] [OutputType([PSCustomObject])] param ( [String]$SQLServer = "localhost", [String]$SQLInstance, [String]$SQLDatabase = 'AppVManagement', [System.Management.Automation.PSCredential]$SQLCredential = [System.Management.Automation.PSCredential]::Empty, [Parameter(Mandatory = $true, ParameterSetName = 'MatchWithMachineGroup')] [switch]$MatchPackageWithMachineGroup, [Parameter(Mandatory = $true, ParameterSetName = 'MachineGroupName')] [String]$MachineGroupFriendlyName, [String[]]$PublishingMachineGroupFriendlyName, [switch]$GUI, [switch]$CachePackages, [ValidateRange(1, 128)] [Int]$ThrottleLimit = 16, [Parameter(DontShow)] [ValidateNotNullOrEmpty()] [String]$ConfigShare = $Script:AppVentiX.ConfigShare ) $PSDefaultParameterValues['Write-AppVentiXError:Cmdlet'] = $PSCmdlet # Correlation id for this invocation; stamped on every debug entry so one run's log can be grouped. $Script:AppVentiXDebugRunId = '{0:yyyyMMddHHmmss}-{1:x4}' -f [datetime]::Now, (Get-Random -Maximum 0x10000) if ($Script:AppVentiXDebugLogEnabled) { # Only re-detect the layout (a few Test-Path probes) when debug logging is on. Write-AppVentiXDebugLog -Message 'Import-AppVManagementPackage started' -Data @{ SQLServer = $SQLServer SQLDatabase = $SQLDatabase MatchPackageWithMachineGroup = [bool]$MatchPackageWithMachineGroup GUI = [bool]$GUI ConfigShare = "$ConfigShare" Layout = "$(Get-AppVentiXConfigStoreLayout -ConfigShare $ConfigShare)" BackendType = "$($Script:AppVentiX.BackendType)" } } if (Test-AppVentiXIsLicensed -ConfigShare $ConfigShare) { try { $SQLParams = @{ SQLServer = $SQLServer SQLInstance = $SQLInstance SQLDatabase = $SQLDatabase SQLCredential = $SQLCredential } $preselectedMachineGroup = $false if (-not [string]::IsNullOrEmpty($MachineGroupFriendlyName)) { $preselectedMachineGroup = $true } try { $connectionResult = Test-AppVManagementSQLConnection @SQLParams -ErrorAction Stop if (-not $connectionResult) { Write-AppVentiXError -Message "Cannot connect to the App-V Management database on server '$serverInstance'." ` -ErrorId 'SQLConnectionFailed' ` -Category ConnectionError ` -Cmdlet $PSCmdlet return } } catch { Write-AppVentiXError -Message "Cannot connect to the App-V Management database on server '$serverInstance'." ` -ErrorId 'SQLConnectionFailed' ` -Category ConnectionError ` -Cmdlet $PSCmdlet return } Write-Host "Connected to App-V Management database '$SQLDatabase' on server '$SQLServer'" Write-AppVentiXDebugLog -Message 'SQL connection verified' -Level Timing Write-Host "Retrieving App-V Management Packages..." # ToDo: cache by package name and version instead of path so packages shared across machine groups are read once. $AppVentiXContentSharePackages = Get-AppVentiXContentSharePackages -ConfigShare $ConfigShare -ThrottleLimit $ThrottleLimit -CachePackages:$CachePackages $MachineGroups = Get-AppVentiXMachineGroup -ConfigShare $ConfigShare Write-AppVentiXDebugLog -Message 'Retrieved Content Store packages and Machine Groups' -Level Timing -Data @{ ContentSharePackageCount = @($AppVentiXContentSharePackages).Count MachineGroupCount = @($MachineGroups).Count } if ($AppVManagementPackageDetails = Get-AppVManagementPackage @SQLParams) { Write-AppVentiXDebugLog -Message 'Retrieved App-V Management packages from database' -Level Timing -Data @{ PackageCount = @($AppVManagementPackageDetails).Count } if ($GUI.IsPresent -eq $true) { Write-AppVentiXDebugLog -Message 'Displaying GUI for package selection' -Level Timing $AppVManagementPackageDetails = @( $AppVManagementPackageDetails | Select-ObjectFromGrid -Title "Select App-V Management Packages to import" ` -ColumnsToShow @('Name', 'Version', 'IsEnabled', 'PackageGuid', 'VersionGuid', 'PackageUrl') ) Write-AppVentiXDebugLog -Message 'GUI selection completed' -Level Timing -Data @{ SelectedPackageCount = @($AppVManagementPackageDetails).Count } } if (-not $AppVManagementPackageDetails -or $AppVManagementPackageDetails.Count -eq 0) { Write-AppVentiXDebugLog -Message 'No packages selected for import' -Level Warning Write-Warning "No App-V Management Packages selected for import." return } Write-Host "Found $($AppVManagementPackageDetails.Count) App-V Management Packages to import." # Collect results and emit after the loop; emitting inside interleaves with Write-Host and breaks table formatting. $ImportResults = [System.Collections.Generic.List[object]]::new() foreach ($appVManagementPackage in $AppVManagementPackageDetails) { # Reset from the parameters each package; the loop reassigns these while matching. $currentMachineGroup = $MachineGroupFriendlyName $currentPublishingGroups = $PublishingMachineGroupFriendlyName Write-Host "`r`n================================" -ForegroundColor Cyan if ($appVManagementPackage.IsEnabled -eq $false) { Write-Host "`r`nSkipping disabled App-V Management Package '$($appVManagementPackage.Name)'" -ForegroundColor Yellow continue } Write-Host "`r`nProcessing package '$($appVManagementPackage.Name)'..." -ForegroundColor Cyan Write-AppVentiXDebugLog -Message 'Processing package' -Level Timing -Data @{ Package = "$($appVManagementPackage.Name)" PackageGuid = "$($appVManagementPackage.PackageGuid)" ADGroups = @($appVManagementPackage.ADGroups).Count } if (-not [string]::IsNullOrEmpty($appVManagementPackage.PackageUrl) -and $appVManagementPackage.PackageUrl.StartsWith('\\')) { $fileServer, $fileserverPath = $appVManagementPackage.PackageUrl.TrimStart('\\').Split('\', 2) $AppVentiXPackage = @($AppVentiXContentSharePackages | Where-Object { $_.FullName -like "\\$($fileServer)*\$($fileserverPath)" }) if ($currentMachineGroup) { $MachineGroup = $MachineGroups | Where-Object { $_.FriendlyName -ieq $currentMachineGroup } } else { $currentMachineGroup = 'All Machine Groups' $MachineGroup = $MachineGroups } if ([string]::IsNullOrEmpty($currentPublishingGroups)) { $currentPublishingGroups = @($currentMachineGroup) } Write-AppVentiXDebugLog -Message 'Matching package with AppVentiX Content Store Packages' -Level Timing -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$($appVManagementPackage.PackageUrl)" MatchCount = @($AppVentiXPackage).Count MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" } if ($MatchPackageWithMachineGroup.IsPresent -eq $false) { if ($AppVentiXPackage.Count -eq 0) { Write-Warning "Package URL: '$($appVManagementPackage.PackageUrl)'" Write-Warning "Package not found in any of the configured Machine Group Content Stores." Write-AppVentiXDebugLog -Message 'Package not found in any configured Content Stores' -Level Warning -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$($appVManagementPackage.PackageUrl)" MatchCount = @($AppVentiXPackage).Count MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" } } } elseif ($AppVentiXPackage.Count -eq 0) { Write-Warning "Package URL: '$($appVManagementPackage.PackageUrl)'" Write-Warning "Package not found in AppVentiX Content Store Packages. Publishing to All Machine Groups." Write-AppVentiXDebugLog -Message 'Package not found in any configured Content Stores' -Level Warning -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$($appVManagementPackage.PackageUrl)" MatchCount = @($AppVentiXPackage).Count MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" } } elseif ($AppVentiXPackage.Count -gt 1) { Write-Warning "Package URL: '$($appVManagementPackage.PackageUrl)'" Write-Warning "Multiple packages found ($($AppVentiXPackage.Count)) in AppVentiX Content Store Packages matching the specified URL." Write-Warning "Publishing to $($currentPublishingGroups -join ', ')" Write-AppVentiXDebugLog -Message 'Multiple packages found in AppVentiX Content Store Packages' -Level Warning -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$($appVManagementPackage.PackageUrl)" MatchCount = @($AppVentiXPackage).Count MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" } } else { Write-Host "Found package in AppVentiX Content Store Packages." -ForegroundColor Green $currentMachineGroup = $AppVentiXPackage | Select-Object -ExpandProperty MachineGroup $MachineGroup = $MachineGroups | Where-Object { $_.FriendlyName -ieq $currentMachineGroup } Write-AppVentiXDebugLog -Message 'Package matched with AppVentiX Content Store Package' -Level Timing -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$($appVManagementPackage.PackageUrl)" MatchCount = @($AppVentiXPackage).Count MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" } } } else { Write-Warning "Package URL: '$($appVManagementPackage.PackageUrl)'" Write-Warning "Package is not a valid UNC path. Skipping package." Write-AppVentiXDebugLog -Message 'Package URL is not a valid UNC path' -Level Warning -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$($appVManagementPackage.PackageUrl)" MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" } continue } $ContentSharePackageRoots = @($MachineGroup.GroupContentshares | ForEach-Object { $_.ContentShare } | Select-Object -ExpandProperty Path -Unique) Write-AppVentiXDebugLog -Message 'Retrieved Content Store roots for Machine Group' -Level Timing -Data @{ MachineGroupFriendlyName = "$currentMachineGroup" ContentShareRootCount = @($ContentSharePackageRoots).Count } Write-Verbose "Found $($ContentSharePackageRoots.Count) Content Store roots for machine group '$currentMachineGroup'." $ContentSharePackageRoots | ForEach-Object { Write-Verbose "Content Store Root: $_" } if ($ContentSharePackageRoots.Count -eq 0) { Write-Warning "No Content Stores found for machine group '$currentMachineGroup'. Skipping package." Write-AppVentiXDebugLog -Message 'No Content Stores found for machine group' -Level Warning -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$($appVManagementPackage.PackageUrl)" MachineGroupFriendlyName = "$currentMachineGroup" } continue } elseif ($ContentSharePackageRoots.Count -gt 1) { Write-Warning "Multiple Content Stores found for machine group '$currentMachineGroup'. Using the first match." Write-AppVentiXDebugLog -Message 'Multiple Content Stores found for machine group.' -Level Warning -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$($appVManagementPackage.PackageUrl)" MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" ContentShareRootCount = $ContentSharePackageRoots.Count } } else { Write-Host "Found Content Store for machine group '$currentMachineGroup': $($ContentSharePackageRoots[0])" -ForegroundColor Green Write-AppVentiXDebugLog -Message 'Found Content Store for machine group' -Level Timing -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$($appVManagementPackage.PackageUrl)" MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" ContentShareRoot = "$($ContentSharePackageRoots[0])" } } Write-Host "Importing App-V Management Package to Machine Group '$($currentMachineGroup -join ', ')'" -ForegroundColor Cyan if ($preselectedMachineGroup) { Write-Verbose "Package validation skipped, Machine Group was specified." if ($ContentSharePackageRoots.Count -gt 1) { Write-Warning "Multiple Content Stores found for machine group '$currentMachineGroup'. Using the first match." $ContentSharePackageRoot = $ContentSharePackageRoots[0] Write-AppVentiXDebugLog -Message 'Multiple Content Stores found for machine group (preselected)' -Level Warning -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$($appVManagementPackage.PackageUrl)" MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" ContentShareRootCount = $ContentSharePackageRoots.Count SelectedContentShareRoot = "$($ContentSharePackageRoot)" } } else { $ContentSharePackageRoot = $ContentSharePackageRoots[0] Write-AppVentiXDebugLog -Message 'Found Content Store for machine group (preselected)' -Level Timing -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$($appVManagementPackage.PackageUrl)" MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" ContentShareRoot = "$($ContentSharePackageRoot)" } } # Probe progressively shorter sub-paths under the content store root to locate the package (handles DFS/nested share layouts). $fileserver, $sharePath = "$($appVManagementPackage.PackageUrl)".TrimStart("\\").Split('\', 2) $nrTests = ($sharePath.Split('\').Count) $testSharePath = $sharePath for ($i = 0; $i -lt $nrTests; $i++) { $newPath = Join-Path -Path $ContentSharePackageRoot -ChildPath $testSharePath if (Test-Path -Path $newPath) { Write-Host "Package found in Content Store: $newPath" -ForegroundColor Green $PackagePath = $newPath break } else { Write-Verbose "Package not found in Content Store: $newPath" $PackagePath = $appVManagementPackage.PackageUrl } $null, $testSharePath = $testSharePath.Split('\', 2) } } else { $Fileserver, $Share, $SharePath = "$($appVManagementPackage.PackageUrl)".TrimStart("\\").Split('\', 3) $PackageContentShareMatch = "\\{0}*\{1}" -f $Fileserver, $Share Write-Verbose "Looking for Content Store matching pattern '$PackageContentShareMatch' in machine group '$currentMachineGroup'" $ContentSharePackageRoot = $ContentSharePackageRoots | Where-Object { $_ -like $PackageContentShareMatch } | Select-Object -First 1 if ([string]::IsNullOrEmpty($ContentSharePackageRoot)) { Write-Verbose "No Content Store match found for package in machine group '$currentMachineGroup'." } else { Write-Verbose "Content Store match for package in machine group '$currentMachineGroup': $($ContentSharePackageRoot)" } Write-AppVentiXDebugLog -Message 'Matching package URL with Content Store roots' -Level Timing -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$($appVManagementPackage.PackageUrl)" MachineGroupFriendlyName = "$currentMachineGroup" ContentShareRootCount = @($ContentSharePackageRoots).Count Matched = if ([string]::IsNullOrEmpty($ContentSharePackageRoot)) { $false } else { $true } } if ([string]::IsNullOrEmpty($ContentSharePackageRoot)) { # Retry one level deeper; the share may be a subfolder of the Content Store root (DFS). $Fileserver, $dfspath, $folder, $SharePath = "$($appVManagementPackage.PackageUrl)".TrimStart("\\").Split('\', 4) $PackageContentShareMatch = "\\{0}*\{1}\{2}" -f $Fileserver, $dfspath, $folder Write-Verbose "Looking for another attempt Content Store matching pattern '$PackageContentShareMatch' in machine group '$currentMachineGroup'" $ContentSharePackageRoot = $ContentSharePackageRoots | Where-Object { $_ -like $PackageContentShareMatch } | Select-Object -First 1 if ([string]::IsNullOrEmpty($ContentSharePackageRoot)) { Write-Verbose "No Content Store match found for package in machine group '$currentMachineGroup'." } else { Write-Verbose "Content Store match for package in machine group '$currentMachineGroup': $($ContentSharePackageRoot)" } Write-AppVentiXDebugLog -Message 'Second attempt matching package URL with Content Store roots' -Level Timing -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$($appVManagementPackage.PackageUrl)" MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" ContentShareRootCount = @($ContentSharePackageRoots).Count Matched = if ([string]::IsNullOrEmpty($ContentSharePackageRoot)) { $false } else { $true } } } } if ([string]::IsNullOrEmpty($ContentSharePackageRoot)) { Write-Warning "No matching Content Store found for package in machine group '$currentMachineGroup'." } Write-Verbose "Content Store match for package in machine group '$currentMachineGroup': $($ContentSharePackageRoot)" if ([string]::IsNullOrEmpty($ContentSharePackageRoot)) { Write-Warning "No matching Content Store found for package in machine group '$currentMachineGroup'. Using Original Package URL." $PackagePath = $appVManagementPackage.PackageUrl Write-AppVentiXDebugLog -Message 'Resolved package path (no Content Store match, using original URL)' -Level Warning -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$PackagePath" MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" Matched = $false } } elseif ($preselectedMachineGroup) { Write-Host "Using preselected Machine Group '$currentMachineGroup' and Content Store '$ContentSharePackageRoot' for package." -ForegroundColor Green Write-AppVentiXDebugLog -Message 'Resolved package path from preselected Machine Group and Content Store' -Level Timing -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$PackagePath" ContentShareRoot = "$ContentSharePackageRoot" MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" Matched = $true } } else { Write-Host "Found matching Content Store for package." -ForegroundColor Green $ContentShareFileserver, $ContentShareShare = $ContentSharePackageRoot.TrimStart("\\").Split('\', 2) $PackagePath = '\\{0}\{1}\{2}' -f $ContentShareFileserver, $ContentShareShare, $SharePath Write-AppVentiXDebugLog -Message 'Resolved package path from Content Store match' -Data @{ Package = "$($appVManagementPackage.Name)" PackagePath = "$PackagePath" ContentShareRoot = "$ContentSharePackageRoot" MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" Matched = $true } } if (Test-Path -Path $PackagePath -PathType Leaf) { Write-Host "Package found in Content Store" -ForegroundColor Green $adGroupDetails = @() $appVManagementPackage.ADGroups | ForEach-Object { $adDomain = $_.Domain $adName = $_.Name Write-Verbose "Processing AD group '$adDomain\$adName' for package '$($appVManagementPackage.Name)'" $adGroupName = '{0}\{1}' -f $adDomain, $adName $adGroupObject = [PSCustomObject]@{ Domain = $adDomain Name = $adName GroupName = $adGroupName UserConfigFilePath = "" } if (-not [string]::IsNullOrEmpty($($_.UserConfigurationXml))) { try { Write-Host "User configuration detected for AD group '$adGroupName'. Saving user configuration XML to appd file..." -ForegroundColor Cyan [xml]$userConfigXml = $($_.UserConfigurationXml) | Format-XML $xmlUserConfigFilePath = "$PackagePath".Replace('.appv', "_$($adName)_UserConfig.xml") Write-Verbose "Saving deployment configuration XML to appd file: $xmlUserConfigFilePath" $adGroupObject.UserConfigFilePath = $xmlUserConfigFilePath $userConfigXml.Save($xmlUserConfigFilePath) } catch { Write-Warning "Failed to save user configuration XML to appd file for AD group '$adGroupName': $($_.Exception.Message)" Write-AppVentiXDebugLog -Message 'Failed to save user configuration appd file' -ErrorRecord $_ -Data @{ Package = "$($appVManagementPackage.Name)" GroupName = "$adGroupName" xmlUserConfigFilePath = "$xmlUserConfigFilePath" } } } else { Write-Verbose "No user configuration detected for AD group '$adGroupName'." } $adGroupDetails += $adGroupObject } # Publish each group as its own task when any group produced a per-group user-config file. $publishSeparately = @($adGroupDetails | Where-Object { -not [string]::IsNullOrEmpty($_.UserConfigFilePath) }).Count -gt 0 if ($publishSeparately) { foreach ($adGroup in $adGroupDetails) { $publishingTaskParams = @{ MachineGroupFriendlyName = $currentPublishingGroups Group = $adGroup.GroupName Path = $PackagePath } if ($adGroup.UserConfigFilePath) { $publishingTaskParams['DynamicUserConfigurationPath'] = $adGroup.UserConfigFilePath } Write-Verbose "Creating publishing task with parameters: $($publishingTaskParams | Out-String)" Write-Host "Creating publishing task..." $newTaskId = New-AppVentiXPublishingTask @publishingTaskParams Write-AppVentiXDebugLog -Message 'Created publishing task' -Level Timing -Data @{ Package = "$($appVManagementPackage.Name)" TaskId = "$($newTaskId.Id)" MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" GroupCount = @($adGroupDetails).Count DynamicUserConfigurationPath = if ($adGroup.UserConfigFilePath) { "$($adGroup.UserConfigFilePath)" } else { "n/a" } } $userConfigPresent = $false if (-not [string]::IsNullOrEmpty($adGroup.UserConfigFilePath)) { $userConfigPresent = $true try { $userConfigFilename = Split-Path -Path $adGroup.UserConfigFilePath -Leaf } catch { $userConfigFilename = $adGroup.UserConfigFilePath } } else { $userConfigFilename = "" } $ImportResults.Add([PSCustomObject]@{ Name = $appVManagementPackage.Name Id = $newTaskId.Id UserConfig = $userConfigPresent UserConfigFilename = $userConfigFilename } ) } } else { $publishingTaskParams = @{ MachineGroupFriendlyName = $currentPublishingGroups Group = @($adGroupDetails.GroupName) Path = $PackagePath } Write-Verbose "Creating publishing task with parameters: $($publishingTaskParams | Out-String)" Write-Host "Creating publishing task..." $newTaskId = New-AppVentiXPublishingTask @publishingTaskParams Write-AppVentiXDebugLog -Message 'Created publishing task' -Level Timing -Data @{ Package = "$($appVManagementPackage.Name)" TaskId = "$($newTaskId.Id)" MachineGroupFriendlyName = "$currentMachineGroup" PublishingMachineGroupFriendlyName = "$($currentPublishingGroups -join ', ')" ADGroupCount = @($adGroupDetails).Count } $ImportResults.Add([PSCustomObject]@{ Name = $appVManagementPackage.Name Id = $newTaskId.Id UserConfig = $false UserConfigFilename = "" } ) } try { if (-not [string]::IsNullOrEmpty($($appVManagementPackage.DeploymentConfigurationXml))) { Write-Host "Deployment configuration XML found. Saving XML data to appd file..." -ForegroundColor Cyan [xml]$DeploymentConfigXml = $($appVManagementPackage.DeploymentConfigurationXml) | Format-XML $appdFilePath = "$PackagePath".Replace('.appv', '_DeploymentConfig.appd') Write-Verbose "Saving deployment configuration XML to appd file: $appdFilePath" $DeploymentConfigXml.Save($appdFilePath) } } catch { Write-Warning "Failed to save deployment configuration XML to appd file: $($_.Exception.Message)" Write-AppVentiXDebugLog -Message 'Failed to save deployment configuration appd file' -ErrorRecord $_ -Data @{ Package = "$($appVManagementPackage.Name)" AppdFilePath = "$appdFilePath" } } } else { Write-Warning "The package could not be found at path '$PackagePath'. Skipping package import." continue } Write-Host "Successfully created publishing task with Task ID '$($newTaskId.Id)'." -ForegroundColor Green } Write-Host "`r`n================================" -ForegroundColor Cyan Write-Host "`r`nFinished processing App-V Management Packages.`r`n" -ForegroundColor Cyan Write-AppVentiXDebugLog -Message 'Finished processing App-V Management packages' -Level Timing -Data @{ TotalPackages = @($AppVManagementPackageDetails).Count DisabledPackages = @($AppVManagementPackageDetails | Where-Object { $_.IsEnabled -eq $false }).Count TasksCreated = $ImportResults.Count TasksWithUserConfig = @($ImportResults | Where-Object { $_.UserConfig }).Count } $ImportResults } else { Write-Warning "No App-V Management Packages found in the database '$SQLDatabase' on server '$SQLServer'." return } } catch { Write-AppVentiXDebugLog -Message 'Import failed' -ErrorRecord $_ $ErrorMessage = @{ Message = "Failed to import App-V Management Packages: $($_.Exception.Message)" ErrorId = "ImportAppVManagementPackageFailed" Category = [System.Management.Automation.ErrorCategory]::NotSpecified TargetObject = $_.Exception } Write-Verbose $($_ | Get-ExceptionDetails -AsPlainText) Write-AppVentiXError @ErrorMessage } finally { # Clear the run id so later unrelated debug entries are not stamped with it. $Script:AppVentiXDebugRunId = $null } } else { throw "AppVentiX is not licensed. Please run the license setup before using this function." } } # SIG # Begin signature block # MII5zAYJKoZIhvcNAQcCoII5vTCCObkCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDun43vRpzrAnxy # xoKGPKDhvC+oPhez/2PGNdVasmNp0qCCIfAwggXMMIIDtKADAgECAhBUmNLR1FsZ # lUgTecgRwIeZMA0GCSqGSIb3DQEBDAUAMHcxCzAJBgNVBAYTAlVTMR4wHAYDVQQK # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jvc29mdCBJZGVu # dGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAy # MDAeFw0yMDA0MTYxODM2MTZaFw00NTA0MTYxODQ0NDBaMHcxCzAJBgNVBAYTAlVT # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jv # c29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRo # b3JpdHkgMjAyMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALORKgeD # Bmf9np3gx8C3pOZCBH8Ppttf+9Va10Wg+3cL8IDzpm1aTXlT2KCGhFdFIMeiVPvH # or+Kx24186IVxC9O40qFlkkN/76Z2BT2vCcH7kKbK/ULkgbk/WkTZaiRcvKYhOuD # PQ7k13ESSCHLDe32R0m3m/nJxxe2hE//uKya13NnSYXjhr03QNAlhtTetcJtYmrV # qXi8LW9J+eVsFBT9FMfTZRY33stuvF4pjf1imxUs1gXmuYkyM6Nix9fWUmcIxC70 # ViueC4fM7Ke0pqrrBc0ZV6U6CwQnHJFnni1iLS8evtrAIMsEGcoz+4m+mOJyoHI1 # vnnhnINv5G0Xb5DzPQCGdTiO0OBJmrvb0/gwytVXiGhNctO/bX9x2P29Da6SZEi3 # W295JrXNm5UhhNHvDzI9e1eM80UHTHzgXhgONXaLbZ7LNnSrBfjgc10yVpRnlyUK # xjU9lJfnwUSLgP3B+PR0GeUw9gb7IVc+BhyLaxWGJ0l7gpPKWeh1R+g/OPTHU3mg # trTiXFHvvV84wRPmeAyVWi7FQFkozA8kwOy6CXcjmTimthzax7ogttc32H83rwjj # O3HbbnMbfZlysOSGM1l0tRYAe1BtxoYT2v3EOYI9JACaYNq6lMAFUSw0rFCZE4e7 # swWAsk0wAly4JoNdtGNz764jlU9gKL431VulAgMBAAGjVDBSMA4GA1UdDwEB/wQE # AwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIftJqhSobyhmYBAcnz1AQ # T2ioojAQBgkrBgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQwFAAOCAgEAr2rd5hnn # LZRDGU7L6VCVZKUDkQKL4jaAOxWiUsIWGbZqWl10QzD0m/9gdAmxIR6QFm3FJI9c # Zohj9E/MffISTEAQiwGf2qnIrvKVG8+dBetJPnSgaFvlVixlHIJ+U9pW2UYXeZJF # xBA2CFIpF8svpvJ+1Gkkih6PsHMNzBxKq7Kq7aeRYwFkIqgyuH4yKLNncy2RtNwx # AQv3Rwqm8ddK7VZgxCwIo3tAsLx0J1KH1r6I3TeKiW5niB31yV2g/rarOoDXGpc8 # FzYiQR6sTdWD5jw4vU8w6VSp07YEwzJ2YbuwGMUrGLPAgNW3lbBeUU0i/OxYqujY # lLSlLu2S3ucYfCFX3VVj979tzR/SpncocMfiWzpbCNJbTsgAlrPhgzavhgplXHT2 # 6ux6anSg8Evu75SjrFDyh+3XOjCDyft9V77l4/hByuVkrrOj7FjshZrM77nq81YY # uVxzmq/FdxeDWds3GhhyVKVB0rYjdaNDmuV3fJZ5t0GNv+zcgKCf0Xd1WF81E+Al # GmcLfc4l+gcK5GEh2NQc5QfGNpn0ltDGFf5Ozdeui53bFv0ExpK91IjmqaOqu/dk # ODtfzAzQNb50GQOmxapMomE2gj4d8yu8l13bS3g7LfU772Aj6PXsCyM2la+YZr9T # 03u4aUoqlmZpxJTG9F9urJh4iIAGXKKy7aIwggalMIIEjaADAgECAhMzAAPYSYKV # Ad9dHyDxAAAAA9hJMA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNVBAYTAlVTMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJ # RCBWZXJpZmllZCBDUyBFT0MgQ0EgMDQwHhcNMjYwODAzMTQxNTE5WhcNMjYwODA2 # MTQxNTE5WjBoMQswCQYDVQQGEwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDEP # MA0GA1UEBxMGSGVpbG9vMRcwFQYDVQQKEw5BcHBWZW50aVggQi5WLjEXMBUGA1UE # AxMOQXBwVmVudGlYIEIuVi4wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIB # gQDMBvk8GVv/OKuFNpoVE3yVe7hkpGgLaq5QJN1HHCgDWU6jHM1M99AR0yNyJkci # UNP701N6wA/F9ZqwDo/AX574HfqDJG5g7q+5mXHH7McXAmYE2FSVvkP2N9rTytb1 # 00Bsxcgg6bAhdMEtJSpr5Pl6fHBp0uZO9Ha84AkrkFYOkcIyGxnTkjmV4y+oxTMB # DanTYTVJVfdgzb6QlVIPn0bHeRP2oUvDEBOYdlTQ1Leo3zhrLNl/G+qIBa7gKkSv # sMoCrCDPz+aCGEcGF+yJEtiTZd7mRaLkIeFY4YQPQg9a8KDmrj6ziX9bFm9Klq6L # /iM4qyqA2J9b24NZBHZqlGaEyuNINtFd9SYMcAwOo7j/7pn/9FHsGMcbn1wzoJP6 # CGCLz5j/YNT1ZxtX19IHQltDskL/WyYdIi3XHh3IOOUAubpeYGQs4WRxmWGs2+5b # zf3Uw46HgbC72jQmTrKhS/VzX635WEGQ/4SbgrkLuAp4w1T6rkuwwEc0nH1qJCTJ # H/ECAwEAAaOCAdQwggHQMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMDsG # A1UdJQQ0MDIGCisGAQQBgjdhAQAGCCsGAQUFBwMDBhorBgEEAYI3YaL8yC6uh9F6 # gZ2lyVCBwcKCJzAdBgNVHQ4EFgQUjPC3d7gEvKwwvfQEwfoVKqHvSsEwHwYDVR0j # BBgwFoAUmvFUd3UMhxY3RqCs3nn59H/BeOkwZwYDVR0fBGAwXjBcoFqgWIZWaHR0 # cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwSUQl # MjBWZXJpZmllZCUyMENTJTIwRU9DJTIwQ0ElMjAwNC5jcmwwdAYIKwYBBQUHAQEE # aDBmMGQGCCsGAQUFBzAChlhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz # L2NlcnRzL01pY3Jvc29mdCUyMElEJTIwVmVyaWZpZWQlMjBDUyUyMEVPQyUyMENB # JTIwMDQuY3J0MFQGA1UdIARNMEswSQYEVR0gADBBMD8GCCsGAQUFBwIBFjNodHRw # Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0w # DQYJKoZIhvcNAQEMBQADggIBAEuJF58u6Pl5xjaytkvPWI4rO8ruvH4JIXNryvyE # hAr816SPRGym0fyNlotEco5QCwqbHtM0iiG/ynZ9tidzXK5YctOCJ/lfFFzyVnYf # Q6FWKON1QqybtdnLiQKtpwP9ZFCFIZCFBtJCkIda8ho56YYtTLI0T189JLKdMO0S # zKhybvo8NpjqYneuDXY82j3FWsKURwjohfIZrIwILI5luRLtIVdbO85Y+oaQEaAX # vi1Z1ws0xdgIR+wzLKPB6Pf6+347xMeOcq/BI3+s8qagFnsBL0J1U4yZsWCnehdS # cA7BSwgQRT325pWcYpUCWi4ve1OD4LH8aFv/ejERvstN2WZGYeVYBpH/n/dlgCki # Y7wgEdbzAFAKEqQfONvzIgz7LINqmhOp5yyN+33FZptvH2x/ZcSvtjp208eQxdz/ # qtSPK239/ZPOQbYUjj5ADGRsSGkQcNnErrCW1ak3no67BOyomlMlUSmzxMNMXbCX # K14FSbAX9d0PobnKu2PkQBoFsam/lP32ptBTHLMuLzqYNPQgGSVe4CKjinQafNTE # XPapu3eCnlARfo/wIOwDUpdt9IgZuhUh+hKzM/dS9IfdvakK74I+cpCPDF0RJHvk # pxX2AxoWX21pAPrJc5+3hiL+X06f+Jc7OGCLf0qkqCr7TyouecM1mqfg7DT/e7kU # WN0ZMIIGpTCCBI2gAwIBAgITMwAD2EmClQHfXR8g8QAAAAPYSTANBgkqhkiG9w0B # AQwFADBaMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 # aW9uMSswKQYDVQQDEyJNaWNyb3NvZnQgSUQgVmVyaWZpZWQgQ1MgRU9DIENBIDA0 # MB4XDTI2MDgwMzE0MTUxOVoXDTI2MDgwNjE0MTUxOVowaDELMAkGA1UEBhMCTkwx # FjAUBgNVBAgTDU5vb3JkLUhvbGxhbmQxDzANBgNVBAcTBkhlaWxvbzEXMBUGA1UE # ChMOQXBwVmVudGlYIEIuVi4xFzAVBgNVBAMTDkFwcFZlbnRpWCBCLlYuMIIBojAN # BgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAzAb5PBlb/zirhTaaFRN8lXu4ZKRo # C2quUCTdRxwoA1lOoxzNTPfQEdMjciZHIlDT+9NTesAPxfWasA6PwF+e+B36gyRu # YO6vuZlxx+zHFwJmBNhUlb5D9jfa08rW9dNAbMXIIOmwIXTBLSUqa+T5enxwadLm # TvR2vOAJK5BWDpHCMhsZ05I5leMvqMUzAQ2p02E1SVX3YM2+kJVSD59Gx3kT9qFL # wxATmHZU0NS3qN84ayzZfxvqiAWu4CpEr7DKAqwgz8/mghhHBhfsiRLYk2Xe5kWi # 5CHhWOGED0IPWvCg5q4+s4l/WxZvSpaui/4jOKsqgNifW9uDWQR2apRmhMrjSDbR # XfUmDHAMDqO4/+6Z//RR7BjHG59cM6CT+ghgi8+Y/2DU9WcbV9fSB0JbQ7JC/1sm # HSIt1x4dyDjlALm6XmBkLOFkcZlhrNvuW8391MOOh4Gwu9o0Jk6yoUv1c1+t+VhB # kP+Em4K5C7gKeMNU+q5LsMBHNJx9aiQkyR/xAgMBAAGjggHUMIIB0DAMBgNVHRMB # Af8EAjAAMA4GA1UdDwEB/wQEAwIHgDA7BgNVHSUENDAyBgorBgEEAYI3YQEABggr # BgEFBQcDAwYaKwYBBAGCN2Gi/MgurofReoGdpclQgcHCgicwHQYDVR0OBBYEFIzw # t3e4BLysML30BMH6FSqh70rBMB8GA1UdIwQYMBaAFJrxVHd1DIcWN0agrN55+fR/ # wXjpMGcGA1UdHwRgMF4wXKBaoFiGVmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w # a2lvcHMvY3JsL01pY3Jvc29mdCUyMElEJTIwVmVyaWZpZWQlMjBDUyUyMEVPQyUy # MENBJTIwMDQuY3JsMHQGCCsGAQUFBwEBBGgwZjBkBggrBgEFBQcwAoZYaHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBJRCUy # MFZlcmlmaWVkJTIwQ1MlMjBFT0MlMjBDQSUyMDA0LmNydDBUBgNVHSAETTBLMEkG # BFUdIAAwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3Br # aW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMA0GCSqGSIb3DQEBDAUAA4ICAQBLiRef # Luj5ecY2srZLz1iOKzvK7rx+CSFza8r8hIQK/Nekj0RsptH8jZaLRHKOUAsKmx7T # NIohv8p2fbYnc1yuWHLTgif5XxRc8lZ2H0OhVijjdUKsm7XZy4kCracD/WRQhSGQ # hQbSQpCHWvIaOemGLUyyNE9fPSSynTDtEsyocm76PDaY6mJ3rg12PNo9xVrClEcI # 6IXyGayMCCyOZbkS7SFXWzvOWPqGkBGgF74tWdcLNMXYCEfsMyyjwej3+vt+O8TH # jnKvwSN/rPKmoBZ7AS9CdVOMmbFgp3oXUnAOwUsIEEU99uaVnGKVAlouL3tTg+Cx # /Ghb/3oxEb7LTdlmRmHlWAaR/5/3ZYApImO8IBHW8wBQChKkHzjb8yIM+yyDapoT # qecsjft9xWabbx9sf2XEr7Y6dtPHkMXc/6rUjytt/f2TzkG2FI4+QAxkbEhpEHDZ # xK6wltWpN56OuwTsqJpTJVEps8TDTF2wlyteBUmwF/XdD6G5yrtj5EAaBbGpv5T9 # 9qbQUxyzLi86mDT0IBklXuAio4p0GnzUxFz2qbt3gp5QEX6P8CDsA1KXbfSIGboV # IfoSszP3UvSH3b2pCu+CPnKQjwxdESR75KcV9gMaFl9taQD6yXOft4Yi/l9On/iX # Ozhgi39KpKgq+08qLnnDNZqn4Ow0/3u5FFjdGTCCBygwggUQoAMCAQICEzMAAAAX # J0UJC4uHr8YAAAAAABcwDQYJKoZIhvcNAQEMBQAwYzELMAkGA1UEBhMCVVMxHjAc # BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjE0MDIGA1UEAxMrTWljcm9zb2Z0 # IElEIFZlcmlmaWVkIENvZGUgU2lnbmluZyBQQ0EgMjAyMTAeFw0yNjAzMjYxODEx # MzFaFw0zMTAzMjYxODExMzFaMFoxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJRCBWZXJpZmll # ZCBDUyBFT0MgQ0EgMDQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCC # x2T+Aw9mKgGVzJ+Tq0PMn49G3itIsYpbx7ClLSRHFe1RELdPcZ1sIqWOhsSfy6yy # qEapClGH9Je9FXA1cQgZvvpQbkg+QInVLr/0EPrVBCwrM96lbRI2PxNeCwXG9Lsy # W2hG6KQgintDmNCBo4zpDIr377plVdSliZm6UB7rHwmvBnR02QT6tnrqWq2ihzB6 # lRJVTEzuh0OafzIMeMnYM0+x+ve5EOLHdfiq+HXiMf9Jb7YLHtYgyHIiJA7bTWLq # FSLGaTh7ZlbxbsLXA91OOroEpv7OjzFuu3tkpC9FflA4Dp2Euq4+qPmxUqfGp+TX # 0gLRJp9NJOzzILjcTD3rkFFFbxUv1xyg6avivFDLtoKBhM2Td138umE1pNOacanu # SYtPHIeQHmB6haFi64avLBLwTTAm/Rbit860cFXR72wq+5Qh4hSmezHqKXERWPpV # Be+APrJ4Iqc+aPeMmIkoCWZQO22HnLNFUFSXjiwyIbgvlH/LIAJEqTafTzxDZgKh # lLU7zr6gwsq3WNpcYQI6NuxWnwh3VVDDyF7onQqKs5Ll7bleVN0Y8VvqgE45ppyB # bvwqN/Run5fMCCRz3aYMY0kZhKO92eP7t4zHqZ5bQMAgZ0tE2Pz/jb0wiykUF/Pc # oOqqk3vVLiRDYst6vd3GEMNzMpUUvQcvBG46+COIbwIDAQABo4IB3DCCAdgwDgYD # VR0PAQH/BAQDAgGGMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBSa8VR3dQyH # FjdGoKzeefn0f8F46TBUBgNVHSAETTBLMEkGBFUdIAAwQTA/BggrBgEFBQcCARYz # aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnku # aHRtMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMBIGA1UdEwEB/wQIMAYBAf8C # AQAwHwYDVR0jBBgwFoAU2UEpsA8PY2zvadf1zSmepEhqMOYwcAYDVR0fBGkwZzBl # oGOgYYZfaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9z # b2Z0JTIwSUQlMjBWZXJpZmllZCUyMENvZGUlMjBTaWduaW5nJTIwUENBJTIwMjAy # MS5jcmwwfQYIKwYBBQUHAQEEcTBvMG0GCCsGAQUFBzAChmFodHRwOi8vd3d3Lm1p # Y3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMElEJTIwVmVyaWZp # ZWQlMjBDb2RlJTIwU2lnbmluZyUyMFBDQSUyMDIwMjEuY3J0MA0GCSqGSIb3DQEB # DAUAA4ICAQCQdVoZ/U0m38l2iKaZFlsxavptpoOLyaR1a9ZK2TSF1kOnFJhMDse6 # KkCgsveoiEjXTVc6Xt86IKHn76Nk5qZB0BXv2iMRQ2giAJmYvZcmstoZqfB2M3Kd # 5wnJhUJOtF/b6HsqSelY6nhrF06zor1lDmDQixBZcLB9zR1+RKQso1jekNxYuUk+ # HaN3k1S57qk0O//YbkwU0mELCW04N5vICMZx5T5c7Nq/7uLvbVhCdD7f2bZpA4U7 # vOkB1ooB4AaER3pjoJ0Mad5LFyi6Na9p9Zu/hrLeOjU5FItS5YxsqvlfXxAThJ17 # 6CmkYstKRmytSHZ7JhKRfV6e9Zftk/ODb/CK4pGVAVqsOf4337bQGrOHHCQ3IvN9 # gmnUuDh8JdvbheoWPHxIN1GB5sUiY584tXN7xdD8LCSsRqJvQ8e7a3gZWTgViugR # s1QWq+N0G9Nje6JHlN1CjJehge+H5PGktJja+juGEr0P+ukSkcL6qaZxFQTh3SDI # 71lvW++3bl/Ezd6SO8N9Udw+reoyvRHCyTiSsplZQSBTVJdPmo3qCpGuyHFtPo5C # Bn3/FPTiqJd3M9BHoqKd0G9Kmg6fGcAvFwnLNXA2kov727wRljL3ypfqL7iAT/Yn # pxul6RwHRlcOf9dDGg1RRvr92NP/CWVXIb68geR2rvU/NsfmtjF1wDCCB54wggWG # oAMCAQICEzMAAAAHh6M0o3uljhwAAAAAAAcwDQYJKoZIhvcNAQEMBQAwdzELMAkG # A1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjFIMEYGA1UE # AxM/TWljcm9zb2Z0IElkZW50aXR5IFZlcmlmaWNhdGlvbiBSb290IENlcnRpZmlj # YXRlIEF1dGhvcml0eSAyMDIwMB4XDTIxMDQwMTIwMDUyMFoXDTM2MDQwMTIwMTUy # MFowYzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjE0MDIGA1UEAxMrTWljcm9zb2Z0IElEIFZlcmlmaWVkIENvZGUgU2lnbmluZyBQ # Q0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALLwwK8ZiCji # 3VR6TElsaQhVCbRS/3pK+MHrJSj3Zxd3KU3rlfL3qrZilYKJNqztA9OQacr1AwoN # cHbKBLbsQAhBnIB34zxf52bDpIO3NJlfIaTE/xrweLoQ71lzCHkD7A4As1Bs076I # u+mA6cQzsYYH/Cbl1icwQ6C65rU4V9NQhNUwgrx9rGQ//h890Q8JdjLLw0nV+ayQ # 2Fbkd242o9kH82RZsH3HEyqjAB5a8+Ae2nPIPc8sZU6ZE7iRrRZywRmrKDp5+Tcm # JX9MRff241UaOBs4NmHOyke8oU1TYrkxh+YeHgfWo5tTgkoSMoayqoDpHOLJs+qG # 8Tvh8SnifW2Jj3+ii11TS8/FGngEaNAWrbyfNrC69oKpRQXY9bGH6jn9NEJv9weF # xhTwyvx9OJLXmRGbAUXN1U9nf4lXezky6Uh/cgjkVd6CGUAf0K+Jw+GE/5VpIVbc # Nr9rNE50Sbmy/4RTCEGvOq3GhjITbCa4crCzTTHgYYjHs1NbOc6brH+eKpWLtr+b # Gecy9CrwQyx7S/BfYJ+ozst7+yZtG2wR461uckFu0t+gCwLdN0A6cFtSRtR8bvxV # FyWwTtgMMFRuBa3vmUOTnfKLsLefRaQcVTgRnzeLzdpt32cdYKp+dhr2ogc+qM6K # 4CBI5/j4VFyC4QFeUP2YAidLtvpXRRo3AgMBAAGjggI1MIICMTAOBgNVHQ8BAf8E # BAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFNlBKbAPD2Ns72nX9c0p # nqRIajDmMFQGA1UdIARNMEswSQYEVR0gADBBMD8GCCsGAQUFBwIBFjNodHRwOi8v # d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wGQYJ # KwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME # GDAWgBTIftJqhSobyhmYBAcnz1AQT2ioojCBhAYDVR0fBH0wezB5oHegdYZzaHR0 # cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwSWRl # bnRpdHklMjBWZXJpZmljYXRpb24lMjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRo # b3JpdHklMjAyMDIwLmNybDCBwwYIKwYBBQUHAQEEgbYwgbMwgYEGCCsGAQUFBzAC # hnVodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29m # dCUyMElkZW50aXR5JTIwVmVyaWZpY2F0aW9uJTIwUm9vdCUyMENlcnRpZmljYXRl # JTIwQXV0aG9yaXR5JTIwMjAyMC5jcnQwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vbmVv # Y3NwLm1pY3Jvc29mdC5jb20vb2NzcDANBgkqhkiG9w0BAQwFAAOCAgEAfyUqnv7U # q+rdZgrbVyNMul5skONbhls5fccPlmIbzi+OwVdPQ4H55v7VOInnmezQEeW4LqK0 # wja+fBznANbXLB0KrdMCbHQpbLvG6UA/Xv2pfpVIE1CRFfNF4XKO8XYEa3oW8oVH # +KZHgIQRIwAbyFKQ9iyj4aOWeAzwk+f9E5StNp5T8FG7/VEURIVWArbAzPt9ThVN # 3w1fAZkF7+YU9kbq1bCR2YD+MtunSQ1Rft6XG7b4e0ejRA7mB2IoX5hNh3UEauY0 # byxNRG+fT2MCEhQl9g2i2fs6VOG19CNep7SquKaBjhWmirYyANb0RJSLWjinMLXN # OAga10n8i9jqeprzSMU5ODmrMCJE12xS/NWShg/tuLjAsKP6SzYZ+1Ry358ZTFcx # 0FS/mx2vSoU8s8HRvy+rnXqyUJ9HBqS0DErVLjQwK8VtsBdekBmdTbQVoCgPCqr+ # PDPB3xajYnzevs7eidBsM71PINK2BoE2UfMwxCCX3mccFgx6UsQeRSdVVVNSyALQ # e6PT12418xon2iDGE81OGCreLzDcMAZnrUAx4XQLUz6ZTl65yPUiOh3k7Yww94lD # f+8oG2oZmDh5O1Qe38E+M3vhKwmzIeoB1dVLlz4i3IpaDcR+iuGjH2TdaC1ZOmBX # iCRKJLj4DT2uhJ04ji+tHD6n58vhavFIrmcxghcyMIIXLgIBATBxMFoxCzAJBgNV # BAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMT # Ik1pY3Jvc29mdCBJRCBWZXJpZmllZCBDUyBFT0MgQ0EgMDQCEzMAA9hJgpUB310f # IPEAAAAD2EkwDQYJYIZIAWUDBAIBBQCgXjAQBgorBgEEAYI3AgEMMQIwADAZBgkq # hkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAvBgkqhkiG9w0BCQQxIgQgKJ6y9oZu3Cde # G2+nvU1b60+1Zq5EWRvPw8xxz97h/jkwDQYJKoZIhvcNAQEBBQAEggGACzN+B7D8 # 3kPhdCijVUKMkg4nhMlYZHkQ4mWV0e4l2SQO5SkatmpwScQ+yvj0xHtGcYlKEASw # bTB4lo5yz7Vp8Wall4ThCPvnIIzBEsJj/LoOO53+iw5Ka5f6LtAvDX7HJdaRRnwW # 2XGXXOBpvBqIcvFqwhcobJRJKUWQZjdLHIs2L2FYsK+aAPW4PflhGGgvcRbXDjC5 # Qmvu7TrFx9pX+OJSbIKjrDY8OBGCTnMn6jR6skUtMUgCgTvbejndJYc4DbQQMWaR # LWXJdODNVumLD+fTsrXUt224W1CLZCqNqi3h5SXFVfc44a7ehDv7QRxxLwhlfm5Y # teryd3Ib/jrtxbHQgchDICOa6aqxD/NhVmsZT+DkavLUEwzkH7/yT/gslvVuV6DD # TVAarxRrjTyL+7Bw5j27FG7s9pip7IzmcUjVrugS3IqyizZZ72orZOnUJ1ozgeOb # E+n8bNtCgfjoEkqA0P6Cw3zMrl5mqcFqJrL0BJ/Joukxx+uk2iDYb66JoYIUsjCC # FK4GCisGAQQBgjcDAwExghSeMIIUmgYJKoZIhvcNAQcCoIIUizCCFIcCAQMxDzAN # BglghkgBZQMEAgEFADCCAWoGCyqGSIb3DQEJEAEEoIIBWQSCAVUwggFRAgEBBgor # BgEEAYRZCgMBMDEwDQYJYIZIAWUDBAIBBQAEIGjAjICcYOtgNih+ppXovaK7fw1j # MI7LLL5UQclgzqGqAgZqcNO3g2kYEzIwMjYwODA0MTkyNjE5LjgxOFowBIACAfSg # gemkgeYwgeMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD # VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTAr # BgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUG # A1UECxMeblNoaWVsZCBUU1MgRVNOOjdCMUEtMDVFMC1EOTQ3MTUwMwYDVQQDEyxN # aWNyb3NvZnQgUHVibGljIFJTQSBUaW1lIFN0YW1waW5nIEF1dGhvcml0eaCCDykw # ggeCMIIFaqADAgECAhMzAAAABeXPD/9mLsmHAAAAAAAFMA0GCSqGSIb3DQEBDAUA # MHcxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x # SDBGBgNVBAMTP01pY3Jvc29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBD # ZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAyMDAeFw0yMDExMTkyMDMyMzFaFw0zNTEx # MTkyMDQyMzFaMGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y # cG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFt # cGluZyBDQSAyMDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnnzn # UmP94MWfBX1jtQYioxwe1+eXM9ETBb1lRkd3kcFdcG9/sqtDlwxKoVIcaqDb+omF # io5DHC4RBcbyQHjXCwMk/l3TOYtgoBjxnG/eViS4sOx8y4gSq8Zg49REAf5huXhI # kQRKe3Qxs8Sgp02KHAznEa/Ssah8nWo5hJM1xznkRsFPu6rfDHeZeG1Wa1wISvlk # pOQooTULFm809Z0ZYlQ8Lp7i5F9YciFlyAKwn6yjN/kR4fkquUWfGmMopNq/B8U/ # pdoZkZZQbxNlqJOiBGgCWpx69uKqKhTPVi3gVErnc/qi+dR8A2MiAz0kN0nh7SqI # NGbmw5OIRC0EsZ31WF3Uxp3GgZwetEKxLms73KG/Z+MkeuaVDQQheangOEMGJ4pQ # ZH55ngI0Tdy1bi69INBV5Kn2HVJo9XxRYR/JPGAaM6xGl57Ei95HUw9NV/uC3yFj # rhc087qLJQawSC3xzY/EXzsT4I7sDbxOmM2rl4uKK6eEpurRduOQ2hTkmG1hSuWY # BunFGNv21Kt4N20AKmbeuSnGnsBCd2cjRKG79+TX+sTehawOoxfeOO/jR7wo3liw # kGdzPJYHgnJ54UxbckF914AqHOiEV7xTnD1a69w/UTxwjEugpIPMIIE67SFZ2PMo # 27xjlLAHWW3l1CEAFjLNHd3EQ79PUr8FUXetXr0CAwEAAaOCAhswggIXMA4GA1Ud # DwEB/wQEAwIBhjAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQUa2koOjUvSGNA # z3vYr0npPtk92yEwVAYDVR0gBE0wSzBJBgRVHSAAMEEwPwYIKwYBBQUHAgEWM2h0 # dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0 # bTATBgNVHSUEDDAKBggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMA # QTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFMh+0mqFKhvKGZgEByfPUBBP # aKiiMIGEBgNVHR8EfTB7MHmgd6B1hnNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20v # cGtpb3BzL2NybC9NaWNyb3NvZnQlMjBJZGVudGl0eSUyMFZlcmlmaWNhdGlvbiUy # MFJvb3QlMjBDZXJ0aWZpY2F0ZSUyMEF1dGhvcml0eSUyMDIwMjAuY3JsMIGUBggr # BgEFBQcBAQSBhzCBhDCBgQYIKwYBBQUHMAKGdWh0dHA6Ly93d3cubWljcm9zb2Z0 # LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwSWRlbnRpdHklMjBWZXJpZmlj # YXRpb24lMjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAyMDIwLmNy # dDANBgkqhkiG9w0BAQwFAAOCAgEAX4h2x35ttVoVdedMeGj6TuHYRJklFaW4sTQ5 # r+k77iB79cSLNe+GzRjv4pVjJviceW6AF6ycWoEYR0LYhaa0ozJLU5Yi+LCmcrdo # vkl53DNt4EXs87KDogYb9eGEndSpZ5ZM74LNvVzY0/nPISHz0Xva71QjD4h+8z2X # MOZzY7YQ0Psw+etyNZ1CesufU211rLslLKsO8F2aBs2cIo1k+aHOhrw9xw6JCWON # NboZ497mwYW5EfN0W3zL5s3ad4Xtm7yFM7Ujrhc0aqy3xL7D5FR2J7x9cLWMq7eb # 0oYioXhqV2tgFqbKHeDick+P8tHYIFovIP7YG4ZkJWag1H91KlELGWi3SLv10o4K # Gag42pswjybTi4toQcC/irAodDW8HNtX+cbz0sMptFJK+KObAnDFHEsukxD+7jFf # EV9Hh/+CSxKRsmnuiovCWIOb+H7DRon9TlxydiFhvu88o0w35JkNbJxTk4MhF/Kg # aXn0GxdH8elEa2Imq45gaa8D+mTm8LWVydt4ytxYP/bqjN49D9NZ81coE6aQWm88 # TwIf4R4YZbOpMKN0CyejaPNN41LGXHeCUMYmBx3PkP8ADHD1J2Cr/6tjuOOCztfp # +o9Nc+ZoIAkpUcA/X2gSMkgHAPUvIdtoSAHEUKiBhI6JQivRepyvWcl+JYbYbBh7 # pmgAXVswggefMIIFh6ADAgECAhMzAAAAWXzacemNXvXAAAAAAABZMA0GCSqGSIb3 # DQEBDAUAMGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y # YXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGlu # ZyBDQSAyMDIwMB4XDTI2MDEwODE4NTkwMVoXDTI3MDEwNzE4NTkwMVowgeMxCzAJ # BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jv # c29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVs # ZCBUU1MgRVNOOjdCMUEtMDVFMC1EOTQ3MTUwMwYDVQQDEyxNaWNyb3NvZnQgUHVi # bGljIFJTQSBUaW1lIFN0YW1waW5nIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEB # BQADggIPADCCAgoCggIBAKYu5/40eEX+hT+5jFa146bid3dA4LnXYntvkP3CGw4L # GARFhnvLMSJ/VtsubzDaeFnm7yb2KSM70WmHQprdCVqpvUH7l0uB4jNw7urLoAR9 # kKHLE0VlMlDStDSxUBI3qwsdrjvdmvV0k+9/njuDEiSlzJTf7Dowd1K3bO4beRya # FhR+Y8tymECOqlOAffYrG2wZdVM51+QSBSe+PEykr8C6OnnqSipuF8fZvCb6/huk # 0Zm6ZwsaixSHIAT2IEGvS7c63Im8jV3a8R0K6i2yiw0NNlnTSpwy/Zfv7iwsLBwh # fbjBTn+XOl6mPzDXQQ3V+SRP9xXbGKOsBTxzGid7aKAHw3o4Ahl9UGWLH9kNP3VU # okE6JYkjlfpuUGZ6gQyqDewfxD4VoYIlopt4HZ0xQvqajuJx+cr8LR/IZ56gLLmw # yMzde5+vtjBoilry/gSZwVGwgkvkIgpKPBQHGsSB0y3szr7Y7wEb6v0yZal1XUvW # nnz3inTaSWsCFrLPVwVmXy3ncY5/d25VpOkht+m697GWNbvsNOhAOHRaftE9j/hh # koM6RsyJfBLnhqMcA/wcavf5oj5NeyRQdGZeLKcls9csKS3sBUzPidxx2iiNH9CP # aDq/bLJEOXasYohXMnRinu+fUk81s8VO7DQSF6ffn5oqSHoV8lf1Ax6u+kdShb8B # AgMBAAGjggHLMIIBxzAdBgNVHQ4EFgQUj5bnC18D0vlnSRhCOiODGGuXNnYwHwYD # VR0jBBgwFoAUa2koOjUvSGNAz3vYr0npPtk92yEwbAYDVR0fBGUwYzBhoF+gXYZb # aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIw # UHVibGljJTIwUlNBJTIwVGltZXN0YW1waW5nJTIwQ0ElMjAyMDIwLmNybDB5Bggr # BgEFBQcBAQRtMGswaQYIKwYBBQUHMAKGXWh0dHA6Ly93d3cubWljcm9zb2Z0LmNv # bS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwUHVibGljJTIwUlNBJTIwVGltZXN0 # YW1waW5nJTIwQ0ElMjAyMDIwLmNydDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQM # MAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIHgDBmBgNVHSAEXzBdMFEGDCsGAQQB # gjdMg30BATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20v # cGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wCAYGZ4EMAQQCMA0GCSqGSIb3DQEB # DAUAA4ICAQBEMhzC/ZcjpG/zURE7z2Yp5vrUxUjsE5Xa3t/2RGvESwvbmsk3bLHh # SFAajgo2XQ8xoGDP3sUhKCLPeICSbkVv6V8sSp8fJ8Jos6yrawf2YVis8tcV+OO7 # U9S6JGPQzpmPncfzQc4ne1fqZ4+HiKabIDEoFdddQT2Egkk9fzxCY/EZ52avJ27d # SfrI/IDmyn9V10O3iQpg2F+C9vNTrk7nVgoDoHa9+Q3pYr0IHGnSmt5irgGT436z # o5WnXP8FxMhswH1aiyiSZiVzhor10C9C52cP3C8/PEoMKUXstLjoPO0TMkeW/1Fr # 186KXD45QRgBo0xImgtWTdzWFnlD+p7+iDBIuSrNcRXDRYuq/aYZaDhWSI0SYdPI # WVh5XvXuWA31a8oQ0SO+oPa3Nk80k0864wiiyJ1KsbSnaaefg9vspeghrpY8ljCw # xfCUtx5HQRNgAJOI8IKACK4d014Mk0hlRO0lQVRHegqIg29K6Xqkc360W2ZJGUcs # tlKokkVj6KAHjGyrLRPzepYfiZUJq4gXyxbpvKb1XJ2FN2682aUoNXo9RyRK1ch0 # f66k6+yj88kzvuC7+vJWtNDs/UpIM6Hhm0kU64JUJ7MMEQcAc7kpft7Gm7YeRK+o # KgqUgYXCfmzbX8nJXJZnPa8ADWVsIqsuNAxCI0CZXkULofqo5Be6zzGCA9QwggPQ # AgEBMHgwYTELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh # dGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFB1YmxpYyBSU0EgVGltZXN0YW1waW5n # IENBIDIwMjACEzMAAABZfNpx6Y1e9cAAAAAAAFkwDQYJYIZIAWUDBAIBBQCgggEt # MBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgcE0Y # N7yFMa1IjgTh4i9Szx+oisRXHC/n31dxoY9mUTMwgd0GCyqGSIb3DQEJEAIvMYHN # MIHKMIHHMIGgBCDLRbqx24bpscXEJ+Hjj9xrcUVw7R8OyyMfSB2YGK3+vDB8MGWk # YzBhMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u # MTIwMAYDVQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBpbmcgQ0Eg # MjAyMAITMwAAAFl82nHpjV71wAAAAAAAWTAiBCB/WqfqZcDF2WYU0sReb3CCsh3W # WXTxghW9jfOy8HS8BTANBgkqhkiG9w0BAQsFAASCAgAiKNKxgPehtMMYs7m/V5/T # i87VECzFLoAg3rueUQfFrcav4Aix9+owN880+C34B7fA8h0z/QqYt1nT6Escu6NV # JCwujug4BY1daT9gbJ8rAH2Ub/wWSEwWvks136YJwvKsN6NdJsbdRR/eanQjAm3H # GbZbxzKBzfp/0vwsVcoFnUIumcdHanRuyiiUF4mHcCT1QcqqfB4jvW3MFAIaDNU+ # k1md7Ngw+pZqQAP1Tw464X5zgalg7Cfjx5mDMhJH3n6JRSzAExYy5HmfTs1tBNTD # Lm+tj89hGd3pY24QS0nj/kUx0bEui9yB7wpkp14RK9bVagDnZoqRrBhibR/xwA6U # 38TT9KBO8jUS1Ju+p0CM65MGUQVuDR0o2oyvf+b75a9KN8RIxbRsTIvGuwZY3FuH # 59+MHhVUvfNANRXgasUrZywtIH/gFP3zSBvAKBP1XkzQbNQZFpgzxRAMR3PUYghd # es0kI3mkCUnVKfcR5nNZcynSmS5XqXBOnBT3lO9rN17KJT1VpNi4zkfgx75FTgLm # blDE9qXpGoGHP4G/YeNLtYVKaP3boRPLpWkT9pBC2ghpYup8wAh1ghwsNgxfZfac # 7CYcUSDz8xLTaYfu8A4u3UIBe8iexdrvIYo6rfYzATQosIe6uYU3gnFTV5CA/+yR # gddmuIkjv8wevFPpXmdNPA== # SIG # End signature block |