VMware Cloud Community
marc045
Contributor
Contributor

How to cache / pre-compile PowerCLI cmdlets ?

Hi All,

The FIRST time I invoke commands like get-vm, get-harddisk, etc. they usually take several seconds to run.

Is there a way/method/hack/workaround to somehow cache or precompile these cmdlets so they are much faster on first run?

Regards,

marc0

Reply
0 Kudos
7 Replies
LucD
Leadership
Leadership

There is a bit of overhead when you first run a cmdlet, but I never experienced seconds.

Could it be that your vCenter Server is suffering from a heavy load ?


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

Reply
0 Kudos
marc045
Contributor
Contributor

Hi Luc,

Here the results of measure-command against the following:

add-pssnapin VMware.VimAutomation.Core [4 seconds]

connect-viserver -server myserver -user myuser -pass mypass [6 seconds]

any of the get-* commands on first run:

get-vm

get-cluster

get-datacenter etc [22 seconds]

Note that as soon as I have invoked ANY get-* command, then following invocations are fast.  However the very first get-* invocation is slow (22 seconds).

The issue seems to be on the VM that I am running PowerCLI from.  During the first get-vm run, the CPU is pinned at 100%.  Memory/Network/Disk metrics are low.

On the vCenter server itself, CPU/memory/network & disk is all low usage while the first get-vm is being executed on the PowerCLI VM.

The get-vm is being run against my lab which has one esx host and around 20 VMs.

Luc - how long does "get-vm" take on the first run in your environment?

And is there a way to cache/pre-compile the get-* commands so they are fast even on first run?

Regards

marc0

Reply
0 Kudos
LucD
Leadership
Leadership

Hi Marc,

The fact that you see the guest where you run the Get-VM spiking at 100% CPU is probably the main reason for the long response times.

Can't you give more CPU resources to that VM, just to see if that improves the response times ?

You could also try using Onyx. That can perhaps shed a light where the long delay comes from.

The duration of the first Get-VM depends of course also on the size of the vSphere environment, but I normally see only a few seconds (2-3) on the first invocation of Get-VM. Subsequent Get-VM invocations tend to be faster. I assume that is due to intelligent coding by the PowerCLI Dev Team. I suspect the subsequent calls of Get-VM only have to retrieve the changes that occurred since the first invocation. But that is just a guess, perhaps someone from the Dev Team can shed some light on this ?

And I'm afraid I have no knowledge of any caching mechanisms that you could configure for PowerCLI cmdlets.

You can perhaps try using the 'Get-View -ViewType VirtualMachine' cmdlet instead of the Get-VM cmdlet.

The Get-View cmdlet is considerably faster than the regular Get- cmdlets.

Note that Get-View returns another type of object than the Get-VM cmdlet. So you probably would have to rewrite part of your scripts.


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

marc045
Contributor
Contributor

Thanks Luc, I did try adding a 2nd vCPU to my PowerCLI VM (so it had a total of 2 vCPUs instead of just 1), and this actually increased the first get-vm duration by a few extra seconds, so I've dropped it back to 1 vCPU.

I will see if Onyx can shed some light on why this CPU spike is lasting so long.

Regards

marc0

Reply
0 Kudos
LucD
Leadership
Leadership

A 2nd vCPU will only help if your tasks are multi-threaded, I'm afraid.

Perhaps try changing the CPU Resource allocations for the guest where you execute the Get-VM.


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

Reply
0 Kudos
marc045
Contributor
Contributor

Hi All,

It appears that the get-vm command takes several seconds on first invocation because PowerCLI is recompiling on the fly all its assemblies.  PowerCLI spends a lot of time inside xmlserializers.dll, the very first time get-vm is invoked.

According to a post on stackoverflow:

In .Net implementation, the XmlSerializer generates a temporary assembly for serializing/deserializing your classes (for performance reasons). It can either be generated on the fly (but it takes time every execution), or it can be pregenerated during compilation and saved in this assembly you are asking about. You can change this behaviour in project options.

It appears the sgen.exe tool can be used to precompile the assemblies.  Is there any way I can do this for PowerCLI, and force it to NOT recompile on the fly at first launch?

This issue appears to be similar to:

http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=87402

Here is an example of VMware SDK project precompiling the assemblies (Line 104):

https://gist.github.com/964083

On this blog, the author reduced execution time by 80% by precompiling with sgen:

http://www.dotnetfunda.com/articles/article1105-optimized-way-of-xml-serialization-using-sgen-utilit...

[1]
Is there any way I can do this for PowerCLI, and force it to NOT recompile on the fly at first launch?

[2]
If not, are there plans to release future versions of PowerCLI with both a "Pre-Compiled assemblies" download option, and the traditional "Compile on-the-fly" download option?

Regards,
marc0

Reply
0 Kudos
LucD
Leadership
Leadership

Wow, you investigated this thoroughly.

I hope the Dev Team has some feedback on this.


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