Testing PowerShell Direct with Windows Server 2016 TP3 Hyper-V
Hey there! I thought we could test PowerShell Direct together today. Here’s the elevator pitch: In Windows Server 2016 and Windows 10, we can send PowerShell commands from the Hyper-V host directly to its corresponding virtual machines (VMs), even in the absence of guest VM networking. Yeah, that’s cool, isn’t it?
What’s just as impressive is that PowerShell Direct works _even if PowerShell remoting is disabled on the guest VM! _PowerShell Direct also circumvents Windows Firewall. Note that PowerShell Direct requires that commands are sent only from a Hyper-V host to its local VMs.
Also, PowerShell Direct is supported at this point only by Windows Server 2016 TP3 and Windows 10. That means a Windows Server 2016 TP3 Hyper-V host cannot leverage PowerShell Direct against, say, Windows Server 2012 R2 virtual machines (give the Hyper-V, PowerShell, and Windows Server teams time; I’m sure this will be supported in the future).
The secret sauce behind PowerShell Direct is PowerShell Remoting Protocol (MS-PSRP), which used to be called just plain ol’ garden variety “PowerShell remoting.”
The Lab Setup
In my test lab, I started with a domain controller and Hyper-V host (yeah, I’m combining server roles–what of it?) named hyperv1.company.pri. That server’s running Windows Server 2016 Technical Preview 3.
In Hyper-V I created a single virtual switch named Internal that is connected to the host/guest network. Of course, we don’t care about the switch fabric because we’re going to use PowerShell Direct.
Next, I built a Windows Server 2016 TP3-based guest VM named server1 and disabled the network adapter as you can see in the following screenshot. No smoke and mirrors here!
Our lab is set up and ready to test PowerShell Direct.
As a final “sanity check” to ensure the guest VM is as theoretically inaccessible as possible, I blocked access to all remote access session configurations and disabled the Windows Remote Management (WinRM) service by running the following command from within the guest (thanks to PowerShell MVP Aleksandar Nikolić for clarification on this point):
Disable-PSRemoting -Force Get-Service -Name WinRM | Stop-Service -Force | Set-Service -StartupType Disabled Okay. Let’s move onto the next phase of our experiment.
Sending Commands to the Guest VM
Let’s obtain the name and globally unique identifier (GUID) of our Windows Server 2016 VM (you’ll see why in just a moment):
`Get-VM | Select-Object -Property Name, VMid Name VMId
server1 31d787fe-02cd-4363-b50b-16bc8243fc77 `PowerShell Direct makes itself manifest by means of two new parameters:
- VMname
- VMGuid
Handy, eh? The following two cmdlets support the -VMname and -VMGuid parameters as of this writing in October 2016:
Time to test! Let’s start a remote session with the server1 guest VM by specifying its GUID. Note that you will need:
- Hyper-V administrative privileges on the host
- Local administrative privileges on the guest
$cred = Get-Credential Enter-PSSession -VMGuid 31d787fe-02cd-4363-b50b-16bc8243fc77 -Credential $cred [server1]: PS C:\Users\Administrator\Documents> We’ll finish by using Invoke-Command to send ad-hoc PowerShell pipelines and entire scripts from host to guest:
Invoke-Command -VMName 'server1' -Credential $cred -ScriptBlock { Get-Service | Where-Object {$_.Status -eq 'Stopped'} } Invoke-Command -VMName 'server1' -FilePath 'D:\scripts\setup-ip.ps1' -Credential $cred ## Conclusions
Convenience is the primary advantage that PowerShell Direct brings to us Hyper-V administrators. We can connect to and fully administer our guest virtual machines regardless of their networking, firewall, or WS-Man state. Thanks for reading, and more power to the shell!
Related Articles
Iron Scripter: Learn PowerShell through code challenges
Hello, friends! Today I want to talk about the Iron Scripter code challenges and the accompanying website. The challenges are excellent for practicing challenging concepts. What’s that you say? Not familiar with Iron Scripter? Let’s get you up to speed. Iron Scripter: A brief history lesson The Iron Scripter website is part of the PowerShell.org family and provides material for the Iron Scripter challenge that takes place at PowerShell Summit each year.
A Peculiar Parse
One of the best enhancements to Powershell was the inclusion of custom classes in v5. We originally wrote scripts, then we wrote cmdlets, followed by modules, and now we’ve graduated, with Class. I recently decided I wanted to write some code that would build a website. What better way to do that than by creating a class just for me? That’s rhetorical by the way. My early class code looked like this:
Pester – Parameters and Hashtable Fun!
I have written a short excerpt on how to pass parameters from an object to a Pester test. I have turned this into a function: Invoke-POVTest. The function is primarily for operational validation tests, where you might have a single operational test but you need to test multiple cases. (Sorry, I am not quite sure if I described it properly). I’ll be interested in any feedback. Link to blog post here.
