Wednesday, February 5, 2014

vCAC - Add VM Requester to Windows Local Admin Group

This is a request that I get frequently.  The person requesting a Windows VM needs to be a local administrator, so that after the VM is provisioned they can begin to access via RDP and perform tasks that require this level of access (install software, for example).

This can be accomplished using the Guest Agent for vCAC.  Installing the Guest Agent on the VM template allows vCAC to perform many post-build activities such as running scripts.  In this post I will show how you can use the Guest Agent to run a script that will add the requester of the machine to local administrators group.

Note: Post updated with a new script that accepts UPN (as provided by vCAC 6.0) or sAMAccount (as provided by vCAC 5.2).  Thanks to Sam Pursch for testing and suggesting the fix!

First, as I indicated, you will need the Guest Agent installed on your template, but I'm not going to cover that here for brevity.  Second, you will need to add the script you wish to run to your template - just place it in the file system somewhere (I use c:\scripts for example).  The script we will use is a VBScript that will take input for the user's name (for example, and add that user to the local administrators group.  Here is our script (borrowed heavily from others, so use it as you wish with no warranty or guarantees):
If you want to try the script out to make sure it works, modify it, whatever, you can go ahead and run it with the input (for example c:\scripts\adduserToLocalAdmin or blackmesa\gfreeman).

Now we need to configure some custom properties in our blueprint to get the Guest Agent to call our script.
This screen shot shows a build profile with the properties you will need to configure:

I'll explain each of these:

VirtualMachine.Admin.UseGuestAgent - set to "true" so that the Guest Agent will be called during provisioning.  Also, for some reason people seem to want to type USER instead of USE (I do this all the time) so double check all the inputs you will be doing here.

VirtualMachine.Customize.WaitComplete -this is set to "true" to allow the scripts to complete before vCAC kicks the machine into the next lifecycle step.

VirtualMachine.Software0.Name - a friendly name for the script, it can be anything you like.

VirtualMachine.Software0.ScriptPath - the full path to your script along with any input parameters.  Now, note that the value set here in our case is the path to the VBScript with an input of {__Legacy.Workflow.User} - what is that?

As you may know, there are many reserved machine properties within vCAC, and we can use them in our scripts by passing them within the curly braces as you see above.  This particular property will supply the machine's requester to the script!  You can also create your own properties and pass them to your scripts.

This should get you started and hopefully give you some good ideas about other scripts you can run with the Guest Agent.  Notice that "Software0" can be followed by "Software1", "SoftwareN"... so you can run several scripts during deployment.


  1. when i run the script as you instructed, i get user not extracted

  2. I'm not sure why you get that. Is that the output in the log file?

  3. yes. that is the output in the log file

  4. Hi John,
    i finally get the script to work now but the log just says "user name extracted"

  5. Thank you for the detailed tutorial. I've verified the script does work when running at the Command Prompt but for some reason, it will not execute via the Guest Agent. When the VM is provisioned, it gets stuck in the "In Progress" status of the Request portion of the vCAC portal. Any suggestions?

  6. There is a much simpler way to do this as instead of a vbs you do a simple.cmd script with one line of "net localgroup Administrators /add %1" as your local script on the template and on your ScriptPath entry you put the script path with {Owner} at the end. Just for informational purposes as another way to do this.

    1. Well, a little simpler but be aware that {Owner} is not a property but a trigger for vCAC to derive the value of the current owner from the DB. Also, depending on the version of vCAC you may have to user {owner} or {Owner}. I'm pretty sure, but not certain, that this will not work with 5.x at any rate.