sanjaygpt171
Enthusiast
Enthusiast

checking box "Automating Upgrade of VMware Tools" for all windows VM created in last 7 days

Jump to solution

I want to check the box  "Automating Upgrade of VMware Tools" for all windows VM created in last 7 days.  Currenlt , i have following script from which i was providing manual VM name but i need to automate it only for windows VM

foreach($vmlist in (Get-Content -Path C:\TEMP\vmliste.txt))

{

$vm = Get-VM -Name $vmlist

 

 # $VM = Get-VM # Filter here if needed

  $VMView = $VM | Get-View

    if($VMview.config.tools.toolsUpgradePolicy -ne "upgradeAtPowerCycle")

  {

    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

    $spec.changeVersion = $VM.ExtensionData.Config.ChangeVersion

    $spec.tools = New-Object VMware.Vim.ToolsConfigInfo

    $spec.tools.ToolsUpgradePolicy = "upgradeAtPowerCycle"

    $_this = Get-View -Id $VM.Id

    $_this.ReconfigVM_Task($spec)

  Write-Host "Update Tools Policy on $vm completed"

 }

  else

  {

  Write-Host "Update Tools Policy on $vm already esxists"

  }

   }

 

foreach($vmlist in (Get-Content -Path C:\TEMP\vmliste.txt))
{
$vm = Get-VM -Name $vmlist
 # $VM = Get-VM # Filter here if needed
  $VMView = $VM | Get-View
  if($VMview.config.tools.toolsUpgradePolicy -ne "upgradeAtPowerCycle")
  {
    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
    $spec.changeVersion = $VM.ExtensionData.Config.ChangeVersion
    $spec.tools = New-Object VMware.Vim.ToolsConfigInfo
    $spec.tools.ToolsUpgradePolicy = "upgradeAtPowerCycle"
    $_this = Get-View -Id $VM.Id
    $_this.ReconfigVM_Task($spec)
Write-Host "Update Tools Policy on $vm completed"
  }
  
  else
  {
  Write-Host "Update Tools Policy on $vm failed"
  }
  foreach($vmlist in (Get-Content -Path C:\TEMP\vmliste.txt))
{
$vm = Get-VM -Name $vmlist
 
 # $VM = Get-VM # Filter here if needed
  $VMView = $VM | Get-View
    if($VMview.config.tools.toolsUpgradePolicy -ne "upgradeAtPowerCycle")
  {
    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
    $spec.changeVersion = $VM.ExtensionData.Config.ChangeVersion
    $spec.tools = New-Object VMware.Vim.ToolsConfigInfo
    $spec.tools.ToolsUpgradePolicy = "upgradeAtPowerCycle"
    $_this = Get-View -Id $VM.Id
    $_this.ReconfigVM_Task($spec)
Write-Host "Update Tools Policy on $vm completed"
 
  }
  
  else
  {
  Write-Host "Update Tools Policy on $vm already esxists"
  }
  $VMview = ""
 }
1 Solution

Accepted Solutions
LucD
Leadership
Leadership

We can add another filter

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec

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

$spec.Tools.ToolsUpgradePolicy = "upgradeAtPowerCycle"


$vmNames = ((Get-VIEvent -Start (Get-Date).AddDays(-7) -MaxSamples ([int]::MaxValue) |

where{$_ -is [VMware.Vim.VmCreatedEvent]}).Vm.Name) -join '|'


$filter = @{

    'Name'=$vmNames

    'Config.GuestFullName'='Windows'

    'Config.Tools.ToolsUpgradePolicy'='^((?!upgradeAtPowerCycle).)*$'

}

Get-View -ViewType VirtualMachine -Filter $filter |

ForEach-Object -Process {

    $_.ReconfigVM_Task($spec)

    Write-Host "Update Tools Policy on $($_.Name) completed"

}


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

View solution in original post

0 Kudos
23 Replies
LucD
Leadership
Leadership

Try something like this

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec

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

$spec.Tools.ToolsUpgradePolicy = "upgradeAtPowerCycle"


$filter = @{

    'Config.GuestFullName'='Windows'

    'Config.Tools.ToolsUpgradePolicy'='^((?!upgradeAtPowerCycle).)*$'

}

Get-View -ViewType VirtualMachine -Filter $filter |

ForEach-Object -Process {

    $_.ReconfigVM_Task($spec)

    Write-Host "Update Tools Policy on $($_.Name) completed"

}


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

0 Kudos
sanjaygpt171
Enthusiast
Enthusiast

Hi LuCD,

I don't see any filters for windows VM created in last 7 days here. Just want to updated the windows VM created on last 7 days.

I don't won't to run it on entire windows system.

Thanks or help !!

0 Kudos
LucD
Leadership
Leadership

We can add another filter

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec

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

$spec.Tools.ToolsUpgradePolicy = "upgradeAtPowerCycle"


$vmNames = ((Get-VIEvent -Start (Get-Date).AddDays(-7) -MaxSamples ([int]::MaxValue) |

where{$_ -is [VMware.Vim.VmCreatedEvent]}).Vm.Name) -join '|'


$filter = @{

    'Name'=$vmNames

    'Config.GuestFullName'='Windows'

    'Config.Tools.ToolsUpgradePolicy'='^((?!upgradeAtPowerCycle).)*$'

}

Get-View -ViewType VirtualMachine -Filter $filter |

ForEach-Object -Process {

    $_.ReconfigVM_Task($spec)

    Write-Host "Update Tools Policy on $($_.Name) completed"

}


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

0 Kudos
sanjaygpt171
Enthusiast
Enthusiast

Hi LuCD,

Thanks for help !!

I have below two questions:

1. Can we create else condition in the above script, just incase if, "Automating Upgrade of VMware Tools"  is already checked for any VM created in last 7 days.

2. Also, is it good , if we keep below commands in a fuction and then call them in foreach loop. Just a thought

$ spec = New-Object VMware.Vim.VirtualMachineConfigSpec

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

$spec.Tools.ToolsUpgradePolicy = "upgradeAtPowerCycle"

Thanks

0 Kudos
LucD
Leadership
Leadership

1. The Filter on the Get-View is doing exactly that

2. Why would you package that in a function?

Those lines are static and don't change for each VM.
That is why I moved that part outside of the foreach loop.


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

0 Kudos
sanjaygpt171
Enthusiast
Enthusiast

Thanks LuCD for help!!

All looks Great!!!!

0 Kudos
Ankushsethi
Enthusiast
Enthusiast

Could you please explain the meaning of this line .

'Config.Tools.ToolsUpgradePolicy'='^((?!upgradeAtPowerCycle).)*$'

?! what it does is equal to where object ? and what is the meaning of ^

0 Kudos
LucD
Leadership
Leadership

First, the Filter parameter on the Get-View cmdlet is a hash table with expressions.
The value part of each entry in the hash table is a RegEx expression.

RegEx is a sequence of characters that define a search pattern.
RegEx is rather complex, and would probably need a few chapters to fully explain.

The '^' indicates that the next part shall match at the beginning of the string.

The '$' indicates that the end of the search string should be the end of the string.

The string '((?!upgradeAtPowerCycle).)*' in short means, do match everything except 'upgradeAtPowerCycle'


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

Ankushsethi
Enthusiast
Enthusiast

thank you ,I will read about RegEX more than as i still not fully understand ^ probably i need some home work on those
thank you for direction

0 Kudos
LucD
Leadership
Leadership

This About Regular Expressions help page is probably a good start.


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

Ankushsethi
Enthusiast
Enthusiast

As i new to advance powershell and trying to learn ,I would like to share my understanding on this expression after reading multiple blogs   '^((?!upgradeAtPowerCycle).)*$'

pastedImage_0.png

1. Line is ?! is for negative look ahead

The difference between ?= and ?! is that the former requires the given expression to match and the latter requires it to not match. For example a(?=b) will match the "a" in "ab", but not the "a" in "ac". Whereas a(?!b) will match the "a" in "ac", but not the "a" in "ab".

2. (.) is a wildcard character in regular expressions. It will match any character except a newline -means it will match our string

3. line is anchor which helps to match the character on basis of position- it means it should end with anything which makes it false

4. line is to indicate ,It will string will have anything

sanjaygpt171
Enthusiast
Enthusiast

Hi LuCD,

The script is taking quite long time to complete it. I have executed it on one of our vcenter to update tools for last 7 days and it take almost 1 hour to complete it. I am not really sure, why it is taking too much time to execute it. Could you please suggest on this.

Thanks

0 Kudos
LucD
Leadership
Leadership

Unfortunately, the Get-VIEvent cmdlet is very slow.

That is, afaik, not due to the cmdlet itself, but primarily due to the way the vCenter handles event retrieval nowadays.

Even my Get-VIEventPlus function became very slow.

Not a lot I can do I'm afraid.


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

0 Kudos
sanjaygpt171
Enthusiast
Enthusiast

Hi LuCD,

I am getting below error while exceuting script on one if the vcenter. Could you please suggest.

Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetEvent

Get-VIEvent The request channel timed out while waiting for a reply after 00:04:59.9959974. 

Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. 

The time allotted to this operation may have been a portion of a longer timeout.

Thanks

Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetEvent
Get-VIEvent The request channel timed out while waiting for a reply after 00:04:59.9959974. 
Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. 
The time allotted to this operation may have been a portion of a longer timeout.
0 Kudos
LucD
Leadership
Leadership

Which PowerCLI version and vSphere version are you running?


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

0 Kudos
sanjaygpt171
Enthusiast
Enthusiast

Hi LucD,

Below are the details:

VMware PowerCLI 11.3.0 build 13990089

Vsphere version : Version 6.5.0.23000 Build 10964411

Thanks

0 Kudos
LucD
Leadership
Leadership

There was a known issue with 11.3 and that kind of timeouts.
Can you eventually try upgrading to 12.0?


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

0 Kudos
sanjaygpt171
Enthusiast
Enthusiast

Hi LuCD,

Could you please suggest to add a filter on this script , so that it can skip templates for checking box "Automating Upgrade of VMware Tools". The existing script is trying to make changes on templates as well and it fails in middle.

Right now, i am using below script 

 

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$spec.Tools = New-Object VMware.Vim.ToolsConfigInfo

$spec.Tools.ToolsUpgradePolicy = "upgradeAtPowerCycle"


$vmNames = ((Get-VIEvent -Start (Get-Date).AddDays(-7) -MaxSamples ([int]::MaxValue) |

where{$_ -is [VMware.Vim.VmCreatedEvent]}).Vm.Name) -join '|'


$filter = @{

'Name'=$vmNames

'Config.GuestFullName'='Windows'

'Config.Tools.ToolsUpgradePolicy'='^((?!upgradeAtPowerCycle).)*$'

}

Get-View -ViewType VirtualMachine -Filter $filter |

ForEach-Object -Process {

$_.ReconfigVM_Task($spec)

Write-Host "Update Tools Policy on $($_.Name) completed"

}

0 Kudos
LucD
Leadership
Leadership

Change the Where-clause

Where-Object { $_ -is [VMware.Vim.VmCreatedEvent] -and -not $_.Template }).Vm.Name) -join '|'


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

0 Kudos