Nov 30

PowerCLI to Check for VMware ToolsOK

Had an issue last night with setting a VM’s IP Address, DNS, and name using Invoke-VMScript after powering on the VM. The Invoke-VMScript would timeout because VMware Tools was not started. I tried using sleeps in the script to pause the script long enough so Tools would start. I could not get this to work consistently so I did some searching around and found this bit of PowerCLI code that loops until the status of VMware Tools returns OK.

write-host “Waiting for VM Tools to Start”
do {
$toolsStatus = (Get-VM $vm | Get-View).Guest.ToolsStatus
write-host $toolsStatus
sleep 3
} until ( $toolsStatus -eq ‘toolsOk’ )

Exactly what I needed it to do. Will probably enhance it to update tools if $toolsStatus is equal to ‘toolsOld’ but not sure that will be necessary I am usually pretty good at keeping the VM tools installs up to date in my templates.

I cannot find the source where I found this, it was part of another script and I should have saved the URL. If this is your snippet – THANKS!

Got an update from Alan Renouf (@alanrenouf) from http://www.virtu-al.net/

“You might want to check out (Get-VM $vm).extensiondata.Guest.ToolsStatus rather than (Get-VM $vm | Get-View).Guest.ToolsStatus it should give you the same results but be slightly quicker. ”

Thanks for the tip Alan!

About the author


Hersey Cartwright is an IT professional with extensive experience designing, implementing, managing, and supporting technologies that improve business processes. Hersey is Solutions Architect for SimpliVity covering Virginia, Washington DC, and Maryland. He holds the VMware Certified Design Expert (VCDX-DV #128) certification. Hersey actively participates in the VMware community and was awarded the VMware vExpert title in 2016, 2015, 2014, 2013, and 2012. He enjoys working with, teaching, and writing about virtualization and other data center technologies. Follow Hersey on Twitter @herseyc


  1. Jake

    This helped me out. For those fooling around with the “Wait-Tools” cmdlet, dont waste your time. Use this little bit of code. I changed it up a bit though

    Write-Host “Waiting for VM Tools to Start on $VM”
    do {
    Set-Variable -name ToolsStatus -Value (Get-VM $VM).extensiondata.Guest.ToolsStatus
    Write-Host $toolsStatus
    sleep 3
    until ($toolsStatus -eq ‘toolsOk’)

    I use the Set-Variable cmdlet so that it ensures it reruns the commands each time it goes through the loop – and I used Alans tip above. Seems to work ok – just alot of output if the VM takes awhile to start

    Thanks again for this!


  2. Corrupted2012

    WORKED GREAT – Thanks so much – I incorporated a few items together and created this
    $vms = Get-Content c:\scripts\bp-vm.txt
    Connect-VIServer -Server -Protocol https -User -Password

    foreach ($vm in $vms){
    Get-VM $vm | Start-VM -Confirm:$false | Out-Null
    Write-Host “Waiting for VM Tools to Start on $VM”
    do {
    Set-Variable -name ToolsStatus -Value (Get-VM $VM).extensiondata.Guest.ToolsStatus
    Write-Host $toolsStatus
    sleep 3
    until ($toolsStatus -eq ‘toolsOk’)

  3. Marcus Z

    This works a lot better for me! Give it a try!
    while($true) {
    $now = Get-Date -format “dd-MMM-yyyy HH:mm:ss”
    Write-Host “===================[ $now ]=======================”
    Get-View -ViewType VirtualMachine | Where-Object {$_.Runtime.PowerState -eq “poweredOn” -and $_.Guest.IPAddress -eq $null} | Select Name,
    if($_.Guest.GuestState -eq “notRunning”){
    “Not running” }
    $_.Guest.ToolsVersionStatus.Replace(“guestToolsNeedUpgrade”,”Out of date”).Replace(“guestToolsNotInstalled”,”Not installed”).Replace(“guestToolsCurrent”,”OK”).Replace(“guestToolsUnmanaged”,”Unmanaged”)
    Write-Host “`n”
    #sleep 3

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

two × 3 =