Hello:
I am wondering how to find (and count later) all VMs that have 2 or more VMDKs on different datastore...
Thanks,
qwert
Argh, you will allways see that the only line in my script that I didn't test, the Export-CSV cmdlet, gives you trouble. The next script I tested from the beginning to the end and gives even better output:
$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 | ` Sort-Object -Property VMName,Datastore -Unique | ` Group-Object -Property VMName | ` Where-Object { $_.Count -gt 1 } | ` Foreach-Object { foreach ($Record in $_.Group) {$Record } } | ` Export-Csv "C:\VM_DS.csv" -NoTypeInformation
Update: I saw that the first line was missing, so I added the first line to the script.
Message was edited by: RvdNieuwendijk
The attached script gets the VM's with vmdk's on more then one datastore.
I have to attach the script because it contains square brackets and the forum software has problems with them.
This script worked great for me. Simple script and it tells you the "VMNAME, DATASTORE, Cluster". If a VM has 2 VMDKs, it just lists the VM on 2 lines, obviously 2nd line shows the other VMDK file. Creates a CSV file in the root of C. You can change it to whatever you like.
$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
The attached script counts the VM's with vmdk's on more then one datastore.
I have to attach the script because it contains square brackets and the forum software has problems with them.
Regards, Robert
Folks,
Thanks a lot for your help!!!
I like this script very much:
$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
However, I cannot figure out how to collect only VMs with vmdks different datastore... I know I should use "-Unique" but could not figure out where...
Any help will be really appreciated.
Thanks,
qwert
Try to change this line
$dstores = $vm | Get-Datastore
into this
$dstores = $vm | Get-Datastore | Select-Object -Unique
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
The next script will do the job:
$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 | ` Sort-Object -Property VMName,Datastore -Unique | ` Group-Object -Property VMName | ` Where-Object { $_.Count -gt 1 } | ` Export-Csv "C:\VM_DS.csv" -NoTypeInformation
Regards, Robert
Luc,
No, it did not change anything at all...
I still have report of all VMs with 2 or more vmdks, but if VM has 2 (or more) vmdks on the same datastore it's still listed in the report, but only once... and I do not to have it in the report at all...
Thanks,
qwert
Oh, I see. Got your question wrong then.
Robert's latest script will do what you want.
The where-clause in there will get rid of VMs who are only using 1 datastore.
____________
Blog: LucD notes
Twitter: lucd22
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Robert,
Looks like onle VMs with vmdks on different datastore were selected. However report does not have any information right now about VMs name, datastore name and cluster...
Instead it give something like that:
System.Collections.ArrayList,2,System.Collections.ObjectModel.Collection`1[http://System.Management.Automation.PSObject|http://System.Management.Automation.PSObject],myvirtualMachine_name
Thanks,
qwert
Argh, you will allways see that the only line in my script that I didn't test, the Export-CSV cmdlet, gives you trouble. The next script I tested from the beginning to the end and gives even better output:
$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 | ` Sort-Object -Property VMName,Datastore -Unique | ` Group-Object -Property VMName | ` Where-Object { $_.Count -gt 1 } | ` Foreach-Object { foreach ($Record in $_.Group) {$Record } } | ` Export-Csv "C:\VM_DS.csv" -NoTypeInformation
Update: I saw that the first line was missing, so I added the first line to the script.
Message was edited by: RvdNieuwendijk
Robert,
Thanks a lot!!!
It's exactly what I was looking for!!!
Thanks again,
qwert
Inspired by a post by Jason Major, jmajor1111, in thread I came to an even more simple solution:
Get-VM | ` ForEach-Object { $vm = $_ $Datastores = $vm | Get-Datastore $Count = ($Datastores | Measure-Object).Count if ($Count -ge 2) { foreach ($ds in $Datastores) { $Report = "" | Select-Object -Property VmName, Datastore, Cluster $Report.VmName = $vm.Name $Report.Datastore = $ds.Name $Report.Cluster = ($vm | Get-Cluster).Name $Report } } }
I even found a bug in the previous script. If you have two VMs with the same name in two different clusters, with both VMs having only one datastore, the previous script will show these VMs. The new script does not.