I am trying to write a simple script to write out some data. I normally don't use Export-Csv, but I am for this report. I went back and read about how Export-Csv may output data like [System.Object] and [System.String], depending on how Powershell sees the data. For the IPaddres section, I was getting them, and then I made the adjustment for it to output the write way, but for the hard drive data, I can't get it to work.
Since some VMs have multiple drives, I see that Powershell shows it has a FlatHardDiskImpl, but I don't know how to get it to output correctly into the csv file. I have tried many things for the hard drive section: subexpression, Select-Object, Array @(), but I can't get export-csv to show both drives. I really thought I would get this by now, but there is still so much more to learn. Here is the script.
Hello, DZ1-
If you are looking to get a list of disk sizes in the 'HD(GB)' property of the $Report object, you can change the line that you mention that you cannot get to work correctly to something like:
...
$Report.'HD(GB)' = ($VMS.HardDisks | %{[Math]::Round($_.CapacityKB/1MB,1)}) -join ","
...
That should get you the given VM's hard disk size(s) in that property.
And, later, you talk about the New-Object cmdlet. Here is an example of using this cmdlet in your script:
&{Get-VM | Foreach {
$vm = $_
New-Object -TypeName PSObject -Property @{
VMname = $vm.name
IPs = ($vm.guest | %{$_.IPaddress}) -join ","
FQDN = $vm.guest.HostName
OStype = $vm.Guest.OSFullname
"Memory(GB)" = $vm.MemoryMB / 1KB
CPU = $vm.NumCPU
"HDs(GB)" = ($vm | Get-HardDisk | %{[Math]::Round($_.CapacityKB/1MB,1)}) -join ","
} ## end new-object
}} | Export-Csv -NoTypeInformation -UseCulture C:\file.csv
ii C:\file.csv
By using New-Object, you do not need to store things, you do not need to add them to an array, so you can help keep memory usage down in your scripts (not that you will run your client machine out of memory, but you can cause scripts to fail with System.OutOfMemoryException errors). And, you can see how it is a bit cleaner with less repetitive typing. I also used the Get-HardDisk cmdlet here, as the .HardDisks property is obsolete.
How do these examples do for you?
Does this helps
Connect-VIServer MYVISERVER$MyCollection = @()$AllVMs = Get-View -ViewType VirtualMachine | Where {-not $_.Config.Template}$SortedVMs = $AllVMs | Select *, @{N="NumDisks";E={@($_.Guest.Disk.Length)}} | Sort-Object -Descending NumDisksForEach ($VM in $SortedVMs){$Details = New-object PSObject$Details | Add-Member -Name Name -Value $VM.name -Membertype NoteProperty$DiskNum = 0Foreach ($disk in $VM.Guest.Disk){$Details | Add-Member -Name "Disk$($DiskNum)path" -MemberType NoteProperty -Value $Disk.DiskPath$Details | Add-Member -Name "Disk$($DiskNum)Capacity(MB)" -MemberType NoteProperty -Value ([math]::Round($disk.Capacity/ 1MB))$Details | Add-Member -Name "Disk$($DiskNum)FreeSpace(MB)" -MemberType NoteProperty -Value ([math]::Round($disk.FreeSpace / 1MB))$DiskNum++}$MyCollection += $Details}$MyCollection | Out-GridView# Export-Csv, ConvertTo-Html or ConvertTo-Xml can be used above instead of Out-GridviewHere is the author of the script
http://www.virtu-al.net/2010/01/27/powercli-virtual-machine-disk-usage/
Thanks, the information you sent isn't quite what I need, but it did give me an idea. I tried to incorporate this into my script:
$Report.'HD(GB)' = $VMS | Foreach { ($_ | Get-HardDisk) | Foreach { $HD = New-Object PSObject; $HD | Add-Member -MemberType NoteProperty -Name Drive -Value $_.CapacityKB } }
I'm hoping that I am on the right track here, I have not used the New-Object cmdlet much, but it is something that I know I need to learn more about.
Hello, DZ1-
If you are looking to get a list of disk sizes in the 'HD(GB)' property of the $Report object, you can change the line that you mention that you cannot get to work correctly to something like:
...
$Report.'HD(GB)' = ($VMS.HardDisks | %{[Math]::Round($_.CapacityKB/1MB,1)}) -join ","
...
That should get you the given VM's hard disk size(s) in that property.
And, later, you talk about the New-Object cmdlet. Here is an example of using this cmdlet in your script:
&{Get-VM | Foreach {
$vm = $_
New-Object -TypeName PSObject -Property @{
VMname = $vm.name
IPs = ($vm.guest | %{$_.IPaddress}) -join ","
FQDN = $vm.guest.HostName
OStype = $vm.Guest.OSFullname
"Memory(GB)" = $vm.MemoryMB / 1KB
CPU = $vm.NumCPU
"HDs(GB)" = ($vm | Get-HardDisk | %{[Math]::Round($_.CapacityKB/1MB,1)}) -join ","
} ## end new-object
}} | Export-Csv -NoTypeInformation -UseCulture C:\file.csv
ii C:\file.csv
By using New-Object, you do not need to store things, you do not need to add them to an array, so you can help keep memory usage down in your scripts (not that you will run your client machine out of memory, but you can cause scripts to fail with System.OutOfMemoryException errors). And, you can see how it is a bit cleaner with less repetitive typing. I also used the Get-HardDisk cmdlet here, as the .HardDisks property is obsolete.
How do these examples do for you?
Thank you so much, I used ' $Report.'HD(GB)' = ($VMS.HardDisks | % {[Math]::Round($_.CapacityKB/1MB,1) }) -join "," ' and it worked perfectly. Just when I think I'm doing great, a problem occurs and I get stuck, I was on a Powershell roll, and then someone asked me for Excel output, and I quickly knew I still doin't know Jack about Powershell. I'm glad it happened though, the experience will make me go back and learn more.
Thanks again for your help, I really appreciate it.