================================================================
what this does is:
1) check the VMtool level, if it's not current, upgrade the VMtool.
2) check virtual hardware level, if it is not current, and VMtool is current, upgrade vm hardware
3) else, break
- made some changes to process the vmtool upgrade with runasync switch, and do the poweroff for all VMs at once. this could save some time if you have many VMs in the list
- link to the .ps1 file - CLICK HERE
=========BEGIN CODE============================================
# HOW TO RUN:
# save the list of vm to be updated in text file, and run
this script. Enter the filename when requested.
# 
$timestamp = Get-Date -format "yyyyMMdd-HH.mm"
$csvfile = ".\$timestamp-vminfo.csv"
Function
VM-Selection{
      $sourcename
= Read-Host "Give the name of the object or inputfile (full path)
you want to upgrade"
      if($sourcename){
         $abort
= Read-Host "You've chosen $sourcetype with this file:
$sourcename, this is your last chance to abort by pressing <CTRL>+C.
Press <ENTER> to continue selecting old hardware VMs"
         #$list = Get-Content $sourcename | Foreach-Object {Get-VM
$_ | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version
-eq "vmx-04" } | Select Name }
         $list
= Get-Content $sourcename
| Foreach-Object {Get-VM $_
|
Get-View | Where-Object {-not $_.config.template} | Select Name }
             $vms = $list
      }
      else{
         Write-Host "$sourcetype file does not exist. Exit the script by
pressing <CTRL>+C and try again."
      }
   return $vms
}
Function
PowerOn-VM($vm){
   Start-VM -VM $vm -Confirm:$false -RunAsync | Out-Null
   Write-Host "$vm is starting!" -ForegroundColor Yellow
   sleep 10
   do {
      $vmview
=
get-VM $vm | Get-View
        $getvm = Get-VM $vm
        $powerstate = $getvm.PowerState
      $toolsstatus
= $vmview.Guest.ToolsStatus
      Write-Host "$vm is starting, powerstate is $powerstate and
toolsstatus is $toolsstatus!" -ForegroundColor
Yellow
      sleep 5
        #NOTE
that if the tools in the VM get the state toolsNotRunning this loop will never
end. There needs to be a timekeeper variable to make sure the loop ends
      }until(($powerstate -match "PoweredOn") -and (($toolsstatus -match "toolsOld") -or ($toolsstatus -match "toolsOk") -or ($toolsstatus -match "toolsNotInstalled")))
      if (($toolsstatus -match "toolsOk") -or ($toolsstatus -match "toolsOld")){
       $Startup
= "OK"
         Write-Host "$vm is started and has
ToolsStatus $toolsstatus"
      }
      else{
       $Startup
= "ERROR"
         [console]::ForegroundColor = "Red"
         Read-Host "The ToolsStatus of $vm
is $toolsstatus. This is unusual. Press <CTRL>+C to quit the script or
press <ENTER> to continue"
         [console]::ResetColor()
      }
    return $Startup
}
Function
PowerOff-VM($vm){
   Shutdown-VMGuest -VM $vm -Confirm:$false | Out-Null
   Write-Host "$vm is stopping!" -ForegroundColor Yellow
   sleep 10
   do {
      $vmview
=
Get-VM $vm | Get-View
      $getvm = Get-VM $vm
        $powerstate = $getvm.PowerState
        $toolsstatus = $vmview.Guest.ToolsStatus
      Write-Host "$vm is stopping with powerstate $powerstate and
toolsStatus $toolsstatus!" -ForegroundColor
Yellow
      sleep 5
   }until($powerstate -match "PoweredOff")
   if (($powerstate -match "PoweredOff") -and (($toolsstatus -match "toolsNotRunning") -or ($toolsstatus -match "toolsNotInstalled"))){
      $Shutdown
= "OK"
        Write-Host "$vm is powered-off"
   }
   else{
      $Shutdown
= "ERROR"
        [console]::ForegroundColor = "Red"
        Read-Host "The ToolsStatus of $vm
is $toolsstatus. This is unusual. Press <CTRL>+C to quit the script or
press <ENTER> to continue"
        [console]::ResetColor()
   }
   return $Shutdown
}
Function
Check-ToolsStatus($vm){
   $vmview = get-VM $vm
|
Get-View
   $status = $vmview.Guest.ToolsStatus
   if ($status -match "toolsOld"){
      $vmTools
= "Old"}
   elseif($status -match "toolsNotRunning"){
      $vmTools
= "NotRunning"}
   elseif($status -match "toolsNotInstalled"){
      $vmTools
= "NotInstalled"}
   elseif($status -match "toolsOK"){
      $vmTools
= "OK"}
   else{
      $vmTools
= "ERROR"
        Read-Host "The ToolsStatus of $vm
is $vmTools. Press <CTRL>+C to quit the script or press <ENTER> to
continue"
        }
   return $vmTools
}
Function
Check-VMHardwareVersion($vm){
   $vmView = get-VM $vm
|
Get-View
   $vmVersion
= $vmView.Config.Version
   $v9 = "vmx-09"
   $v10 = "vmx-10"
   if (($vmVersion -ne $v9) -or ($vmVersion -ne $v10)){
      $vmHardware
= "Old"}
   elseif(($vmVersion -eq $v9) -or ($vmVersion -eq $v10)){
      $vmHardware
= "OK"}
   else{
      $vmHardware
= "ERROR"
        [console]::ForegroundColor = "Red"
        Read-Host "The Hardware version of
$vm is not set to $v4 or $v9. This is unusual. Press <CTRL>+C to quit the
script or press <ENTER> to continue"
        [console]::ResetColor()
   }
   return $vmHardware
}
Function
Upgrade-VMHardware($vm){
   $vmview = Get-VM $vm
| Get-View
   $vmVersion
= $vmView.Config.Version
   $v9 = "vmx-09"
   if ($vmVersion -ne $v9){
      Write-Host "Old Version detected" -ForegroundColor Red
# Update Hardware
      Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow
      Get-View ($vmView.UpgradeVM_Task($v9)) | Out-Null
   }
}
Function
CheckAndUpgradeTools($vm){
   $vmview = Get-VM $VM
|
Get-View
   $family = $vmview.Guest.GuestFamily
   $vmToolsStatus
=
Check-ToolsStatus $vm
   if($vmToolsStatus -eq "OK"){
      Write-Host "The VM tools are $vmToolsStatus on $vm"}
   elseif(($family -eq "windowsGuest") -and ($vmToolsStatus -ne "NotInstalled")){
      Write-Host "The VM tools are $vmToolsStatus on $vm. Starting
update/install now! This will take at few minutes." -ForegroundColor Red
        Get-Date
      Get-VMGuest $vm
|
Update-Tools -NoReboot -RunAsync
      ###############changes###########################
#       do{
#       sleep 10
#       Write-Host "Checking ToolsStatus $vm
now"
#       $vmToolsStatus = Check-ToolsStatus $vm
#       }until($vmToolsStatus -eq "OK") 
#       sleep 60
#     PowerOff-VM
$vm
#       PowerOn-VM $vm
        #############end
changes#######################
   }
   else{
        #
We're skipping all non-windows guest since automated installs are not supported
        Write-Host "$vm is a $family with
tools status $vmToolsStatus. Therefore we're skipping this VM" -ForegroundColor Red
   }
}
Function
CheckAndUpgrade($vm){
   $vmHardware
=
Check-VMHardwareVersion $vm
   $vmToolsStatus
=
Check-ToolsStatus $vm
   if($vmHardware -eq "OK"){
      Write-Host "The hardware level is $vmHardware on $vm"}
   elseif($vmToolsStatus -eq "OK"){
      Write-Host "The hardware level is $vmHardware on $vm." -ForegroundColor Red
      $PowerOffVM
=
PowerOff-VM $vm
        if($PowerOffVM -eq "OK"){
           Write-Host "Starting upgrade
hardware level on $vm." 
             Upgrade-VMHardware $vm
           sleep 5
             PowerOn-VM $vm
           Write-Host $vm "is
up to date" -ForegroundColor
Green
        }
        else{
        Write-Host "There is something wrong
with the hardware level or the tools of $vm. Skipping $vm."
        }
   }   
}
Function
CreateHWList($vms, $csvfile){
# The setup for this hwlist comes from
http://www.warmetal.nl/powerclicsvvminfo
   Write-Host "Creating a CSV File with VM info" -ForegroundColor Yellow
   $MyCol = @()
      ForEach ($item in $vms){
         $vm = $item.Name
             #
Variable getvm is required, for some reason the $vm cannot be used to query the
host and the IP-address
             $getvm = Get-VM $vm
             $vmview = Get-VM $vm
|
Get-View
             #
VM has to be turned on to make sure all information can be recorded 
             $powerstate = $getvm.PowerState
             if ($powerstate -ne "PoweredOn"){
                PowerOn-VM $vm}
             $vmnic =
Get-NetworkAdapter -VM $vm
         $nicmac
= Get-NetworkAdapter
-VM $vm
| ForEach-Object {$_.MacAddress}
         $nictype
=
Get-NetworkAdapter -VM $vm | ForEach-Object {$_.Type}
         $nicname
=
Get-NetworkAdapter -VM $vm | ForEach-Object {$_.NetworkName}
         $VMInfo
= "" | Select
VMName,NICCount,IPAddress,MacAddress,NICType,NetworkName,GuestRunningOS,PowerState,ToolsVersion,ToolsStatus,ToolsRunningStatus,HWLevel,VMHost
         $VMInfo.VMName = $vmview.Name
         $VMInfo.NICCount = $vmview.Guest.Net.Count
         $VMInfo.IPAddress = [String]$getvm.Guest.IPAddress
         $VMInfo.MacAddress = [String]$nicmac
         $VMInfo.NICType = [String]$nictype
         $VMInfo.NetworkName = [String]$nicname
         $VMInfo.GuestRunningOS = $vmview.Guest.GuestFullname
         $VMInfo.PowerState = $getvm.PowerState
         $VMInfo.ToolsVersion = $vmview.Guest.ToolsVersion
         $VMInfo.ToolsStatus = $vmview.Guest.ToolsStatus
         $VMInfo.ToolsRunningStatus
= $vmview.Guest.ToolsRunningStatus
         $VMInfo.HWLevel = $vmview.Config.Version
         $VMInfo.VMHost = $getvm.VMHost
         $myCol
+= $VMInfo
        }
   if ((Test-Path -path $csvfile) -ne $True){
      $myCol |Export-csv -NoTypeInformation $csvfile
   }
   else{
      $myCol |Export-csv -NoTypeInformation $csvfile-after.csv
   }
}
function
PowerOffAll-VM($vm){
      shutdown-vmguest
-VM $vm
-Confirm:$false | out-null
}
function
PowerOff-vm-check($vm){
            $vmview
=
get-vm $vm | get-view
            $getvm
=
get-vm $vm
            $powerstate
= $getvm.PowerState
            $toolsstatus
= $vmview.Guest.ToolsStatus
            #write-host "$vm is stopping with powerstate
$powerstate and toolsStatus $toolsstatus!" -foregroundcolor yellow
            if (($powerstate -match "PoweredOff") -and (($toolsstatus -match "toolsNotRunning") -or ($toolsstatus -match "toolsNotInstalled"))){
                        $Shutdown = "OK"
            #     Write-Host
"$vm is powered-off"
            }
            else{
                        $Shutdown = "ERROR"
                  [console]::ForegroundColor
= "Red"
                  Read-Host "The ToolsStatus of $vm is $toolsstatus. This is
unusual. Press <CTRL>+C to quit the script or press <ENTER> to
continue"
                  [console]::ResetColor()
            }
            return $shutdown
}
##################################
# main function
##################################
$vms = VM-Selection
#CreateHWList $vms $csvfile
$vmupgraded = "NO"
foreach($item in $vms){
   $vm = $item.Name
   Write-Host "Working on $vm"
  
CheckAndUpgradeTools $vm
}
do{
            sleep 20
            $count
= 0
            foreach($vmname in $vms){
                  $vm
= $vmname.Name
                  #write-host "checking status for $vm"
                  $vmToolsStatus
=
Check-ToolsStatus $vm
                  if($vmToolsStatus -ne "OK"){
                        $count
+= 1
                        $vmupgraded
= "yes"
                  }
            }
            write-host "$count VM still in progress"
      }until($count -eq 0)
      write-host "All VM has vmtools upgraded"
write-host "VMtool upgraded status = $vmupgraded"     
Read-Host "Continue to virtual hardware upgrade. Press
<CTRL>+C to quit the script or press <ENTER> to continue"
if($vmupgraded -eq "yes"){
      foreach($vmname in $vms){
            $vm
= $vmname.Name
            PowerOffAll-VM
$vm
      }
      do{
            sleep 10
            $count
= 0
            write-host "checking power state for all VMs"
            foreach($vmname in $vms){
                  $vm
= $vmname.Name
                  $powerState
=
PowerOff-vm-check $vm
                  if($powerState -ne "OK"){
                        $count
+= 1
                  }
            }
            write-host "$count VM still powering off" -foregroundcolor yellow
      }until($count -eq 0)
      write-host "All VMs powered off"
      foreach($vmname in $vms){
            $vm
= $vmname.Name
            PowerOn-VM
$vm
      }
}
foreach($item in $vms){
      $vm = $item.Name
      Write-Host "Working on $vm"
      CheckAndUpgrade
$vm
}
#CreateHWList $vms $csvfile
###################################
# end main
###################################
