I am sure there is a way to do this but im new to powershell. I would like to know how to combine get-vm and get-disk results so i can output to one line per server. The only way i saw so far was 3 seperate loops one for get-vm info one for get-disk and one for extensiondata.guest.disk info (part of get-vm but seperate). I have removed them sense that made output to a csv look like crud. I currently am pulling the values per machine which give me multiple values for disk for example and diskpath etc and i want to out put them independently but all on one line per server. So server1 i would like to get all disk, vm info, extension data and put it in different cells but one line if possilbe. Also the ability to format the data with /1 gb etc switches would be nice. Right now extension data is as is or i get a system error about operator not found naming the math operator i as trying to use division in particular since kb is not pretty to read for disk space.
Here is the working sample not pretty but works. Is there a way to do combine the cmdlets so output will be easier. Right now i can't format some of the data since it is a system object vs the seperate values for each object if that makes sense.
$LogFile = $LogPath + (Get-Date -Format "yyyy-MM-dd_HHmmss-") + "VcVmDiskInfo.csv"
"Virtual Center VM Information " + "`r`n" | Out-File $LogFile -Append
"Name `t Host `t DataStore `t Provisioned Space `t Used Space `t Disk Name `t VmDK Name `t Format `t Persistence `t DiskType `t Capacity GB `t Partition Path `t Capacity GB `t Free Space `n" | Out-File $LogFile -Append
Import-CSV $importCSV | Foreach-Object{
$strComputer = $_.computer
$VM = get-vm $strComputer | Select name,VmHost,ProvisionedSpaceGB,UsedSpaceGB,DatastoreIdList,ExtensionData,guest,disk
$Disk = Get-HardDisk $strComputer | Select filename,storageFormat,persistence,disktype,Capacitykb,name
#Write-Host $vm.name $disk.storageformat.count $vm.DatastoreIdList
foreach($object in $VM){
$Name= $object.name
$vmhost = $object.vmhost
$datastoreidList = $object.datastoreidList
$provisionedspacegb = $object.provisionedspacegb
$usedspacegb = $object.usedspacegb
$output = "$name `t $vmhost `t $datastoreidlist `t $provisionedspacegb `t $usedspacegb `t"
$vmdk = $disk.filename
$DiskFormat = $disk.storageFormat
$DiskPersistence = $disk.persistence
$DiskType = $disk.disktype
$Capacity = $disk.capacitykb
$diskName = $disk.name
$vmdiskpath = $VM.extensiondata.guest.disk.diskpath
$vmdiskcapacity = $VM.extensiondata.guest.disk.capacity
$vmdiskfreespace=$VM.extensiondata.guest.disk.freespace
#$capacityGB = "{0:N2}" -f ($disk.Capacity /1024/1024)
$output = $output + "$diskName `t $vmdk `t $diskFormat `t $DiskPersistence `t $DiskType `t $Capacity `t $vmdiskpath `t $vmdiskcapacity `t $vmdiskfreespace" | Out-File $logfile -Append
}
}
If you want the output in a CSV file, the easiest way is to use a Select-Object cmdlet.
On the Select-Object cmdlet you can select the properties from the object that was fed into the cmdlet ($vm in this case), but you can also use "calculated properties" to do in fact whatever you want. Such as retrieving values from other objects (the $hd for example).
Since the outer loop is a ForEach, there will be no objects in the pipeline. To force that the script uses the call operator (&).
$LogFile = $LogPath + (Get-Date -Format "yyyy-MM-dd_HHmmss-") + "VcVmDiskInfo.csv"
&{Import-CSV $importCSV | %{
$vm = Get-Vm $_.computer
$hd = Get-HardDisk -VM $vm
$vm | Select Name,VMHost,DatastoreIdList,ProvisionedSpaceGB,UsedSpaceGB,
@{N="DiskName";E={$hd.Name}},
@{N="DiskFormat";E={$hd.StorageFormat}},
@{N="Persistence";E={$hd.Persistence}},
@{N="DiskType";E={$hd.DiskType}},
@{N="CapacityGB";E={[math]::Round(($hd.Capacity/1GB),2)}},
@{N="VMDK";E={$hd.FileName}},
@{N="VMDiskPath";E={$_.extensiondata.guest.disk.diskpath}},
@{N="VMDiskCapacity";E={$_.extensiondata.guest.disk.capacity}},
@{N="VMDiskFreeSpace";E={$_.extensiondata.guest.disk.freespace}}
}} | Export-Csv $LogFile -NoTypeInformation -UseCulture
Note that this script will have problems when you have VMs that have more than 1 harddisk.
In that case you need an additional loop over all the harddisks.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks i'll play with this. I was close but the formating in the script is one area i went wrong. I was doing old shcool vbscript type format then output. What is the call operator that threw me haven't see that one yet.
how would i get the loop to keep adding to the output? the select puts the info in the cells but how do i get @{n="DiskName";E= for example to append to what the select statement added. I tried to add a foreach under that for $hd and i was back where i started pretty much.
$vm | Select Name,VMHost,DatastoreIdList,ProvisionedSpaceGB,UsedSpaceGB,
@{N="DiskName";E={$hd.Name}},
@{N="DiskFormat";E={$hd.StorageFormat}},
@{N="Persistence";E={$hd.Persistence}},
@{N="DiskType";E={$hd.DiskType}},
@{N="CapacityGB";E={[math]::Round(($hd.Capacity/1GB),2)}},
@{N="VMDK";E={$hd.FileName}},
@{N="VMDiskPath";E={$_.extensiondata.guest.disk.diskpath}},
@{N="VMDiskCapacity";E={$_.extensiondata.guest.disk.capacity}},
@{N="VMDiskFreeSpace";E={$_.extensiondata.guest.disk.freespace}}
I'm not 100% sure I understood the question correctly, but the Select cmdlet should be in the inner ForEach loop.
Something like this
Foreach($vm in $vms) {
foreach($hd in Get-HardDisk -VM $vm){
Select ....
}
}
This of course will mean that the same VM information will appear in each row for each harddisk of that VM.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference