Src/Public/Start-LabConfiguration.ps1
function Start-LabConfiguration { <# .SYNOPSIS Invokes the deployment and configuration of a VM for each node defined in a PowerShell DSC configuration document. .DESCRIPTION The Start-LabConfiguration initiates the configuration of all nodes defined in a PowerShell DSC configuration document. The AllNodes array is enumerated and a virtual machine is created per node, using the NodeName property. If any existing virtual machine exists with the same name as the NodeName declaration of the AllNodes array, the cmdlet will throw an error. If this behaviour is not desired, you can forcibly remove the existing VM with the -Force parameter. NOTE: THE VIRTUAL MACHINE'S EXISTING DATA WILL BE LOST. The virtual machines' local administrator password must be specified when creating the lab VMs. The local administrator password can be specified as a [PSCredential] or a [SecureString] type. If a [PSCredential] is used then the username is not used. It is possible to override the module's virtual machine default settings by specifying the required property on the node hashtable in the PowerShell DSC configuration document. Default settings include the Operating System image to use, the amount of memory assigned to the virtual machine and/or the virtual switch to connect the virtual machine to. If the settings are not overridden, the module's defaults are used. Use the Get-LabVMDefault cmdlet to view the module's default values. Each virtual machine created by the Start-LabConfiguration cmdlet, has its PowerShell DSC configuraion (.mof) file injected into the VHD file as it is created. This configuration is then applied during the first boot process to ensure the virtual machine is configured as required. If the path to the VM's .mof files is not specified, the module's default Configuration directory is used. Use the Get-LabHostDefault cmdlet to view the module's default Configuration directory path. The virtual machine .mof files must be created before creating the lab. If any .mof files are missing, the Start-LabConfiguration cmdlet will generate an error. You can choose to ignore this error by specifying the -SkipMofCheck parameter. If you skip the .mof file check - and no .mof file is found - no configuration will be applied to the virtual machine's Operating System settings. When deploying a lab, the module will create a default baseline snapshot of all virtual machines. This snapshot can be used to revert all VMs back to their default configuration. If this snapshot is not required, it can be surpressed with the -NoSnapshot parameter. .NOTES The same local administrator password is used for all virtual machines created in the same lab configuration. .PARAMETER ConfigurationData Specifies a PowerShell DSC configuration data hashtable or a path to an existing PowerShell DSC .psd1 configuration document used to create the virtual machines. One virtual machine is created per node defined in the AllNodes array. .PARAMETER Credential Specifies the local administrator password of all virtual machines in the lab configuration. The same password is used for all virtual machines in the same lab configuration. The username is not used. .PARAMETER Password Specifies the local administrator password of all virtual machines in the lab configuration. The same password is used for all virtual machines in the same lab configuration. .PARAMETER Path Specifies the directory path containing the individual PowerShell DSC .mof files. If not specified, the module's default location is used. .PARAMETER NoSnapshot Specifies that no default snapshot will be taken when creating the virtual machine. NOTE: If no default snapshot is not created, the lab cannot be restored to its initial configuration with the Reset-Lab cmdlet. .PARAMETER SkipMofCheck Specifies that the module will configure a virtual machines that do not have a corresponding .mof file located in the -Path specfified. By default, if any .mof file cannot be located then the cmdlet will generate an error. NOTE: If no .mof file is found and the -SkipMofCheck parameter is specified, no configuration will be applied to the virtual machine's Operating System configuration. .PARAMETER IgnorePendingReboot The host's configuration is checked before invoking a lab configuration, including checking for pending reboots. The -IgnorePendingReboot specifies that a pending reboot should be ignored and the lab configuration applied. .PARAMETER Force Specifies that any existing virtual machine with a matching name, will be removed and recreated. By default, if a virtual machine already exists with the same name, the cmdlet will generate an error. NOTE: If the -Force parameter is specified - and a virtual machine with the same name already exists - ALL EXISTING DATA WITHIN THE VM WILL BE LOST. .LINK about_ConfigurationData about_Bootstrap Get-LabHostDefault Set-LabHostDefault Get-LabVMDefault Set-LabVMDefault Reset-Lab #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'PSCredential')] param ( ## Lab DSC configuration data [Parameter(Mandatory, ValueFromPipeline)] [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, ## Path to .MOF files created from the DSC configuration [Parameter(ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [System.String] $Path, ## Skip creating baseline snapshots [Parameter(ValueFromPipelineByPropertyName)] [System.Management.Automation.SwitchParameter] $NoSnapshot, ## Forces a reconfiguration/redeployment of all nodes. [Parameter(ValueFromPipelineByPropertyName)] [System.Management.Automation.SwitchParameter] $Force, ## Ignores missing MOF file [Parameter(ValueFromPipelineByPropertyName)] [System.Management.Automation.SwitchParameter] $SkipMofCheck, ## Skips pending reboot check [Parameter(ValueFromPipelineByPropertyName)] [System.Management.Automation.SwitchParameter] $IgnorePendingReboot ) 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'); } if (-not (Test-LabHostConfiguration -IgnorePendingReboot:$IgnorePendingReboot) -and (-not $Force)) { throw $localized.HostConfigurationTestError; } } process { WriteVerbose $localized.StartedLabConfiguration; $nodes = $ConfigurationData.AllNodes | Where-Object { $_.NodeName -ne '*' }; ## There is an assumption here is all .mofs are in the same folder $resolveConfigurationPathParams = @{ ConfigurationData = $ConfigurationData; Name = $nodes | Select-Object -First 1 | ForEach-Object { $_.NodeName }; Path = $Path; UseDefaultPath = $SkipMofCheck; } $Path = Resolve-ConfigurationPath @resolveConfigurationPathParams; foreach ($node in $nodes) { $assertLabConfigurationMofParams = @{ ConfigurationData = $ConfigurationData; Name = $node.NodeName; Path = $Path; } Assert-LabConfigurationMof @assertLabConfigurationMofParams -SkipMofCheck:$SkipMofCheck; } #end foreach node $currentNodeCount = 0; foreach ($node in (Test-LabConfiguration -ConfigurationData $ConfigurationData)) { $currentNodeCount++; [System.Int16] $percentComplete = (($currentNodeCount / $nodes.Count) * 100) - 1; $activity = $localized.ConfiguringNode -f $node.Name; Write-Progress -Id 42 -Activity $activity -PercentComplete $percentComplete; if ($node.IsConfigured -and $Force) { WriteVerbose -Message ($localized.NodeForcedConfiguration -f $node.Name); $shouldProcessMessage = $localized.PerformingOperationOnTarget -f 'New-VM', $node.Name; $verboseProcessMessage = Get-FormattedMessage -Message ($localized.CreatingVM -f $node.Name); if ($PSCmdlet.ShouldProcess($verboseProcessMessage, $shouldProcessMessage, $localized.ShouldProcessWarning)) { $newLabVirtualMachineParams = @{ Name = $node.Name; ConfigurationData = $ConfigurationData; Path = $Path; NoSnapshot = $NoSnapshot; Credential = $Credential; } New-LabVirtualMachine @newLabVirtualMachineParams; } } elseif ($node.IsConfigured) { WriteVerbose ($localized.NodeAlreadyConfigured -f $node.Name); } else { WriteVerbose -Message ($localized.NodeMissingOrMisconfigured -f $node.Name); $shouldProcessMessage = $localized.PerformingOperationOnTarget -f 'Start-LabConfiguration', $node.Name; $verboseProcessMessage = Get-FormattedMessage -Message ($localized.CreatingVM -f $node.Name); if ($PSCmdlet.ShouldProcess($verboseProcessMessage, $shouldProcessMessage, $localized.ShouldProcessWarning)) { $newLabVirtualMachineParams = @{ Name = $node.Name; ConfigurationData = $ConfigurationData; Path = $Path; NoSnapshot = $NoSnapshot; Credential = $Credential; } New-LabVirtualMachine @newLabVirtualMachineParams; } } } #end foreach node Write-Progress -Id 42 -Activity $activity -Completed; WriteVerbose $localized.FinishedLabConfiguration; } #end process } #end function Start-LabConfiguration # SIG # Begin signature block # MIIX1gYJKoZIhvcNAQcCoIIXxzCCF8MCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUlhQheeq7ZhPo8hNn8KT+DzF+ # WlegghMJMIID7jCCA1egAwIBAgIQfpPr+3zGTlnqS5p31Ab8OzANBgkqhkiG9w0B # AQUFADCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIG # A1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhh # d3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcg # Q0EwHhcNMTIxMjIxMDAwMDAwWhcNMjAxMjMwMjM1OTU5WjBeMQswCQYDVQQGEwJV # UzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNVBAMTJ1N5bWFu # dGVjIFRpbWUgU3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMjCCASIwDQYJKoZIhvcN # AQEBBQADggEPADCCAQoCggEBALGss0lUS5ccEgrYJXmRIlcqb9y4JsRDc2vCvy5Q # WvsUwnaOQwElQ7Sh4kX06Ld7w3TMIte0lAAC903tv7S3RCRrzV9FO9FEzkMScxeC # i2m0K8uZHqxyGyZNcR+xMd37UWECU6aq9UksBXhFpS+JzueZ5/6M4lc/PcaS3Er4 # ezPkeQr78HWIQZz/xQNRmarXbJ+TaYdlKYOFwmAUxMjJOxTawIHwHw103pIiq8r3 # +3R8J+b3Sht/p8OeLa6K6qbmqicWfWH3mHERvOJQoUvlXfrlDqcsn6plINPYlujI # fKVOSET/GeJEB5IL12iEgF1qeGRFzWBGflTBE3zFefHJwXECAwEAAaOB+jCB9zAd # BgNVHQ4EFgQUX5r1blzMzHSa1N197z/b7EyALt0wMgYIKwYBBQUHAQEEJjAkMCIG # CCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMBIGA1UdEwEB/wQIMAYB # Af8CAQAwPwYDVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NybC50aGF3dGUuY29tL1Ro # YXd0ZVRpbWVzdGFtcGluZ0NBLmNybDATBgNVHSUEDDAKBggrBgEFBQcDCDAOBgNV # HQ8BAf8EBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFRpbWVTdGFtcC0y # MDQ4LTEwDQYJKoZIhvcNAQEFBQADgYEAAwmbj3nvf1kwqu9otfrjCR27T4IGXTdf # plKfFo3qHJIJRG71betYfDDo+WmNI3MLEm9Hqa45EfgqsZuwGsOO61mWAK3ODE2y # 0DGmCFwqevzieh1XTKhlGOl5QGIllm7HxzdqgyEIjkHq3dlXPx13SYcqFgZepjhq # IhKjURmDfrYwggSjMIIDi6ADAgECAhAOz/Q4yP6/NW4E2GqYGxpQMA0GCSqGSIb3 # DQEBBQUAMF4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3Jh # dGlvbjEwMC4GA1UEAxMnU3ltYW50ZWMgVGltZSBTdGFtcGluZyBTZXJ2aWNlcyBD # QSAtIEcyMB4XDTEyMTAxODAwMDAwMFoXDTIwMTIyOTIzNTk1OVowYjELMAkGA1UE # BhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMTQwMgYDVQQDEytT # eW1hbnRlYyBUaW1lIFN0YW1waW5nIFNlcnZpY2VzIFNpZ25lciAtIEc0MIIBIjAN # BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAomMLOUS4uyOnREm7Dv+h8GEKU5Ow # mNutLA9KxW7/hjxTVQ8VzgQ/K/2plpbZvmF5C1vJTIZ25eBDSyKV7sIrQ8Gf2Gi0 # jkBP7oU4uRHFI/JkWPAVMm9OV6GuiKQC1yoezUvh3WPVF4kyW7BemVqonShQDhfu # ltthO0VRHc8SVguSR/yrrvZmPUescHLnkudfzRC5xINklBm9JYDh6NIipdC6Anqh # d5NbZcPuF3S8QYYq3AhMjJKMkS2ed0QfaNaodHfbDlsyi1aLM73ZY8hJnTrFxeoz # C9Lxoxv0i77Zs1eLO94Ep3oisiSuLsdwxb5OgyYI+wu9qU+ZCOEQKHKqzQIDAQAB # o4IBVzCCAVMwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAO # BgNVHQ8BAf8EBAMCB4AwcwYIKwYBBQUHAQEEZzBlMCoGCCsGAQUFBzABhh5odHRw # Oi8vdHMtb2NzcC53cy5zeW1hbnRlYy5jb20wNwYIKwYBBQUHMAKGK2h0dHA6Ly90 # cy1haWEud3Muc3ltYW50ZWMuY29tL3Rzcy1jYS1nMi5jZXIwPAYDVR0fBDUwMzAx # oC+gLYYraHR0cDovL3RzLWNybC53cy5zeW1hbnRlYy5jb20vdHNzLWNhLWcyLmNy # bDAoBgNVHREEITAfpB0wGzEZMBcGA1UEAxMQVGltZVN0YW1wLTIwNDgtMjAdBgNV # HQ4EFgQURsZpow5KFB7VTNpSYxc/Xja8DeYwHwYDVR0jBBgwFoAUX5r1blzMzHSa # 1N197z/b7EyALt0wDQYJKoZIhvcNAQEFBQADggEBAHg7tJEqAEzwj2IwN3ijhCcH # bxiy3iXcoNSUA6qGTiWfmkADHN3O43nLIWgG2rYytG2/9CwmYzPkSWRtDebDZw73 # BaQ1bHyJFsbpst+y6d0gxnEPzZV03LZc3r03H0N45ni1zSgEIKOq8UvEiCmRDoDR # EfzdXHZuT14ORUZBbg2w6jiasTraCXEQ/Bx5tIB7rGn0/Zy2DBYr8X9bCT2bW+IW # yhOBbQAuOA2oKY8s4bL0WqkBrxWcLC9JG9siu8P+eJRRw4axgohd8D20UaF5Mysu # e7ncIAkTcetqGVvP6KUwVyyJST+5z3/Jvz4iaGNTmr1pdKzFHTx/kuDDvBzYBHUw # ggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3DQEBCwUAMGUx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9v # dCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIxCzAJBgNVBAYT # AlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2Vy # dC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNp # Z25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD407Mcfw4R # r2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl+YnUNxnXtqrw # nIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQzUHSxKCa7JGnC # wlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNxPqxwoqvOf+l8 # y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqrhPOsZ061xPeM # 0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItqcyDQD2RzPJ6f # pjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1Ud # DwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEFBQcBAQRtMGsw # JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcw # AoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElE # Um9vdENBLmNydDCBgQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2NybDQuZGlnaWNl # cnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDigNoY0aHR0cDov # L2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDBP # BgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93 # d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4EFgQUWsS5eyoK # o6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8w # DQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0cLToaxO8wYdd+ # C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9xjmMOE0ut119E # efM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpxKAI8LpGjwCUR # 4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUIQjKyNookAv4v # cn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhizgZtPxpMQBvwH # gfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggU4MIIEIKADAgEC # AhAPxQCJrE9ObGzkCRS7EwyyMA0GCSqGSIb3DQEBCwUAMHIxCzAJBgNVBAYTAlVT # MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j # b20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25p # bmcgQ0EwHhcNMTcwNTI2MDAwMDAwWhcNMTkwOTI3MTIwMDAwWjB1MQswCQYDVQQG # EwJHQjETMBEGA1UECBMKR2Fyc2luZ3RvbjEPMA0GA1UEBxMGT3hmb3JkMR8wHQYD # VQQKExZWaXJ0dWFsIEVuZ2luZSBMaW1pdGVkMR8wHQYDVQQDExZWaXJ0dWFsIEVu # Z2luZSBMaW1pdGVkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnB1O # DV2jw/aMIUWnD9f9RCbAoiJ8LQcznYo42P22YEi6g7QY+kKmAzGgEhbsE4UVuGWS # el4y6FxGWq51SK5P/gqgZgzyP8FkIUzLxsCrtx9OBnsPPeL+/An5CpcsKsl2lCSz # NMwcz16hjcE0vCLio1NOcwvfO65qdNT2gRIEnIYhRX88dG3V30BH2aKWG5X9t1IW # RmozjZ8I7iLEoWFJWQSuICSGyvyiPqnXF3nxdroE8O4fc1U90x5qefX0RlwKeq47 # UFuI0Y/59pB3/jss5BYvAXp3g+6EKlDwgW1a/MLVsLQbdzlALFUv5YxEqkXA8IEM # xpwgBjm117SmyZ98QQIDAQABo4IBxTCCAcEwHwYDVR0jBBgwFoAUWsS5eyoKo6Xq # cQPAYPkt9mV1DlgwHQYDVR0OBBYEFL5NkOqMm0S8AyuXI1EZIdoK9DD/MA4GA1Ud # DwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzB3BgNVHR8EcDBuMDWgM6Ax # hi9odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLWNzLWcxLmNy # bDA1oDOgMYYvaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1j # cy1nMS5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAwEwKjAoBggrBgEFBQcCARYc # aHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBBAEwgYQGCCsGAQUF # BwEBBHgwdjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME4G # CCsGAQUFBzAChkJodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRT # SEEyQXNzdXJlZElEQ29kZVNpZ25pbmdDQS5jcnQwDAYDVR0TAQH/BAIwADANBgkq # hkiG9w0BAQsFAAOCAQEAQC8qzSz1bIoEqbjDx3VtYDjtUjuFEVDFYi9+vREl6jM+ # iqOiNiwCXUkbxGTuDrWW9I1YOn8a7SCCYapZ+T0G3RMa+rQHXFYKbYTmXC3C41Cd # MQzZn4wTuGRNQLTgNSuclwMnNmFVe7K5S/0Dv+GaLSKuRLAxpcPxeTtmRZIIBXF7 # wwRS0+V28jB9VyeSOdqsPIFYf5GSfu7KcIhmNQ/DUroulaS5JIrPUhwkf1LZMm0B # /0adpaPbFy95M1emij96rrgy2hX8N/FrWBh13/81V6NO3b8mhCfjqb632dG4EUTi # FXDvqP2hpWw0nO/pFZsMsEK88eiV93XDDEG/MjAApzGCBDcwggQzAgEBMIGGMHIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJ # RCBDb2RlIFNpZ25pbmcgQ0ECEA/FAImsT05sbOQJFLsTDLIwCQYFKw4DAhoFAKB4 # MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQB # gjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkE # MRYEFAb+DwaBSi8qR2WPLWA0lu3IA9GUMA0GCSqGSIb3DQEBAQUABIIBAIr/lB0w # lZzheryd44G+4pSShE2WOoT7z0V40CAG5RQPxoZTOHR/zi4jdEz54J1ZWgs3CHuj # gZbzR5gAR0F4oxAv8izj6iP7iRIax8op30QaQMC6Kg1OXaqR92MCVtgF6kKRz8xs # PwiP4wskMGNj/3nhOBCw37bA7YaPJr08zpuOzf08dqmom2FtqU1FyFecg2hLHJSG # CLTTHZtgfhMzFP7xgOhOSQbPOcG39CfCReK3NkdSB9/DiHJg/kKTTuTXY6sY3PNR # DI8bZ58g/yNvI2Yao6FQdWKcw4SfyUTCsjlKl8jGP1Nf1MpU9z72iHRAV8MJ/B/4 # sNJ8cwsDA8b98MChggILMIICBwYJKoZIhvcNAQkGMYIB+DCCAfQCAQEwcjBeMQsw # CQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xMDAuBgNV # BAMTJ1N5bWFudGVjIFRpbWUgU3RhbXBpbmcgU2VydmljZXMgQ0EgLSBHMgIQDs/0 # OMj+vzVuBNhqmBsaUDAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3 # DQEHATAcBgkqhkiG9w0BCQUxDxcNMTcwOTA0MTMzNTIyWjAjBgkqhkiG9w0BCQQx # FgQUjxUAQ8/wE6LtZqzbRHtHHvSrjkgwDQYJKoZIhvcNAQEBBQAEggEAhW0Kdyzn # q33tHrhSPuxAdOjQJjJk5X5DvEJWt4aLwoW5fq2+ZwLBxI1LdcXd+VMd6CELEbpL # p1AFD6UEiJticVanVECQJL71TuW4QHwIHfLiJ9Z6ppdoCk3RdatHzQXCzmkdqXo9 # hoTaw0xeQ+xSG7LLL56SnVQXJWDHtV7xBs8HlBFgMi+oWxzwOT5/DIN/JWe/osgD # 2rTY9UHHvKQKOyARwMd2PAKyoi8gGionzH2z4KDSnnXj6wy5yCCdEJxXsIU51Ctd # 4BBy5uWuv3gXRiVN5ZTEhe+2K3nifYBhK5MHpSqzaHmTFC/OYU0gws81+aXxKvsq # pCISZKRpKqMemg== # SIG # End signature block |