Managing Hyper-V Virtual Machines with PowerShell Direct
Managing VMs Without a Network, Beast Mode Activated
What if you needed to access a virtual machine (VM) when the firewall is misconfigured, Remote Desktop is not allowed, the guest OS is in an isolated network (e.g., a DMZ), or it doesn’t even have a virtual switch assigned?
In those cases, PowerShell Direct is your answer. You could use VMConnect if the OS has a GUI, but in this post, we’ll focus on PowerShell Direct.
TL;DR
PowerShell Direct lets you manage Hyper‑V VMs without relying on the network stack, making it a powerful fallback when connectivity breaks or isn’t available.
How it Works
PowerShell Direct allows you to connect to a VM using the VMBus without any networking. It’s extremely fast and low latency. There’s also no need to configure WinRM, open network ports, or assign IP addresses.
According to Microsoft Documentation the VMBus is a “Channel-based communication mechanism used for inter-partition communication and device enumeration on systems with multiple active virtualized partitions. The VMBus is installed with Hyper-V Integration Services.”
Prerequisites and Requirements
Host OS: Windows 10/11 or Windows Server 2016/2019/2022.
Guest OS: Windows 10/11 or Windows Server 2016 or newer.
Hyper-V: The VM must be running locally on the host you are logged in to.
Permissions: You must have administrative credentials for the guest VM.
How to Use PowerShell Direct
To use PowerShell Direct you will need to use the VM name or ID with the VMId or VMName parameters of Enter-PSSession or Invoke-command.
Identifying Compatible VMs
First of all we need to find out the Id or Name of the VM. Remember that the VM name does not necessarily match the name in the guest OS of the VM.
# List VMs, their state, and version to check for compatibility
Get-VM | Select-Object Name, State, Version, VMId | Format-TableSometimes VM names are duplicated or change, but the VMId (GUID) is unique. You can use this for a more "hardcoded" connection in scripts.
# Grab the ID of a specific VM
$TargetID = (Get-VM -Name "Finance-Prod-01").VMId
# Connect using the unique GUID
Enter-PSSession -VMId $TargetID -Credential (Get-Credential)Usage Examples
A. One-Off Commands
In this example I used VMName, but VMId is also available.
Invoke-Command -VMName "FinanceServer" -ScriptBlock { Get-Service } -Credential (Get-Credential)B. Interactive Sessions
Enter-PSSession -VMName "FinanceServer" -Credential (Get-Credential)C. Copying Files
Create persistent session
These are two different examples, you can also use the VMId or the VMName with New-PSSession.
Example 1
$s = New-PSSession -VMName <VMName> -Credential (Get-Credential)Example 2
$s = New-PSSession -VMId <VMId> -Credential (Get-Credential)Copy a file into the virtual machine
Copy-Item -ToSession $s -Path C:\host_path\data.txt -Destination C:\guest_path Copy a file from the virtual machine
Copy-Item -FromSession $s -Path C:\guest_path\data.txt -Destination C:\host_path Remove session
Remove-PSSession $sUsing Copy-VMFile
Out of interest, I tried this Cmdlet and it failed. It doesn’t need any networking protocols but it does does not use PowerShell Direct either.
$copyParams = @{
VMName = "MyVM"
SourcePath = "C:\dummy.txt"
DestinationPath = "C:\test.txt"
CreateFullPath = $true
FileSource = "Host"
}
Copy-VMFile @copyParamsIt fails as one of the guest services is disabled
Copy-VMFile : Failed to initiate copying files to the guest.
'MyVM' failed to initiate copying files to the guest: The device is not ready. (0x80070015). (Virtual machine
ID 011C855E-2BD2-4981-A421-B60B619D1837)
At line:1 char:1
+ Copy-VMFile @copyParams
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Copy-VMFile], VirtualizationException
+ FullyQualifiedErrorId : Unspecified,Microsoft.HyperV.PowerShell.Commands.CopyVMFileYou can find out what is disabled using Get-VMIntegrationService. You can see below that the Guest Service Interface is disabled.
Get-VMIntegrationService -VMName "MyVM" | Select-Object -Property name, enabled
Name Enabled
---- -------
Guest Service Interface False
Heartbeat True
Key-Value Pair Exchange True
Shutdown True
Time Synchronization True
VSS TrueOnce you turn on this service using the following command, the Copy-VMFile will work.
Enable-VMIntegrationService -VMName 'MyVM' -Name 'Guest Service Interface'Final Thought
PowerShell Direct is very useful and makes connecting to a Hyper-V VM a snap. I have also combined it with background jobs and Scheduled Jobs to automate things like user profile clean ups.
Because PowerShell Direct uses the VMBus instead of the network stack, it doesn’t require WinRM, RDP, SMB, or any firewall rules. The host and VM communicate through a private Hyper‑V channel, which means you can manage the VM without introducing any additional network‑exposed services.
PowerShell Direct serializes the output objects into XML before sending them over the VMBus. The commands themselves are not serialized — they execute inside the guest VM, and only the resulting data is returned to the host. Any operations that require real objects must be performed inside the Invoke-Command script block or an Enter-PSSession interactive session.

