Author: Ingmar Verheij
If you want to connect to the console of a virtual machine running on Citrix XenServer you either need XenCenter or the Web Self Service portal.
I created a PowerShell script that connects to the console of the virtual machine, without the use of both. This script can be used to offer a shortcut to a virtual machine without requiring the user to have XenCenter installed, or having a XenServer Enterprise or Platinum license (it works with the free license).
VNC
XenServer uses virtual network computing (VNC) to connect to the console of a virtual machine. In this script I’m using the TightVNC viewer to connect to the console, but you can use any other VNC viewer (although it requires you to change the script and might give issues when used via Citrix ICA).
SSH tunnel
The VNC connector on the XenServer only listens on the localhost, so you’re unable to connect to it directly. Before you can connect your VNC viewer to the console you need to tunnel the data through an SSL tunnel. This will encapsulate all VNC data through a secured channel and deliver it on the XenServer. I’m using plink (a component of the PuTTY suite) to send SSH commands and setup a SSL tunnel between the host and the XenServer host (just like XenCenter does when you connect to the console of a VM).
Note: The sa2 key fingerprint is accepted automatically by the script.
Note: I’m aware there is a Powershell cmdlet for SSH (which could prevent the use of plink) but this cmdlet is unable to set up a SSL tunnel.
Connect to who and where?
Before you can setup the SSL tunnel you need to know two thing. The XenServer the VM is running on (1) and the port the VNC server is running on (2). So before setting up the SSL tunnel I’m querying the XenServer (pool master) for IP address of the XenServer host where the VM is running.
The name of my virtual machine is ‘WS01’ and I added custom field ‘STUDENT’ with the value ‘1’.
xe vm-list name-label="WS01" other-config:XenCenter.CustomFields.STUDENT=1 os-version:distro="windows" params=resident-on --minimal xe pif-list management=true params=IP host-uuid=(uuid of XenServer host) --minimal
Now I know the IP address of the XenServer where the VM is running I can search for the domain ID of the virtual machine. With the domain ID I can search for the VNC server process qemu-dm-<domid>.
xe vm-list name-label="WS01" other-config:XenCenter.CustomFields.STUDENT=1 os-version:distro="windows" params=dom-id --minimal netstat -lp|grep -w $varDomPrefix(domID of the VM)|awk '{print $4}'|cut -d: -f2
Okay, so now I know the IP address of the XenServer where the VM is running (1) and the port where the VNC host is running (2).
plink -N –L (VNC port):localhost:(VNC port) root@(IP Address of XenServer)
Connecting though ICA (Citrix XenApp / XenDesktop)
I published the console of a virtual machine as a published application so my users can access the console from anywhere (via the CloudGateway). During testing I found out that both RealVNC and UltraVNC had performance issues, only TightVNC in 8-bit mode worked at a proper speed.
If you don’t want the connect in 8-bit mode, change the line $vncUse8Bit=$true to $vncUse8Bit=$false.
PowerShell script (this is where it’s all about)
Download: ConsoleXSConnect.ps1
Usage
The script requires 4 arguments and has 2 optional arguments
Usage powershell.exe .\ConsoleConnect.ps1 (XenServerPoolMaster) (XenServerUsername) (XenServerPassword) (VMName) [CustomFieldName] [CustomFieldValue] Example powershell.exe .\ConsoleConnect.ps1 172.16.1.1 root Passw0rd WS01 STUDENT 1
XenServerPoolMaster: The IP/FQDN of the XenServer (pool master) host
XenServerUsername: The username to connect to the XenServer
XenServerPAssword: The password to connect to the XenServer
VMName: The name of the virtual machine
CustomFieldName (optional): The name of a custom field
CustomFieldValue (optional): The value of the custom field
The custom field can be used to uniquely identify a virtual machine if the name of the machine is reused. In my environment I cloned the virtual machine ‘WS01’ multiple times and added a CustomField ‘STUDENT’. For each student a virtual machine is published.
Additional downloads (required)
Hi,
Thank you for the script. I’ve made some changes and wonder if I could upload it to github or something.
Everything looks great, but then I get the error below… any suggestions?
The virtual machine ‘ OCVDI-PUBLIC-000’ is running on host 10.88.0.9
The VNC port for virtual machine ‘ OCVDI-PUBLIC-000’ is 5909
Exception calling “Start” with “0” argument(s): “The system cannot find the file specified”
At C:\Users\jhendren\downloads\ConsoleXSConnect\ConsoleXSConnect.ps1:40 char:27
+ $temp = $process.start <<<< ()
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Exception calling "WaitForExit" with "0" argument(s): "No process is associated with this object."
At C:\Users\jhendren\downloads\ConsoleXSConnect\ConsoleXSConnect.ps1:191 char:30
+ $processVNCViewer.WaitForExit <<<