How to install integration services when the virtual machine is not running

How to install integration services when the virtual machine is not running

  • Comments 14
  • Likes

We’ve been talking to a lot of people about deploying integration services (integration components) lately.  As it turns out, they’re pretty easy to patch offline with existing Hyper-V tools.

First, why would you update integration services on a not-running (offline) VM?

Offline VM servicing is valuable for VM templates places that create new VMs frequently since it allows you to keep VM templates up-to-date.  While this post targets exclusively integration service updates, the same update approach applies to many updates as well as any configurations specific to the environment.  Keeping the VM images fully up to date and configured before they are deployed saves significant setup time and support every time a new VM is created.

Here is a detailed write-up about deploying and updating integration services on an offline VM – both VHD/VHDX – using out of box PowerShell tools and a cab (cabinet) file that comes bundled with Server 2008 or later Hyper-V hosts.

Before you start, open a PowerShell console as administrator.  Make sure Hyper-V is installed and you’re working from the management (host) OS. The management OS must be Server 2008R2 or newer and more recent than the VM OS you’re patching.  I tested this script with a Server 2012 host.

For default Hyper-V installs, the CAB containing the up-to-date integration components will be located in [HostDrive]:\windows\vmguest\support.  From there, choose your architecture; for my machine, I choose amd64.  X86 people, you’re files are there too.  This file contains all of the components built into the VM Guest ISO.  To update integration components offline, we’re only interested in the two cab files highlighted below.

There will be two files:

  • Windows6.x-HyperVIntegrationServices-x64.cab corresponds with Windows 7 and earlier guests. Tested: Server 2008 R2, Windows 7 (enterprise and enterprise sp1).
  • Windows6.2-HyperVIntegrationServices-x64.cab corresponds with windows 8 and Server 2012 guests. Tested: Server 2012, Windows 8.

Note: this process only works for Windows 2008R2 / Windows 7 and later operating systems. It works with both vhd and vhdx files.

You will need the path to this file.  From here on out I’ll refer to it as $integrationServicesCabPath.  If you pick the wrong one it will fail a version check without harming the guest.

$integrationServicesCabPath="C:\Windows\vmguest\support\amd64\Windows6.2-HyperVIntegrationServices-x64.cab"


The next step is to apply the cab to the offline VM.

First, you’ll need the path to your VM image, I’m going to refer to this as $virtualHardDiskToUpdate.

$virtualHardDiskToUpdate="D:\client_professional_en-us_vl.vhd"

Next, mount the image as a pass-through disk (unprotected data and direct I/O) and keep track of the disk number returned.

$diskNo=(Mount-VHD -Path $ virtualHardDiskToUpdate –Passthru).DiskNumber

Check to make sure the operational status is online and find the drive letter so we know which drive to patch.

(Get-Disk $diskNo).OperationalStatus

$driveLetter=(Get-Disk $diskNo | Get-Partition | Get-Volume).DriveLetter

In my case this returned “online” and “E” (stored in $driveLetter).  If you mounted a VM with Windows fully installed, the chances are good it’ll mount more than one drive depending on the VMs particular setup.  If this is the case, find the drive with all of the Windows OS files – apply the integration service update to that one.  If the status returns not online prepare the image by running:

Set-Disk $diskNo -IsOffline:$false -IsReadOnly:$false

Now the mounted VHD is ready to be patched.

Add-WindowsPackage -PackagePath $integrationServicesCabPath -Path ($driveLetter+":\")

You should see a blue progress bar at the top of PowerShell.  Enjoy watching the little yellow o’s fill your screen.  If the cab couldn’t apply, make sure you’re using the right version for your guest OS and the right drive.  If the VM is running, it will not patch.

Finally, dismount the VHD.  Notice you dismount using the image path and not the mounted drive letter.

Dismount-VHD -Path $virtualHardDiskToUpdate


Here’s a more reasonable, consolidated, PowerShell Script:

$virtualHardDiskToUpdate="D:\client_professional_en-us_vl.vhd"
$integrationServicesCabPath="C:\Windows\vmguest\support\amd64\Windows6.2-HyperVIntegrationServices-x64.cab"

#Mount the VHD
$diskNo=(Mount-VHD -Path $virtualHardDiskToUpdate –Passthru).DiskNumber

#Get the driver letter associated with the mounted VHD, note this assumes it only has one partition if there are more use the one with OS bits
$driveLetter=(Get-Disk $diskNo Get-Partition).DriveLetter

#Check to see if the disk is online if it is not online it
if ((Get-Disk $diskNo).OperationalStatus -ne 'Online')
{Set-Disk $MountedVHD.Number -IsOffline:$false -IsReadOnly:$false}

#Install the patch
Add-WindowsPackage-PackagePath $integrationServicesCabPath -Path ($driveLetter ":\")

#Dismount the VHD
Dismount-VHD-Path $virtualHardDiskToUpdate

Thank you to Taylor Brown (http://blogs.msdn.com/b/taylorb), for the script!

Cheers,
Sarah Cooley

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Is the process above almost replication the behavior of the SCVMM "Set-SCVirtualMachine -InstallVirtualizationGuestServices"? If so, then thank you very much.

    PS. The script has several errors due to incorrect spacing. Incorrect vs Correct:

    $diskNo=(Mount-VHD-Path$virtualHardDiskToUpdate -Passthru).DiskNumber

    $diskNo=(Mount-VHD -Path$virtualHardDiskToUpdate -Passthru).DiskNumber

    and

    Dismount-VHD-Path$virtualHardDiskToUpdate

    Dismount-VHD -Path$virtualHardDiskToUpdate

    DISM is required on the guest it seems, hence the Windows 2008R2 / Windows 7 requirement.

    Just tested with a Windows 2003 guest. Obviously, the result is:

    "Add-WindowsPackage : An error occurred. No operation was performed.

    Verify that DISM is installed properly in the image, and then try the operation again."

    Any suggestion on how to perform the same for Windows 2003 guests?

    Thank you. :)

  • Nice blog !!!

  • Thanks Jon, the formatting issues should be fixed.

    There isn't an easy way (that I know of) to do this on Windows 2003 guests.

  • Thanks

  • nice

  • The script has a typo. Add-WindowsPackage-PackagePath should be Add-WindowsPackage -PackagePath

  • This does not work at all. Are there better instructions for accomplishing this out in this cyberworld?

  • Larry, what problem are you seeing?

  • Definitely does NOT work in 2008 R2, but only in 2012 & above

  • Definitely does NOT work in 2008 R2, but only in 2012 & above

  • I get the following messages when I try to run the script:

    WARNING: Failed to add package C:\Windows\vmguest\support\amd64\Windows6.2-HyperVIntegrationServices-x64.cab
    WARNING: Add-WindowsPackage failed. Error code = 0x800f081e

    The VHD is 2008 R2 with integration services 6.1.7601.17514. It has three partitions, and when I go into disk manager, I see the OS partition as the G:\ drive.

    I am running the script on a 2012 R2 system @ 6.3.9600.16384.

    I see Operation Running" and a green bar appears, then the warning message appear.

    0x800f081e means package is not applicable.

    Any suggestions on how to resolve this? We are converting VM hosts to 2012 R2 and inserting integration services manually on all the VMs will be "quite tedious".

  • In addition to the warnings, PowerShell display these messages:

    WARNING: Failed to add package C:\Windows\vmguest\support\amd64\Windows6.2-HyperVIntegrationServices-x64.cab
    WARNING: Add-WindowsPackage failed. Error code = 0x800f081e
    Add-WindowsPackage : Add-WindowsPackage failed. Error code = 0x800f081e
    At line:15 char:1
    + Add-WindowsPackage -PackagePath $integrationServicesCabPath -Path "G:\"
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Add-WindowsPackage], COMException
    + FullyQualifiedErrorId : Microsoft.Dism.Commands.AddWindowsPackageCommand

  • Problem Solved!!! Needed to use the 6.x CAB for 2008 R2. the 6.2 CAB is for 2012.