VMware Cloud Community
astrolab
Contributor
Contributor
Jump to solution

List VMs and their datastores

I took a stab at listing all VMs in my VC with the datastores where their vmdks are located:

$report = @()

$allvms = Get-VM

foreach ($vm in $allvms) {

$row = "" | select VMNAME, DATASTORE

$row.VMNAME = $vm.name

{color:#ff0000}$row.DATASTORE = (Get-VM | get-datastore)

$report += $row

}

$report | Export-Csv "C:\vm_ds.csv" -NoTypeInformation

No luck. I know the problem is with the get-datastore cndlet, The file shows the VMNAME column populated with the VMs as expected, but the DATASTORE column reports System.Object[].

Any help would be appreciated.

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

You are already in a loop through all the guests (the foreach loop in line 3), so there is no need to get (again) all the guest with the Get-VM cmdlet in the 6th line.

You can just pass the guest (i $vm) to the Get-Datastore cmdlet in that line

The System.Object[] entry in the CSV file is caused by the fact that the Export-CSV cmdlet doesn't know how to handle objects or arrays of objects.

A solution is to loop through all the datastore names that are returned.

And store the datastore name in the DATASTORE property.

The result is that there will be multiple lines in the CSV file for guests that have more than 1 datastore.

$report = @()

$allvms = Get-VM
foreach ($vm in $allvms) {
	$dstores = $vm | Get-Datastore
	foreach($ds in $dstores){
		$row = "" | select VMNAME, DATASTORE
		$row.VMNAME = $vm.name
		$row.DATASTORE = $ds.Name
		$report += $row
	}
}

$report | Export-Csv "C:\vm_ds.csv" -NoTypeInformation


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

View solution in original post

0 Kudos
10 Replies
LucD
Leadership
Leadership
Jump to solution

You are already in a loop through all the guests (the foreach loop in line 3), so there is no need to get (again) all the guest with the Get-VM cmdlet in the 6th line.

You can just pass the guest (i $vm) to the Get-Datastore cmdlet in that line

The System.Object[] entry in the CSV file is caused by the fact that the Export-CSV cmdlet doesn't know how to handle objects or arrays of objects.

A solution is to loop through all the datastore names that are returned.

And store the datastore name in the DATASTORE property.

The result is that there will be multiple lines in the CSV file for guests that have more than 1 datastore.

$report = @()

$allvms = Get-VM
foreach ($vm in $allvms) {
	$dstores = $vm | Get-Datastore
	foreach($ds in $dstores){
		$row = "" | select VMNAME, DATASTORE
		$row.VMNAME = $vm.name
		$row.DATASTORE = $ds.Name
		$report += $row
	}
}

$report | Export-Csv "C:\vm_ds.csv" -NoTypeInformation


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

0 Kudos
astrolab
Contributor
Contributor
Jump to solution

LucD,

What does the += in $report += $row stand for?

And the "" in $row = "" | select VMNAME, DATASTORE ?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The first is shorthand notation for

$report = $report + $row

The 2nd is the initialisation of the variable $row with an empty string.


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

astrolab
Contributor
Contributor
Jump to solution

Thank you.

0 Kudos
jasonrobinson
Enthusiast
Enthusiast
Jump to solution

If I wanted to add the Cluster Name for each vm to this report how would I go about doing that? Thanks for any input.

I think I might have figured it out, please tell me if this looks correct?

$report = @()

$allvms = Get-VM

foreach ($vm in $allvms) {

$dstores = $vm | Get-Datastore

foreach($ds in $dstores){

$cluster = $vm | Get-Cluster

foreach ($clus in $cluster){

$row = "" | select VMNAME, DATASTORE, CLUSTER

$row.VMNAME = $vm.name

$row.DATASTORE = $ds.Name

$row.CLUSTER = $clus.name

$report += $row

}

}

}

$report | Export-Csv "C:\vm_ds.csv" -NoTypeInformation

Jason @jrob24
0 Kudos
esarakaitis
Enthusiast
Enthusiast
Jump to solution

try this:

get-cluster |`
  %{$cluster = $_; get-vm -Location $_ |
    %{$vm = $_; $dsNames = get-datastore -vm $_ | % {$_.name};
      write-host $cluster.name $vm.name $dsNames
    }
  }

http://www.vmwarescripting.com

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The Get-Cluster cmdlet returns an object.

You would probably only want the name of the cluster.

You could do that like this

$report = @() 
$allvms = Get-VM 
foreach ($vm in $allvms) { 
        $clusterName = ($vm | Get-Cluster).Name
        $dstores = $vm | Get-Datastore 
        foreach($ds in $dstores){ 
                $row = "" | select VMNAME, DATASTORE, Cluster 
                $row.VMNAME = $vm.name 
                $row.DATASTORE = $ds.Name 
                $row.Cluster = $clusterName
                $report += $row 
        } 
} 
$report | Export-Csv "C:\vm_ds.csv" -NoTypeInformation 


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

0 Kudos
jasonrobinson
Enthusiast
Enthusiast
Jump to solution

Guys,

Thanks for your help, one thing I noticed is that it takes a very long time for the script to run and return the info, is there anyway I can speed it up?

Jason @jrob24
0 Kudos
esarakaitis
Enthusiast
Enthusiast
Jump to solution

0 Kudos
jasonrobinson
Enthusiast
Enthusiast
Jump to solution

LMAO....so true, I was just hoping there was something else up your sleeve.

Jason @jrob24
0 Kudos