Hi,
I'm trying to create a script that will provide some General VM info.
I'm collecting this information as I'm about to perform an SRM failover and want to have as much info about each VM as is necessary in case I need to rebuild anything from Scratch :smileycry:
I've put the following together and it works except
For example, my script produced the following output for HDD's in the VM
HDD Info : {@{Name=Hard disk 1; Filename=[VMFS_IRL_1] Server1/Server1_2.vmdk; CapacityGB=40}, @{Name=Hard disk 2;
Filename=[VMFS_IRL_1] Server1/Server1_1.vmdk; CapacityGB=90}}
I would prefer the following for each VM's Hard Disk info
HDD1 Name | HDD1 Path | HDD1 CapacityGB | HDD2 Name | HDD2 Path | HDD2 CapacityGB | HDD3 Name |
---|---|---|---|---|---|---|
Hard disk 1 | [VMFS_IRL_1] Server1/Server1_2.vmdk | 40 | Hard disk 2 | [VMFS_IRL_1] Server1/Server1_1.vmdk | 90 |
Here's the script
$content = get-vm (Get-Content C:\Temp\vmList.txt)
foreach($Computer in $content){
$GeneralProp=[ordered]@{
'ComputerName'=$computer.Name;
'PowerState'=$Computer.PowerState;
'OS'=$Computer.GuestId;
'VMware Tools'=$Computer.Guest.ToolsVersion;
'Num CPU'=$Computer.NumCpu;
'Memory GB'=$Computer.MemoryGB;
'Host'=$Computer.VMHost;
'ResourcePool'=$Computer.ResourcePool;
'Num HDD'=$Computer.HardDisks.Count;
'HDD Info'=$Computer | Get-HardDisk | select Name, Filename, CapacityGB;
'Num NIC'=$Computer.NetworkAdapters.Count;
'NIC Info'=$Computer | Get-VirtualPortGroup | select VirtualSwitch, vlanID, Name;
'NIC IP'=$Computer.Guest.IPAddress;
}
$Obj=New-Object -TypeName PSObject -Property $GeneralProp
Write-Output $Obj
}
Any help would be great,
Thanks
You should collect each $obj in an array, and then write the array to a CSV.
Something like this
$content = get-vm (Get-Content C:\Temp\vmList.txt)
$report = @()
foreach($Computer in $content){
$GeneralProp=[ordered]@{
'ComputerName'=$computer.Name;
'PowerState'=$Computer.PowerState;
'OS'=$Computer.GuestId;
'VMware Tools'=$Computer.Guest.ToolsVersion;
'Num CPU'=$Computer.NumCpu;
'Memory GB'=$Computer.MemoryGB;
'Host'=$Computer.VMHost;
'ResourcePool'=$Computer.ResourcePool;
}
$hdd = 1
$Computer | Get-HardDisk | foreach {
$GeneralProp.Add("HDD$($hdd) Name",$_.Name)
$GeneralProp.Add("HDD$($hdd) Path",$_.FileName)
$GeneralProp.Add("HDD$($hdd) Capacity",$_.CapacityGb)
$hdd++
}
$nic = 1
$Computer | Get-VirtualPortGroup | foreach {
$GeneralProp.Add("NIC$($nic) vSwitch",$_.VirtualSwitch)
$GeneralProp.Add("NIC$($nic) PortGroup",$_.Name)
$GeneralProp.Add("NIC$($nic) VLAN ID",$_.VlanID)
$GeneralProp.Add("NIC$($nic) IP", $Computer.Guest.IPAddress[$nic-1])
$nic++
}
$report += New-Object -TypeName PSObject -Property $GeneralProp
}
$report | Export-Csv C:\Temp\SRM\VMdetails.csv -NoTypeInformation
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Try like this
$content = get-vm (Get-Content C:\Temp\vmList.txt)
foreach($Computer in $content){
$GeneralProp=[ordered]@{
'ComputerName'=$computer.Name;
'PowerState'=$Computer.PowerState;
'OS'=$Computer.GuestId;
'VMware Tools'=$Computer.Guest.ToolsVersion;
'Num CPU'=$Computer.NumCpu;
'Memory GB'=$Computer.MemoryGB;
'Host'=$Computer.VMHost;
'ResourcePool'=$Computer.ResourcePool;
'Num HDD'=$Computer.HardDisks.Count;
'HDD Info'=$Computer | Get-HardDisk | select Name, Filename, CapacityGB;
'Num NIC'=$Computer.NetworkAdapters.Count;
'NIC Info'=$Computer | Get-VirtualPortGroup | select VirtualSwitch, vlanID, Name;
'NIC IP'=$Computer.Guest.IPAddress;
}
$i = 1
$Computer | Get-HardDisk | %{
$GeneralProp.Add("HDD$($i) Name",$_.Name)
$GeneralProp.Add("HDD$($i) Path",$_.FileName)
$GeneralProp.Add("HDD$($i) Capacity",$_.CapacityGb)
$i++
}
$Obj=New-Object -TypeName PSObject -Property $GeneralProp
$Obj
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
Thanks for the advice on this. What you advised worked and I was able to use it to also get some needed Network Config information.
The script is almost working 100%, there's just one small issue. It only returns the information for a single VM, despite a list of VM's being given in C:\Temp\vmList.txt
The line $content = get-vm (Get-Content C:\Temp\vmList.txt) works.
When I output $content I see the entire list of VM names, their PowerState, Num CPUs and MemoryGB
I would expect the foreach($computer in $content) loop to iterate for every VM but, it doesn't for some reason.
I just get the results that I need for a single (random) VM in the list.
Can you see what's wrong with the following ?
$content = get-vm (Get-Content C:\Temp\vmList.txt)
foreach($Computer in $content){
$GeneralProp=[ordered]@{
'ComputerName'=$computer.Name;
'PowerState'=$Computer.PowerState;
'OS'=$Computer.GuestId;
'VMware Tools'=$Computer.Guest.ToolsVersion;
'Num CPU'=$Computer.NumCpu;
'Memory GB'=$Computer.MemoryGB;
'Host'=$Computer.VMHost;
'ResourcePool'=$Computer.ResourcePool;
}
$hdd = 1
$Computer | Get-HardDisk | foreach {
$GeneralProp.Add("HDD$($hdd) Name",$_.Name)
$GeneralProp.Add("HDD$($hdd) Path",$_.FileName)
$GeneralProp.Add("HDD$($hdd) Capacity",$_.CapacityGb)
$hdd++
}
$nic = 1
$Computer | Get-VirtualPortGroup | foreach {
$GeneralProp.Add("NIC$($nic) vSwitch",$_.VirtualSwitch)
$GeneralProp.Add("NIC$($nic) PortGroup",$_.Name)
$GeneralProp.Add("NIC$($nic) VLAN ID",$_.VlanID)
$GeneralProp.Add("NIC$($nic) IP", $Computer.Guest.IPAddress[$nic-1])
$nic++
}
$Obj=New-Object -TypeName PSObject -Property $GeneralProp
$Obj | Export-Csv C:\Temp\SRM\VMdetails.csv -NoTypeInformation
}
You should collect each $obj in an array, and then write the array to a CSV.
Something like this
$content = get-vm (Get-Content C:\Temp\vmList.txt)
$report = @()
foreach($Computer in $content){
$GeneralProp=[ordered]@{
'ComputerName'=$computer.Name;
'PowerState'=$Computer.PowerState;
'OS'=$Computer.GuestId;
'VMware Tools'=$Computer.Guest.ToolsVersion;
'Num CPU'=$Computer.NumCpu;
'Memory GB'=$Computer.MemoryGB;
'Host'=$Computer.VMHost;
'ResourcePool'=$Computer.ResourcePool;
}
$hdd = 1
$Computer | Get-HardDisk | foreach {
$GeneralProp.Add("HDD$($hdd) Name",$_.Name)
$GeneralProp.Add("HDD$($hdd) Path",$_.FileName)
$GeneralProp.Add("HDD$($hdd) Capacity",$_.CapacityGb)
$hdd++
}
$nic = 1
$Computer | Get-VirtualPortGroup | foreach {
$GeneralProp.Add("NIC$($nic) vSwitch",$_.VirtualSwitch)
$GeneralProp.Add("NIC$($nic) PortGroup",$_.Name)
$GeneralProp.Add("NIC$($nic) VLAN ID",$_.VlanID)
$GeneralProp.Add("NIC$($nic) IP", $Computer.Guest.IPAddress[$nic-1])
$nic++
}
$report += New-Object -TypeName PSObject -Property $GeneralProp
}
$report | Export-Csv C:\Temp\SRM\VMdetails.csv -NoTypeInformation
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD, you are The Man
I started thinking that I needed to collect everything in an array and, spent the last hour or two attempting it.
I only succeeded in making the code look ugly!
Your solution was simple, efficient and clean.
Thank you so mush, you've (again) made my life that bit easier
One thing to note, the Export-Csv cmdlet takes the first row in the array to determine how many columns there will be.
So if your first VM only has 1 harddisk, and subsequent VMs have more than 1 harddisk, you might be missing columns in the CSV.
One way to fix this is to sort the array on the number of properties, in descending order.
The last line could be
$report |
Sort-Object -Property {$_.Count} -Descending |
Export-Csv C:\Temp\SRM\VMdetails.csv -NoTypeInformation
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I had exactly that problem :smileyconfused:
Thanks for following up before I had the chance to ask for more help
nope, still struggling i'm afraid
I've even piped $report to get-member to see what I could use as a counter, it only lists a max of two HDDs and a single NIC (even though some VM's have multiple NICS)
more help needed please
Seems to be working for me.
Can you check a couple of things ?
How many rows in $report
$report.Count
And how many properties in each row in $report
$report | %{$_.Count}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
For $report.Count i'm getting a value of 67
This matches what I get for $content.Count
For $report | %{$_.Count} i don't get any value at all
What's strange is that when I try this in the ISE, it doesn't Tab Complete the command. That is, I type $report | %{$_.Cou and hit Tab, it doesn't complete the spelling for Count ?
If I output $report to the display, it 100% has all the required information
I've attached a copy of the full script that i'm running, in case there are any silly typo's or brackets in the wrong places
Thanks
My mistake, the objects that are in the array do not have a counter.
Try with these lines
$report |
Sort-Object -Property {($_ | Get-Member -MemberType NoteProperty).Count} -Descending |
Export-Csv C:\Temp\SRM\VMdetails.csv -NoTypeInformation
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I gave it another go, still without success.
I added a Count into the array for the number of Hard Disks
foreach($Computer in $content){
$GeneralProp=[ordered]@{
'ComputerName'=$computer.Name;
'PowerState'=$Computer.PowerState;
'OS'=$Computer.GuestId;
'VMware Tools'=$Computer.Guest.ToolsVersion;
'Num CPU'=$Computer.NumCpu;
'Memory GB'=$Computer.MemoryGB;
'Host'=$Computer.VMHost;
'ResourcePool'=$Computer.ResourcePool;
'Num HDD'=$Computer.HardDisks.Count;
}
Some VM's have up to 12 Hard Disks
At the end, when piping into the .csv, I tried the following
$report | Sort-Object -Property {$GeneralProp.'Num HDD'} -Descending | Export-Csv 'C:\Temp\SRM\SRM VM Details - sorted.csv'
Still the same result, only information for two Hard Disks displayed in the .csv.
I'm thinking that maybe the Details of first VM inserted into the $report array only contains 2 Hard Disks and that it's the $report array that isn't able to grow.
Does this make Sense ?
I assume you missed my last reply ?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference