How to check template settings without converting it to vm using get-teamplate and get-view?

So if we will look at a template vm using vSphere client we can’t see more than basic settings. We can check the guest OS, vm version, cpu, memory, vmware tools status, state, on which host was it registered, and on which datastore it resides. That’s it.
Ok, so in order to get some more information from template we can use get-view.

get-template vm2
Name                Id
----                --
vm2            VirtualMachine-vm-738

Is this all ? Let’s see what else can we see using this view id

get-view -id (get-template vm2).id
Capability           : VMware.Vim.VirtualMachineCapability
Config               : VMware.Vim.VirtualMachineConfigInfo
Layout               : VMware.Vim.VirtualMachineFileLayout
LayoutEx             : VMware.Vim.VirtualMachineFileLayoutEx
Storage              : VMware.Vim.VirtualMachineStorageInfo
EnvironmentBrowser   :
ResourcePool         :
ParentVApp           :
ResourceConfig       : VMware.Vim.ResourceConfigSpec
Runtime              : VMware.Vim.VirtualMachineRuntimeInfo
Guest                : VMware.Vim.GuestInfo
Summary              : VMware.Vim.VirtualMachineSummary
Datastore            : ...
Network              : {}
Snapshot             :
RootSnapshot         : {}
GuestHeartbeatStatus : gray
LinkedView           :
Parent               : Folder-group-v..0
CustomValue          : {..}
OverallStatus        : green
ConfigStatus         : green
ConfigIssue          : {}
EffectiveRole        : {-1}
Permission           : {}
Name                 : vm2
DisabledMethod       : {MakePrimaryVM_Task, TerminateFaultTol
RecentTask           : {}
DeclaredAlarmState   : {}
TriggeredAlarmState  : {}
AlarmActionsEnabled  : True
Tag                  : {}
Value                : {507}
AvailableField       : {}
MoRef                : VirtualMachine-vm-738
Client               : VMware.Vim.VimClient

So as you can see we can see similar output as if you would apply get-view to normal virtual machine. From here you can query your template just as it would be virtual machine. What is worth mentioning here is that it will be impossible to make any tasks on the template, but still we can get information.
So let’s check for example what network interfaces our templates has:

$templateview=get-view -id (get-template vm1).id
($templateview.config.hardware.device | ? {$_ -is [vmware.vim.VirtualVmxnet]})|%{$_.DeviceInfo}
Label                      Summary
-----                      -------
Network adapter 1          VM Network

So we can see that we have 1 network adapter which is connected to ‘VM Network’ portgroup.
Now let’s see how were the disks configured

($templateview.config.hardware.device | ? {$_ -is [vmware.vim.VirtualDisk]})|%{$_.DeviceInfo}
Label                         Summary
-----                         -------
Hard disk 1                   1,048,576 KB
Hard disk 2                   1,048,576 KB

Now again, we create some templates and we try to remind “have i put this floppy device or not ?” So normally you would have to mark template as a vm, then edit settings and so on..
Let’s check if i have put floppy to template:

($templateview.config.hardware.device | ? {$_ -is [vmware.vim.VirtualFloppy]})|%{$_.DeviceInfo}
Label                                        Summary
-----                                        -------
Floppy drive 1                               Remote
Floppy drive 2                               Remote

Wow! Not one but two! 😉
Ok few times i have seen situation when people were surprised that some of vms have memory reservations/limit on them and they were wondering how ?! “i did not set it up”
Let’s see if we have some memory limits or reservations

Reservation           : 100
ExpandableReservation : False
Limit                 : -1
Shares                : VMware.Vim.SharesInfo

Well it seems that my template has 100 mb memory reserved, and no limit set. You can query cpu allocation as well:

Reservation           : 0
ExpandableReservation : False
Limit                 : -1
Shares                : VMware.Vim.SharesInfo

What tools upgrade policy will my vms have after deployment ? We can also check this :


Nice… And all this information AND MORE! we can grab without converting template to vm. So if you want really quickly take a look on some specific property of your template , get-view will help you out 😉

Checking vmware tools upgrade policy using powercli, setting vmware tools upgrade policy

If you want to check what is the policy regarding upgrading vmware tools for vms in cluster, here it is 😉

get-view -ViewType virtualmachine -SearchRoot (get-Cluster 'your-cluster').id | select name,@{N='ToolsUpgradePolicy';E={$_.Config.Tools.ToolsUpgradePolicy } }

If you want to query all vms in VC

get-view -ViewType virtualmachine | select name,@{N='ToolsUpgradePolicy';E={$_.Config.Tools.ToolsUpgradePolicy } }

Ok nice, we know what tools upgrade policy settings have our vms. Now we want to change this settings for example to ‘upgradeAtPowerCycle’. I am assuming that we want to change this setting only for vms that have ‘manual’ settings selected for toolsupgradepolicy. There is no need to force it on all vms.

get-view -ViewType virtualmachine -SearchRoot (get-Cluster 'your_Cluster').id -Filter @{'Config.Tools.ToolsUpgradePolicy' = 'manual' } | select name,@
{N='ToolsUpgradePolicy';E={$_.Config.Tools.ToolsUpgradePolicy } }

If you want to limit the vms for which we will be changing this setting, don’t forget that you still can filter them
|? {$_.guest.guestFamily -eq ‘windowsGuest’}
|? {$_.guest.guestFamily -eq ‘linuxGuest’}
|? {$_.guest.guestFullName -eq ‘Microsoft Windows Server 2008 R2 (64-bit)’}
And so on and on…
for example to apply this only for windows 2k8 r2 64bit, you would select them applying proper filter:

get-view -ViewType virtualmachine -SearchRoot (get-Cluster 'your_Cluster').id -Filter @{'Config.Tools.ToolsUpgradePolicy' = 'manual' } |? {$_.guest.guestFullName -eq 'Microsoft Windows Server 2008 R2 (64-bit)'} |select name,@ {N='ToolsUpgradePolicy';E={$_.Config.Tools.ToolsUpgradePolicy } }

As you can see by running get-view for vms using filter ‘Config.Tools.ToolsUpgradePolicy’ = ‘manual’ , we will select only those which have manual. Alright, now the upgrade part.
Right, so i could not find any cmdlet within powercli to do this. Still let’s not give up on this one yet 😉 What to do in this case ?
Download/extract onyx from While running onyx, select option to run using vSphere client. Make sure that onyx is recording from this moment

So we received vsphere api code that our vSphere client executed.

# ------- ReconfigVM_Task -------

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$spec.changeVersion = "2012-08-01T08:26:54.934341Z"
$ = New-Object VMware.Vim.ToolsConfigInfo
$ = "manual"

$_this = Get-View -Id 'VirtualMachine-vm-754'

We need to apply this part of code to our vms that have wrong upgradetoolspolicy.
Let’s take our query part here first:

get-view -ViewType virtualmachine -SearchRoot (get-Cluster 'your_Cluster').id -Filter @{'Config.Tools.ToolsUpgradePolicy' = 'manual' }

Those will be our vms
Let’s make a loop for them

Foreach($vmview in get-view -ViewType virtualmachine -SearchRoot (get-Cluster 'your_cluster').id -Filter @{'Config.Tools.ToolsUpgradePolicy' = 'manual' } ) {

Ok, loop with your get-view from vms is ready.

Now let’s take closer look at the configuration spec

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec 
$spec.changeVersion = "2012-08-01T08:26:54.934341Z" 
$ = New-Object VMware.Vim.ToolsConfigInfo 
$ = "manual" 


If you want to read about those objects and their specification in vmware api use the above links. One thing that could be not so simple to understand is the ChangeVersion. The rest should be self explanatory i believe.
1. Create configuration specification object
2. Populate changeversion
3. In order to set the toolsUpgradePolicy property , we have to initialize ToolsConfigInfo object first.
4. Execute method on vsphere api vm object called ReconfigVM_task which takes as a parameter the specification object which we have just created.

ad.2 To be honest it will work even without giving this parameter. It is not necessary. Let’s say we are going to configure this settings, but meanwhile some evil evil evil administrator has changed some other settings in some particular vm on which we are running our loop. Now, as we do not know what has he changed(this evil evil administrator) then we might ask, do we still want to make our change ? IF we do not care about this, i guess there is no point in filling the changeversion at all. If we do, we have first assign to some variable current changeversion number, and then while reconfiguring our vm, give the changeversion on which we wanted to work. If meanwhile (evil evil evil) administrator did some reconfiguration of this machine, the changeversion number will be not equal to our number. Guess what will happen ?

Our change will not proceed as the number does not match. When that evil…il..l… administrator has reconfigured our vm, the changeversion number has changed to some 9999 for example…, but when we started our script, and wrote to variable the current change number it was 7777, so we are trying to do a spec with $spec.changeVersion = “xxxxxx7777” , and it fails because it’s not 7777 anymore but 9999.
Back to our loop 😉

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec 
$ = New-Object VMware.Vim.ToolsConfigInfo 
$ = "upgradeAtPowerCycle" 
Foreach($vmview in get-view -ViewType virtualmachine -SearchRoot (get-Cluster 'my_cluster').id -Filter @{'Config.Tools.ToolsUpgradePolicy' = 'manual' } ) {

And this is it 😉
Lines: 1-3 : We create specification object , we are putting information bout the toolsUpgradePolicy
Lines: 4-6 : In our loop where we query for vms that have manual option for toolsUpgradePolicy, we invoke method ReconfigVM_Task and giving it our $spec specification object
Like i mentioned earlier you could use here the changeversion if you want to be really sure. Where i work i have no evil evil evil admins 😉 No need to set it here ! but… if you have them , do it like this 😉

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec 
$ = New-Object VMware.Vim.ToolsConfigInfo 
$ = "upgradeAtPowerCycle" 
Foreach($vmview in get-view -ViewType virtualmachine -SearchRoot (get-Cluster 'my_cluster').id -Filter @{'Config.Tools.ToolsUpgradePolicy' = 'manual' } ) {

One more example, few seconds ago i had to update this only on vms that were in text file so in order to do that:

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec 
$ = New-Object VMware.Vim.ToolsConfigInfo 
$ = "upgradeAtPowerCycle" 
foreach ($vm in gc c:\vmlist.txt) {
$vmview = get-view -viewtype virtualmachine -Filter @{'name'=$vm}