Tag Archives: VMware

Adding VMware Tools to WinPE 4.0

I’m trying to augment the Bare Metal Recovery boot image provided by EMC as part of the NetWorker Client to support recovery in our VMware vSphere environment. The BMR .ISOs include a sources\boot.wim file that I should be able to modify.

I started with these somewhat date instructions in the VMware knowledgebase. I copied the contents of the .ISO file to a temporary directory on my PE Build system (Windows 8 guest). Using the Windows ADK, I mounted the sources\boot.wim file.

C:\Temp>dism /mount-image /imagefile:c:\temp\NW-MBR-ISO\sources\boot.wim /index:1 /mountdir:c:\temp\mount

I downloaded the latest VMware Tools, then used the /A switch (administrative install) on the setup file to extract the contents to a local folder. The driver files are contained within Program Files\VMware\VMware Tools\VMware\Drivers. I copied that directory to my working location, then added the drivers to the WIM files.

dism /image:c:\temp\mount /add-driver /driver:c:\temp\drivers /recurse

DISM reported success, so I committed the changes and umounted the WIM file.

dism /unmount-image /mountdir:c:\temp\mount /commit

The files I copied off of the EMC-provided ISO were not sufficient to create a new bootable image. So I used the CopyPE command to create a new base image, which included a file source for the PE image as well as the appropriate boot sector files. Since the image source files were identical to the file in the EMC disk image (because this is how they created the image), I just copied my customized boot.wim over the default boot.wim. Then I was able to use the makewinpemedia command to create a new .ISO image.

I’ve been able to boot the image, and it loaded the VMXNET3 like a champ. We’ll see how the Bare Metal Recover process goes. Thankfully, this is a test and not a crisis.

Which Disk is that volume on?

I administer a server VM with a lot of disks, and many of them are the same size. When I need to make changes to the system’s storage, I’m always nervous that I’m going to poke the wrong disk. I could trust that the order of the disks listed in the vSphere client is the same as the order that the guest OS lists (starting at 1 and 0 respectively). But I want a little more assurance.

Using diskpart, you can list the details for individual disks, partitions and volumes, but I wanted a report showing all the disks, the partitions on those disks, and the volumes residing on those partitions. I have reported some of this info previously, using PowerShell’s Get-WMIObject cmdlet to query the Win32_DiskDrive, Win32_Partition, and Win32_Volume classes. I figured there must me a way to correlate instances of these classes.

I found these two blog posts:

They did most of the heavy lifting in building the WQL ASSOCIATOR OF queries. I put together a short script to give me a little more detail. Here’s some sample output:

PS C:\local\scripts> .\Get-DiskInfo.ps1
Disk 0 - SCSI 0:0:2:0 - 45.00 GB
    Partition 0  100.00 MB  Installable File System
    Partition 1  44.90 GB  Installable File System
        C: [NTFS] 44.90 GB ( 3.46 GB free )
[...]
Disk 5 - SCSI 0:0:2:5 - 39.99 GB
    Partition 0  40.00 GB  Installable File System
        B: [NTFS] 40.00 GB ( 34.54 GB free )

This will make it easier to be sure about the vSphere storage element that corresponds to a particular volume (or, more accurately, the Physical Disk on which the volume resides).

Here’s the actual script:

<#
.SYNOPSIS
Get information about the physical disks and volumes on a system.

.DESCRIPTION
Get details about the physical disks and the volumes located on
those disks, to make it easier to identify corresponding vSphere
storage (VMDKs).

.EXAMPLE

PS C:\> .\Get-DiskInfo.ps1

.NOTES
    Author: Geoff Duke <Geoffrey.Duke@uvm.edu>
    Based on http://bit.ly/XowLns and http://bit.ly/XeIqFh
#>

Set-PSDebug -Strict

Function Main {

    $diskdrives = get-wmiobject Win32_DiskDrive | sort Index

    $colSize = @{Name='Size';Expression={Get-HRSize $_.Size}}

    foreach ( $disk in $diskdrives ) {

        $scsi_details = 'SCSI ' + $disk.SCSIBus         + ':' +
                                  $disk.SCSILogicalUnit + ':' +
                                  $disk.SCSIPort        + ':' +
                                  $disk.SCSITargetID
        write $( 'Disk ' + $disk.Index + ' - ' + $scsi_details +
                 ' - ' + ( Get-HRSize $disk.size) )

        $part_query = 'ASSOCIATORS OF {Win32_DiskDrive.DeviceID="' +
                      $disk.DeviceID.replace('\','\\') +
                      '"} WHERE AssocClass=Win32_DiskDriveToDiskPartition'

        $partitions = @( get-wmiobject -query $part_query | 
                         sort StartingOffset )
        foreach ($partition in $partitions) {

            $vol_query = 'ASSOCIATORS OF {Win32_DiskPartition.DeviceID="' +
                         $partition.DeviceID +
                         '"} WHERE AssocClass=Win32_LogicalDiskToPartition'
            $volumes   = @(get-wmiobject -query $vol_query)

            write $( '    Partition ' + $partition.Index + '  ' +
                     ( Get-HRSize $partition.Size) + '  ' +
                     $partition.Type
                   )

            foreach ( $volume in $volumes) {
                write $( '        ' + $volume.name + 
                         ' [' + $volume.FileSystem + '] ' + 
                         ( Get-HRSize $volume.Size ) + ' ( ' +
                         ( Get-HRSize $volume.FreeSpace ) + ' free )'
                       )

            } # end foreach vol

        } # end foreach part

        write ''

    } # end foreach disk

}

#--------------------------------------------------------------------
function Get-HRSize {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$True, ValueFromPipeline=$True)]
        [INT64] $bytes
    )
    process {
        if     ( $bytes -gt 1pb ) { "{0:N2} PB" -f ($bytes / 1pb) }
        elseif ( $bytes -gt 1tb ) { "{0:N2} TB" -f ($bytes / 1tb) }
        elseif ( $bytes -gt 1gb ) { "{0:N2} GB" -f ($bytes / 1gb) }
        elseif ( $bytes -gt 1mb ) { "{0:N2} MB" -f ($bytes / 1mb) }
        elseif ( $bytes -gt 1kb ) { "{0:N2} KB" -f ($bytes / 1kb) }
        else   { "{0:N} Bytes" -f $bytes }
    }
} # End Function:Get-HRSize

Main

Please let me know if you find this helpful.

Capture Windows VM memory dump in ESX

I’m working with Microsoft to identify a problem I’m seeing with LSASS, possibly related to the VSS snapshot created by our backup software. At this point, I need to be able to capture the memory state on the system, even if I can’t log into the box.

There are several ways to trigger a crash in order to collect a memory dump, but this system is a guest running in VMWare VSphere (ESX4). I asked VMWare support, and they pointed me to KB article 1009187, Generating a Windows core dump from an ESX virtual machine.

I configured my test system guest to crash and collect a memory dump on an NMI event, then used the vmdumper command to send the NMI to the guest.

It worked like a champ:

vm-crash-nmi

I verified the integrity of the dump file with dumpchk. It looks good. I’m setting the same thing up on my production guest.

Domain Controller Blue Screen

CDC02-STOP During an upgrade of our VMware ESX infrastructure, I ran into an issue with our domain controllers. As part of the process we needed to upgrade the virtual hardware that is part of the guest vm. After updating the domain controller guest’s VMware Tools software, I shut down the guest and select Upgrade virtual hardware. Things looked good, so then I powered on the guest and it started to boot. After a moment, it threw a quick bluescreen and auto-rebooted.

My first order of business was to change the auto-reboot option so I could actually see the error message. I know now that I could just hit F8 during the boot process. However, I did it the hard way.

 

I booted to the Windows 2008 install media, and ran regedit from the recovery environment. I loaded the HKLM hive, and set the HKLM\SYSTEM\CurrentControlSet\Control\CrashControl\AutoReboot DWORD value to 0 (zero). I see in the KB 307973 article that there’s also a wmic command that will set the option. I don’t know if wmic is available in the WinPE recovery mode.

Continue reading