I have been looking at further ways to automate alot of the work that we do within our testing environment at work. This is mainly due to the fact that I want to keep our testing set in a standardized format, while removing the dependency on a SME resource to monitor the tests / set them up.

A majority of the time we end up using full clones for all testing due to the fact that we want to test de-dupe along with performance. This means that all scripts that I will post moving forward will reference that model.

Upon further reading I found out that View PowerCLI is different from traditional PowerCLI since it can only be executed locally on the connection server opposed to remotely.

First thing we need to do is figure out a standard script that will serve multiple purposes. Here is the one that I use.

This script does the following:

  • Loads the View PowerCLI snapin
  • Asks you what you want the PoolID to be
  • Asks you what you want the Pool Display Name to be
  • Asks you what cluster you would like the VMs to be placed in
  • Asks you how many desktops you want to create

For this to work in your environment then there are going to be a few things that you need to change

Lab is the name of the Datacenter which has a hidden sub folder of vm. This is going to be the same in all environments. The sub folder is then Testing and that is where I am dumping these desktops. Here is how you would have to change it if the folder structure was as follows


The same goes for the portion of the script where we are defining where the resource pools are

There are 2 folders in this line that aren’t visible but actually exist and it’s host and Resources

The variable $CObject is the name of the cluster where you want to put the VMs SO you really only need to change these lines if you are throwing the VMs in a resource pool below the cluster object

Template path is pretty straight forward. This is just the folder structure that is below the datacenter object and this too has a hidden folder of vm after the object.

Datastore paths are somewhat interesting . I have a standard naming convention of VDI_LUNID for all of my desktops BUT it might be different for your environment depending on how you do it. These datastores have to be present in the cluster object where you are putting the desktops

In the example above I only show one datastore but you can specify multiples by just doing the following

I haven’t really tested how well it works but it shouldn’t be any different than specifying multiple datastores within the pool settings.

Since we found that the script works with what I pasted above we should enable the Connection Server to accept remote Powershell tasks from other domain machines.

Open a Powershell administrative window and run the following

So now that, that works we could just save the script at the root of C:\ as FULL.ps1 since the next script that I will be referencing is a launcher menu that executes it based on the name and location.

Now here is the current menu that I am using that is based all in Powershell that I found somewhere online. If this is yours or you know who made it please let me know so I can give you credit.

So we can see that this when executed will prompt us for VMware View or Citrix.


This top level menu is based off of these lines here

When Selecting VMware View you will get the following sub menu


This sub menu is based off of this code here

I will select Create a pool which brings me here


This is based off of this section here

So since I only have the option for Full Clone it will call the function named FULL this function is really what is going to authenticate against the CS and run the script. I should mention that this user that you are specifying in the invoke-command task needs to be an administrative user in the View Admin UI. If the user isn’t then you will get a Not Authorized generic error that will just piss you off as much as it did me.

Here is the function as above in the script

This is literally the only way I have found this to actually work. If you don’t have a pre-defined testing set that you are using I believe that you can actually specify your commands directly within the { } of the script block but it would be interesting since you would have to load the snapin prior to the execution on the destination.

The one thing that I need to do is have it actually provide somewhat of feedback when it creates the desktops by doing some form of Get from the CS but I am still learning this.  This entire thing isn’t done but I have seen people talking about it lately so I just wanted to provide something that I would have found helpful as I was sifting through documentation attempting to figure this out on my own.  If you have any ways that you think that this could be done better let me know! You can always contact me on twitter @kalenarndt and I will adjust it accordingly. I always love to see how things can be done more efficiently.