SHIFT

--- Sjoerd Hooft's InFormation Technology ---

User Tools

Site Tools


Sidebar

Recently Changed Pages:

View All Pages


View All Tags


LinkedIn




WIKI Disclaimer: As with most other things on the Internet, the content on this wiki is not supported. It was contributed by me and is published “as is”. It has worked for me, and might work for you.
Also note that any view or statement expressed anywhere on this site are strictly mine and not the opinions or views of my employer.


Pages with comments

View All Comments

changeguestselectedos

Scripts: PowerCLI: Detect and Change Guest Selected OS

The Guest Selected OS is the VM value to determine how the VMware Tools should work. If this setting is not correct then weird issues may occur on your VMs from errors and BSOD to performance issues. These scripts will help you correct this issue:

Manually this can be done like this, but be aware that the VM needs to be turned off:

  1. In the vSphere Client inventory, right-click the virtual machine and select Edit Settings.
  2. Click the Options tab and select General Options.
  3. Select a guest operating system type and version.
  4. Click OK to save your changes and close the dialog box.

But scripted everything can be done automatically, which is useful when a lot of VMs are configured wrong.

Make an Overview

# Make an overview of all VMs that have the wrong OS configured
ForEach ($VM in (Get-VM)){
   $vmview = Get-VM $VM | Get-View
   $GuestFamily = $vmview.Guest.GuestFamily
   $GuestSelectedOS = $vmview.Summary.Config.GuestFullName
   $GuestRunningOS = $vmview.Guest.GuestFullname
   if (($GuestFamily -eq "windowsGuest") -and ($GuestSelectedOS -ne $GuestRunningOS)){
      # Choose your output: The first will give you a pretty but further useless output, the second one can be used to save as a cvs file, and the third can be directly used as input in the next script.
      #Write-Host "VM = $VM `n`t Guest Family = $GuestFamily `n`t Set OS       = $GuestSelectedOS `n`t Running OS   = $GuestRunningOS"
      #Write-Host "$vm,$GuestFamily,$GuestSelectedOS,$GuestRunningOS"
      #Write-Host "$vm"
   }
}

Change the Guest Selected OS

# Change the Guest selected OS for all VMs from an inputfile
## The inputfile needs to have one VM per line
## The VM will be turned off, and this will be checked before the change is made
## Afterwards the VM will be started again
 
# Start directory for the input file
$startdir = "D:\sjoerd"
 
# Creating Source List
$sourcename = "$startdir\inputfile.txt"
$vms = Get-Content $sourcename | Foreach-Object {Get-VM $_ }
 
# Scipt functions
# Note that you can suppress output from commands using | Out-Null
Function logger ($message) {Write-Host -ForegroundColor Green (Get-Date -format "yyyyMMdd-HH.mm.ss") `n "$message" `n}
Function loggeralert ($message) {Write-Host -ForegroundColor Red (Get-Date -format "yyyyMMdd-HH.mm.ss") `n "$message" `n}
 
Function PowerOn-VM($vm){
   Start-VM -VM $vm -Confirm:$false -RunAsync | Out-Null
   logger "$vm is starting!"
   sleep 5
   $time = 1
   # Now check if the VM is started within 120 loops with each 5 seconds of waittime
   do {
      $vmview = Get-VM $VM | Get-View
      $getvm = Get-VM $vm
      $powerstate = $getvm.PowerState
      $toolsstatus = $vmview.Guest.ToolsRunningStatus
      logger "$vm is starting, powerstate is $powerstate and toolsstatus is $toolsstatus!"
      sleep 5
      $time++
   # Adjust the timer $time to wait longer or shorter for the VM to start up. Lowering this value will not break anything, you'll just have to check manually whether the VM started successfully.
   }until((($powerstate -match "PoweredOn") -and ($toolsstatus -match "guestToolsRunning")) -or ($time -eq 2))
   if ($toolsstatus -match "guestToolsRunning"){
      logger "$vm is started and has ToolsStatus $toolsstatus"
   }
    else{$Startup = "ERROR"}
    return $Startup
}
 
Function PowerOff-VM($vm){
   Shutdown-VMGuest -VM $vm -Confirm:$false | Out-Null
   Logger "$vm is stopping!"
   sleep 5
   $shutdown = "starting"
   $time = 1
   # Now check if the VM is shutdown in 60 loops with each 5 seconds of waittime, and if not perform a hard shutdown
   do {
      $vmview = Get-VM $vm | Get-View
      $getvm = Get-VM $vm
      $powerstate = $getvm.PowerState
      $toolsstatus = $vmview.Guest.ToolsStatus
      logger "$vm is stopping with powerstate $powerstate and toolsStatus $toolsstatus!"
      sleep 5
      $time++
      if($time -eq 60){
        loggeralert "$vm is taking more than 5 minutes to shutdown. Hard powering off the VM."
        Stop-VM -VM $vm -Confirm:$false | Out-Null
      }
   }until(($powerstate -match "PoweredOff") -or ($time -eq 120))
   if ($powerstate -match "PoweredOff"){
      logger "$vm is powered-off"
   }
   else{$shutdown = "ERROR"}
   return $shutdown
}
 
# Handle each VM
foreach($item in $vms){
   $vm = $item.Name
   # ForEach ($VM in (Get-VM)){
   $vmview = Get-VM $VM | Get-View
   $GuestFamily = $vmview.Guest.GuestFamily
   $GuestSelectedOS = $vmview.Summary.Config.GuestFullName
   $GuestRunningOS = $vmview.Guest.GuestFullname
   if (($GuestFamily -eq "windowsGuest") -and ($GuestSelectedOS -ne $GuestRunningOS)){
      #logger "VM = $VM `n`t Guest Family = $GuestFamily `n`t Set OS       = $GuestSelectedOS `n`t Running OS   = $GuestRunningOS"
      #logger "$vm,$GuestFamily,$GuestSelectedOS,$GuestRunningOS"
      if ($GuestRunningOS -eq "Microsoft Windows Server 2008 R2 (64-bit)"){
         $poweroff = PowerOff-VM $vm
         if ($poweroff -ne "ERROR"){
            Get-VM $vm | Set-VM -GuestId "windows7Server64Guest" -Confirm:$false
            PowerOn-VM $vm
         }
      }
   }
}

Resources

You could leave a comment if you were logged in.
changeguestselectedos.txt · Last modified: 2021/09/24 00:24 (external edit)