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"
}
}
We can add another filter
$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
Try something like this
$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
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 !!
We can add another filter
$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
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
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
Thanks LuCD for help!!
All looks Great!!!!
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 ^
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
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
This About Regular Expressions help page is probably a good start.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
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).)*$'
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
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
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
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
Which PowerCLI version and vSphere version are you running?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD,
Below are the details:
VMware PowerCLI 11.3.0 build 13990089
Vsphere version : Version 6.5.0.23000 Build 10964411
Thanks
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
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"
}
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