VMware Cloud Community
DavidRiberdy
Contributor
Contributor
Jump to solution

Updating VMTools with VI Toolkit

I have tried using the example script given in the Powershell FAQ to update VMtools on my virtual machines and have also tried using the update-tools command in the VI Toolkit with no success. Does anyone have a VI Toolkit example that I can follow to point to a specific virtual machine and have it launch the Upgrade Tools feature?

I am super new to all this scripting....

Thanks!

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

I overlooked that you did twice a Get-View.

This should work

get-viserver -server <server> -user <user> -password <password>

$viview = get-vm | foreach-object { get-view ($_.ID)}
$viview | foreach-object {
$vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo
$vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"
$_.ReconfigVM($vmConfigSpec)
} 

And if you want to avoid the variable you could do

get-viserver -server <server> -user <user> -password <password>

get-vm | foreach-object { get-view ($_.ID)} | foreach-object {
  $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
  $vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo
  $vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"
  $_.ReconfigVM($vmConfigSpec)
} 

and even shorter

get-viserver -server <server> -user <user> -password <password>

get-vm | foreach-object {
  $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
  $vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo
  $vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"
  (Get-View $_.ID).ReconfigVM($vmConfigSpec)
} 


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

View solution in original post

0 Kudos
14 Replies
halr9000
Commander
Commander
Jump to solution

Can you give us more details on what exactly goes wrong?

Hal Rottenberg

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

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
DavidRiberdy
Contributor
Contributor
Jump to solution

Using the following script:

get-viserver -server &lt;server&gt; -user &lt;user&gt; -password &lt;pwd&gt;

$vm = Get-View (Get-VM VMName).Id

$vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec

$vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo $vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"

$vm.ReconfigVM($vmConfigSpec)

It will connect to the VC server fine, but I get a :

Get-View : Cannot bind argument to parameter 'MoRef' because it is null.

At line:1 char:15

+ $vm = Get-View &lt;&lt;&lt;&lt; (Get-VM VMName).Id

For the second line.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Is there a guest called "VMName" ?

Does this return anything ?

$vm = Get-VM VMName

You can also try stopping/starting the environment from which you run the script.


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

DavidRiberdy
Contributor
Contributor
Jump to solution

I have the script working by putting the name of the virtual machine in the place where VM-Name was. Is there a way to have to do all the virtual machines in the environment without having to do:

<code>get-viserver -server &lt;server&gt; -user &lt;user&gt; -password &lt;pwd&gt;
$vm = Get-View (Get-VM &lt;VMName&gt;).Id
$vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo
$vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"
$vm.ReconfigVM($vmConfigSpec)</code>

for each of my 100+ servers?

0 Kudos
halr9000
Commander
Commander
Jump to solution

I have the script working by putting the name of the virtual machine in the place where VM-Name was. Is there a way to have to do all the virtual machines in the environment?

Oh yeah, of course! That's the whole point of scripting, after all. If you could only do things one-at-a-time, you might as well use the GUI. Smiley Happy

$viview = get-vm | foreach-object { get-view ($_.ID) }

Now the $viview variable contains all of your VMs.

$viview | foreach-object {

  1. put code here

}

Put the code you want to execute for each object inside the braces, replacing the vmname portion with $_ which is an automatic variable meaning "the current object in the pipeline".

Hal Rottenberg

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

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
DavidRiberdy
Contributor
Contributor
Jump to solution

If I run the first line without the $viview (or even with it and then do a $viview) I get the following:

Capability :

Config :

Layout :

EnvironmentBrowser :

ResourcePool :

ResourceConfig :

Runtime :

Guest :

Summary :

Datastore :

Network :

Snapshot :

GuestHeartbeatStatus : gray

Parent :

CustomValue :

OverallStatus : gray

ConfigStatus : gray

ConfigIssue :

EffectiveRole :

Permission :

Name :

DisabledMethod :

RecentTask :

DeclaredAlarmState :

TriggeredAlarmState :

Value :

AvailableField :

MoRef : VMware.Vim.ManagedObjectReference

I have connected to the VIServer, since I can run: get-vm and it pulls all the names up with their powered state,cpus and memory.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Try stopping/starting the environment (VMware VI Toolkit (for Windows), PowerShellPlus, PowerGUI...) from which you run the cmdlets.

I was in fact able to reproduce the behavior in this way:

- connect to the VC

- run the command Get-VM | %{Get-View $_.ID} ==> all OK

- from VI Client-Administration-Sessions terminate the sessions (mostly 2) that are open for the environment

- connect to the VC with Get-VIServer

- run the command ==> Get-VM is OK but the Get-View $_.ID returns an empty object


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

DavidRiberdy
Contributor
Contributor
Jump to solution

From a cleanly opened VI Toolkit Window:

get-viserver -server &lt;server&gt; -user &lt;user&gt; -password &lt;password&gt;

$viview = get-vm | foreach-object { get-view ($_.ID)}

$viview | foreach-object {

$vm = Get-View (Get-VM $_)

$vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec

$vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo

$vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"

$vm.ReconfigVM($vmConfigSpec)

}

Which is the modified version of the one in the FAQ:

get-viserver -server &lt;server&gt; -user &lt;user&gt; -password &lt;pwd&gt;

$vm = Get-View (Get-VM VMName).Id

$vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec

$vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo

$vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"

$vm.ReconfigVM($vmConfigSpec)

When I run the script, I get the following error messages:

You cannot call a method on a null-valued expression.

At line:6 char:15

+ $vm.ReconfigVM( &lt;&lt;&lt;&lt; $vmConfigSpec)

You cannot call a method on a null-valued expression.

At line:6 char:15

+ $vm.ReconfigVM( &lt;&lt;&lt;&lt; $vmConfigSpec)

You cannot call a method on a null-valued expression.

At line:6 char:15

+ $vm.ReconfigVM( &lt;&lt;&lt;&lt; $vmConfigSpec)

You cannot call a method on a null-valued expression.

At line:6 char:15

+ $vm.ReconfigVM( &lt;&lt;&lt;&lt; $vmConfigSpec)

0 Kudos
LucD
Leadership
Leadership
Jump to solution

The fourth line in your script should read

$vm = Get-View (Get-VM $_).ID

The Get-View cmdlet works on a MoRef which is a Managed Object reference.

For a guest it is something like "VirtualMachine-vm-1351".

You can see this property by inserting a line with $_.ID before the fourth line.


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

0 Kudos
DavidRiberdy
Contributor
Contributor
Jump to solution

In using the script:

get-viserver -server &lt;server&gt; -user &lt;user&gt; -password &lt;password&gt;

$viview = get-vm | foreach-object { get-view ($_.ID)}

$viview | foreach-object {

$vm = Get-View (Get-VM $_).ID

$vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec

$vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo

$vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"

$vm.ReconfigVM($vmConfigSpec)

}

I get the error messages:

Get-View : Cannot bind argument to parameter 'MoRef' because it is null.

At line:2 char:15

+ $vm = Get-View &lt;&lt;&lt;&lt; (Get-VM $_).ID

You cannot call a method on a null-valued expression.

At line:6 char:15

+ $vm.ReconfigVM( &lt;&lt;&lt;&lt; $vmConfigSpec)

if I do a $viview, I get a lot of fully populated data. If I do a $_.ID, it returns nothing.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

You did replace the with the actual VC server and user account and password for that VC server ?


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

0 Kudos
DavidRiberdy
Contributor
Contributor
Jump to solution

Yes.

When I run the original script with the name of a server in the place of the VMName, it works fine. The problems started coming in when wanting to do all the servers at once without having to specify a single server.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I overlooked that you did twice a Get-View.

This should work

get-viserver -server <server> -user <user> -password <password>

$viview = get-vm | foreach-object { get-view ($_.ID)}
$viview | foreach-object {
$vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo
$vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"
$_.ReconfigVM($vmConfigSpec)
} 

And if you want to avoid the variable you could do

get-viserver -server <server> -user <user> -password <password>

get-vm | foreach-object { get-view ($_.ID)} | foreach-object {
  $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
  $vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo
  $vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"
  $_.ReconfigVM($vmConfigSpec)
} 

and even shorter

get-viserver -server <server> -user <user> -password <password>

get-vm | foreach-object {
  $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
  $vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo
  $vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"
  (Get-View $_.ID).ReconfigVM($vmConfigSpec)
} 


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

0 Kudos
DavidRiberdy
Contributor
Contributor
Jump to solution

The first script worked like a champ!

Thanks

0 Kudos