{"id":79040,"date":"2018-06-04T12:20:06","date_gmt":"2018-06-04T12:20:06","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=79040"},"modified":"2021-04-27T13:55:24","modified_gmt":"2021-04-27T13:55:24","slug":"hyper-v-and-powershell-shielded-virtual-machines","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/hyper-v-and-powershell-shielded-virtual-machines\/","title":{"rendered":"Hyper-V Shielded Virtual Machines with PowerShell: Guarded Fabric, Host Guardian Service, and vTPM Configuration"},"content":{"rendered":"<p><strong>The series so far:<\/strong><\/p>\n<ol>\n<li><a href=\"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/hyper-v-powershell-basics\/\">Hyper-V and PowerShell: The Basics<\/a><\/li>\n<li><a href=\"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/hyper-v-and-powershell-shielded-virtual-machines\/\">Hyper-V and PowerShell: Shielded Virtual Machines<\/a><\/li>\n<\/ol>\n\n<p><a id=\"post-79040-_Hlk515530835\"><\/a> In Windows Server 2016, Microsoft implemented a strong security concept called Shielded VMs. Shielded VMs have been improved in the Windows Server 2019 release. In the second part of this series, Nicolas describes what Shielded Virtual Machines are and how to configure them using PowerShell.<\/p>\n<p>One key investment area that Microsoft improves in every Windows Server release is security. Whether you work for a small company or a multinational company, security is essential. But sometimes, it can be hard to secure your machines. If you work with physical machines, then you simply put these machines in a secure datacenter with padlocks and <a id=\"post-79040-_Hlk514871023\"><\/a>provide access only to authorized administrators. On top of that you could have security guards in front of the datacenter. With Virtual Machines, you don\u2019t have this security perimeter because many administrators can access these VMs, such as: Hyper-V administrators, backup administrators, storage administrators, or maybe network administrators. These administrators can access your virtual machines because they need access to VMs in order to do their jobs! Thus, they must be able to access the VHD disks.<\/p>\n<h3>What are the security risks?<\/h3>\n<p>The first risk that you can encounter is, for example, that your storage administrator with access to Hyper-V, will copy and paste one or many VHD disks to a USB device. The reason why Hyper-V presents such a huge risk has to do with Hyper-V anatomy. A virtual machine is a VHD disk which is nothing more than a file. Rather than booting the virtual machine, anyone could simply mount the VHD disk on a different Windows Server, thus giving the administrator access to the full contents of the VHD disk. In a better case, you will be notified that a copy has been made to an external drive; in the worst case you will have no awareness that your data has been compromised. Another risk is a malware attack. Imagine your Hyper-V host is compromised; all your VHD disks will be vulnerable and the malware will have full access to your Virtual Machines.<\/p>\n<p>To reduce such risks, Microsoft has introduced Shielded Virtual Machines.<\/p>\n<h3>How Do Shielded Virtual Machines Work?<\/h3>\n<p>Shielded Virtual Machines are based on the following concepts:<\/p>\n<ul>\n<li><strong>Code integrity<\/strong>: Code integrity checks whether the Hyper-V hosts meet the criteria to run Shielded Virtual Machines.<\/li>\n<li><strong>Virtual Trusted Platform Module (TPM v2)<\/strong>: vTPM will allow BitLocker encryption of the VM\u2019s disks. A vTPM device is encrypted with a transport key. Thanks to vTPM, the TPM technology can be used even if the hardware Hyper-V host does not have a physical TPM.<\/li>\n<li><strong>Host Guardian Service (HGS)<\/strong>: The Host Guardian Service exists in Windows Server 2016. The Host Guardian Service is a host level component that provides two services \u2013 attestation and key protection. When a Shielded Virtual Machine is turned on, HGS will check to see if the host is eligible to run the Shielded VM or not.<\/li>\n<\/ul>\n<p>Shielded VMs offer protection for virtual machines and will ensure that your Hyper-V environment running your Virtual Machines (such as: Domain Controller, SharePoint, Exchange, SQL Server, and so on\u2026) is safe. Moreover, Shielded VMs will only run on an infrastructure you designate.<\/p>\n<p>A picture is worth more than a thousand words; this image <a href=\"https:\/\/blogs.technet.microsoft.com\/datacentersecurity\/2016\/03\/14\/windows-server-2016-shielded-vms-protecting-tenant-secrets\/\">from TechNet<\/a> provides an overview of the full process:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"708\" height=\"325\" class=\"wp-image-79041\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/06\/word-image.png\" \/><\/p>\n<h2>Shielded Virtual Machines in Practice<\/h2>\n<p>Let\u2019s see how to implement Shielded VMs in a test environment. This is the environment used in the example explained in this article:<\/p>\n<ul>\n<li><strong>DC1<\/strong>: This VM is the Domain Controller for the following AD Forest: <em>GET-CMD.local<\/em>. The IP Address is 10.0.0.6<\/li>\n<li><strong>HYPV1<\/strong>: This is the Hyper-V host that will become a Guarded Host. The IP Address is 10.0.0.5<\/li>\n<li><strong>HGS01<\/strong>: This is a standalone HGS Server that will be unclustered because this is a test environment. The IP Address is 10.0.0.4. HGS Will create a standalone Active Directory Forest. In my case, the forest will be named: <em>GET-CMD-HGS.local<\/em>.<\/li>\n<li><strong>Shielded-WinServer2019<\/strong>: This is the Shielded VM based on Windows Server 2019 that will be deployed on the HYPV1 host.<\/li>\n<\/ul>\n<p>The figure below explains the lab environment for this article.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"588\" height=\"402\" class=\"wp-image-79042\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/06\/word-image-1.png\" \/><\/p>\n<p>If you lack sufficient resources to test on your laptop or your server, you can use your Azure subscription. That\u2019s what I did to create my lab environment, and, thanks to Nested Virtualization, it works like a charm. Just remember to use at least <em>Standard Ds_v3<\/em> VM size for your Hyper-V host.<\/p>\n<h3><a href=\"https:\/\/docs.microsoft.com\/en-us\/windows-server\/virtualization\/guarded-fabric-shielded-vm\/guarded-fabric-configure-hgs-with-authorized-hyper-v-hosts\">Deploying Active Directory and a Guarded Host<\/a><\/h3>\n<p>Begin this deployment by installing DC1 with an Active Directory domain called <em>GET-CMD.local<\/em>. I will not provide the PowerShell commands because that is not the goal of this article, but you can easily retrieve the commands on the Internet. Once your AD forest has been successfully created, you must install the Hyper-V role on your Hyper-V host. On HYPV1, run the following command:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Install-WindowsFeature Hyper-V -IncludeManagementTools \u2013Restart<\/pre>\n<p>If you need more information about PowerShell and Hyper-V, refer to the following article: <a href=\"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/hyper-v-powershell-basics\/\">https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/hyper-v-powershell-basics\/<\/a><\/p>\n<p>Next, join your Hyper-V host to your AD domain.<\/p>\n<h3>Deploying HGS Server<\/h3>\n<p>Connect to your HGS Server called HGS1 and install the Host Guardian Server role:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Install-WindowsFeature HostGuardianServiceRole -IncludeManagementTools\r\nSuccess Restart Needed Exit Code      Feature Result\r\n------- -------------- ---------      --------------\r\nTrue    No             Success        {Active Directory Domain Services, Failove...\r\nWARNING: You need to configure Host Guardian Service by calling Install-HgsServer &amp; Initialize-HgsServer PowerShell commands.<\/pre>\n<p>Install the Host Guardian Service by running the following commands. This cmdlet will create a standalone Active Directory Forest with your HGS Server as a primary Domain Controller. You can join this server to an existing AD Domain, but the best practice is to create a new one:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; $HGSPwd = ConvertTo-SecureString -AsPlainText 'xxxxxxxxxxx' -Force\r\nPS &gt; Install-HgsServer -HgsDomainName 'get-cmd-hgs.local' -SafeModeAdministratorPassword $HGSPwd \u2013Restart<\/pre>\n<p>The machine will reboot. Log in with the domain account which is your local administrator account with the same password. Now, you need to generate some certificates in order to initialize the HGS node. In a test environment, consider generating self-signed certificates:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; $CertPwd = ConvertTo-SecureString -AsPlainText 'xxxxxxxxx' -Force\r\nPS &gt; $Cert = New-SelfSignedCertificate -DnsName \"hgs.get-cmd-hgs.local\"\r\nPS &gt; Export-PfxCertificate -Cert $Cert -Password $CertPwd -FilePath 'C:\\HGSCert.pfx'\r\n    Directory: C:\\\r\nMode                LastWriteTime         Length Name\r\n----                -------------         ------ ----\r\n-a----        3\/30\/2018   9:24 PM           2661 HGSCert.pfx\r\nPS &gt; $encryptCert = New-SelfSignedCertificate -DnsName \"hgs.get-cmd-hgs.local\"\r\nPS &gt; Export-PfxCertificate -Cert $encryptCert -Password $certPwd -FilePath 'C:\\encryptCert.pfx'\r\n    Directory: C:\\\r\nMode                LastWriteTime         Length Name\r\n----                -------------         ------ ----\r\n-a----        3\/30\/2018   9:24 PM           2661 encryptCert.pfx<\/pre>\n<p>Two certificates have been generated:<\/p>\n<ul>\n<li><strong>HGSCert.pfx<\/strong>: This is the certificate for signing<\/li>\n<li><strong>encryptCert.pfx<\/strong>: This is the certificate for encryption<\/li>\n<\/ul>\n<h3>Initialize HGS Server<\/h3>\n<p>The next step is the initialization process. The <strong>Initialize-HGSServer<\/strong> cmdlet will check the status of the Active Directory domain controller and configure both certificates previously created:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Initialize-HgsServer -HgsServiceName 'HGS' -SigningCertificatePath 'C:\\HGSCert.pfx' -SigningCertificatePassword $certPwd -EncryptionCertificatePath 'C:\\encryptCert.pfx' -EncryptionCertificatePassword $certPwd -TrustTpm\r\nLogPath: C:\\Windows\\Logs\\HgsServer\\180330212859\\HyperVShielded<\/pre>\n<p>You can check to see if the HGS server exists in your AD Domain:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-ADComputer -Identity HGS1\r\nDistinguishedName : CN=HGS1,OU=Domain Controllers,DC=get-cmd-hgs,DC=local\r\nDNSHostName       : HGS1.get-cmd-hgs.local\r\nEnabled           : True\r\nName              : HGS1\r\nObjectClass       : computer\r\nObjectGUID        : 031528cd-27ff-4680-aa3a-5b7304ccaf6b\r\nSamAccountName    : HGS1$\r\nSID               : S-1-5-21-87811353-1222259967-1591882773-1000\r\nUserPrincipalName :<\/pre>\n<p>Set the HGS server configuration by switching to the Active Directory Mode:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Set-HgsServer \u2013TrustActiveDirectory<\/pre>\n<p>Note: You could also configure the HGS server to be accessible over HTTPS. You can now create a conditional forwarding that point to the first AD domain:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Add-DnsServerConditionalForwarderZone -Name \"get-cmd.local\" -ReplicationScope \"Forest\" -MasterServers 10.0.0.6<\/pre>\n<p>Create a One-Way trust relationship from the HGS Domain to the Corporate AD Domain:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; netdom trust get-cmd-hgs.local \/domain:get-cmd.local \/userD:get-cmd.local\\Nicolas \/passwordD:xxxxxxxx \/add\r\nThe command completed successfully.<\/pre>\n<p>Confirm that the outbound trust relationship has been created on HGS1:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-ADTrust -Filter * | select Name, Direction, Source, Target\r\nName          Direction Source                  Target\r\n----          --------- ------                  ------\r\nget-cmd.local  Outbound DC=get-cmd-hgs,DC=local get-cmd.local<\/pre>\n<p>As expected, the inbound trust relationship exists on DC1 as well.<\/p>\n<h3>Configure the Guarded Host \u2013 Part 1<\/h3>\n<p>Connect to DC1 and create a group called <em>GuardedHosts<\/em> with <em>Global<\/em> scope and a <em>Security<\/em> type. Then add the guarded host server to the newly created group:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Add-ADGroupMember \"GuardedHosts\" \u2013Members \"HYPV1$\"<\/pre>\n<p>You must add conditional forwarding to the HGS domain name. The next task is to get the SID for this AD Group. Run the following command and copy\/paste this SID in notepad:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-ADGroup \u2018GuardedHosts\u2019 | Select-Object SID<\/pre>\n<h3>Configure HGS Server \u2013 Part 1<\/h3>\n<p>Switch back to HGS1 and run the <strong>Add-HgsAttestationHostGroup<\/strong> cmdlet:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Add-HgsAttestationHostGroup -Name \u2018GuardedHosts\u2019 -Identifier \"S-1-5-21-1700574040-1668240534-2077627731-1105\"\r\nS-1-5-21-1700574040-1668240534-2077627731-1105:GuardedHosts<\/pre>\n<p>This command adds the host group called <em>GuardedHosts<\/em> from the <em>get-cmd.local<\/em> Active Directory fabric to the Attestation service on HGS1. The Identifier parameter specifies the SID previously stored in notepad. After you run this command, the Attestation service trusts all hosts that belong to this group to host Shielded Virtual Machines. You can check the HGS Attestation Group:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-HgsAttestationHostGroup\r\nName         Identifier\r\n----         ----------\r\nGuardedHosts S-1-5-21-1700574040-1668240534-2077627731-1105<\/pre>\n<p>Ok great! AD and HGS are configured. You can now connect to the guarded host.<\/p>\n<h3>Configure the Guarded Host \u2013 Part 2<\/h3>\n<p>You need to create the Code Integrity Policy. This policy will be applied to every machine with the same configuration and is used to prevent unauthorized software from running on the host. First, you need to scan a reference system to create an XML policy file. This should capture most files that Windows needs to boot and run. In my case, the Guarded Host is a fresh and clean install, so I will scan the whole system. Doing so may take a while. If you add or change something on the host, you must start a new scan to update the policy<\/p>\n<p>Then, you will convert the XML file into a <em>.p7b<\/em> file. If you just want to scan and restrict to a single directory, remember to add the <strong>\u2013ScanPath <\/strong>parameter. This command will create the XML file that you will convert into a Device Guard Policy using the the <strong>ConvertFrom-CIPolicy<\/strong> cmdlet:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; New-CIPolicy -Level FilePublisher -Fallback Hash -FilePath 'C:\\CodeIntegrity.xml'\r\n\"Scan completed successfully\"\r\nPS &gt; ConvertFrom-CIPolicy -XmlFilePath 'C:\\CodeIntegrity.xml' -BinaryFilePath 'C:\\CodeIntegrity.p7b'\r\nC:\\CodeIntegrity.p7bPS C:\\Users\\nicolas&gt;<\/pre>\n<p>Note: If this cmdlet cannot generate a rule at the specified level, in my case at the <strong>FilePublisher<\/strong> level, then this cmdlet attempts to generate it at a fallback level (in my case at the hash level).<\/p>\n<p>Once the binary has been created, copy this file to HGS1.<\/p>\n<h3>Configure HGS Server \u2013 Part2<\/h3>\n<p>On HGS1, run the following command to add the Code Integrity policy to the Attestation service, based on the specified <em>.p7b<\/em> file.<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Add-HgsAttestationCIPolicy -Path C:\\CodeIntegrity.p7b -Name \"Hyper-V Enforced CI Policy\"\r\nName                       PolicyType   State\r\n----                       ----------   -----\r\nHyper-V Enforced CI Policy {CiPolicy} Enabled<\/pre>\n<p>You must retrieve the <em>AttestationUrl<\/em> and <em>KeyProtectionUrl<\/em>\u00a0to configure the Guarded Host:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-HgsServer\r\nName                           Value\r\n----                           -----\r\nAttestationOperationMode       AD\r\nAttestationUrl                 {http:\/\/hgs.get-cmd-hgs.local\/Attestation}\r\nKeyProtectionUrl               {http:\/\/hgs.get-cmd-hgs.local\/KeyProtection}<\/pre>\n<h3>Configure the Guarded Host \u2013 Part3<\/h3>\n<p>Switch back to HYPV1 and configure it to use the Host Guardian Service. This command configures the URLs used by the attestation client and the key protection client:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-HgsClientConfiguration\r\nIsHostGuarded            : False\r\nMode                     : Local\r\nKeyProtectionServerUrl   :\r\nAttestationServerUrl     :\r\nAttestationOperationMode : Unknown\r\nAttestationStatus        : NotConfigured\r\nAttestationSubstatus     : NoInformation\r\nPS &gt; Set-HgsClientConfiguration -KeyProtectionServerUrl \"http:\/\/hgs.get-cmd-hgs.local\/KeyProtection\" -AttestationServerUrl \"http:\/\/hgs.get-cmd-hgs.local\/Attestation\"\r\nIsHostGuarded            : True\r\nMode                     : HostGuardianService\r\nKeyProtectionServerUrl   : http:\/\/hgs.get-cmd-hgs.local\/KeyProtection\r\nAttestationServerUrl     : http:\/\/hgs.get-cmd-hgs.local\/Attestation\r\nAttestationOperationMode : ActiveDirectory\r\nAttestationStatus        : Passed\r\nAttestationSubstatus     : NoInformation<\/pre>\n<p>HYPV1 has switched from <strong>HostGuarded:False<\/strong> to <strong>HostGuarded:True<\/strong>. It means that you can create and run Shielded VMs on this host. To validate the HGS deployment, run the <strong>Get-HgsTrace<\/strong> cmdlet.<\/p>\n<h3><a href=\"https:\/\/docs.microsoft.com\/en-us\/windows-server\/virtualization\/guarded-fabric-shielded-vm\/guarded-fabric-configuration-scenarios-for-shielded-vms-overview\">Deploy shielded VMs<\/a><\/h3>\n<p>To confirm that this works, deploy a simple Virtual Machine. <em>Enable the Remote Desktop Protocol because after enabling Shielded Mode on this VM, you will not be able to access to this VM, except through RDP:<\/em><\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; # Rhe guardian metadata is available at http:\/\/&lt;HGSCLUSTERNAME&gt;\/KeyProtection\/service\/metadata\/2014-07\/metadata.xml\r\nPS &gt; Invoke-WebRequest \"http:\/\/hgs.get-cmd-hgs.local\/KeyProtection\/service\/metadata\/2014-07\/metadata.xml\" -OutFile \"C:\\Guard\r\nPS &gt; # Import the HGS guardian for each fabric you want to run your shielded VM\r\nPS &gt; Import-HgsGuardian -path \"C:\\GuardianMetadata.xml\" -Name \"Get-CMD\" -AllowUntrustedRoot\r\nName    HasPrivateSigningKey Signing Certificate Subject\r\n----    -------------------- ---------------------------\r\nGet-CMD False                CN=hgs.get-cmd-hgs.local\r\nPS &gt; # The certificate is stored at Cert:\\LocalMachine\\Shielded VM Local Certificates\r\nPS &gt; $Owner = New-HgsGuardian -Name \"Owner\" -GenerateCertificates\r\nPS &gt; $Guardian = Get-HgsGuardian -Name \"Get-CMD\"\r\nPS &gt; $HGSKeyProtector = New-HgsKeyProtector -Owner $Owner -Guardian $Guardian \u2013AllowUntrustedRoot<\/pre>\n<p>After creating a simple VM called <em>Shielded-WinServer2019<\/em>, confirm that Shielded Mode is disabled:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-VM -Name Shielded-WinServer2019\r\nName                   State   CPUUsage(%) MemoryAssigned(M) Uptime           Status             Version\r\n----                   -----   ----------- ----------------- ------           ------             -------\r\nShielded-WinServer2019 Running 0           546               00:48:15.5960000 Operating normally 8.0\r\nPS &gt; Get-VM -Name Shielded-WinServer2019 | Get-VMSecurity\r\nTpmEnabled                        : False\r\nKsdEnabled                        : False\r\nShielded                          : False\r\nEncryptStateAndVmMigrationTraffic : False\r\nVirtualizationBasedSecurityOptOut : False\r\nCimSession                        : CimSession: .\r\nComputerName                      : HGS\r\nIsDeleted                         : False<\/pre>\n<p>Enable Shielded Mode on this Virtual Machine:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; $VMName = \"Shielded-WinServer2019\"\r\nPS &gt; Get-VM -Name $VMName | Stop-VM -Force\r\nPS &gt; Set-VMKeyProtector -VMName $VMName -keyprotector $HGSKeyProtector.RawData\r\nPS &gt; Set-VMSecurityPolicy -VMName $VMName -Shielded $true\r\nPS &gt; Enable-VMTPM -VMName $VMName\r\nPS &gt; Start-VM -Name $VMName<\/pre>\n<p>The VM has been started, and you can confirm that it can\u2019t be accessed to through VMConnect:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-VM -Name Shielded-WinServer2019\r\nName                   State   CPUUsage(%) MemoryAssigned(M) Uptime           Status             Version\r\n----                   -----   ----------- ----------------- ------           ------             -------\r\nShielded-WinServer2019 Running 0           512               00:01:53.3890000 Operating normally 8.0\r\nPS C:\\Users\\nicolas&gt; Get-VM -Name Shielded-WinServer2019 | Get-VMSecurity\r\nTpmEnabled                        : True\r\nKsdEnabled                        : False\r\nShielded                          : True\r\nEncryptStateAndVmMigrationTraffic : True\r\nVirtualizationBasedSecurityOptOut : False\r\nCimSession                        : CimSession: .\r\nComputerName                      : HGS\r\nIsDeleted                         : False<\/pre>\n<p><strong><img loading=\"lazy\" decoding=\"async\" width=\"642\" height=\"507\" class=\"wp-image-79043\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/06\/word-image-2.png\" \/><\/strong><\/p>\n<p>Open the settings for this Virtual Machine and confirm that <em>Enable Shielding <\/em>is selected. At this step, you cannot modify the security settings because the VM is running in a guarded fabric.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" width=\"722\" height=\"687\" class=\"wp-image-79044\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/06\/word-image-3.png\" \/><\/strong><\/p>\n<h2>What\u2019s new in Windows Server 2019?<\/h2>\n<p>Microsoft states that the Shielded VMs concept in Windows Server 2016 was well received by customers, so in Windows Server 2019, Microsoft has extended the Shielded Virtual Machine concept to encompass Linux Virtual Machines. Windows Server 2019 also includes the ability to encrypt network segments. Microsoft has improved troubleshooting of Shielded VMs for Windows Server and Linux. You can for example use PowerShell Direct to connect to Shielded VMs even if you\u2019ve lost network connectivity to these VMs.<\/p>\n<h2>Conclusion<\/h2>\n<p>In my point of view, Shielded VMs are not very well documented. If you want to implement Shielded VMs in your environment, be sure that all the prerequisites are satisfied, and, if it\u2019s possible, use a testing environment before implementing in production.<\/p>\n<p>Even though it is possible to run the Host Guardian Service on a standalone server, I should advise you to only use Shielded VMs within Hyper-V clusters. Otherwise, in case of a host level failure, the Shielded Virtual Machines could be permanently inaccessible. For those of you who want to test Shielded VMs, you can use nested Hyper-V for testing but not in production. To finish, remember that a shielded VM can exist only on a guarded host, and a shielded VM cannot run on a normal Hyper-V Host. But a normal Virtual Machine, without encryption, can coexist with Shielded VMs on guarded Hyper-V Hosts.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Configuring Hyper-V shielded virtual machines with PowerShell &#8211; the guarded fabric architecture, Host Guardian Service (HGS) for attestation, virtual TPM (vTPM) for BitLocker-protected disks, and shielding-template configuration to prevent untrusted administrator access to VM contents.&hellip;<\/p>\n","protected":false},"author":158223,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143513,35],"tags":[95506],"coauthors":[6804],"class_list":["post-79040","post","type-post","status-publish","format-standard","hentry","category-containers-and-virtualization","category-powershell","tag-automate"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/79040","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/158223"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=79040"}],"version-history":[{"count":7,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/79040\/revisions"}],"predecessor-version":[{"id":85641,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/79040\/revisions\/85641"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=79040"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=79040"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=79040"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=79040"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}