MSFT_PSModule.psm1 (38882B)
1 # 2 # Copyright (c) Microsoft Corporation. 3 # 4 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 5 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 6 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 7 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 8 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 9 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 10 # THE SOFTWARE. 11 # 12 13 $resourceModuleRoot = Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent 14 15 # Import localization helper functions. 16 $helperName = 'PowerShellGet.LocalizationHelper' 17 $dscResourcesFolderFilePath = Join-Path -Path $resourceModuleRoot -ChildPath "Modules\$helperName\$helperName.psm1" 18 Import-Module -Name $dscResourcesFolderFilePath 19 20 $script:localizedData = Get-LocalizedData -ResourceName 'MSFT_PSModule' -ScriptRoot $PSScriptRoot 21 22 # Import resource helper functions. 23 $helperName = 'PowerShellGet.ResourceHelper' 24 $dscResourcesFolderFilePath = Join-Path -Path $resourceModuleRoot -ChildPath "Modules\$helperName\$helperName.psm1" 25 Import-Module -Name $dscResourcesFolderFilePath 26 27 <# 28 .SYNOPSIS 29 This DSC resource provides a mechanism to download PowerShell modules from the PowerShell 30 Gallery and install it on your computer. 31 32 Get-TargetResource returns the current state of the resource. 33 34 .PARAMETER Name 35 Specifies the name of the PowerShell module to be installed or uninstalled. 36 37 .PARAMETER Repository 38 Specifies the name of the module source repository where the module can be found. 39 40 .PARAMETER RequiredVersion 41 Provides the version of the module you want to install or uninstall. 42 43 .PARAMETER MaximumVersion 44 Provides the maximum version of the module you want to install or uninstall. 45 46 .PARAMETER MinimumVersion 47 Provides the minimum version of the module you want to install or uninstall. 48 49 .PARAMETER Force 50 Forces the installation of modules. If a module of the same name and version already exists on the computer, 51 this parameter overwrites the existing module with one of the same name that was found by the command. 52 53 .PARAMETER AllowClobber 54 Allows the installation of modules regardless of if other existing module on the computer have cmdlets 55 of the same name. 56 57 .PARAMETER SkipPublisherCheck 58 Allows the installation of modules that have not been catalog signed. 59 #> 60 function Get-TargetResource { 61 <# 62 These suppressions are added because this repository have other Visual Studio Code workspace 63 settings than those in DscResource.Tests DSC test framework. 64 Only those suppression that contradict this repository guideline is added here. 65 #> 66 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-ForEachStatement', '')] 67 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-FunctionBlockBraces', '')] 68 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-IfStatement', '')] 69 [CmdletBinding()] 70 [OutputType([System.Collections.Hashtable])] 71 param 72 ( 73 [Parameter(Mandatory = $true)] 74 [System.String] 75 $Name, 76 77 [Parameter()] 78 [System.String] 79 $Repository = 'PSGallery', 80 81 [Parameter()] 82 [System.String] 83 $RequiredVersion, 84 85 [Parameter()] 86 [System.String] 87 $MaximumVersion, 88 89 [Parameter()] 90 [System.String] 91 $MinimumVersion, 92 93 [Parameter()] 94 [System.Boolean] 95 $Force, 96 97 [Parameter()] 98 [System.Boolean] 99 $AllowClobber, 100 101 [Parameter()] 102 [System.Boolean] 103 $SkipPublisherCheck 104 ) 105 106 $returnValue = @{ 107 Ensure = 'Absent' 108 Name = $Name 109 Repository = $Repository 110 Description = $null 111 Guid = $null 112 ModuleBase = $null 113 ModuleType = $null 114 Author = $null 115 InstalledVersion = $null 116 RequiredVersion = $RequiredVersion 117 MinimumVersion = $MinimumVersion 118 MaximumVersion = $MaximumVersion 119 Force = $Force 120 AllowClobber = $AllowClobber 121 SkipPublisherCheck = $SkipPublisherCheck 122 InstallationPolicy = $null 123 } 124 125 Write-Verbose -Message ($localizedData.GetTargetResourceMessage -f $Name) 126 127 $extractedArguments = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters ` 128 -ArgumentNames ('Name', 'Repository', 'MinimumVersion', 'MaximumVersion', 'RequiredVersion') 129 130 # Get the module with the right version and repository properties. 131 $modules = Get-RightModule @extractedArguments -ErrorAction SilentlyContinue -WarningAction SilentlyContinue 132 133 # If the module is found, the count > 0 134 if ($modules.Count -gt 0) { 135 Write-Verbose -Message ($localizedData.ModuleFound -f $Name) 136 137 # Find a module with the latest version and return its properties. 138 $latestModule = $modules[0] 139 140 foreach ($module in $modules) { 141 if ($module.Version -gt $latestModule.Version) { 142 $latestModule = $module 143 } 144 } 145 146 # Check if the repository matches. 147 $repositoryName = Get-ModuleRepositoryName -Module $latestModule -ErrorAction SilentlyContinue -WarningAction SilentlyContinue 148 149 if ($repositoryName) { 150 $installationPolicy = Get-InstallationPolicy -RepositoryName $repositoryName -ErrorAction SilentlyContinue -WarningAction SilentlyContinue 151 } 152 153 if ($installationPolicy) { 154 $installationPolicyReturnValue = 'Trusted' 155 } 156 else { 157 $installationPolicyReturnValue = 'Untrusted' 158 } 159 160 $returnValue.Ensure = 'Present' 161 $returnValue.Repository = $repositoryName 162 $returnValue.Description = $latestModule.Description 163 $returnValue.Guid = $latestModule.Guid 164 $returnValue.ModuleBase = $latestModule.ModuleBase 165 $returnValue.ModuleType = $latestModule.ModuleType 166 $returnValue.Author = $latestModule.Author 167 $returnValue.InstalledVersion = $latestModule.Version 168 $returnValue.InstallationPolicy = $installationPolicyReturnValue 169 } 170 else { 171 Write-Verbose -Message ($localizedData.ModuleNotFound -f $Name) 172 } 173 174 return $returnValue 175 } 176 177 <# 178 .SYNOPSIS 179 This DSC resource provides a mechanism to download PowerShell modules from the PowerShell 180 Gallery and install it on your computer. 181 182 Test-TargetResource validates whether the resource is currently in the desired state. 183 184 .PARAMETER Ensure 185 Determines whether the module to be installed or uninstalled. 186 187 .PARAMETER Name 188 Specifies the name of the PowerShell module to be installed or uninstalled. 189 190 .PARAMETER Repository 191 Specifies the name of the module source repository where the module can be found. 192 193 .PARAMETER InstallationPolicy 194 Determines whether you trust the source repository where the module resides. 195 196 .PARAMETER RequiredVersion 197 Provides the version of the module you want to install or uninstall. 198 199 .PARAMETER MaximumVersion 200 Provides the maximum version of the module you want to install or uninstall. 201 202 .PARAMETER MinimumVersion 203 Provides the minimum version of the module you want to install or uninstall. 204 205 .PARAMETER Force 206 Forces the installation of modules. If a module of the same name and version already exists on the computer, 207 this parameter overwrites the existing module with one of the same name that was found by the command. 208 209 .PARAMETER AllowClobber 210 Allows the installation of modules regardless of if other existing module on the computer have cmdlets 211 of the same name. 212 213 .PARAMETER SkipPublisherCheck 214 Allows the installation of modules that have not been catalog signed. 215 #> 216 function Test-TargetResource { 217 <# 218 These suppressions are added because this repository have other Visual Studio Code workspace 219 settings than those in DscResource.Tests DSC test framework. 220 Only those suppression that contradict this repository guideline is added here. 221 #> 222 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-FunctionBlockBraces', '')] 223 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-IfStatement', '')] 224 [CmdletBinding()] 225 [OutputType([System.Boolean])] 226 param 227 ( 228 [Parameter()] 229 [ValidateSet('Present', 'Absent')] 230 [System.String] 231 $Ensure = 'Present', 232 233 [Parameter(Mandatory = $true)] 234 [System.String] 235 $Name, 236 237 [Parameter()] 238 [System.String] 239 $Repository = 'PSGallery', 240 241 [Parameter()] 242 [ValidateSet('Trusted', 'Untrusted')] 243 [System.String] 244 $InstallationPolicy = 'Untrusted', 245 246 [Parameter()] 247 [System.String] 248 $RequiredVersion, 249 250 [Parameter()] 251 [System.String] 252 $MaximumVersion, 253 254 [Parameter()] 255 [System.String] 256 $MinimumVersion, 257 258 [Parameter()] 259 [System.Boolean] 260 $Force, 261 262 [Parameter()] 263 [System.Boolean] 264 $AllowClobber, 265 266 [Parameter()] 267 [System.Boolean] 268 $SkipPublisherCheck 269 ) 270 271 Write-Verbose -Message ($localizedData.TestTargetResourceMessage -f $Name) 272 273 $extractedArguments = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters ` 274 -ArgumentNames ('Name', 'Repository', 'MinimumVersion', 'MaximumVersion', 'RequiredVersion') 275 276 $status = Get-TargetResource @extractedArguments 277 278 # The ensure returned from Get-TargetResource is not equal to the desired $Ensure. 279 if ($status.Ensure -ieq $Ensure) { 280 Write-Verbose -Message ($localizedData.InDesiredState -f $Name) 281 return $true 282 } 283 else { 284 Write-Verbose -Message ($localizedData.NotInDesiredState -f $Name) 285 return $false 286 } 287 } 288 289 <# 290 .SYNOPSIS 291 This DSC resource provides a mechanism to download PowerShell modules from the PowerShell 292 Gallery and install it on your computer. 293 294 Set-TargetResource sets the resource to the desired state. "Make it so". 295 296 .PARAMETER Ensure 297 Determines whether the module to be installed or uninstalled. 298 299 .PARAMETER Name 300 Specifies the name of the PowerShell module to be installed or uninstalled. 301 302 .PARAMETER Repository 303 Specifies the name of the module source repository where the module can be found. 304 305 .PARAMETER InstallationPolicy 306 Determines whether you trust the source repository where the module resides. 307 308 .PARAMETER RequiredVersion 309 Provides the version of the module you want to install or uninstall. 310 311 .PARAMETER MaximumVersion 312 Provides the maximum version of the module you want to install or uninstall. 313 314 .PARAMETER MinimumVersion 315 Provides the minimum version of the module you want to install or uninstall. 316 317 .PARAMETER Force 318 Forces the installation of modules. If a module of the same name and version already exists on the computer, 319 this parameter overwrites the existing module with one of the same name that was found by the command. 320 321 .PARAMETER AllowClobber 322 Allows the installation of modules regardless of if other existing module on the computer have cmdlets 323 of the same name. 324 325 .PARAMETER SkipPublisherCheck 326 Allows the installation of modules that have not been catalog signed. 327 #> 328 function Set-TargetResource { 329 <# 330 These suppressions are added because this repository have other Visual Studio Code workspace 331 settings than those in DscResource.Tests DSC test framework. 332 Only those suppression that contradict this repository guideline is added here. 333 #> 334 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-ForEachStatement', '')] 335 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-FunctionBlockBraces', '')] 336 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-IfStatement', '')] 337 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-TryStatement', '')] 338 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-CatchClause', '')] 339 [CmdletBinding()] 340 param 341 ( 342 [Parameter()] 343 [ValidateSet('Present', 'Absent')] 344 [System.String] 345 $Ensure = 'Present', 346 347 [Parameter(Mandatory = $true)] 348 [System.String] 349 $Name, 350 351 [Parameter()] 352 [System.String] 353 $Repository = 'PSGallery', 354 355 [Parameter()] 356 [ValidateSet('Trusted', 'Untrusted')] 357 [System.String] 358 $InstallationPolicy = 'Untrusted', 359 360 [Parameter()] 361 [System.String] 362 $RequiredVersion, 363 364 [Parameter()] 365 [System.String] 366 $MaximumVersion, 367 368 [Parameter()] 369 [System.String] 370 $MinimumVersion, 371 372 [Parameter()] 373 [System.Boolean] 374 $Force, 375 376 [Parameter()] 377 [System.Boolean] 378 $AllowClobber, 379 380 [Parameter()] 381 [System.Boolean] 382 $SkipPublisherCheck 383 ) 384 385 # Validate the repository argument 386 if ($PSBoundParameters.ContainsKey('Repository')) { 387 Test-ParameterValue -Value $Repository -Type 'PackageSource' -ProviderName 'PowerShellGet' -Verbose 388 } 389 390 if ($Ensure -ieq 'Present') { 391 # Version check 392 $extractedArguments = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters ` 393 -ArgumentNames ('MinimumVersion', 'MaximumVersion', 'RequiredVersion') 394 395 $null = Test-VersionParameter @extractedArguments 396 397 try { 398 $extractedArguments = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters ` 399 -ArgumentNames ('Name', 'Repository', 'MinimumVersion', 'MaximumVersion', 'RequiredVersion') 400 401 Write-Verbose -Message ($localizedData.StartFindModule -f $Name) 402 403 $modules = Find-Module @extractedArguments -ErrorVariable ev 404 } 405 catch { 406 $errorMessage = $script:localizedData.ModuleNotFoundInRepository -f $Name 407 New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ 408 } 409 410 $trusted = $null 411 $moduleFound = $null 412 413 foreach ($m in $modules) { 414 # Check for the installation policy. 415 $trusted = Get-InstallationPolicy -RepositoryName $m.Repository -ErrorAction SilentlyContinue -WarningAction SilentlyContinue 416 417 # Stop the loop if found a trusted repository. 418 if ($trusted) { 419 $moduleFound = $m 420 break; 421 } 422 } 423 424 try { 425 # The repository is trusted, so we install it. 426 if ($trusted) { 427 Write-Verbose -Message ($localizedData.StartInstallModule -f $Name, $moduleFound.Version.toString(), $moduleFound.Repository) 428 429 # Extract the installation options. 430 $extractedSwitches = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters -ArgumentNames ('Force', 'AllowClobber', 'SkipPublisherCheck') 431 432 $moduleFound | Install-Module @extractedSwitches 2>&1 | out-string | Write-Verbose 433 } 434 # The repository is untrusted but user's installation policy is trusted, so we install it with a warning. 435 elseif ($InstallationPolicy -ieq 'Trusted') { 436 Write-Warning -Message ($localizedData.InstallationPolicyWarning -f $Name, $modules[0].Repository, $InstallationPolicy) 437 438 # Extract installation options (Force implied by InstallationPolicy). 439 $extractedSwitches = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters -ArgumentNames ('AllowClobber', 'SkipPublisherCheck') 440 441 # If all the repositories are untrusted, we choose the first one. 442 $modules[0] | Install-Module @extractedSwitches -Force 2>&1 | out-string | Write-Verbose 443 } 444 # Both user and repository is untrusted 445 else { 446 $errorMessage = $script:localizedData.InstallationPolicyFailed -f $InstallationPolicy, 'Untrusted' 447 New-InvalidOperationException -Message $errorMessage 448 } 449 450 Write-Verbose -Message ($localizedData.InstalledSuccess -f $Name) 451 } 452 catch { 453 $errorMessage = $script:localizedData.FailToInstall -f $Name 454 New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ 455 } 456 } 457 # Ensure=Absent 458 else { 459 460 $extractedArguments = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters ` 461 -ArgumentNames ('Name', 'Repository', 'MinimumVersion', 'MaximumVersion', 'RequiredVersion') 462 463 # Get the module with the right version and repository properties. 464 $modules = Get-RightModule @extractedArguments 465 466 if (-not $modules) { 467 $errorMessage = $script:localizedData.ModuleWithRightPropertyNotFound -f $Name 468 New-InvalidOperationException -Message $errorMessage 469 } 470 471 foreach ($module in $modules) { 472 # Get the path where the module is installed. 473 $path = $module.ModuleBase 474 475 Write-Verbose -Message ($localizedData.StartUnInstallModule -f $Name) 476 477 try { 478 <# 479 There is no Uninstall-Module cmdlet for Windows PowerShell 4.0, 480 so we will remove the ModuleBase folder as an uninstall operation. 481 #> 482 Microsoft.PowerShell.Management\Remove-Item -Path $path -Force -Recurse 483 484 Write-Verbose -Message ($localizedData.UnInstalledSuccess -f $module.Name) 485 } 486 catch { 487 $errorMessage = $script:localizedData.FailToUninstall -f $module.Name 488 New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ 489 } 490 } # foreach 491 } # Ensure=Absent 492 } 493 494 <# 495 .SYNOPSIS 496 This is a helper function. It returns the modules that meet the specified versions and the repository requirements. 497 498 .PARAMETER Name 499 Specifies the name of the PowerShell module. 500 501 .PARAMETER RequiredVersion 502 Provides the version of the module you want to install or uninstall. 503 504 .PARAMETER MaximumVersion 505 Provides the maximum version of the module you want to install or uninstall. 506 507 .PARAMETER MinimumVersion 508 Provides the minimum version of the module you want to install or uninstall. 509 510 .PARAMETER Repository 511 Specifies the name of the module source repository where the module can be found. 512 #> 513 function Get-RightModule { 514 <# 515 These suppressions are added because this repository have other Visual Studio Code workspace 516 settings than those in DscResource.Tests DSC test framework. 517 Only those suppression that contradict this repository guideline is added here. 518 #> 519 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-ForEachStatement', '')] 520 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-FunctionBlockBraces', '')] 521 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-IfStatement', '')] 522 [CmdletBinding()] 523 param 524 ( 525 [Parameter(Mandatory = $true)] 526 [ValidateNotNullOrEmpty()] 527 [System.String] 528 $Name, 529 530 [Parameter()] 531 [System.String] 532 $RequiredVersion, 533 534 [Parameter()] 535 [System.String] 536 $MinimumVersion, 537 538 [Parameter()] 539 [System.String] 540 $MaximumVersion, 541 542 [Parameter()] 543 [System.String] 544 $Repository 545 ) 546 547 Write-Verbose -Message ($localizedData.StartGetModule -f $($Name)) 548 549 $modules = Microsoft.PowerShell.Core\Get-Module -Name $Name -ListAvailable -ErrorAction SilentlyContinue -WarningAction SilentlyContinue 550 551 if (-not $modules) { 552 return $null 553 } 554 555 <# 556 As Get-Module does not take RequiredVersion, MinimumVersion, MaximumVersion, or Repository, 557 below we need to check whether the modules are containing the right version and repository 558 location. 559 #> 560 561 $extractedArguments = New-SplatParameterHashTable -FunctionBoundParameters $PSBoundParameters ` 562 -ArgumentNames ('MaximumVersion', 'MinimumVersion', 'RequiredVersion') 563 $returnVal = @() 564 565 foreach ($m in $modules) { 566 $versionMatch = $false 567 $installedVersion = $m.Version 568 569 # Case 1 - a user provides none of RequiredVersion, MinimumVersion, MaximumVersion 570 if ($extractedArguments.Count -eq 0) { 571 $versionMatch = $true 572 } 573 574 # Case 2 - a user provides RequiredVersion 575 elseif ($extractedArguments.ContainsKey('RequiredVersion')) { 576 # Check if it matches with the installed version 577 $versionMatch = ($installedVersion -eq [System.Version] $RequiredVersion) 578 } 579 else { 580 581 # Case 3 - a user provides MinimumVersion 582 if ($extractedArguments.ContainsKey('MinimumVersion')) { 583 $versionMatch = ($installedVersion -ge [System.Version] $extractedArguments['MinimumVersion']) 584 } 585 586 # Case 4 - a user provides MaximumVersion 587 if ($extractedArguments.ContainsKey('MaximumVersion')) { 588 $isLessThanMax = ($installedVersion -le [System.Version] $extractedArguments['MaximumVersion']) 589 590 if ($extractedArguments.ContainsKey('MinimumVersion')) { 591 $versionMatch = $versionMatch -and $isLessThanMax 592 } 593 else { 594 $versionMatch = $isLessThanMax 595 } 596 } 597 598 # Case 5 - Both MinimumVersion and MaximumVersion are provided. It's covered by the above. 599 # Do not return $false yet to allow the foreach to continue 600 if (-not $versionMatch) { 601 Write-Verbose -Message ($localizedData.VersionMismatch -f $Name, $installedVersion) 602 $versionMatch = $false 603 } 604 } 605 606 # Case 6 - Version matches but need to check if the module is from the right repository. 607 if ($versionMatch) { 608 # A user does not provide Repository, we are good 609 if (-not $PSBoundParameters.ContainsKey('Repository')) { 610 Write-Verbose -Message ($localizedData.ModuleFound -f "$Name $installedVersion") 611 $returnVal += $m 612 } 613 else { 614 # Check if the Repository matches 615 $sourceName = Get-ModuleRepositoryName -Module $m 616 617 if ($Repository -ieq $sourceName) { 618 Write-Verbose -Message ($localizedData.ModuleFound -f "$Name $installedVersion") 619 $returnVal += $m 620 } 621 else { 622 Write-Verbose -Message ($localizedData.RepositoryMismatch -f $($Name), $($sourceName)) 623 } 624 } 625 } 626 } # foreach 627 628 return $returnVal 629 } 630 631 <# 632 .SYNOPSIS 633 This is a helper function that returns the module's repository name. 634 635 .PARAMETER Module 636 Specifies the name of the PowerShell module. 637 #> 638 function Get-ModuleRepositoryName { 639 <# 640 These suppressions are added because this repository have other Visual Studio Code workspace 641 settings than those in DscResource.Tests DSC test framework. 642 Only those suppression that contradict this repository guideline is added here. 643 #> 644 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-FunctionBlockBraces', '')] 645 [Diagnostics.CodeAnalysis.SuppressMessageAttribute('DscResource.AnalyzerRules\Measure-IfStatement', '')] 646 [CmdletBinding()] 647 param 648 ( 649 [Parameter(Mandatory = $true)] 650 [ValidateNotNullOrEmpty()] 651 [System.Object] 652 $Module 653 ) 654 655 <# 656 RepositorySourceLocation property is supported in PS V5 only. To work with the earlier 657 PowerShell version, we need to do a different way. PSGetModuleInfo.xml exists for any 658 PowerShell modules downloaded through PSModule provider. 659 #> 660 $psGetModuleInfoFileName = 'PSGetModuleInfo.xml' 661 $psGetModuleInfoPath = Microsoft.PowerShell.Management\Join-Path -Path $Module.ModuleBase -ChildPath $psGetModuleInfoFileName 662 663 Write-Verbose -Message ($localizedData.FoundModulePath -f $psGetModuleInfoPath) 664 665 if (Microsoft.PowerShell.Management\Test-path -Path $psGetModuleInfoPath) { 666 $psGetModuleInfo = Microsoft.PowerShell.Utility\Import-Clixml -Path $psGetModuleInfoPath 667 668 return $psGetModuleInfo.Repository 669 } 670 } 671 672 # SIG # Begin signature block 673 # MIIjkgYJKoZIhvcNAQcCoIIjgzCCI38CAQExDzANBglghkgBZQMEAgEFADB5Bgor 674 # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG 675 # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCig4H1kVMWxA7U 676 # uX1JaRBJmDsHSZHmuBUTkDBwWHafCqCCDYEwggX/MIID56ADAgECAhMzAAABh3IX 677 # chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD 678 # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy 679 # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p 680 # bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw 681 # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u 682 # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy 683 # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB 684 # AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB 685 # znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH 686 # sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d 687 # weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ 688 # itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV 689 # Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE 690 # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw 691 # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 692 # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu 693 # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu 694 # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w 695 # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 696 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx 697 # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy 698 # S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K 699 # NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV 700 # BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr 701 # qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx 702 # zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe 703 # yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g 704 # yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf 705 # AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI 706 # 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5 707 # GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea 708 # jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS 709 # AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK 710 # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 711 # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 712 # ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla 713 # MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS 714 # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT 715 # H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB 716 # AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG 717 # OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S 718 # 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz 719 # y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7 720 # 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u 721 # M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33 722 # X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl 723 # XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP 724 # 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB 725 # l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF 726 # RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM 727 # CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ 728 # BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud 729 # DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO 730 # 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0 731 # LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y 732 # Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p 733 # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y 734 # Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB 735 # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw 736 # cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA 737 # XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY 738 # 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj 739 # 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd 740 # d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ 741 # Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf 742 # wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ 743 # aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j 744 # NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B 745 # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 746 # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 747 # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I 748 # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZzCCFWMCAQEwgZUwfjELMAkG 749 # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx 750 # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z 751 # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN 752 # BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor 753 # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg2t+ikpO2 754 # 0WdDEf/JRKsEEOWFz2O6CEnKmWwPbrvPFuIwQgYKKwYBBAGCNwIBDDE0MDKgFIAS 755 # AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN 756 # BgkqhkiG9w0BAQEFAASCAQBaj/JIwAbud/IMJN3SHVwenJwEjzrmM3cPznYlvkyE 757 # rnB6RiDYnohm+72wkCmVWobuualV9Xw8OGA9w7MvJjZuEnFP9TwDjlWinR4FpdVl 758 # YX49u4g50iMR2isaKTxMA2nA2LbyFpTLMqi6ynPLnv251xTdumj/XRLZjHdpr4Pt 759 # p6HQz45/jMWRtlh8x3piJPrgpINuJtmO91tnMQnykF++QgteDqKSboXOu2Wg0oCn 760 # Ao0eOifIujyUp2ez9Cqx2hzkMOqNa5jZD4JetiDTWBTkN8XHRbsfCVwyEQzxrpXn 761 # wAFT7jMzuI8o8xdCuCvuDokIzcnm+rKZJIy6Rwp6Cn11oYIS8TCCEu0GCisGAQQB 762 # gjcDAwExghLdMIIS2QYJKoZIhvcNAQcCoIISyjCCEsYCAQMxDzANBglghkgBZQME 763 # AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB 764 # MDEwDQYJYIZIAWUDBAIBBQAEIL/3GmTbcOXlRJe8Pu+1/QVBo0Mk83o/PGK7iApB 765 # aAutAgZfYQoJ7SUYEzIwMjAwOTIyMjIxOTUxLjg4NlowBIACAfSggdSkgdEwgc4x 766 # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt 767 # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p 768 # Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg 769 # VFNTIEVTTjo4OTdBLUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt 770 # U3RhbXAgU2VydmljZaCCDkQwggT1MIID3aADAgECAhMzAAABLCKvRZd1+RvuAAAA 771 # AAEsMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo 772 # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y 773 # cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw 774 # MB4XDTE5MTIxOTAxMTUwM1oXDTIxMDMxNzAxMTUwM1owgc4xCzAJBgNVBAYTAlVT 775 # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK 776 # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy 777 # YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo4OTdB 778 # LUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj 779 # ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPK1zgSSq+MxAYo3qpCt 780 # QDxSMPPJy6mm/wfEJNjNUnYtLFBwl1BUS5trEk/t41ldxITKehs+ABxYqo4Qxsg3 781 # Gy1ugKiwHAnYiiekfC+ZhptNFgtnDZIn45zC0AlVr/6UfLtsLcHCh1XElLUHfEC0 782 # nBuQcM/SpYo9e3l1qY5NdMgDGxCsmCKdiZfYXIu+U0UYIBhdzmSHnB3fxZOBVcr5 783 # htFHEBBNt/rFJlm/A4yb8oBsp+Uf0p5QwmO/bCcdqB15JpylOhZmWs0sUfJKlK9E 784 # rAhBwGki2eIRFKsQBdkXS9PWpF1w2gIJRvSkDEaCf+lbGTPdSzHSbfREWOF9wY3i 785 # Yj8CAwEAAaOCARswggEXMB0GA1UdDgQWBBRRahZSGfrCQhCyIyGH9DkiaW7L0zAf 786 # BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH 787 # hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU 788 # aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF 789 # BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0 790 # YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG 791 # AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQBPFxHIwi4vAH49w9Svmz6K3tM55RlW 792 # 5pPeULXdut2Rqy6Ys0+VpZsbuaEoxs6Z1C3hMbkiqZFxxyltxJpuHTyGTg61zfNI 793 # F5n6RsYF3s7IElDXNfZznF1/2iWc6uRPZK8rxxUJ/7emYXZCYwuUY0XjsCpP9pbR 794 # RKeJi6r5arSyI+NfKxvgoM21JNt1BcdlXuAecdd/k8UjxCscffanoK2n6LFw1PcZ 795 # lEO7NId7o+soM2C0QY5BYdghpn7uqopB6ixyFIIkDXFub+1E7GmAEwfU6VwEHL7y 796 # 9rNE8bd+JrQs+yAtkkHy9FmXg/PsGq1daVzX1So7CJ6nyphpuHSN3VfTMIIGcTCC 797 # BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC 798 # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV 799 # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv 800 # b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN 801 # MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv 802 # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 803 # aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw 804 # DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0 805 # VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw 806 # RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe 807 # dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx 808 # Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G 809 # kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA 810 # AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7 811 # fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC 812 # AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX 813 # zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v 814 # cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI 815 # KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j 816 # b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g 817 # AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93 818 # d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB 819 # BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA 820 # bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh 821 # IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS 822 # +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK 823 # kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon 824 # /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi 825 # PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/ 826 # fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII 827 # YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0 828 # cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a 829 # KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ 830 # cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+ 831 # NR4Iuto229Nfj950iEkSoYIC0jCCAjsCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT 832 # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD 833 # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP 834 # cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo4 835 # OTdBLUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy 836 # dmljZaIjCgEBMAcGBSsOAwIaAxUADE5OKSMoNx/mYxYWap1RTOohbJ2ggYMwgYCk 837 # fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH 838 # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD 839 # Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF 840 # AOMUwsMwIhgPMjAyMDA5MjIyMjM2NTFaGA8yMDIwMDkyMzIyMzY1MVowdzA9Bgor 841 # BgEEAYRZCgQBMS8wLTAKAgUA4xTCwwIBADAKAgEAAgIlfwIB/zAHAgEAAgIRzTAK 842 # AgUA4xYUQwIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB 843 # AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAEmZCk5PsMA6oG40 844 # YulPUpxDtQA+JAuXyNrLI4wJcdmv34Bzmj9gk3gv6ZxQZxlvZjA1O1P3lcKGIYco 845 # 9UkRdAeP6Zzfim6U3UoiUz1AHKuSm6iLux7Z/hNtgEs2ZpYXxOK5JZ/9Pa2I5mg0 846 # VxsGdXBxl6TOZqbB6aGNG1ZKytRWMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMC 847 # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV 848 # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp 849 # bWUtU3RhbXAgUENBIDIwMTACEzMAAAEsIq9Fl3X5G+4AAAAAASwwDQYJYIZIAWUD 850 # BAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0B 851 # CQQxIgQgioHn9SQtTXybUUTzgPmt61UPBGskDV9AErEC62Y8+H4wgfoGCyqGSIb3 852 # DQEJEAIvMYHqMIHnMIHkMIG9BCBbn/0uFFh42hTM5XOoKdXevBaiSxmYK9Ilcn9n 853 # u5ZH4TCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u 854 # MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp 855 # b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB 856 # LCKvRZd1+RvuAAAAAAEsMCIEIJmkMFyuUW5yiXAemMCWHyk8T1EMMlB1cEiVD4/E 857 # +vhqMA0GCSqGSIb3DQEBCwUABIIBAOyFm0zpO+VogyMfTuCFeJjMyyDnAJRy/KhW 858 # jtq11pPg3e11HU0LuNa+ZpCrJXbSWlF+tLkU9eQXPpGPzO7ITGhxhnq5wyhfzA8a 859 # 9TRGlDMUNHp+6WhH6BZ86zUqMpcYx5zN0H9TaJTpC8JJ7HrNTW8zp032ocr6IXVr 860 # M6mOa0MUZsE366+OXRpCCm0fokT50uvXWbcRdngS9ZT5xmz134T1iS4Fds7ZOC5W 861 # m0VofKEuaTYbTc5aF0WN/OGMvowHRxlJhG7zhMX8ZuXGvbgzANq/o7tZu0HmGFTN 862 # rPs5smC3VEWVpNWgOTfrO3bfaWkAdsuBeLVXZUog+M4wmTDFSPs= 863 # SIG # End signature block