rtunisi
Contributor
Contributor

Weird issues on VM HardDisk information Script

hello everyone

i am designing some simple script to retrieve VM Hard Disk information with PowerCli and i got some pretty weird issue: i ocasionally get runtime execution errors with vc server disconnection, but after the error, i can retrieve info on the same vcenter with simple commands (like Get-VM for instance). The vc farms still available over viclient and powercli all the time, so it must be something on the code


the steps i use to reproduce the strange behavior:

(Using Powercli 5.5 and Powershell 3.0. Error still happens with Powercli 5.1)

- Connect to vcenter (multiple servers)

- run the command and it eventually gets stuck in line 12 ($ghd = Get-HardDisk (Get-VIObjectByVIView $VMView)) with the error 'Server XXXX is disconnected'

- Run some other command (like get-vm) to certify that server is still connected

sample script is below

Function Get-VMDiskInfo {

  [CmdletBinding()]

  Param (

  [Parameter(Mandatory=$true,

  ValueFromPipeline=$True,

  ValueFromPipelineByPropertyName=$true)]

  [Alias('Name')]

  $VM

  )

  PROCESS{

  $VMView = Get-View -ViewType VirtualMachine -Filter @{"Name" = $VM}

  $ghd = Get-HardDisk (Get-VIObjectByVIView $VMView)

    $output = @()

  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})){

  $VMSummary = “” | Select  VM,Disk, SCSI, DiskType, DiskFormat, DiskSizeGB, DiskFile

  $VMSummary.VM = $VM

  $VMSummary.SCSI = [string]::Concat($VirtualSCSIController.BusNumber,":",$VirtualDiskDevice.UnitNumber)

  $VMSummary.Disk = $VirtualDiskDevice.DeviceInfo.Label

  #pegando info do Get-Harddisks

  $d = $ghd | ? {$_.Name -match $VirtualDiskDevice.DeviceInfo.Label}

  $VMSummary.DiskType = $d.DiskType

  $VMSummary.DiskSizeGB = [Math]::Round($d.capacityGB,2)

  $VMSummary.DiskFile = $d.filename

  if($d.Disktype -eq "Flat"){

  $VMSummary.DiskFormat = $d.StorageFormat

  }

    

  $output += $VMSummary

            }

  }

            Write-Output $output

  }

}

does anyone have any idea whats going on ?


almost forgot, sorry about the messy code and the poor english...


thanks in advance


Tags (3)
Reply
0 Kudos
LucD
Leadership
Leadership

You mention that you have multiple connections to vSphere servers open.

Are these all vCenters, or are they ESXi servers ?

Could it be that 1 such connection was dropped after the error ?

You could insert a

$global:DefaultVIServers.Count

before and after line 12 to check if that is the case.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
rtunisi
Contributor
Contributor

these are all vcenters, multiple versions (4.1, 5.0 and 5.1)

its really odd that i can use Get-VM on the same server that it claimed disconnection with no errors, something like this:

1) Connected to 3 vCenters: vc01, vc02 and vc03

2) Run script and i get the error 'vc01 is not connected'

3) Get-VM vm01 (which happens to be at 'vc01', that just disconnected) and it retrieves it normally

edit:

ran the command with the modifications to troubleshoot disconnection like you said, and no disconnections at all ! All the 15 vCenters still connected while running the command

The exception is below

Get-VIObjectByVIView : 25/09/2013 11:25:27    Get-VIObjectByVIView        Server XXXXX is not connected.

Reply
0 Kudos
LucD
Leadership
Leadership

I suspect it might be an issue with the Get-VIObjectByVIView cmdlet.

Do you also get the error when you replace line 12 by

$ghd = Get-HardDisk -VM $VM


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
rtunisi
Contributor
Contributor

the issue does not occur when i substitute the command parameter, however, the execution time went thru the roof, as i expected.

Seconds           : 24

Milliseconds      : 93

(Measure-Command Statistic)

I believe thats because of the string parameter, that forces get-harddisk cmdlet to create a VirtualMachine object (i believe it calls Get-VM, which is very, VERY slow. Thats why i used the Get-View with -ViewType in the first place).


Luc, is there anyway i can make this quickier without the Get-VIObjectByVIView? I tested many options while creating this script and this proved to be the most efficient one, with runtimes around 1 to 2 seconds in the same environment (as i said, the script randomly fails with the disconnection issue, sometimes i can make it work and its pretty fast )






Reply
0 Kudos
LucD
Leadership
Leadership

Try like this

Function Get-VMDiskInfo {

    [CmdletBinding()]

    Param (

        [Parameter(Mandatory=$true,

            ValueFromPipeline=$True,

            ValueFromPipelineByPropertyName=$true)]

        [Alias('Name')]

        $VM

    )

    PROCESS{

        $VMView = Get-View -ViewType VirtualMachine -Filter @{"Name" = $VM}

        $output = @()

        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})){

                $VMSummary = “” | Select VM,Disk, SCSI, DiskType, DiskFormat, DiskSizeGB, DiskFile

                $VMSummary.VM = $VM

                $VMSummary.SCSI = [string]::Concat($VirtualSCSIController.BusNumber,":",$VirtualDiskDevice.UnitNumber)

                $VMSummary.Disk = $VirtualDiskDevice.DeviceInfo.Label

                #pegando info do Get-Harddisks

                $VMSummary.DiskType = &{

                        switch -regex ($VirtualDiskDevice.Backing.GetType().Name){

                        "Flat" {

                            "Flat"

                            if($VirtualDiskDevice.Backing.ThinProvisioned){$VMSummary.DiskFormat = "Thin"}

                            else{$VMSummary.DiskFormat = "Thick"}}

                        "Raw" {

                            "Raw" + $VirtualDiskDevice.Backing.CompatibilityMode.TrimEnd("Mode")

                        }

                        Default {"Unknown"}

                        }

                }

                $VMSummary.DiskSizeGB = [Math]::Round(($VirtualDiskDevice.CapacityInKb/1MB),2)

                $VMSummary.DiskFile = $VirtualDiskDevice.Backing.FileName

                $output += $VMSummary

            }

        }

        Write-Output $output

    }

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

Reply
0 Kudos
rtunisi
Contributor
Contributor

simple code and trully brilliant... less than 1 second execution time

didnt know about the &{} construct... will look closely to this

Thanks really much for the PCLI lesson, Mr Dekens.. going back to study book Smiley Happy

Reply
0 Kudos
LucD
Leadership
Leadership

The & is the call operator, it executes the scriptblock that follows (everything between the curly braces).


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos