Hi,
Need a powershell script to collect the below given info from virtual center.
vmname | ESX Name | memory(GB) | vCPU count | vNIC Count | IP address(all) | vmdk(s) size(GB) | Total vmdk size(GB) | Datastore name | Tools version | tools update | shares | reservations(MB) | limit(MB) | snapshot count | Guest OS
vmdk(s) size(GB) ---> Need all vmdk size of the vm seperated by "". EX: for a vm of 3 vmdk's of size 20,20,10GB each the output would be 2020+10
Datastore Name ---> Name of the datastore where VMX is located.
Tools update ---> Need status like old or updated
Hi LucD,
Thanks for this script, it's really useful.
I was wondering if it was possible to add something? I'm trying to figure it out in the inventory script below. I was wondering if you could help figure out a way to add a few columns in the script for drivepath, disk space and disk usage? I know it's possible based on this post:
http://communities.vmware.com/thread/292032
For example, (similar to the IP address and DatastoreURL), I was hoping to add a few fields where the number of drives are separated by commas for each VM?
VMname, drivepath, diskspace, diskusage, disk%
+++++++++++++++++++++++++++++++++++++++++
SomeVM, C:\,D:\, 50GB, 30GB, 40GB, 20GB, 80%,66.66%
Another(linux), / , 100GB, 75GB, 75%
So if you were reading the above, you could easily tell that the C: drive is 50GB in size, it's using 40GB and is 80% full.
I know it's possible based on the thread above but if I could incorporate it in this script, that would be perfect.
Keep up the great work!
Mike
Here you go, I hope that's what you were looking for.
The new lines are added at the end and all the properties start with GuestDisk
$allLines = @() # Line added
$null | Out-File "C:\vmnotfound.txt" Get-Content -Path "C:\vmnames.txt" | %{ $vm = Get-VM -Name $_ -ErrorAction SilentlyContinue if(!$vm){ $_ | Out-File "C:\vmnotfound.txt" -Append } else{ $VMResourceConfiguration = $VM | Get-VMResourceConfiguration
$VMHardDisks = $VM | Get-HardDisk
$HardDisksSizesGB = @() $Temp = $VMHardDisks | ForEach-Object { $HardDisksSizesGB += [Math]::Round($_.CapacityKB/1MB) } $VmdkSizeGB = ""
$Temp = $HardDisksSizesGB | ForEach-Object { $VmdkSizeGB += "$_+" } $VmdkSizeGB = $VmdkSizeGB.TrimEnd("+") $TotalHardDisksSizeGB = 0
$Temp = $HardDisksSizesGB | ForEach-Object { $TotalHardDisksSizeGB += $_ } $VMDKnames = @() $Temp = $VMHardDisks | ForEach-Object { $VMDKnames += $_.Filename.Split("/")[1] } $Snapshots = $VM | Get-Snapshot
$Report = "" | Select-Object VMname,vmCreatedByUser,vmCreatedDate,ESXname,ClusterName,MemoryGB,vCPUcount,vNICcount,vNICType, IPaddresses,VMXname,VMDKname,VmdkSizeGB,TotalVmdkSizeGB,DatastoreName,ToolsVersion,ToolsUpdate,NumCpuShares, CpuLimitMHZ,CpuReservationMHZ,NumMemShares,ReservationsMB,LimitMB,SnapshotCount,GuestOS,VLANid,Portgroup, RDMPath,GuestDisks,GuestDiskspaceGB,GuestDiskspaceUsedGB,GuestDiskspaceUsed $Report.VMName = $VM.name $Report.vmCreatedByUser = $VM.CustomFields["CreatedBy"] $Report.vmCreatedDate = $VM.CustomFields["CreatedOn"] $Report.ESXname = $VM.Host $Report.ClusterName = ($VM | Get-Cluster).Name $Report.MemoryGB = $VM.MemoryMB/1KB $Report.vCPUcount = $VM.NumCpu $Report.vNICcount = $VM.Guest.Nics.Count $report.vNicType = [string]::Join(',',($vm.NetworkAdapters | %{$_.Type})) $Report.IPaddresses = [string]::Join(',',$VM.Guest.IPAddress) $Report.VMXname = $vm.Extensiondata.Config.Files.VmPathName.Split("/")[1] $Report.VMDKname = [string]::Join(',',$VMDKnames) $Report.VmdkSizeGB = $VmdkSizeGB
$Report.TotalVmdkSizeGB = $TotalHardDisksSizeGB
$Report.DatastoreName = [string]::Join(',',($vm.Extensiondata.Config.DatastoreUrl | %{$_.Name})) $Report.ToolsVersion = $vm.Extensiondata.Config.Tools.ToolsVersion $Report.ToolsUpdate = $vm.Extensiondata.Guest.ToolsStatus $Report.NumCpuShares = $VMResourceConfiguration.NumCPUShares $Report.CpuLimitMHZ = &{if($VMResourceConfiguration.CpuLimitMhz -eq -1){"No Limit"}else{$VMResourceConfiguration.CpuLimitMhz}} $Report.CpuReservationMHZ = $VMResourceConfiguration.CpuReservationMhz $Report.NumMemShares = $VMResourceConfiguration.NumMemShares $Report.ReservationsMB = $VMResourceConfiguration.MemReservationMB $Report.LimitMB = &{if($VMResourceConfiguration.MemLimitMB -eq -1){"No Limit"}else{$VMResourceConfiguration.MemLimitMB}} $Report.SnapshotCount = (@($VM | Get-Snapshot)).Count $Report.GuestOS = $VM.Guest.OSFullName $Report.VLANid = [string]::Join(',',(Get-VirtualPortgroup -VM $vm | %{$_.VlanId})) $Report.Portgroup = [string]::Join(',',(Get-VirtualPortgroup -VM $vm | %{$_.Name})) $RDMPaths = $vm | Get-HardDisk | where {$_.DiskType -like "Raw*"} $Report.RDMPath = &{if($RDMPaths){[string]::Join(',',($RDMPaths | %{$_.ScsiCanonicalName}))}else{"No RDM"} } $Report.GuestDisks = [string]::Join(',',($VM.Guest.Disks | %{$_.Path})) $Report.GuestDiskspaceGB = [string]::Join(',',($VM.Guest.Disks | %{"{0:f0}" -f ($_.Capacity/1GB)})) $Report.GuestDiskspaceUsedGB = [string]::Join(',',($VM.Guest.Disks | %{"{0:f0}" -f (($_.Capacity - $_.FreeSpace)/1GB)})) $Report.GuestDiskspaceUsed = [string]::Join(',',($VM.Guest.Disks | %{"{0:p0}" -f (($_.Capacity - $_.FreeSpace)/$_.Capacity)})) $allLines += $Report # Line changed } } $allLines | Export-Csv "C:\VMreport.csv" -NoTypeInformation -UseCulture
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Great! That's it. Thanks LucD!
One quick comment. If Tools are not running there will be errors like this:
It's not really a big deal as I'm aware that VMware Tools should be installed on VMs so their supported. Is there a way we could add an if clause to this? Maybe if Toolsversion = 0, do not look for disk info?
Again, not a big deal at all because the export still succeeds and just leaves those values as 0 for guest.disk.
Thanks again!
Mike
Yes, you easily can add a test.
Something like this for example
$Report.GuestDiskspaceUsedGB = &{if($VM.Guest){[string]::Join(',',($VM.Guest.Disks | %{"{0:f0}" -f (($_.Capacity - $_.FreeSpace)/1GB)}))}}
When $VM.Guest is not $null, the expression will be calculated. Otherwise the property will be left empty.
You will have to do something similar for the other property that involves a division.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Great! Thanks again, LucD.
I have one more question regarding this excellent script. Say I wanted to run the script in a loop, i can do something like this (which I found elsewhere on this forum):
$viservers = "192.168.0.100", "192.168.0.200", "192.168.0.230", "192.168.0.240"
foreach ($singleViserver in $viservers)
$VMObject | Export-csv "$filelocation" -NoTypeInformation
The for loop works (it connects and disconnects to each of the 4 hosts). But when the $VMObject is exported to the CSV file, it only exports the last one (the 192.168.0.240 host).
Is there a way I can modify the loop so that it will export the data from all four hosts into one CSV file? That would be ideal.
Thanks again for your help.
Mike
That's probably because the script overwrites $VMObject everytime it goes trough the loop.
PowerCLI supports multiple connections
Just remove the complete loop and just provide the array of viservers to the connect-viserver cmdlet
$viservers = "192.168.0.100", "192.168.0.200", "192.168.0.230", "192.168.0.240"
Connect-VIServer $Viservers -user $username -password $password
###script goes here###
Disconnect-viserver
Hi Avlieshout,
Thanks for the speedy reply. I think I jumped the gun in posting my question because I tried one more thing after i posted and it worked!
Here's my solution:
$viservers = "192.168.0.100", "192.168.0.200", "192.168.0.230", "192.168.0.240"
foreach ($singleViserver in $viservers)
$FullReport | Export-csv "$filelocation" -NoTypeInformation
I simply added a new variable for FullReport and made it increment off VMObject. Then I exported the 'full report' instead of VMobject. Worked like a charm!
Thanks again for your quick reply.
Mike
Glad to hear that you've got it working!
You should definitely try my suggestion if you find the time. It will make your scripts a lot easier.
Hi LucD
Could you help in explaining what am I doing wrong here to replace the input vmnames.txt with the Get-VM command but am getting the errors attached in the error.txt file.
Unfortunately could not trace it to the exact reason why this would be happening. Any help is highly appreciated.
The first lines should be
$allLines = @() # Line added
Get-VM | ForEach-Object { $VMview = Get-View $_
...
The $VM variable you had in your version would only have a content at the end of the Foreach loop.
The lines above get the guests and place them in the pipeline.
The Foreach-Object will take the objects one-by-one, make the object accessible through the $_ variable and execute the Foreach-Object code block for each object.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi,
Could you add support for think provisioned disks with the same totaling as you've done for the current disks stats?
ie: list each disk thin provisioned size and total?
Thanks
Ray
Hi LucD,
Need your help for your good script for VM inventory.Its shows error and i need IP address too
[vSphere PowerCLI] C:\tmp> .\VM-inventory.ps1
Missing closing '}' in statement block.
At C:\tmp\VM-inventory.ps1:62 char:1
+ <<<<
+ CategoryInfo : ParserError: (CloseBraceToken:TokenId) [], ParseException
+ FullyQualifiedErrorId : MissingEndCurlyBrace
Thanks
Kumar
There was a curly brace missing.
Try the attached version.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Kumar,
it could be a simple copy paste error..
I was planning ot upload this latest version anyways for others to use.. try downloading this new file and see if it runs without errors for you.
Details:
Thanks for prompt response.Is it possible that script should prompt for my credential becuase while executing its taking default credential
for windows while VC having diffirent id and diffrent passwd with more previlge.
Thanks
Kumar
I need some assistance with grabbing just the MAC address of a given VM's Network Adapter 1 using powershell and then redirecting that output to a CSV file. I don't think I can use the scripts that have been posted on this thread because they involve getting the entire VM. I tried running the following:
Get-NetworkAdapter -VM <VM>
But this command spits out all of the NICs (I have 4 NICs) and a bunch of information I do not want. All I need is the MAC address of the first nic and to throw that information into a CSV file.
Thanks in advance for the help.
CJ
Hi LucD
Needed some help. with the attached script I am getting some errors and the macaddress being collected in the output is getting prefixed as follows. any help is highly appreciated.
Macaddress -->
Line 92 of the script.
output is:
VMMac == @{MacAddress=00:50:56:93:46:10}
errors i am getting
Exception calling "Join" with "2" argument(s): "Value cannot be null.
Parameter name: value"
At U:\Scripts\VMInventory-v4.ps1:47 char:50
+ $Report.vNicType = &{if($_.Guest){[string]::Join <<<< (',',($vm.NetworkAd
apters | %{$_.Type}))}}
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Exception calling "Join" with "2" argument(s): "Value cannot be null.
Parameter name: value"
At U:\Scripts\VMInventory-v4.ps1:58 char:52
+ $Report.GuestDisks = &{if($_.Guest){[string]::Join <<<< (',',($_.Guest.Di
sks | %{$_.Path}))}}
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
Attempted to divide by zero.
At U:\Scripts\VMInventory-v4.ps1:62 char:130
+ $Report.GuestDiskspaceUsed = &{if($_.Guest){[string]::Join(',',($_.Guest.
Disks | %{"{0:p0}" -f (($_.Capacity - $_.FreeSpace)/ <<<< $_.Capacity)}))}}
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
Exception calling "Join" with "2" argument(s): "Value cannot be null.
Parameter name: value"
At U:\Scripts\VMInventory-v4.ps1:62 char:63
+ $Report.GuestDiskspaceUsed = &{if($_.Guest){[string]::Join <<<< (',',($_.
Guest.Disks | %{"{0:p0}" -f (($_.Capacity - $_.FreeSpace)/$_.Capacity)}))}}
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
For the Join error, you should change this line
$Report.vNicType = &{if($_.Guest){[string]::Join(',',($vm.NetworkAdapters | %{$_.Type}))}}
into this
$Report.vNicType = &{if($_.Guest){[string]::Join(',',($_.NetworkAdapters | %{$_.Type}))}}
For the zero-divide error, it looks as if you have some VMs that zero-capacity harddisks.
Is that possible ?
You can try changing this line
$Report.GuestDiskspaceUsed = &{if($_.Guest){[string]::Join(',',($_.Guest.Disks | %{"{0:p0}" -f (($_.Capacity - $_.FreeSpace)/$_.Capacity)}))}}
into this
$Report.GuestDiskspaceUsed = &{if($_.Guest){[string]::Join(',',($_.Guest.Disks | where {$_.Capacity -ne 0} | %{"{0:p0}" -f (($_.Capacity - $_.FreeSpace)/$_.Capacity)}))}}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
How about above script to HTML? Thank you.
Basically when you replace the Export-CSV by a ConvertTo-Html | Set-Content, you should have a HTML file.
But the fancy formatting will require playing with style sheets and using the Body and Head parameters.
There are numerous examples in this community.
Alan's vCheck is a good example how far you can go in producing HTML reports.
Anything specific you're after ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference