Src/Private/New-LabVirtualMachine.ps1
function New-LabVirtualMachine { <# .SYNOPSIS Creates and configures a new lab virtual machine. .DESCRIPTION Creates an new VM, creating the switch if required, injecting all resources and snapshotting as required. #> [CmdletBinding(DefaultParameterSetName = 'PSCredential')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions','')] param ( ## Specifies the lab virtual machine/node name. [Parameter(Mandatory, ValueFromPipeline)] [ValidateNotNullOrEmpty()] [System.String] $Name, ## Specifies a PowerShell DSC configuration document (.psd1) containing the lab configuration. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [System.Collections.Hashtable] [Microsoft.PowerShell.DesiredStateConfiguration.ArgumentToConfigurationDataTransformationAttribute()] $ConfigurationData, ## Local administrator password of the VM. The username is NOT used. [Parameter(ParameterSetName = 'PSCredential', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [System.Management.Automation.PSCredential] [System.Management.Automation.CredentialAttribute()] $Credential = (& $credentialCheckScriptBlock), ## Local administrator password of the VM. [Parameter(Mandatory, ParameterSetName = 'Password', ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [System.Security.SecureString] $Password, ## Virtual machine DSC .mof and .meta.mof location [Parameter(ValueFromPipelineByPropertyName)] [System.String] $Path = (Get-LabHostDscConfigurationPath), ## Skip creating baseline snapshots [Parameter(ValueFromPipelineByPropertyName)] [System.Management.Automation.SwitchParameter] $NoSnapshot, ## Is a quick VM, e.g. created via the New-LabVM cmdlet [Parameter(ValueFromPipelineByPropertyName)] [System.Management.Automation.SwitchParameter] $IsQuickVM ) begin { ## If we have only a secure string, create a PSCredential if ($PSCmdlet.ParameterSetName -eq 'Password') { $Credential = New-Object -TypeName 'System.Management.Automation.PSCredential' -ArgumentList 'LocalAdministrator', $Password; } if (-not $Credential) {throw ($localized.CannotProcessCommandError -f 'Credential'); } elseif ($Credential.Password.Length -eq 0) { throw ($localized.CannotBindArgumentError -f 'Password'); } } process { $node = Resolve-NodePropertyValue -NodeName $Name -ConfigurationData $ConfigurationData -ErrorAction Stop; $nodeName = $node.NodeName; ## Display name includes any environment prefix/suffix $displayName = $node.NodeDisplayName; if (-not (Test-ComputerName -ComputerName $node.NodeName.Split('.')[0])) { throw ($localized.InvalidComputerNameError -f $node.NodeName); } ## Don't attempt to check certificates for 'Quick VMs' if (-not $IsQuickVM) { ## Check for certificate before we (re)create the VM if (-not [System.String]::IsNullOrWhitespace($node.ClientCertificatePath)) { $expandedClientCertificatePath = [System.Environment]::ExpandEnvironmentVariables($node.ClientCertificatePath); if (-not (Test-Path -Path $expandedClientCertificatePath -PathType Leaf)) { throw ($localized.CannotFindCertificateError -f 'Client', $node.ClientCertificatePath); } } else { Write-Warning -Message ($localized.NoCertificateFoundWarning -f 'Client'); } if (-not [System.String]::IsNullOrWhitespace($node.RootCertificatePath)) { $expandedRootCertificatePath = [System.Environment]::ExpandEnvironmentVariables($node.RootCertificatePath); if (-not (Test-Path -Path $expandedRootCertificatePath -PathType Leaf)) { throw ($localized.CannotFindCertificateError -f 'Root', $node.RootCertificatePath); } } else { Write-Warning -Message ($localized.NoCertificateFoundWarning -f 'Root'); } } #end if not quick VM $environmentSwitchNames = @(); foreach ($switchName in $node.SwitchName) { ## Retrieve prefixed switch names for VM creation (if necessary) $resolveLabSwitchParams = @{ Name = $switchName; ConfigurationData = $ConfigurationData; WarningAction = 'SilentlyContinue'; } $networkSwitch = Resolve-LabSwitch @resolveLabSwitchParams; Write-Verbose -Message ($localized.SettingVMConfiguration -f 'Virtual Switch', $networkSwitch.Name); $environmentSwitchNames += $networkSwitch.Name; ## Set-LabSwitch also resolves/prefixes the switch name, so pass the naked name (#251) Set-LabSwitch -Name $switchName -ConfigurationData $ConfigurationData; } if (-not (Test-LabImage -Id $node.Media -ConfigurationData $ConfigurationData)) { [ref] $null = New-LabImage -Id $node.Media -ConfigurationData $ConfigurationData; } Write-Verbose -Message ($localized.ResettingVMConfiguration -f 'VHDX', "$displayName.vhdx"); $resetLabVMDiskParams = @{ Name = $displayName; NodeName = $nodeName; Media = $node.Media; ConfigurationData = $ConfigurationData; } Reset-LabVMDisk @resetLabVMDiskParams -ErrorAction Stop; Write-Verbose -Message ($localized.SettingVMConfiguration -f 'VM', $displayName); $setLabVirtualMachineParams = @{ Name = $DisplayName; SwitchName = $environmentSwitchNames; Media = $node.Media; StartupMemory = $node.StartupMemory; MinimumMemory = $node.MinimumMemory; MaximumMemory = $node.MaximumMemory; ProcessorCount = $node.ProcessorCount; MACAddress = $node.MACAddress; SecureBoot = $node.SecureBoot; GuestIntegrationServices = $node.GuestIntegrationServices; AutomaticCheckPoints = $node.AutomaticCheckpoints; ConfigurationData = $ConfigurationData; } ## Add VMProcessor, Dvd Drive and additional HDD options foreach ($additionalProperty in 'DvdDrive','ProcessorOption','HardDiskDrive') { if ($node.ContainsKey($additionalProperty)) { $setLabVirtualMachineParams[$additionalProperty] = $node[$additionalProperty]; } } Set-LabVirtualMachine @setLabVirtualMachineParams; $media = Resolve-LabMedia -Id $node.Media -ConfigurationData $ConfigurationData; if (($media.OperatingSystem -eq 'Linux') -or ($media.MediaType -eq 'NULL')) { ## Skip injecting files for Linux VMs.. } else { Write-Verbose -Message ($localized.AddingVMCustomization -f 'VM'); $setLabVMDiskFileParams = @{ NodeName = $nodeName; ConfigurationData = $ConfigurationData; Path = $Path; Credential = $Credential; CoreCLR = $media.CustomData.SetupComplete -eq 'CoreCLR'; MaxEnvelopeSizeKb = $node.MaxEnvelopeSizeKb; } if (-not [System.String]::IsNullOrEmpty($media.CustomData.DefaultShell)) { $setLabVMDiskFileParams['DefaultShell'] = $media.CustomData.DefaultShell; } $resolveCustomBootStrapParams = @{ CustomBootstrapOrder = $node.CustomBootstrapOrder; ConfigurationCustomBootstrap = $node.CustomBootstrap; MediaCustomBootStrap = $media.CustomData.CustomBootstrap; } $customBootstrap = Resolve-LabCustomBootStrap @resolveCustomBootStrapParams; if ($customBootstrap) { $setLabVMDiskFileParams['CustomBootstrap'] = $customBootstrap; } if (-not [System.String]::IsNullOrEmpty($media.CustomData.ProductKey)) { $setLabVMDiskFileParams['ProductKey'] = $media.CustomData.ProductKey; } Set-LabVMDiskFile @setLabVMDiskFileParams; } #end Windows VMs if (-not $NoSnapshot) { $snapshotName = $localized.BaselineSnapshotName -f $labDefaults.ModuleName; Write-Verbose -Message ($localized.CreatingBaselineSnapshot -f $snapshotName); Hyper-V\Checkpoint-VM -Name $displayName -SnapshotName $snapshotName -Confirm:$false; } if ($node.WarningMessage) { if ($node.WarningMessage -is [System.String]) { Write-Warning -Message ($localized.NodeCustomMessageWarning -f $nodeName, $node.WarningMessage.Trim("`n")); } else { Write-Warning -Message ($localized.IncorrectPropertyTypeError -f 'WarningMessage', '[System.String]') } } Write-Output -InputObject (Hyper-V\Get-VM -Name $displayName); } #end process } #end function # SIG # Begin signature block # MIIdMgYJKoZIhvcNAQcCoIIdIzCCHR8CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUWHlyOSjF74eI14KbqzihbnBa # j5+gghfKMIIE/jCCA+agAwIBAgIQDUJK4L46iP9gQCHOFADw3TANBgkqhkiG9w0B # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz # c3VyZWQgSUQgVGltZXN0YW1waW5nIENBMB4XDTIxMDEwMTAwMDAwMFoXDTMxMDEw # NjAwMDAwMFowSDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu # MSAwHgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyMTCCASIwDQYJKoZIhvcN # AQEBBQADggEPADCCAQoCggEBAMLmYYRnxYr1DQikRcpja1HXOhFCvQp1dU2UtAxQ # tSYQ/h3Ib5FrDJbnGlxI70Tlv5thzRWRYlq4/2cLnGP9NmqB+in43Stwhd4CGPN4 # bbx9+cdtCT2+anaH6Yq9+IRdHnbJ5MZ2djpT0dHTWjaPxqPhLxs6t2HWc+xObTOK # fF1FLUuxUOZBOjdWhtyTI433UCXoZObd048vV7WHIOsOjizVI9r0TXhG4wODMSlK # XAwxikqMiMX3MFr5FK8VX2xDSQn9JiNT9o1j6BqrW7EdMMKbaYK02/xWVLwfoYer # vnpbCiAvSwnJlaeNsvrWY4tOpXIc7p96AXP4Gdb+DUmEvQECAwEAAaOCAbgwggG0 # MA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsG # AQUFBwMIMEEGA1UdIAQ6MDgwNgYJYIZIAYb9bAcBMCkwJwYIKwYBBQUHAgEWG2h0 # dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAfBgNVHSMEGDAWgBT0tuEgHf4prtLk # YaWyoiWyyBc1bjAdBgNVHQ4EFgQUNkSGjqS6sGa+vCgtHUQ23eNqerwwcQYDVR0f # BGowaDAyoDCgLoYsaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJl # ZC10cy5jcmwwMqAwoC6GLGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWFz # c3VyZWQtdHMuY3JsMIGFBggrBgEFBQcBAQR5MHcwJAYIKwYBBQUHMAGGGGh0dHA6 # Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBPBggrBgEFBQcwAoZDaHR0cDovL2NhY2VydHMu # ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRFRpbWVzdGFtcGluZ0NB # LmNydDANBgkqhkiG9w0BAQsFAAOCAQEASBzctemaI7znGucgDo5nRv1CclF0CiNH # o6uS0iXEcFm+FKDlJ4GlTRQVGQd58NEEw4bZO73+RAJmTe1ppA/2uHDPYuj1UUp4 # eTZ6J7fz51Kfk6ftQ55757TdQSKJ+4eiRgNO/PT+t2R3Y18jUmmDgvoaU+2QzI2h # F3MN9PNlOXBL85zWenvaDLw9MtAby/Vh/HUIAHa8gQ74wOFcz8QRcucbZEnYIpp1 # FUL1LTI4gdr0YKK6tFL7XOBhJCVPst/JKahzQ1HavWPWH1ub9y4bTxMd90oNcX6X # t/Q/hOvB46NJofrOp79Wz7pZdmGJX36ntI5nePk2mOHLKNpbh6aKLzCCBTEwggQZ # oAMCAQICEAqhJdbWMht+QeQF2jaXwhUwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UE # BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj # ZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4X # DTE2MDEwNzEyMDAwMFoXDTMxMDEwNzEyMDAwMFowcjELMAkGA1UEBhMCVVMxFTAT # BgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEx # MC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBD # QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3QMu5LzY9/3am6gpnF # OVQoV7YjSsQOB0UzURB90Pl9TWh+57ag9I2ziOSXv2MhkJi/E7xX08PhfgjWahQA # OPcuHjvuzKb2Mln+X2U/4Jvr40ZHBhpVfgsnfsCi9aDg3iI/Dv9+lfvzo7oiPhis # EeTwmQNtO4V8CdPuXciaC1TjqAlxa+DPIhAPdc9xck4Krd9AOly3UeGheRTGTSQj # MF287DxgaqwvB8z98OpH2YhQXv1mblZhJymJhFHmgudGUP2UKiyn5HU+upgPhH+f # MRTWrdXyZMt7HgXQhBlyF/EXBu89zdZN7wZC/aJTKk+FHcQdPK/P2qwQ9d2srOlW # /5MCAwEAAaOCAc4wggHKMB0GA1UdDgQWBBT0tuEgHf4prtLkYaWyoiWyyBc1bjAf # BgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzASBgNVHRMBAf8ECDAGAQH/ # AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDCDB5BggrBgEF # BQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBD # BggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0 # QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2Ny # bDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDig # NoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v # dENBLmNybDBQBgNVHSAESTBHMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYc # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzALBglghkgBhv1sBwEwDQYJKoZI # hvcNAQELBQADggEBAHGVEulRh1Zpze/d2nyqY3qzeM8GN0CE70uEv8rPAwL9xafD # DiBCLK938ysfDCFaKrcFNB1qrpn4J6JmvwmqYN92pDqTD/iy0dh8GWLoXoIlHsS6 # HHssIeLWWywUNUMEaLLbdQLgcseY1jxk5R9IEBhfiThhTWJGJIdjjJFSLK8pieV4 # H9YLFKWA1xJHcLN11ZOFk362kmf7U2GJqPVrlsD0WGkNfMgBsbkodbeZY4UijGHK # eZR+WfyMD+NvtQEmtmyl7odRIeRYYJu6DC0rbaLEfrvEJStHAgh8Sa4TtuF8QkIo # xhhWz0E0tmZdtnR79VYzIi8iNrJLokqV2PWmjlIwggawMIIEmKADAgECAhAIrUCy # YNKcTJ9ezam9k67ZMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYD # VQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAf # BgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBa # Fw0zNjA0MjgyMzU5NTlaMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2Vy # dCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25p # bmcgUlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4IC # DwAwggIKAoICAQDVtC9C0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc # 9es0JAfhS0/TeEP0F9ce2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyA # VxJrQ5qZ8sU7H/Lvy0daE6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQ # IXhFLqGfLOEYwhrMxe6TSXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/ # sk+FLEikVoQ11vkunKoAFdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na5 # 9zHh3K3kGKDYwSNHR7OhD26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pg # VItJwZPt4bRc4G/rJvmM1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7Bzzosm # JQayg9Rc9hUZTO1i4F4z8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQ # okbIYViY9XwCFjyDKK05huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jL # chApQfDVxW0mdmgRQRNYmtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHM # IRroOBl8ZhzNeDhFMJlP/2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQAB # o4IBWTCCAVUwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8R # hvv+YXsIiGX0TkIwHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYD # VR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGsw # aTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUF # BzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVk # Um9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2Vy # dC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeB # DAEDMAgGBmeBDAEEATANBgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bg # Ahql+Eg08yy25nRm95RysQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7 # FoFFUP2cvbaF4HZ+N3HLIvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZ # GM1hmYFW9snjdufE5BtfQ/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG # 3RywYFzzDaju4ImhvTnhOE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5U # bdldAhQfQDN8A+KVssIhdXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WI # IIJw8MzK7/0pNVwfiThV9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956 # rEnPLqR0kq3bPKSchh/jwVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuW # TatEQOON8BUozu3xGFYHKi8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3 # E+bnKD+sEq6lLyJsQfmCXBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60b # hQjiWQ1tygVQK+pKHJ6l/aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOIm # YIbqyK+p/pQd52MbOoZWeE4wggbbMIIEw6ADAgECAhAEyswKPFRr9qgYCxGuzc8m # MA0GCSqGSIb3DQEBCwUAMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2Vy # dCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25p # bmcgUlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwHhcNMjExMDE5MDAwMDAwWhcNMjMx # MTA0MjM1OTU5WjBgMQswCQYDVQQGEwJHQjEPMA0GA1UEBxMGTG9uZG9uMR8wHQYD # VQQKExZWaXJ0dWFsIEVuZ2luZSBMaW1pdGVkMR8wHQYDVQQDExZWaXJ0dWFsIEVu # Z2luZSBMaW1pdGVkMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAtbm3 # o57mQYxu0idSifhlyZaDVO0Zu0BnGTFZOtZLibBotgpKp7Be3k9WDyIbOiUHVaFY # 7DG8aL8krpArj+3KJR49U5pLXcevNUQFLL18pi9lZ+e2w+dcBAfuJ30J760VtPDw # AA7nmAff3f9o+tEB1ZnIeXzlPRyMz7YZS43sDeAft8p8jFzmM0jRtt9SXNxKcC0g # nX6Cx0vw4AkxmMtreX/Igvj5VVq4M81E84CefWsU/IpqIL24xpxl3OOwZ53wzn+r # PA3T9bj0PUyI/6VvONUIRD/EfODxurVdSDduLHsRag4+Q3xFvZm/WNqsr2qGv7LH # T3uKPsjuPBo1Mz9fM/AfPwdEfM3xJ+Y1rBqUxnDhwYS97Fw3LM63lTKl3bN4TOFE # JX8YPgC02J4vzYSIP0fwBBPyd7MtbiXzFvSoXnl0EQmjH+k4fjOCwn1tgWnI77NE # T05Jd06F3Od52In9qIJ5Bhu4zlMFEQgE7JONOI4/Hl/dBzfNkyItMMRcNiPJAgMB # AAGjggIGMIICAjAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiIZfROQjAdBgNV # HQ4EFgQUEr+p1bWwrT+zl6+TXhHWz9ewYuAwDgYDVR0PAQH/BAQDAgeAMBMGA1Ud # JQQMMAoGCCsGAQUFBwMDMIG1BgNVHR8Ega0wgaowU6BRoE+GTWh0dHA6Ly9jcmwz # LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5 # NlNIQTM4NDIwMjFDQTEuY3JsMFOgUaBPhk1odHRwOi8vY3JsNC5kaWdpY2VydC5j # b20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIx # Q0ExLmNybDA+BgNVHSAENzA1MDMGBmeBDAEEATApMCcGCCsGAQUFBwIBFhtodHRw # Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgZQGCCsGAQUFBwEBBIGHMIGEMCQGCCsG # AQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUHMAKGUGh0 # dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVT # aWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0MAwGA1UdEwEB/wQCMAAwDQYJ # KoZIhvcNAQELBQADggIBAB35Ee2voPHjrdDlB80kocW2ZrVcKO5/POchPOvxL1ev # XPdoaexNDCwXzM/6GXa4U1VhV+GqbeQ+JCZFXWbiycxqXEfi5fxj2sRzdF3CDoot # FiqxK1eqz2W82KR5FX45LTsQMrg6O8kA2nb2eBxk6TWYUtS+3jtdS/nwDp/B/A+o # l0CaD51hlzq9QY0NNkwsbZ+fKmIxinqEFF6ntaOmQNWS0EOtNQBYdlf0pNThBuPx # ENsDtWRS56pg3qfl3+khteed8sFoyY/9g1Sofbc7DAQiYtTikmekA+s5WkHY1ewi # SF/NcXSNNMNgbuAsizoMQ9NkJ/vMhs89+hNUe6Tlk9bFffOP9oh5z6Df/XHJslhN # Y3DxWYQQxtqzZpAk/4GCJ8L9qdeEDvtulPp3p6VqNBxQPu98C46pfXgCX0vIieVy # 3RZOhHD2JCytWNFWXJFvoo03akcyTumiq2+mew6ALwXKKtFeoDHfnzDkVsZRPqY4 # 9gECVKifY7Z7Usuf3SBOB6txOlzK15eMR2EIRsBSCPVZCevU9z51DP/GLZ6/kCDG # 6hcu6isenIWAxWw1wiGv6HJpca73ummRYoUeKtNV8hg7ItlPimtrjjoT+0ciE8Oh # uv5GDBqK0GE4ikCIUZyFg74ppkHV4q+YghXvubkwMSV7ymFRKhgcGQLlDXP+OaVQ # MYIE0jCCBM4CAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs # IEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5n # IFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAEyswKPFRr9qgYCxGuzc8mMAkGBSsO # AwIaBQCgeDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEM # BgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMCMGCSqG # SIb3DQEJBDEWBBRwzhT2m3YCK3JOx+BKTMbE6k75AzANBgkqhkiG9w0BAQEFAASC # AYB9S+xozvbQADuBNFcRtbo5T9vQOEo4pSOXdbCXl03Br5r/qPdnTxUidAH4K1ZC # R95UQzzQ4w3p8U6cbd4xCAEt1ukRXe6h8xaZzURkoJTw+9bHhS9NK4H0rnqAtEYS # uzEWB+oWpoS3nVXt419f6l+2tIVB1Trs/QUWw5AanP3WPQDHaK5B85JxF1zQcKcV # E2z2q+m0tqH8rM0AunM/gxBqyo46dmwuBKY5VmIVKAo6L14SRuVYkSa0DVL0BgPv # WOEmop2rcTU8xdduZrSCRMPiumjLBFBotnFyMYfXDxcyPs/Fgjmo1bp6qLHTCA3K # Dy4mRW4VI+pixVYoTsvtqfhhLN+junypDOBKGbaP94FmvnTlBwqjiACsJ962TuIf # kje60QkdjPi6L2cqDfkwwDQ94ki4S7XOsC8GnS6SVvJZvrqAnZ2hicAdNTBcQd9Q # 2OIcspH8vJCkf07niZyIHtSUfbwbe/CTMXZzkzJ8bQjSexwaBPBiDjYJfNYuPc/J # EZ6hggIwMIICLAYJKoZIhvcNAQkGMYICHTCCAhkCAQEwgYYwcjELMAkGA1UEBhMC # VVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0 # LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFt # cGluZyBDQQIQDUJK4L46iP9gQCHOFADw3TANBglghkgBZQMEAgEFAKBpMBgGCSqG # SIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTIyMDQwMTExNDcz # NVowLwYJKoZIhvcNAQkEMSIEIHGoyFwZCDNYigquY2UuyllJlXMUrNfp+5jTVVr9 # /TAjMA0GCSqGSIb3DQEBAQUABIIBABu1SERI0w4C4QoiG9NrLxYYWodOlEvrjuxI # ChaEcdSuiLTG/HIU/4g4iHBWfmZ0rlQ/wGKlRdxWydaBkz78X9lnRA65LwhxYQyr # nmnnJYq/fUsI7fwgUKnR+SA00YA7BPX1deSnJryw9CmYEHiwXz7kc9qgwBSxpGTs # Yj9+wCz8MK7UxOX0TQmpLWUMxZn1H2XYlznF6TXMXEnegLsQHyiZhBk/IB4D57k2 # ry1/ip0bydja9f+71QrnhicKTS16o5oljTjGq2iTpJX+66qkWyYyhMNVY/z+v1ek # daa1SlMhe50VmEk1ld0y3YRQyATxpXaC1vV0uZQ/3R/Heu8YLAY= # SIG # End signature block |