ShieldingDataAnswerFile/ShieldingDataAnswerFile.psm1
# Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. function New-ShieldingDataAnswerFile { <# .SYNOPSIS Creates an OS specialization answer file for use with shielded virtual machines. .DESCRIPTION Shielded VMs require unattended OS installations due to the security features that prevent you from seeing the VM console while the VM is running. These unattended installations require answer files to configure the operating system. For example, the administrator password must be set on your VM before you can use it. This function creates simple answer files for use with Windows and Linux shielded VMs that are compatible with System Center Virtual Machine Manager. SCVMM is not required to deploy VMs using these answer files, however they are designed to be compatible with it. Any text included in the answer file is encrypted in the shielding data file and cannot be changed by a malicious user. Such information includes your administrator password and domain join credentials. There are several substitution strings available for fields that must change when the VM is deployed, such as its computer name and static IP configuration, if required. These substitution strings are printed at the end of the command execution and should be supplied to New-ShieldedVMSpecializationDataFile with the actual, intended values. All answer files will include a command to turn off the VM after provisioning completes. This is required for most virtualization fabric managers to know when a shielded VM guest OS has finished specializing. .PARAMETER Path Location to save the answer file (.xml extension). .PARAMETER AdminCredentials The desired username and password for a new user account (with administrator privileges) to be created on the VM. .PARAMETER RootPassword The password for the root user account. .PARAMETER RootSshKey SSH public key blob to associate with the root user account. Either the path to a public key file (.pub) or the raw public key data can be provided. .PARAMETER DomainName Name of the Active Directory domain to which the VM should join. .PARAMETER DomainJoinCredentials User credentials privileged to join the VM to the specified Active Directory domain. .PARAMETER ProductKeyRequired Indicates that the VM OS requires a product key during installation. The product key will be provided at deployment time by Virtual Machine Manager or your fabric specialization keyfile. By default, the answer file will not include a field for the product key and assumes you have evaluation or volume licensed media. .PARAMETER RDPCertificatePath Path to a PFX file containing a certificate and private key that should be used to secure inbound Remote Desktop connections. .PARAMETER RDPCertificatePassword Password for the Remote Desktop certificate file. .PARAMETER StaticIPPool Indicates the VM should use a static IP address provided by a System Center Virtual Machine Manager IP pool. 'All' will provision a static IPv4 address, IPv6 address, primary DNS server, and gateway. 'IPv4Address' only provisions a static IPv4 address, primary DNS server, and gateway. 'IPv6Address' only provisions a static IPv6 address, primary DNS server, and gateway. 'DnsServerOnly' sets the primary DNS server but uses DHCP for IPv4 and IPv6 addresses. Omit this parameter if your VM should use DHCP to obtain its IPv4, IPv6 and DNS server addresses. .PARAMETER ConfigurationScript Path to any configuration scripts that should run during installation. Only .ps1 and .bat scripts are supported. .PARAMETER Locale Configures Windows to use a specific locale for language and UI elements. Defaults to en-US. .PARAMETER Force Skips all safety checks when creating the answer file. This switch will allow the use of default administrator account and overwrite existing files. .EXAMPLE $admin = Get-Credential 'administrator' -Message 'Local administrator account credentials' New-ShieldingDataAnswerFile -Path .\unattend.xml -AdminCredentials $admin Create a basic Windows answer file and sets the built-in administrator account password .EXAMPLE $admin = Get-Credential -Message "Local administrator account credentials" $djcred = Get-Credential -Message "Domain join credentials" New-ShieldingDataAnswerFile -Path .\unattend.xml -AdminCredentials $admin -DomainName 'contoso.com' -DomainJoinCredentials $djcred -ConfigurationScript .\mycustomconfig.ps1 Create a Windows answer file that joins the VM to a domain and runs a configuration script .EXAMPLE $password = Read-Host -Prompt "Root Password" -AsSecureString New-ShieldingDataAnswerFile -Path ./linuxanswer.xml -RootPassword $password -RootSshKey ~/.ssh/id_rsa.pub Create a Linux answer file and associate your public SSH key with the root user account. #> [CmdletBinding(DefaultParameterSetName='WindowsAnswerFile')] param( [Parameter(Mandatory = $true, Position = 0)] [string] $Path, [Parameter(ParameterSetName='WindowsAnswerFile', Mandatory=$true)] [pscredential] $AdminCredentials, [Parameter(ParameterSetName='LinuxAnswerFile', Mandatory=$true)] [securestring] $RootPassword, [Parameter(ParameterSetName='LinuxAnswerFile')] [string] $RootSshKey, [Parameter(ParameterSetName='WindowsAnswerFile')] [string] $DomainName, [Parameter(ParameterSetName='WindowsAnswerFile')] [pscredential] $DomainJoinCredentials, [Parameter(ParameterSetName='WindowsAnswerFile')] [switch] $ProductKeyRequired, [Parameter(ParameterSetName='WindowsAnswerFile')] [string] $RDPCertificatePath, [Parameter(ParameterSetName='WindowsAnswerFile')] [securestring] $RDPCertificatePassword, [ValidateSet('All', 'IPv4Address', 'IPv6Address', 'DnsServerOnly')] [string] $StaticIPPool, [Parameter(ParameterSetName='WindowsAnswerFile')] [string[]] $ConfigurationScript, [Parameter(ParameterSetName='WindowsAnswerFile')] [ValidateSet("ar-SA", "bg-BG", "zh-HK", "zh-CN", "zh-TW", "hr-HR", "cs-CZ", "da-DK", "nl-NL", "en-US", "en-GB", "et-EE", "fi-FI", "fr-FR", "de-DE", "el-GR", "he-IL", "hu-HU", "it-IT", "ja-JP", "ko-KR", "lv-LV", "lt-LT", "nb-NO", "pl-PL", "pt-BR", "pt-PT", "ro-RO", "ru-RU", "sr-Latn-CS", "sr-Latn-RS", "sk-SK", "sl-SI", "es-ES", "sv-SE", "th-TH", "tr-TR", "uk-UA")] [string] $Locale = 'en-US', [switch] $Force = $false ) $Windows = $PSCmdlet.ParameterSetName -eq 'WindowsAnswerFile' ## Parameter Validation # Ensure path has an XML extension if ($Path -notlike '*.xml') { throw [System.ArgumentException] "Answer file path must have a .xml extension" } # Validate path location $ParentPath = Split-Path $Path -Parent if ($ParentPath) { $ParentPath = Resolve-Path $ParentPath -ErrorAction SilentlyContinue if (-not (Test-Path $ParentPath -PathType Container)) { throw [System.IO.DirectoryNotFoundException] ("Answer file path is invalid: directory could not be found.") } } else { $ParentPath = Get-Location -PSProvider FileSystem } $Path = Join-Path $ParentPath (Split-Path $Path -Leaf) # Parse credentials if ($Windows) { $AdminUsername = $AdminCredentials.UserName $AdminPassword = $AdminCredentials.GetNetworkCredential().Password } else { $AdminUsername = 'root' $tempAdminCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList 'root', $RootPassword $AdminPassword = $tempAdminCredential.GetNetworkCredential().Password $tempAdminCredential = $null } # Validate username if ([string]::IsNullOrEmpty($AdminUsername)) { throw [System.ArgumentException] 'Administrator username cannot be empty' } elseif ($Windows -and $AdminUsername -eq 'Administrator') { if ($Force) { Write-Warning "The built-in 'Administrator' account will be enabled by this answer file." } else { throw [System.ArgumentException] "It is not recommended to enable the built-in 'Administrator' account in the VM. Select a different username or use -Force if you are sure you want to use this account." } } elseif ($AdminUsername -and $Windows -and $AdminUsername -match '["/\\\[\]:;\|=,\+\*\?<>]+') { throw [System.ArgumentException] 'Administrator username cannot contain any of the following characters: " / \ [ ] : ; | = , + * ? < >' } # Validate password if ([string]::IsNullOrEmpty($AdminPassword)) { throw [System.ArgumentException] 'Administrator password cannot be empty' } # Ensure domain credentials are provided if a domain name is provided if ($DomainName -and -not $DomainJoinCredentials) { throw [System.ArgumentNullException] "Domain join credentials are required when a domain name is specified." } # Ensure the RDP certificate exists if ($RDPCertificatePath -and -not (Test-Path $RDPCertificatePath -PathType Leaf)) { throw [System.IO.FileNotFoundException] ("Could not find the RDP certificate at '{0}'. Please provide a path to a valid PFX file." -f $RDPCertificatePath) } # Ensure the RDP certificate is a PFX file if ($RDPCertificatePath -and $RDPCertificatePath -notlike '*.pfx') { throw [System.ArgumentException] "The RDP certificate must be in the Personal Information Exchange (.pfx) file format, containing both the certificate and its private key." } # Ensure an RDP certificate password is provided if an RDP certificate path is provided if ($RDPCertificatePath -and -not $RDPCertificatePassword) { throw [System.ArgumentNullException] "The RDP certificate password is required when an RDP certificate path is specified." } # Check if the RDP certificate password is valid for the specified file if ($RDPCertificatePath) { try { $null = Get-PfxData -FilePath $RDPCertificatePath -Password $RDPCertificatePassword } catch { throw [System.ArgumentException] "The RDP certificate password is invalid for the specified RDP certificate file." } } # Prevent users from passing more than one value to StaticIPPool if 'All' is included if ($StaticIPPool -and $StaticIPPool.Count -gt 1 -and ($StaticIPPool -contains 'All' -or $StaticIPPool -contains 'DnsServerOnly')) { throw [System.ArgumentException] "The Static IP Pool configuration specified is invalid. Valid combinations are: empty, 'All', 'DnsServerOnly', 'IPv4Address', 'IPv6Address', or both 'IPv4Address' and 'IPv6Address'." } # Validate configuration script extension for Windows if ($ConfigurationScript) { foreach ($script in $ConfigurationScript) { if ($script -notlike '*.ps1' -and $script -notlike '*.bat') { throw [System.ArgumentException] ("The configuration script '{0}' is invalid. Only PowerShell (.ps1) and batch scripts (.bat) are supported.") } } } ## Load the sample answer file $ScriptModulePath = Split-Path $PSCommandPath -Parent -Resolve | Convert-Path if ($Windows) { $AnswerFilePath = Join-Path $ScriptModulePath 'WindowsUnattend.xml' } else { $AnswerFilePath = Join-Path $ScriptModulePath 'LinuxUnattend.xml' } if (-not (Test-Path $AnswerFilePath -PathType Leaf)) { throw [System.IO.FileNotFoundException] ("Unable to load the template unattend file from '{0}'." -f $AnswerFilePath) } [xml]$AnswerFile = Get-Content -Path $AnswerFilePath -ErrorAction Stop $FilesToIncludeInPDK = @() $FSKSubstitutionStrings = @( [pscustomobject] @{ Key = '@ComputerName@'; Purpose = 'Network name for the VM' } ) $FSK_IPv4Sub = $FSK_IPv6Sub = $FSK_DNSSub = $true if ($Windows) { $nsmgr = New-Object System.Xml.XmlNamespaceManager $AnswerFile.NameTable $nsmgr.AddNamespace('ns', 'urn:schemas-microsoft-com:unattend') $nsmgr.AddNamespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance') $nsmgr.AddNamespace('wcm', 'http://schemas.microsoft.com/WMIConfig/2002/State') # Configure the local administrator account if ($AdminUsername -eq 'Administrator') { $AdminAccount = $AnswerFile.SelectSingleNode("//ns:AdministratorPassword", $nsmgr) $AdminAccount.Value = $AdminPassword $LocalAccounts = $AnswerFile.SelectSingleNode("//ns:LocalAccounts", $nsmgr) $null = $LocalAccounts.ParentNode.RemoveChild($LocalAccounts) } else { $LocalAccount = $AnswerFile.SelectSingleNode("//ns:LocalAccount", $nsmgr) $LocalAccount.Name = $AdminUsername $LocalAccount.Password.Value = $AdminPassword $AdminAccount = $AnswerFile.SelectSingleNode("//ns:AdministratorPassword", $nsmgr) $null = $AdminAccount.ParentNode.RemoveChild($AdminAccount) } # Remove product key if not required if (-not $ProductKeyRequired) { $pk = $AnswerFile.SelectSingleNode("//ns:ProductKey", $nsmgr) $null = $pk.ParentNode.RemoveChild($pk) } else { $FSKSubstitutionStrings += [pscustomobject] @{ Key = '@ProductKey@'; Purpose = 'Windows product key for activation' } } # Replace domain join information if ($DomainName) { $djinfo = $AnswerFile.SelectSingleNode("//ns:component[contains(@name, 'Microsoft-Windows-UnattendedJoin')]/ns:Identification", $nsmgr) $djinfo.JoinDomain = $DomainName $usercreds = $DomainJoinCredentials.GetNetworkCredential() if ($usercreds.Domain) { $userdomain = $usercreds.Domain } else { $userdomain = $DomainName } $djinfo.Credentials.Domain = $userdomain $djinfo.Credentials.Username = $usercreds.UserName $djinfo.Credentials.Password = $usercreds.Password } else { $djinfo = $AnswerFile.SelectSingleNode("//ns:component[contains(@name, 'Microsoft-Windows-UnattendedJoin')]", $nsmgr) $null = $djinfo.ParentNode.RemoveChild($djinfo) } # Add RDP certificate installation steps if ($RDPCertificatePath) { $flatname = Convert-Path $RDPCertificatePath | Split-Path -Leaf $password = (New-Object System.Management.Automation.PSCredential -ArgumentList 'anyuser', $RDPCertificatePassword).GetNetworkCredential().Password $passwordbytes = [System.Text.Encoding]::Unicode.GetBytes($password) $base64password = [System.Convert]::ToBase64String($passwordbytes) $RDPConfigPath = Join-Path $ParentPath 'RDPCertificateConfig.ps1' if ((Test-Path $RDPConfigPath) -and -not $Force) { throw [System.IO.IOException] ("RDP configuration file already exists at '{0}'. Use -Force to overwrite." -f $RDPConfigPath) } else { $command = @' $Password = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String("{0}")) $SecurePassword = ConvertTo-SecureString -AsPlainText -String $Password -Force $Certificate = Import-PfxCertificate -FilePath "$env:SystemDrive\temp\{1}" -Password $SecurePassword -CertStoreLocation Cert:\LocalMachine\My Get-CimInstance -Namespace root/CIMV2/TerminalServices -ClassName Win32_TSGeneralSetting | Set-CimInstance -Property @{{ SSLCertificateSHA1Hash = $Certificate.Thumbprint }} Remove-Item "$env:SystemDrive\temp\{1}" -Force Remove-Item "$env:SystemDrive\temp\RDPCertificateConfig.ps1" -Force '@ -f $base64password, $flatname Set-Content -Path $RDPConfigPath -Value $command -Force $firstCommand = $AnswerFile.SelectSingleNode("//ns:RunSynchronousCommand", $nsmgr) $clone = $firstCommand.CloneNode($true) $clone.Description = "Configures the RDP certificate" $clone.Path = 'cmd.exe /c "echo powershell.exe -File %SYSTEMDRIVE%\temp\RDPCertificateConfig.ps1" >> %WINDIR%\Setup\Scripts\SetupComplete.cmd' $null = $firstCommand.ParentNode.InsertBefore($clone, $firstCommand) $FilesToIncludeInPDK += [pscustomobject] @{ LocalPath = $RDPCertificatePath; VMPath = "%SYSTEMDRIVE%\temp\$flatname" } $FilesToIncludeInPDK += [pscustomobject] @{ LocalPath = $RDPConfigPath; VMPath = "%SYSTEMDRIVE%\temp\RDPCertificateConfig.ps1" } } } # Remove unnecessary networking nodes if ($StaticIPPool -ne 'All' -and $StaticIPPool -ne 'IPv4Address') { $IPNode = $AnswerFile.SelectSingleNode("//ns:Ipv4Settings", $nsmgr) $null = $IPNode.ParentNode.RemoveChild($IPNode) $IPv4Address = $AnswerFile.SelectSingleNode("//ns:component[contains(@name, 'Microsoft-Windows-TCPIP')]//ns:IpAddress[. = '@IP4Addr-1@']", $nsmgr) $IPv6Address = $AnswerFile.SelectSingleNode("//ns:component[contains(@name, 'Microsoft-Windows-TCPIP')]//ns:IpAddress[. = '@IP6Addr-1@']", $nsmgr) $null = $IPv4Address.ParentNode.RemoveChild($IPv4Address) $IPv6Address.keyValue = '1' $FSK_IPv4Sub = $false } if ($StaticIPPool -ne 'All' -and $StaticIPPool -ne 'IPv6Address') { $IPNode = $AnswerFile.SelectSingleNode("//ns:Ipv6Settings", $nsmgr) $null = $IPNode.ParentNode.RemoveChild($IPNode) $IPv6Address = $AnswerFile.SelectSingleNode("//ns:component[contains(@name, 'Microsoft-Windows-TCPIP')]//ns:IpAddress[. = '@IP6Addr-1@']", $nsmgr) $null = $IPv6Address.ParentNode.RemoveChild($IPv6Address) $FSK_IPv6Sub = $false } if (-not $StaticIPPool) { $IPNode = $AnswerFile.SelectSingleNode("//ns:component[contains(@name, 'Microsoft-Windows-TCPIP')]", $nsmgr) $null = $IPNode.ParentNode.RemoveChild($IPNode) $DnsNode = $AnswerFile.SelectSingleNode("//ns:component[contains(@name, 'Microsoft-Windows-DNS-Client')]", $nsmgr) $null = $DnsNode.ParentNode.RemoveChild($DnsNode) $FSK_IPv4Sub = $FSK_IPv6Sub = $FSK_DNSSub = $false } # Add configuration scripts if ($ConfigurationScript) { $originalnode = $AnswerFile.SelectSingleNode("//ns:RunSynchronousCommand", $nsmgr) $parentnode = $originalnode.ParentNode $templatenode = $originalnode.CloneNode($true) $null = $templatenode.RemoveChild($newnode.ChildNodes.Where({ $_.Name -eq 'Description'})) foreach ($script in $ConfigurationScript) { $newnode = $templatenode.CloneNode($true) $flatname = Split-Path -Path $script -Leaf if ($script -like '*.bat') { $newnode.Path = 'cmd.exe /c "echo cmd.exe /c "%SYSTEMDRIVE%\temp\{0}"" >> %WINDIR%\Setup\Scripts\SetupComplete.cmd' -f $flatname } else { $newnode.Path = 'cmd.exe /c "echo powershell.exe -File "%SYSTEMDRIVE%\temp\{0}"" >> %WINDIR%\Setup\Scripts\SetupComplete.cmd' -f $flatname } $null = $parentnode.InsertBefore($newnode, $originalnode) $FilesToIncludeInPDK += [pscustomobject] @{ LocalPath = $script; VMPath = ("%SYSTEMDRIVE%\temp\{0}" -f $flatname) } } } # Add command to delete existing setupcomplete.cmd if it exists $firstCommand = $AnswerFile.SelectSingleNode("//ns:RunSynchronousCommand", $nsmgr) $synchronousCommandsNode = $firstCommand.ParentNode $setupCompleteNode = $firstCommand.CloneNode($true) $setupCompleteNode.Description = "Delete existing setupcomplete.cmd file" $setupCompleteNode.Path = 'cmd.exe /c "IF EXIST %WINDIR%\Setup\Scripts\setupcomplete.cmd ( del /F %WINDIR%\Setup\Scripts\setupcomplete.cmd )"' $null = $synchronousCommandsNode.InsertBefore($setupCompleteNode, $firstCommand) # Add command to create script folder if it does not exist $scriptNode = $firstCommand.CloneNode($true) $scriptNode.Description = "Creates the scripts directory if required" $scriptNode.Path = 'cmd.exe /c "IF NOT EXIST %WINDIR%\Setup\Scripts ( md %WINDIR%\Setup\Scripts )"' $null = $synchronousCommandsNode.InsertBefore($scriptNode, $setupCompleteNode) # Ensure synchronous commands are ordered correctly $current = 1 foreach ($commandnode in $AnswerFile.SelectSingleNode("//ns:RunSynchronous", $nsmgr).ChildNodes) { $commandnode.Order = $current.ToString() $current += 1 } # Update locale placeholders $AnswerFile.SelectSingleNode("//ns:InputLocale", $nsmgr).'#text' = $Locale $AnswerFile.SelectSingleNode("//ns:UserLocale", $nsmgr).'#text' = $Locale $AnswerFile.SelectSingleNode("//ns:SystemLocale", $nsmgr).'#text' = $Locale $AnswerFile.SelectSingleNode("//ns:UILanguage", $nsmgr).'#text' = $Locale } # End Windows Configuration # Start Linux Configuration else { $nsmgr = New-Object System.Xml.XmlNamespaceManager $AnswerFile.NameTable $nsmgr.AddNamespace('ns', 'http://www.microsoft.com/schema/linuxvmmst') $nsmgr.AddNamespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance') $nsmgr.AddNamespace('xsd', 'http://www.w3.org/2001/XMLSchema') $nsmgr.AddNamespace('d4p1', 'http://www.microsoft.com/schema/linuxvmmst') # Configure the administrator account $User = $AnswerFile.SelectSingleNode("//ns:User", $nsmgr) $User.Password = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($AdminPassword)) # Configure the SSH key if ($RootSshKey) { # Check if a file path was provided if ((Test-Path -Path $RootSshKey -PathType Leaf -ErrorAction Continue)) { $RootSshKey = Get-Content -Path $RootSshKey -ErrorAction Stop } $User.SSHKey = $RootSshKey } else { $SSHKey = $User.SelectSingleNode("//ns:SSHKey", $nsmgr) $null = $User.RemoveChild($SSHKey) } # Configure networking if ($StaticIPPool -ne 'All' -and $StaticIPPool -ne 'IPv4Address') { $IPv4Node = $AnswerFile.SelectSingleNode("//ns:IPV4Property", $nsmgr) $null = $IPV4Node.ParentNode.RemoveChild($IPv4Node) $FSK_IPv4Sub = $false } if ($StaticIPPool -ne 'All' -and $StaticIPPool -ne 'IPv6Address') { $IPv6Node = $AnswerFile.SelectSingleNode("//ns:IPV6Property", $nsmgr) $null = $IPV6Node.ParentNode.RemoveChild($IPv6Node) $FSK_IPv6Sub = $false } if (-not $StaticIPPool) { $NetNode = $AnswerFile.SelectSingleNode("//ns:VNetAdapters", $nsmgr) $null = $NetNode.ParentNode.RemoveChild($NetNode) $FSK_IPv4Sub = $FSK_IPv6Sub = $FSK_DNSSub = $false } } # End Linux Configuration ## Finish collecting FSK substitution string messages if ($FSK_DNSSub) { $FSKSubstitutionStrings += [pscustomobject] @{ Key = '@MACAddr-1@'; Purpose = 'MAC address for vNIC' } $FSKSubstitutionStrings += [pscustomobject] @{ Key = '@DnsAddr-1-1@'; Purpose = 'Static DNS server address' } } if ($FSK_IPv4Sub -or $FSK_IPv6Sub) { $FSKSubstitutionStrings += [pscustomobject] @{ Key = '@NextHop-1-1@'; Purpose = 'Static gateway address (e.g. 192.168.0.1)' } $FSKSubstitutionStrings += [pscustomobject] @{ Key = '@Prefix-1-1@'; Purpose = 'Prefix length for the route (e.g. 24)'} } if ($FSK_IPv4Sub) { $FSKSubstitutionStrings += [pscustomobject] @{ Key = '@IP4Addr-1@'; Purpose = 'Static IPv4 Address with prefix (CIDR notation)' } } if ($FSK_IPv6Sub) { $FSKSubstitutionStrings += [pscustomobject] @{ Key = '@IP6Addr-1@'; Purpose = 'Static IPv6 Address (CIDR notation)' } } ## Write answer file to disk if ((Test-Path $Path) -and -not $Force) { throw [System.IO.IOException] ("Answer file already exists at '{0}'. Use -Force to overwrite." -f $Path) } try { $AnswerFile.Save($Path) } catch { $e = [System.IO.IOException] "Unable to create the answer file." $e.InnerException = $_ throw $e } ## Write required files and substitution strings to the console Write-Output ("Shielding data answer file was created successfully and saved to '{0}'" -f $Path) if ($FilesToIncludeInPDK.Count -gt 0) { Write-Output "" Write-Output "When creating your Shielding Data File, be sure to include the following items in the 'Other Files' section." Format-Table -AutoSize -InputObject $FilesToIncludeInPDK } Write-Output "", "The following substitution strings are included in the answer file and should be supplied when creating your shielded VM fabric specialization keyfile for a VM instance." Format-Table -AutoSize -InputObject $FSKSubstitutionStrings } # SIG # Begin signature block # MIIkdwYJKoZIhvcNAQcCoIIkaDCCJGQCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDGlksrEZCGHEvw # 0wHh+U6ei29lX4EEbiMRP55SHwLrlqCCDYEwggX/MIID56ADAgECAhMzAAABA14l # HJkfox64AAAAAAEDMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMTgwNzEyMjAwODQ4WhcNMTkwNzI2MjAwODQ4WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDRlHY25oarNv5p+UZ8i4hQy5Bwf7BVqSQdfjnnBZ8PrHuXss5zCvvUmyRcFrU5 # 3Rt+M2wR/Dsm85iqXVNrqsPsE7jS789Xf8xly69NLjKxVitONAeJ/mkhvT5E+94S # nYW/fHaGfXKxdpth5opkTEbOttU6jHeTd2chnLZaBl5HhvU80QnKDT3NsumhUHjR # hIjiATwi/K+WCMxdmcDt66VamJL1yEBOanOv3uN0etNfRpe84mcod5mswQ4xFo8A # DwH+S15UD8rEZT8K46NG2/YsAzoZvmgFFpzmfzS/p4eNZTkmyWPU78XdvSX+/Sj0 # NIZ5rCrVXzCRO+QUauuxygQjAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUR77Ay+GmP/1l1jjyA123r3f3QP8w # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDM3OTY1MB8GA1UdIwQYMBaAFEhu # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAn/XJ # Uw0/DSbsokTYDdGfY5YGSz8eXMUzo6TDbK8fwAG662XsnjMQD6esW9S9kGEX5zHn # wya0rPUn00iThoj+EjWRZCLRay07qCwVlCnSN5bmNf8MzsgGFhaeJLHiOfluDnjY # DBu2KWAndjQkm925l3XLATutghIWIoCJFYS7mFAgsBcmhkmvzn1FFUM0ls+BXBgs # 1JPyZ6vic8g9o838Mh5gHOmwGzD7LLsHLpaEk0UoVFzNlv2g24HYtjDKQ7HzSMCy # RhxdXnYqWJ/U7vL0+khMtWGLsIxB6aq4nZD0/2pCD7k+6Q7slPyNgLt44yOneFuy # bR/5WcF9ttE5yXnggxxgCto9sNHtNr9FB+kbNm7lPTsFA6fUpyUSj+Z2oxOzRVpD # MYLa2ISuubAfdfX2HX1RETcn6LU1hHH3V6qu+olxyZjSnlpkdr6Mw30VapHxFPTy # 2TUxuNty+rR1yIibar+YRcdmstf/zpKQdeTr5obSyBvbJ8BblW9Jb1hdaSreU0v4 # 6Mp79mwV+QMZDxGFqk+av6pX3WDG9XEg9FGomsrp0es0Rz11+iLsVT9qGTlrEOla # P470I3gwsvKmOMs1jaqYWSRAuDpnpAdfoP7YO0kT+wzh7Qttg1DO8H8+4NkI6Iwh # SkHC3uuOW+4Dwx1ubuZUNWZncnwa6lL2IsRyP64wggd6MIIFYqADAgECAgphDpDS # AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 # ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla # MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT # H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB # AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG # OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S # 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz # y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7 # 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u # M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33 # X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl # XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP # 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB # l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF # RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM # CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ # BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud # DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO # 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0 # LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y # Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y # Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw # cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA # XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY # 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj # 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd # d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ # Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf # wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ # aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j # NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIWTDCCFkgCAQEwgZUwfjELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAQNeJRyZH6MeuAAAAAABAzAN # BglghkgBZQMEAgEFAKCB0DAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgGk6zhY6b # gTDXUdnnnGhW89FyA50xxc9i3VQ3zFAePWYwZAYKKwYBBAGCNwIBDDFWMFSgNIAy # AEcAdQBhAHIAZABlAGQARgBhAGIAcgBpAGMAVABvAG8AbABzACAAdgAxACAAMQAg # ADChHIAaaHR0cHM6Ly93d3cubWljcm9zb2Z0LmNvbSAwDQYJKoZIhvcNAQEBBQAE # ggEAJKVkcTZ4o2n59d3BQ/OMJZCAUhnpxogu6X3L1TDGzn+50/2U6QulT1JKJrGv # mdAk5YHHub85ktiseteFISG7cnQ0KWssw66M6DM42GmQkmBQmGLYP44t4LAI/iJG # DmBohDQfH/6NdmDT9N0sFmg1CTXqfwiTXLhxs0dnfbLMEzezlXQ+7xKWfKgWAQDg # l5Fryy9q4m3DV5IHul5FTbbYXAxP15wUcqQsbTRqYwUsnfdOOzAetWjFOvD73jzE # jRCV3oPEiRZch3+BsBKjVuIQt9Su2dBmYwWUZrVApUaxL8xwQETeULo/InjrsQoc # eBsed6RWxKscgOeTXCIyZZLtkqGCE7QwghOwBgorBgEEAYI3AwMBMYIToDCCE5wG # CSqGSIb3DQEHAqCCE40wghOJAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFVBgsqhkiG # 9w0BCRABBKCCAUQEggFAMIIBPAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQC # AQUABCCwGGDxKf5SKfYDvSxLEddnvdypeHLQwnekhNmusp37BwIGXJPuAFu+GBMy # MDE5MDMyNjAwMTE1OC41ODhaMASAAgH0oIHUpIHRMIHOMQswCQYDVQQGEwJVUzET # MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV # TWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYDVQQLEyBNaWNyb3NvZnQgT3BlcmF0 # aW9ucyBQdWVydG8gUmljbzEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046MTQ4Qy1D # NEI5LTIwNjYxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2Wg # gg8fMIIE9TCCA92gAwIBAgITMwAAANWnI+V4lWoJ/wAAAAAA1TANBgkqhkiG9w0B # AQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD # VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAeFw0xODA4MjMyMDI2 # NDVaFw0xOTExMjMyMDI2NDVaMIHOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz # aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv # cnBvcmF0aW9uMSkwJwYDVQQLEyBNaWNyb3NvZnQgT3BlcmF0aW9ucyBQdWVydG8g # UmljbzEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046MTQ4Qy1DNEI5LTIwNjYxJTAj # BgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggEiMA0GCSqGSIb3 # DQEBAQUAA4IBDwAwggEKAoIBAQDCFAkrrhfxNIIy/O6J8HbudDNQcFMUMLa2VhEG # ApizIRoTUf93kMQQ/ZamOBWMYUWdW8X7CI7O0ir3BdJtWH4YCuY/QXWb87nnnZBG # PDFVLuNcwdfHZ/jZmnpc+bxc/QS6uYSTwBHWYN2UfuHT+9fbVVyT/4lZLJS00yh/ # 2Kk/FXInplzlGgrCv0Xu8XQXvKgUobDsG4A+8VWMIJnr8/m0md1LFgpXHAQfZDIT # R4Z4iCpLjKOATSebXvsqfCgVcs6J7SprToUtVyjUiMsBFgM0RimbZT9+g1RjsvUh # mo8HldEYx5KmTFA9bRIiGg6AaYmV2nBz53tRUBsEoyuDTJRLAgMBAAGjggEbMIIB # FzAdBgNVHQ4EFgQUKWijMZR2Q9lfXQ2bn9OyhPZiN4QwHwYDVR0jBBgwFoAU1WM6 # XIoxkPNDe3xGG8UzaFqFbVUwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5t # aWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljVGltU3RhUENBXzIwMTAt # MDctMDEuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNUaW1TdGFQQ0FfMjAxMC0wNy0w # MS5jcnQwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDCDANBgkqhkiG # 9w0BAQsFAAOCAQEAednLwunE0cCrLQ7SJr/aZ6AL/fbAtsEC8uK5gc1i9pCP7JXg # TV6O+HKnQFqGHy0QkKPg7ltpuf9JjHuA6bzwy2AkEkiZALbv4VC/NMIpOWamjbyH # 6e4dfwifyjLiIHfFm4TWcS8huUuFuwLOuu0DYn8Hgq4xamTFfV7QTtsI8/ULYtUY # 3TiJoV+1eJHQmCkrXUINsSYVFPWbT6hqa7YWj6raPRYXqrN+wsNrzt7QI2KjF02Q # r8m8/uG1B8SFr6rySFy6bjz89cwrwqLS3wc8wYlfZoiBAV7J79qiCJHQ5yEqpayG # dZ13UR3V5eGYQX98AGUfxMCC7ympLChWM65OCzCCBnEwggRZoAMCAQICCmEJgSoA # AAAAAAIwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX # YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg # Q29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRl # IEF1dGhvcml0eSAyMDEwMB4XDTEwMDcwMTIxMzY1NVoXDTI1MDcwMTIxNDY1NVow # fDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl # ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMd # TWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwggEiMA0GCSqGSIb3DQEBAQUA # A4IBDwAwggEKAoIBAQCpHQ28dxGKOiDs/BOX9fp/aZRrdFQQ1aUKAIKF++18aEss # X8XD5WHCdrc+Zitb8BVTJwQxH0EbGpUdzgkTjnxhMFmxMEQP8WCIhFRDDNdNuDgI # s0Ldk6zWczBXJoKjRQ3Q6vVHgc2/JGAyWGBG8lhHhjKEHnRhZ5FfgVSxz5NMksHE # pl3RYRNuKMYa+YaAu99h/EbBJx0kZxJyGiGKr0tkiVBisV39dx898Fd1rL2KQk1A # UdEPnAY+Z3/1ZsADlkR+79BL/W7lmsqxqPJ6Kgox8NpOBpG2iAg16HgcsOmZzTzn # L0S6p/TcZL2kAcEgCZN4zfy8wMlEXV4WnAEFTyJNAgMBAAGjggHmMIIB4jAQBgkr # BgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQU1WM6XIoxkPNDe3xGG8UzaFqFbVUwGQYJ # KwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF # MAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8w # TTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVj # dHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBK # BggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9N # aWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwgaAGA1UdIAEB/wSBlTCBkjCBjwYJ # KwYBBAGCNy4DMIGBMD0GCCsGAQUFBwIBFjFodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vUEtJL2RvY3MvQ1BTL2RlZmF1bHQuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwA # ZQBnAGEAbABfAFAAbwBsAGkAYwB5AF8AUwB0AGEAdABlAG0AZQBuAHQALiAdMA0G # CSqGSIb3DQEBCwUAA4ICAQAH5ohRDeLG4Jg/gXEDPZ2joSFvs+umzPUxvs8F4qn+ # +ldtGTCzwsVmyWrf9efweL3HqJ4l4/m87WtUVwgrUYJEEvu5U4zM9GASinbMQEBB # m9xcF/9c+V4XNZgkVkt070IQyK+/f8Z/8jd9Wj8c8pl5SpFSAK84Dxf1L3mBZdmp # tWvkx872ynoAb0swRCQiPM/tA6WWj1kpvLb9BOFwnzJKJ/1Vry/+tuWOM7tiX5rb # V0Dp8c6ZZpCM/2pif93FSguRJuI57BlKcWOdeyFtw5yjojz6f32WapB4pm3S4Zz5 # Hfw42JT0xqUKloakvZ4argRCg7i1gJsiOCC1JeVk7Pf0v35jWSUPei45V3aicaoG # ig+JFrphpxHLmtgOR5qAxdDNp9DvfYPw4TtxCd9ddJgiCGHasFAeb73x4QDf5zEH # pJM692VHeOj4qEir995yfmFrb3epgcunCaw5u+zGy9iCtHLNHfS4hQEegPsbiSpU # ObJb2sgNVZl6h3M7COaYLeqN4DMuEin1wC9UJyH3yKxO2ii4sanblrKnQqLJzxlB # TeCG+SqaoxFmMNO7dDJL32N79ZmKLxvHIa9Zta7cRDyXUHHXodLFVeNp3lfB0d4w # wP3M5k37Db9dT+mdHhk4L7zPWAUu7w2gUDXa7wknHNWzfjUeCLraNtvTX4/edIhJ # EqGCA60wggKVAgEBMIH+oYHUpIHRMIHOMQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMSkwJwYDVQQLEyBNaWNyb3NvZnQgT3BlcmF0aW9ucyBQdWVy # dG8gUmljbzEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046MTQ4Qy1DNEI5LTIwNjYx # JTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiJQoBATAJBgUr # DgMCGgUAAxUArcMkvNHZdfBd0N1FHzkxnm7WnrGggd4wgdukgdgwgdUxCzAJBgNV # BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w # HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29m # dCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMScwJQYDVQQLEx5uQ2lwaGVyIE5UUyBF # U046NERFOS0wQzVFLTNFMDkxKzApBgNVBAMTIk1pY3Jvc29mdCBUaW1lIFNvdXJj # ZSBNYXN0ZXIgQ2xvY2swDQYJKoZIhvcNAQEFBQACBQDgQ4bMMCIYDzIwMTkwMzI2 # MDA1NjQ0WhgPMjAxOTAzMjcwMDU2NDRaMHQwOgYKKwYBBAGEWQoEATEsMCowCgIF # AOBDhswCAQAwBwIBAAICBM0wBwIBAAICGQEwCgIFAOBE2EwCAQAwNgYKKwYBBAGE # WQoEAjEoMCYwDAYKKwYBBAGEWQoDAaAKMAgCAQACAwehIKEKMAgCAQACAwehIDAN # BgkqhkiG9w0BAQUFAAOCAQEAG0z6r+VXSdjujNVADnV2Bft8i5fIEOpqDBGXPxJe # EyWOqOYmKSZVmUkPRy+RH2iKntQfhZqHI+vL3FxXbG/kbqA/yUTRIkD0dOcEWryf # prPYbh54oVZ6pQKarx+7et4u4ctRFIbibpDkU8DA/sJdnBMYkXPvd7Ydn/udnMap # KAhc3WFE36uykNgFH8AQQjqvk/cyu8ZF0rzyOyasfE/HMue5uRH7GJwLBvORaI5E # X9CT0N+JsnN9yWwf3G5MnQ5VQoCcdp93s4v9W3iO0Xd0opNgufDHCF1/bBSNmxbZ # WxA1GW+yTEZIxyaF/Rc3OBhl75NGgOVji7CzDnlVrc1dMDGCAvUwggLxAgEBMIGT # MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT # HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAA1acj5XiVagn/AAAA # AADVMA0GCWCGSAFlAwQCAQUAoIIBMjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQ # AQQwLwYJKoZIhvcNAQkEMSIEID7v4qEZXKFY75O0yigsUTu8RTI1a+u+SCFwvYWp # cyN4MIHiBgsqhkiG9w0BCRACDDGB0jCBzzCBzDCBsQQUrcMkvNHZdfBd0N1FHzkx # nm7WnrEwgZgwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 # aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAA # ANWnI+V4lWoJ/wAAAAAA1TAWBBTIW3RXEkfCXMgdo5WkOis6Rph9oTANBgkqhkiG # 9w0BAQsFAASCAQCMnxguSD7/ZsdawPpEy9oDpWi8DyrM1b6rXMoVNyOX4uiYnGUS # QaI28AGsb3ZRZtV1YLC9TTxxdmsJXFL155v4wShVHbPZ/LYiXJtvy+XLg4hsOwka # FC+SeULYRUkTTozoqcLkg1SDDim2Y1RkECJXCUqpCzW3KukxfOYdL1g6VOcomRV4 # r/I19pmOO2xe5i5SMpycdevDOmQbmwGJy+wcwZLKENn2Yj0cLL3FCQfBwiC2a4q2 # gVkHS7lxN4bQxcZDWRgi+chVD5Zzuput0hfaG0Y1KRQ3gSChKQY2dzheL6nd26DK # +Z/mgceqdEyIoacAXUQeUlok5YyQKqGYCD8K # SIG # End signature block |