Search code examples
powershellvmwarevcenter

Powershell Match virtual hard disks in Virtual Center with their disk labels


I would like to match the drive in the windows os to the vCenter *.vmdk.

Here is a link for the informations I need. I find no way to get "Location 192 (Bus Number 0, Target Id 0, LUN 0)" with powershell (info from disk). From the WMI I don't get this information...

Can someone help?





The modified script:

$Vm = "VMName"
if (($VmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = $Vm})) {

    $Out = Get-WmiObject -Class win32_diskdrive -Property Index, SCSIPort, SCSITargetId -ComputerName $Vm 
    #Invoke-VMScript "wmic path win32_diskdrive get Index, SCSIPort, SCSITargetId /format:csv" -vm $VM -scripttype "bat"
        foreach ($VirtualSCSIController in ($VMView.Config.Hardware.Device | where {$_.DeviceInfo.Label -match "SCSI-Controller"})) {
            foreach ($VirtualDiskDevice in ($VMView.Config.Hardware.Device | where {$_.ControllerKey -eq $VirtualSCSIController.Key})) {
                $VirtualDisk = "" | Select SCSIController, DiskName, SCSI_Id, DiskFile,  DiskSize, WindowsDisk
                $VirtualDisk.SCSIController = $VirtualSCSIController.DeviceInfo.Label
                $VirtualDisk.DiskName = $VirtualDiskDevice.DeviceInfo.Label
                $VirtualDisk.SCSI_Id = "$($VirtualSCSIController.BusNumber) : $($VirtualDiskDevice.UnitNumber)"
                $VirtualDisk.DiskFile = $VirtualDiskDevice.Backing.FileName
                $VirtualDisk.DiskSize = $VirtualDiskDevice.CapacityInKB * 1KB / 1GB
                # Match disks based on SCSI ID
                $DiskMatch = $Out | ?{($_.SCSIPort - 2) -eq $VirtualSCSIController.BusNumber -and $_.SCSITargetID -eq $VirtualDiskDevice.UnitNumber}
                if ($DiskMatch){
                    $VirtualDisk.WindowsDisk = "Disk $($DiskMatch.Index)"
                }
                else {Write-Host "No matching Windows disk found for SCSI id $($VirtualDisk.SCSI_Id)"}
                $DiskInfo += $VirtualDisk
            }
        }
        $DiskInfo | Out-GridView 


I had to change $DiskMatch = $Out | ?{($_.SCSIPort - 2) -eq <-- Replace - 1 with - 2.
And put an "-" between SCSI Controller by {$_.DeviceInfo.Label -match "SCSI-Controller"})). Why do I have to subtract 2 from the SCSIPort?


Solution

  • The following script will match the local windows disk with the vmWare disk.

    Date                          : 2017.10.27 21:28:01
    vCenterName                   : vCenterName
    vmName                        : SERVER
    vmWareSCSIController          : SCSI controller 0
    wmWareSCSIID                  : 0 : 0
    vmWareDiskName                : Hard disk 1
    vmWareDiskFile                : [Datastore] vm.vmdk
    vmWareSizeGB                  : 40
    WindowsSerialNumber           : WindowsSerialNumber
    WindowsSCSIBus                : 0
    WindowsSCSILogicalUnit        : 0
    WindowsSCSIPort               : 2
    WindowsSCSITargetId           : 0
    WindowsDisk                   : \\SERVER\root\cimv2:Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE0"
    WindowsDriveLetter            : C:
    WindowsLocicalDiskSizeGB      : 39.9980430603027
    WindowsLocicalDiskFreeSpaceGB : 9.30975723266602
    WindowsLocicalDiskUsedSpaceGB : 30.6882858276367
    
    
    
    #Variables
    $Vm = Get-VM -Name 'VMName'
    $ComputerName = 'ComputerName'
    
    $obj_DiskDrive = @()
    $obj_LogicalDisk = @()
    $obj_LogicalDiskToPartition = @()
    $obj_DiskDriveToDiskPartition = @()
    $obj_VMView = @()
    $obj_DiskInfos = @()
    
    
    #Get wmi objects
    $obj_DiskDrive = Get-WmiObject -Class win32_DiskDrive -ComputerName $ComputerName
    $obj_LogicalDisk = Get-WmiObject -Class Win32_LogicalDisk -ComputerName $ComputerName
    $obj_LogicalDiskToPartition = Get-WmiObject -Class Win32_LogicalDiskToPartition -ComputerName $ComputerName
    $obj_DiskDriveToDiskPartition = Get-WmiObject -Class Win32_DiskDriveToDiskPartition -ComputerName $ComputerName
    
    #Get vm               
    $obj_VMView = Get-View -ViewType VirtualMachine -Filter @{"Name" = "$($Vm.Name)"}
    
    #Get vm disk
    $obj_VMDisk = Get-HardDisk -VM $Vm
    
    #Match the informations      
    foreach ($obj_vmWareSCSIController in ($obj_VMView.Config.Hardware.Device | Where-Object -FilterScript {$_.DeviceInfo.Label -match "SCSI"})) 
    {
        foreach ($obj_vmWareDiskDevice in ($obj_VMView.Config.Hardware.Device | Where-Object -FilterScript {$_.ControllerKey -eq $obj_vmWareSCSIController.Key})) 
        {                                    
            $obj_tempDiskInfos = "" | Select-Object -Property Date, vCenterName, vmName, vmWareSCSIController, wmWareSCSIID, vmWareDiskName, vmWareDiskFile,
                vmWareSizeGB, WindowsSerialNumber, WindowsSCSIBus, WindowsSCSILogicalUnit, WindowsSCSIPort, WindowsSCSITargetId, WindowsDisk, WindowsDriveLetter,
                WindowsLocicalDiskSizeGB, WindowsLocicalDiskFreeSpaceGB, WindowsLocicalDiskUsedSpaceGB
    
            #Select WMI object
            $obj_currentDiskDrive = @()
            $obj_currentDiskDrive = $obj_DiskDrive | Where-Object -FilterScript {$_.SerialNumber -eq $obj_vmWareDiskDevice.Backing.Uuid.Replace("-","")}
    
            $obj_currentDiskDriveToDiskPartition = @()
            $obj_currentDiskDriveToDiskPartition = $obj_DiskDriveToDiskPartition | Where-Object -FilterScript {$_.Antecedent -eq $obj_currentDiskDrive.Path}
    
            $obj_currentLogicalDiskToPartition = @()
            $obj_currentLogicalDiskToPartition = $obj_LogicalDiskToPartition | Where-Object -FilterScript {$_.Antecedent -eq $obj_currentDiskDriveToDiskPartition.Dependent}
    
            $obj_currentLogicalDisk = @()
            $obj_currentLogicalDisk = $obj_LogicalDisk | Where-Object -FilterScript {$_.Path.Path -eq $obj_currentLogicalDiskToPartition.Dependent}
    
            #Select vmWare object
            $obj_CurrentvmWareHarddisk = @()
            $obj_CurrentvmWareHarddisk = $obj_VMDisk | Where-Object -FilterScript {$_.Name -eq $obj_vmWareDiskDevice.DeviceInfo.Label}
    
            #Generate output
            $obj_tempDiskInfos.Date = Get-Date -Format "yyyy.MM.dd HH:mm:ss"
            $obj_tempDiskInfos.vCenterName = $defaultVIServer.Name
            $obj_tempDiskInfos.vmName = $Vm.Name
            $obj_tempDiskInfos.vmWareSCSIController = $obj_vmWareSCSIController.DeviceInfo.Label
            $obj_tempDiskInfos.wmWareSCSIID = "$($obj_vmWareSCSIController.BusNumber) : $($obj_vmWareDiskDevice.UnitNumber)"
            $obj_tempDiskInfos.vmWareDiskName = $obj_vmWareDiskDevice.DeviceInfo.Label
            $obj_tempDiskInfos.vmWareDiskFile = $obj_vmWareDiskDevice.Backing.FileName
            $obj_tempDiskInfos.vmWareSizeGB = $obj_CurrentvmWareHarddisk.CapacityGB              
            $obj_tempDiskInfos.WindowsSerialNumber = $obj_currentDiskDrive.SerialNumber
            $obj_tempDiskInfos.WindowsSCSIBus = $obj_currentDiskDrive.SCSIBus
            $obj_tempDiskInfos.WindowsSCSILogicalUnit = $obj_currentDiskDrive.SCSILogicalUnit
            $obj_tempDiskInfos.WindowsSCSIPort = $obj_currentDiskDrive.SCSIPort
            $obj_tempDiskInfos.WindowsSCSITargetId = $obj_currentDiskDrive.SCSITargetId
            $obj_tempDiskInfos.WindowsDisk = $obj_currentDiskDrive.Path.Path
            $obj_tempDiskInfos.WindowsDriveLetter = ($obj_currentLogicalDisk).Caption
            $obj_tempDiskInfos.WindowsLocicalDiskSizeGB = $obj_currentLogicalDisk.Size / 1GB
            $obj_tempDiskInfos.WindowsLocicalDiskFreeSpaceGB = $obj_currentLogicalDisk.FreeSpace / 1GB
            $obj_tempDiskInfos.WindowsLocicalDiskUsedSpaceGB = ($obj_currentLogicalDisk.Size / 1GB) - ($obj_currentLogicalDisk.FreeSpace / 1GB)
    
            $obj_DiskInfos += $obj_tempDiskInfos
        }
    }
    
    $obj_DiskInfos