VMware Cloud Community
VirtualNoitall
Virtuoso
Virtuoso

really slow performance or bad code?

Hello,

I am no programmer so feel free to sharply criticize the following code without holding back -):

foreach ($ds in Get-Datastore -Name datastore*) {

$a = 0

foreach ($vm in get-VM -Datastore $ds){

$a++}

Write-Host $ds.Name " VMs: " $a " Capacity: " $ds.CapacityMB " Free: " $ds.FreeSpaceMB

}

All I want to to is iterate through the datstores and find out the number of VMs, the free space and the capacity for each. The later two are actually available by just querying the datastore but I don't think the first is so I wrote what you see above. I have probably 100 datastore of which roughly half follow the naming scheme that would include them in the query. This seemed pretty straigh forward but the query takes over an hour to run Smiley Sad

The long running part is the querying of each included datastore for VMs so I can count them. Does the beta perform poorly or is there a better way to get what I am after?

Thanks!

0 Kudos
25 Replies
halr9000
Commander
Commander

Oh, duh, I wasn't really reading your script closely. What you need to do is to do the Get commands only once if you can help it. I see that you are doing get-vm at the top, and get-vm | get-view at the bottom. There's actually much to be optimized with this script, especially as your environment is so large. My lab's not on at the moment, I'll play with this later if Luc doesn't beat me to it.






[PowerShell MVP|https://mvp.support.microsoft.com/profile=5547F213-A069-45F8-B5D1-17E5BD3F362F], VI Toolkit forum moderator

Author of the upcoming book: Managing VMware Infrastructure with PowerShell

Co-Host, PowerScripting Podcast (http://powerscripting.net)

Need general, non-VMware-related PowerShell Help? Try the forums at PowerShellCommunity.org

My signature used to be pretty, but then the forum software broked it. vExpert. Microsoft MVP (Windows PowerShell). Author, Podcaster, Speaker. I'm @halr9000
0 Kudos
ykalchev
VMware Employee
VMware Employee

Hi,

I can recommend following optimization changes:

1. Getting datastoreview should be done before foreach loop since it's same for all vms. This will save you 1 server call for each vm.

2. You don't need get-vm before pipe to get-view when you already have $vm object. You can just pipe $vm object to get-view cmdlet. This will boost you script because as you noticed get-vm | get-view is a slow operation even for 1 vm in a large environment. If you accept datastore object as input parameter you can do the same with $dastoreView

$ds_origin = $args[0]
$ds_destination = $args[1]
$datastoreview = $ds_destination | get-view
foreach ($vm in get-vm -datastore $ds_origin)
{
$relocationSpec = new-object VMware.Vim.VirtualMachineRelocateSpec
$relocationSpec.Datastore = $datastoreView.MoRef

$vmview = $vm | get-view
$vmView.RelocateVM_Task($relocationSpec)
}

Regards,

Yasen

Yasen Kalchev, vSM Dev Team
0 Kudos
yboychev
Hot Shot
Hot Shot

Hi Milk Man,

You can make some improvements to you script in order to boost the performance. Here are my suggestions:

$ds_origin = $args[0]

$ds_destination = $args[1]

#get the view object corresponding to the destination datastore

$datastoreview = get-datastore $ds_destination | get-view

#You use the same spec, so create it once and save it for later reuse

$relocationSpec = new-object VMware.Vim.VirtualMachineRelocateSpec

$relocationSpec.Datastore = $datastoreView.MoRef

foreach ($vm in get-vm -datastore $ds_origin)

{

#No need to call get-vm again

$vmview = get-view -Id $vm.Id

$vmView.RelocateVM_Task($relocationSpec)

}

>

0 Kudos
yboychev
Hot Shot
Hot Shot

Hi all,

This is a great thread and thank you all for performance results and user experience shared. I filed the problem to the dev team and the performance of the Get-Vm -Datastore $datastore will be furtherly investigated.

\Yavor

0 Kudos
Engelsman
Enthusiast
Enthusiast

I also have performance troubles with some scripts, especially when using get-vm.

Do you suggest using the beta version Hal?

Whoops, missed the 2nd page. the Get-View -ViewType virtualmachine method works pretty fast.

But i can't get it to fit into my script somehow..

$AllVM = Get-Cluster mycluster | Get-VM

foreach ($VM in $AllVM){

etc ..

}

0 Kudos
yboychev
Hot Shot
Hot Shot

In our latest release PowerCLI 4.1.1 we have significantly improved the performance for retrieving vms by specifying a particular datastore. It used to be the case where the time for retrieving vms specifying 1 and 100 vms will be relatively the same. No it should be much faster which hopefully will significantly improve user experience.

Best regards,

Yavor

0 Kudos