Really Easy Ways to Capture VM Screenshot

Since vSphere 2.5, there is a feature allowing you to capture screen shot of a running virtual machine. It’s not well publicized but you can find a short description with screenshotSupported (boolean) in the HostCapability data object. Thanks to Nikita for bringing this up in the comment of the vSphere Java API 2.1 GA post.

Indicates whether the screenshot retrival over https is supported for this host’s virtual machines. If true, a screenshot can be retrieved at the HTTPS relative path /screen?id=<managed object ID of virtual machine or snapshot>. If any of the optional parameters ‘top’, ‘left’, ‘bottom’, and ‘right’ is specified, the returned image will be cropped from the rectangle with upper left corner (left, top) and bottom right corner (right – 1, bottom – 1). These values default to the top, left, bottom and right edges of the image. The client must use an authenticated session with privilege VirtualMachine.Interact.ConsoleInteract on the requested virtual machine or, in the case of a snapshot, the virtual machine associated with that snapshot.

Lost VMs or Containers? Too Many Consoles? Too Slow GUI? Time to learn how to "Google" and manage your VMware and clouds in a fast and secure HTML5 App.

The managed object ID of virtual machine is the value of ManagedObjectReference, which can be easily found using MOB.

Once you have it, you can issue a URL as follows in any browser and get the screen shot in PNG format.

https://esx.acme.com/screen?id=48

Supposedly you can also get the screenshot of a snapshot using a URL like the following:

https://esx.acme.com/mob/?moid=80%2dsnapshot%2d3

It took a long time before I canceled it. So I was not able to make it working. I also tried top/left/bottom/right with no luck. If you make it working, please feel free to share here.

You cannot use the above URL with a vCenter server which manages the host running the VM. The following URL gets you an error saying the webpage cannot be found.

https://vc.acme.com/screen?id=vm%2d693

So capturing screen shot with URL is a host only feature.

In addition to this, you can also use the CreateScreenshot_Task() defined with VirtualMachine type. It works only with ESX(i) as well. The location of the screenshot image file is returned in the Task’s info.result sub-property upon success.

“/vmfs/volumes/4bfac83a-f48e7595-8b0d-00237dfba01d/MyVM/MyVM-screenshot-0.png”

You can have multiple screen shots captured with number incremented as you can find with Web based datastore browser:

MyVM-screenshot-0.png 07-Sep-2010 04:01 292561
MyVM-screenshot-1.png 07-Sep-2010 04:07 292561

As you know to download a file from datastore using HTTP access, you need a URL pattern as follows:

https://esx.acme.com/folder/MyVM/MyVM-screenshot-0.png?dcPath=ha-datacenter&dsName=FCLun2

Now the question is: how to convert the above UUID in the info.result to the corresponding datastore’s name. It’s relatively easy task, I would leave it to you. Hint: check out the datastore property of HostSystem type.

This entry was posted in vSphere API and tagged , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

7 Comments

  1. Posted September 8, 2010 at 1:25 am | Permalink

    I found workaround: I have read screenshot file content directly by means of SSH2 (http://www.jcraft.com/jsch/).

    The way of using HTTPS for retrieving screenshot file content from ESX is morу complex because in first you need install SSL certificates, then provide login and password for authorization (Basic Auithorization Method) and only after send request in order to get screenshot.

  2. Posted September 8, 2010 at 10:58 pm | Permalink

    Hi Nikita,

    Thanks for sharing your SSH2 approach! With HTTPS, you don’t have to install SSL certificate. Check out the WSClient.java in vijava for the trick to handle this. In general, you want to use HTTPS over SSH because SSH might not be open by default.

    Steve

  3. Abhinav
    Posted September 14, 2010 at 5:20 am | Permalink

    Can I improve something (I am worried about the way I am parsing image url returned by screenshot task) in the code below?

    public BufferedImage getThumbnail(VirtualMachine vm) throws Exception {
    Task screenshotTask = vm.CreateScreenshot_Task();
    if (TaskInfoState.success.toString().equals(screenshotTask.waitForTask(500, 100))) {
    String fileDatastoreUrl = (String) screenshotTask.getTaskInfo().getResult();
    // file datastore url should be of format
    // “/vmfs/volumes/4c063bc6-f462ed19-2974-002492fdd84e/vesx5.0/vesx5.0-screenshot-0.png”
    // split it into 5 parts as “”, “vmfs”, “volumes”,
    // “4c063bc6-f462ed19-2974-002492fdd84e”, and
    // “vesx5.0/vesx5.0-screenshot-0.png”. Second part is
    // datastore type, fourth part is datastore uuid, and 5th part
    // is filename.
    String[] filenameParts = fileDatastoreUrl.split(“/”, 5);
    String datastoreType = filenameParts[1];
    String datastoreUuid = filenameParts[3];
    String filename = filenameParts[4];

    Datastore[] datastores = vm.getDatastores();
    if (datastores != null) {
    for (Datastore datastore : datastores) {
    DatastoreSummary summary = datastore.getSummary();
    if (datastoreType.equalsIgnoreCase(summary.getType())
    && summary.getUrl().contains(datastoreUuid)) {
    // Found correct datastore.
    String datastoreName = datastore.getName();

    // Find datacenter.
    ManagedEntity datacenter = vm;
    for(; datacenter!=null && !”Datacenter”.equals(datacenter.getMOR().getType()); datacenter = datacenter.getParent());
    String datacenterName = datacenter.getName();

    String serverUrl = vm.getServerConnection().getUrl().toString();

    // Build url as
    // https://xxx.xxx.xxx.xxx/folder/vesx5.0/vesx5.0-screenshot-0.png?dcPath=CBM&dsName=CBM470GB
    // to download screenshot file.
    StringBuilder fileUrlBuilder = new StringBuilder(serverUrl);
    if (!serverUrl.endsWith(“/”)) {
    fileUrlBuilder.append(‘/’);
    }
    fileUrlBuilder.append(“folder/”);
    fileUrlBuilder.append(URLEncoder.encode(filename, “UTF-8”));
    fileUrlBuilder.append(“?dcPath=”);
    fileUrlBuilder.append(URLEncoder.encode(datacenterName, “UTF-8”));
    fileUrlBuilder.append(“&dsName=”);
    fileUrlBuilder.append(URLEncoder.encode(datastoreName, “UTF-8”));
    String fileUrlString = fileUrlBuilder.toString();

    System.out.println(“Downloading screenshot from ” + fileUrlString + ” for vm ”
    + vm.getName());

    String cookie = vm.getServerConnection().getSessionStr();

    URL url = new URL(fileUrlString);
    URLConnection conn = url.openConnection();

    conn.setDoInput(true);
    conn.setDoOutput(true);
    conn.setAllowUserInteraction(true);
    conn.setRequestProperty(“Cookie”, cookie);

    conn.connect();

    InputStream screenInputStream = conn.getInputStream();
    try {
    return ImageIO.read(screenInputStream);
    } finally {
    if(screenInputStream!=null){
    screenInputStream.close();
    }
    if (conn != null && conn instanceof HttpURLConnection) {
    ((HttpURLConnection) conn).disconnect();
    }
    }
    }
    }
    }
    }

    throw new Exception(“Thumbnail is not available.”);
    }

  4. Posted September 14, 2010 at 10:39 am | Permalink

    Thanks a lot for sharing the code with the community!

    -Steve

  5. Posted April 1, 2011 at 11:19 pm | Permalink

    “In addition to this, you can also use the CreateScreenshot_Task() defined with VirtualMachine type. It works only with ESX(i) as well.”

    That is actually not true, nothing prevents you from executing the CreateScreenshot_Task() from vCenter and retrieving the image from the ESX host (assuming the credentials of the ESX are known) with this method.

  6. Posted April 5, 2011 at 1:22 am | Permalink

    Thanks Virgil, I think your description is clearer and more precise.

    Steve

  7. Posted September 17, 2015 at 11:42 am | Permalink

    Grandes cosas por venir.

5 Trackbacks

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

  • NEED HELP?


    My company has created products like vSearch ("Super vCenter"), vijavaNG APIs, EAM APIs, ICE tool. We also help clients with virtualization and cloud computing on customized development, training. Should you, or someone you know, need these products and services, please feel free to contact me: steve __AT__ doublecloud.org.

    Me: Steve Jin, VMware vExpert who authored the VMware VI and vSphere SDK by Prentice Hall, and created the de factor open source vSphere Java API while working at VMware engineering. Companies like Cisco, EMC, NetApp, HP, Dell, VMware, are among the users of the API and other tools I developed for their products, internal IT orchestration, and test automation.