I've got around 900 vm's to update the tools on. Whats the best practice as far as how many you should run at once? They are spread out on about 45-50 different hosts and clusters. I'm using the following script that seems to work perfect:
$insParm = '/S /v"/qn REBOOT=ReallySuppress"'
$vmView = Get-VM | Get-View | Where {$_.guest.toolsstatus -ilike "toolsOld"}
foreach ($vm in $vmView){
$vm.UpgradeTools_Task($insParm)
Start-Sleep
-Seconds 30
}
Its taking roughly 3-4 minutes per vm to update the tools. I imagine I would crash some things if I ran one every 30 seconds. How can I restrict this task to only 3-5 at a time?
I imagine there is some thread magic you could do to keep track of each upgrade, but would using a simple for loop with a longer pause during the last iteration work for this?:
$insParm = '/S /v"/qn REBOOT=ReallySuppress"'
$vmView = Get-VM | Get-View | Where {$_.guest.toolsstatus -ilike "toolsOld"}
If I had a smaller list to do that would probably be a good solution. The only thing that worries me about doing it like that is if one errors or they start taking longer and longer to finish. I won't be able to get as many done. Probably don't need the start-sleep in the in the first four either.
Try perhaps something like this, it will start 5 updates every 5 minutes.
I used the Get-VIew cmdlet with the Filter parameter because that is way faster then a Get-VM followed by a Get-View in a bigger environment.
$insParm = '/S /v"/qn REBOOT=ReallySuppress"'
$vmView = Get-View -ViewType VirtualMAchine -Filter @{"Guest.toolsstatus"="toolsOld"} $interval = 300 $vmPerBlock = 5 $nrBlocks = [int]($vmView.Count/$vmPerBlock) 0..$nrBlocks | %{ $vmView[($_ * $vmPerBlock).. ((($_ + 1) * $vmPerBlock) - 1)] | %{ $_.UpgradeTools_Task($insParm) } sleep 300
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
If I want to specify a folder to run this script in, would it be:
$vmView = Get-View -SearchRoot Foldername -ViewType VirtualMachine -Filter @{"Guest.toolsstatus"="toolsOld"}
Also, since I have the list that I need to update, I probably don't even need the get-view section do I? I could just do this, correct?
$insParm = '/S /v"/qn REBOOT=ReallySuppress"'
$list = (Get-Content servers.txt)
$vmView = Get-VM $list
$interval = 300 $vmPerBlock = 5 $nrBlocks = [int]($vmView.Count/$vmPerBlock) 0..$nrBlocks | %{ $vmView[($_ * $vmPerBlock).. ((($_ + 1) * $vmPerBlock) - 1)] | %{ $_.UpgradeTools_Task($insParm) } sleep 300
}
Yes, you use the SerachRoot parameter to start from a specific folder.
Yes, that will work.
Note that Get-View is considerably faster in bigger environments.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Whats the best way to provide a list of vm names to the get-view cmdlet?
get-view -filter @{'name'='vm1'}
IS this what are you looking for ?
REgards,
Greg
The filter is a hash table which can use regular expressions.
So you could do
$names = [string]::Join('|',(Get-Content c:\names.txt))
Get-View -ViewType VirtualMachine -Filter @{"Name"=$names}
All the names seperated by a vertical bar (the regex expression for OR)
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference