VMware Cloud Community
snteran
Contributor
Contributor

Get VM info - Drives / Disk space / Free Space / OS / WWN

I have been working on a report that captures VM information utilizing "Get-WmiObject" which requires that I provide login credentials for different domains.  This causes errors and other issues that takes a lot of manual input and very time cosuming which takes away from the automation we are trying to implement.

I'm working with PowerCLI and trying to find ways to get my current report utilizing scripting connecting to vsphere.

I've done a lot of googling and have not come across any scripts or ideas on how to get my needed data utilizing powerCLI without having to use some of the powershell objects like WMI.

any help/advice would be greatly appreciated.

Thanks,

Reply
0 Kudos
19 Replies
snteran
Contributor
Contributor

I have come across a script that will work, just need to add the WWN (PortWorldWideName) and could use some help:

Get-VM | Select Name, NumCPU, MemoryMB, ProvisionedSpaceGB, UsedSpaceGB, @{N=”ESX Host”;E={Get-VMHost -VM $_}}, @{N=”Datastore”;E={Get-Datastore -VM $_}}, @{N=”Guest OS”;E={Get-VMGuest -VM $_}} | export-csv C:\vmhostInfoByVM.csv

What I need to do is add one more column for WWN, using the same configuration in the "@" portion:

@{N=”WWPN”;E={Get-VMHostHba -VM $_}}

I have a current script that gets the WWN utilizing the information below but i'm not able to figure out what parts are needed and how to implement them in the portion above to get the WWN's for each VM:

$vm = Get-VM $computer

                $ESX = Get-VMHost -name $vm.VMhost.name

                $Hbas = Get-VMhostHba -vmhost $ESX -Type FibreChannel

               

                $Hbas |

                    ForEach-object {

                        $Hba=$_

                        $wwns += "{0:x}" -f $Hba.PortWorldWideName

                    }

                   

                $Wwpn = $wwns -join ' '

Any help on understanding components of this added part and how to think it through to get the WWN's in a separate column would be greatly appreciated.

Reply
0 Kudos
LucD
Leadership
Leadership

Try like this

    @{N="WWN";E={

        [string]::Join(',',(Get-VMHost VM $_ | Get-VMHostHba -Type Fibrechannel | %{

            "{0:X}" -f $_.PortWorldWideName}))}}


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

Reply
0 Kudos
snteran
Contributor
Contributor

Hey LucD,

thank you again for your assistance.

I tried to figure out my error but still not sure of the "in method call"

Missing ')' in method call.

At line:1 char:250

+ Get-VM $vm | Select Name, NumCPU, MemoryMB, ProvisionedSpaceGB, UsedSpaceGB, @{N=”ESX Host”;E={Get-VMHost -VM $_}}, @

{N=”Datastore”;E={Get-Datastore -VM $_}}, @{N=”Guest OS”;E={Get-VMGuest -VM $_}},@{N="WWN";E={[string]::Join(',',(Get-V

MHost VM $_ ) <<<< | Get-VMHostHba -Type Fibrechannel | %{"{0:X}" -f $_.PortWorldWideName})}} | export-csv c:\scripts\s

chTasks\Disk_allocation_report\vmGuestInfo.csv

    + CategoryInfo          : ParserError: (CloseParenToken:TokenId) [], ParentContainsErrorRecordException

    + FullyQualifiedErrorId : MissingEndParenthesisInMethodCall

It appears that a couple of closing Parenthesis were missing.  I added but looks like i'm still missing something.

btw - my hope is to move the results to a database, have you moved a powercli result to a database before?  I was at PDXVMUG yesterday and I saw a great presentation on something similar and thought it would be awesome to move this information to a DB to then allow others to view over an internal site.  Just curious, once i begin that process I can start a new thread.

Thanks,

Reply
0 Kudos
LucD
Leadership
Leadership

My mistake, some parenthesis were dropped during my copy/paste.

I corrected the code above, please try again.


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

Reply
0 Kudos
snteran
Contributor
Contributor

Well with a LOT of help from the community, especially LucD, I have a working copy of a script to help us keep track of VM's.  We use this to help track SAN space as well as VM monitoring in the environment.

param (

    [parameter(Mandatory = $true, ValueFromPipeline = $true )]

    [alias("InputObject", "VirtualMachine")]

    [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VirtualMachineImpl[]]$VM

    )

    process {

    $VM | ForEach-Object {

        $vmPV            = $_ | Get-Member

        $vmview         = $_ | Get-View

        $vmDisks        = (($_.Guest.Disks | %{$_.CapacityGB - $_.FreeSpaceGB} | Measure-Object -Sum | Select -ExpandProperty Sum)).ToString("N2")

        $totalSpace        = (($_.HardDisks | Measure-Object -Sum CapacityGB ).Sum).ToString("N2")

        $freeSpace        = (($_.Guest.Disks | Measure-Object -Sum FreeSpaceGB ).Sum).ToString("N2")

        $OSsize         = $_.guest.OSFullName

        $subtractedAmt    = if ($OSsize -like '*2003*' -or $OSsize -like '*2000*') { 60 } else {80}

        $wwn            = (Get-VMHost -VM $_ | Get-VMHostHba -Type Fibrechannel | %{"{0:X}" -f $_.PortWorldWideName})

        $VMProp = @{

            Name            = $_.Name

            VirtualPhysical    = if ($vmPV) {'V'} else {'P'}

            MemoryMB        = $_.MemoryMB

            TotalSpace        = $totalSpace

            FreeSpace        = $freeSpace

            PerentageUsed    = (($vmDisks / $totalSpace) * 100).ToString("N2")

            DiskSpaceUsed    = $vmDisks           

            NumCPU             = $_.NumCpu

            SubtractedAmt    = $subtractedAmt

            BillableAmt        = $totalSpace - $subtractedAmt

            OSName            = $vmview.config.GuestFullName

            WWN                = $wwn

        }

        New-Object PSObject -Property $VMProp

        }

    }

   

The only drawback to using the hash table as I found out, that you can't keep the order as I have it listed.

So when I run this script: get-vmhost vmhostName | get-vm | .\scriptName.ps1 | export-csv vmexport.csv


I am still a newbie and will continue to look towards this community and the web to keep developing my skill set.

Reply
0 Kudos
LucD
Leadership
Leadership

A quick solution is to use a Select-Object before the Export-Csv cmdlet.

That allows you to specify the order of the properties.

get-vmhost vmhostName | get-vm | .\scriptName.ps1 |

Select Name,VirtualPhysical,MemoryMB,TotalSpace,FreeSpace,PercentageUsed,DiskSpaceUsed,NumCPU,SubtractedAmt,BillableAmt,OSName,WWN |

export-csv vmexport.csv

Since PowerShell v3 there is now the [ordered] option, that maintains the order of the properties of the object.


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

Reply
0 Kudos
esxi1979
Expert
Expert

I got an error

Bad numeric constant: 1,164.00.

At C:\xxx\vm-disk-free.ps1:43 char:44

+             PerentageUsed    = (($vmDisks / <<<<  $totalSpace) * 100).ToString("N2")

    + CategoryInfo          : InvalidOperation: (1,164.00:String) [], RuntimeException

    + FullyQualifiedErrorId : BadNumericConstant

Reply
0 Kudos
esxi1979
Expert
Expert

Got 1 more diff

You cannot call a method on a null-valued expression.

At C:\xxxt\vm-disk-free.ps1:23 char:95

+         $freeSpace        = (($_.Guest.Disks | Measure-Object -Sum FreeSpaceGB ).Sum).ToString <<<< ("N2")

    + CategoryInfo          : InvalidOperation: (ToString:String) [], RuntimeException

    + FullyQualifiedErrorId : InvokeMethodOnNull

I copied the script to above ps1 file & ran as

get-vmhost -location xxx | get-vm | .\vm-disk-free.ps1 |

Select Name,VirtualPhysical,MemoryMB,TotalSpace,FreeSpace,PercentageUsed,DiskSpaceUsed,NumCPU,SubtractedAmt,BillableAmt,OSName,WWN |export-csv vmexport.csv

Reply
0 Kudos
esxi1979
Expert
Expert

also its taking huge time for cluster with  30 odd vms last 12 min & couting

Reply
0 Kudos
snteran
Contributor
Contributor

Yes, the script does take a long time to run with the added WWN component.  If you remove that aspect, it should run a bit faster.

One thing i just noticed, when I run the script without exporting, I get the WWN numbers.  However when I export-csv , it returns a Cell with:

pastedImage_0.png

going to do some additional testing.

As for the other error, i believe that might have to do with a template or blank vmdk file.  I need to update the script to include for powered on VM's and no templates.  Again, just a guess, still in the process of learning.

Reply
0 Kudos
LucD
Leadership
Leadership

The square brackets on there indicate that you are trying to export an array into the CSV.

And the Export-Csv cmdlet doesn't know how to translate an array to a single column value, it will tell you by displaying this System.Object[] entry in the cell.


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

Reply
0 Kudos
esxi1979
Expert
Expert

i did ctrl+z & it moved head ..

PercentageUsed

was empty

I did not understand the logic for

SubtractedAmtBillableAmt

Please guide

Reply
0 Kudos
snteran
Contributor
Contributor

thank you for the explanation LucD, I have updated and testing now:

$wwn   = ((Get-VMHost -VM $_ | Get-VMHostHba -Type Fibrechannel | %{"{0:X}" -f $_.PortWorldWideName}) -join ',')

As far as the logic, this script is to show how to gather some information from vcenter.  Logic is an internal necessity.

Reply
0 Kudos
esxi1979
Expert
Expert

I would not need WWN as well if i am using it for juts seeing space left for corrective action .

Ya got it for :-

SubtractedAmt

BillableAmt

Reply
0 Kudos
snteran
Contributor
Contributor

Just to confirm, that worked.  Adding the -join did the trick.

I must credit my source - Avoiding System.Object[] (or Similar Output) when using Export-Csv | Learn Powershell | Achieve More

The script does take sometime to run but this has been a great learning opportunity.  Next step, setup a daily task to run powershell on a server and send specific information to a database.

Reply
0 Kudos
esxi1979
Expert
Expert

I removed the ToString("N2")  stuff & the errors stopped coming

    #$vmDisks    = (($_.Guest.Disks | %{$_.CapacityGB - $_.FreeSpaceGB} | Measure-Object -Sum | Select -ExpandProperty Sum)).ToString("N2")
    #$totalSpace    = (($_.HardDisks | Measure-Object -Sum CapacityGB ).Sum).ToString("N2")
    #$freeSpace    = (($_.Guest.Disks | Measure-Object -Sum FreeSpaceGB ).Sum).ToString("N2")
  
   $vmDisks    = (($_.Guest.Disks | %{$_.CapacityGB - $_.FreeSpaceGB} | Measure-Object -Sum | Select -ExpandProperty Sum))
    $totalSpace    = (($_.HardDisks | Measure-Object -Sum CapacityGB ).Sum)
    $freeSpace    = (($_.Guest.Disks | Measure-Object -Sum FreeSpaceGB ).Sum)
Reply
0 Kudos
snteran
Contributor
Contributor

Hello LucD, I hope you don't mind a direct question about my ultimate goal.  This report is just for an overview of our existing VM's, however we have several other servers that are not VM's and I was thinking I could write a local ps script to extract specific wmi information and then send to a central DB where I can later create a web page.

I came across your post and wanted to see if this is the correct path to get to my ultimate goal.

Re: writing on sql db

Thanks,

Reply
0 Kudos
LucD
Leadership
Leadership

No problem.

So if I understand correctly, you want to retrieve information from all servers in your environment, be they virtual or physical.

That is perfectly possible if a couple of conditions are met:

  • all servers should be running a Windows OS
  • WMI calls to each server must be permitted

With the WMI calls, you can retrieve information from the servers.

For example, teh following code will query AD to find all stations whose name starts with 'Srv', and then display the name of the station, and wether or not it is a physical or virtual (vSPhere based) box.

Get-ADComputer -LDAPFilter "(name=Srv*)" | %{

    Get-WmiObject -Class Win32_ComputerSystem -ComputerName $_.Name |

    Select Name,Domain,@{N='HW';E={

        if($_.Model -match '^VMware'){'virtual'}else{'physical'}

    }}

}


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

Reply
0 Kudos
snteran
Contributor
Contributor

Thank you for the information.  We currently have a VB script that is installed on all servers and sends a lot of vital server information to a sql database.  The information covers Server name, OS version to local user accts, installed apps and soon on.  All our servers are Windows and I was thinking we might be able to transfer from the VB script to a powershell that would include a bit more information.  We lack some patching information as well as some other requested data.  I figured if I was going to pull information, I would try to create a new DB with all of the data so it could be pulled from one location.  The person who created the VB script is long gone and no one knows where the original code is located.  I saw a demonstration on something very similar and thought I check with you.

Thanks again for all your assistance

Reply
0 Kudos