build 7bbbddf7 | content blog-content@c8490fa · 338 posts | profiles 20 · corpus 267 | 0 skipped | | format
apiVersion: soultec.ch/v1kind: Postmetadata: name: powercli-automating-vmware-tools-and-hardware-upgrades locale: de labels: author: dario-doerflinger series: scripting capability/automation: 1.78 vendor/vmware: 0.88 annotations: source: blog-content/posts/de/powercli-automating-vmware-tools-and-hardware-upgrades.md route: /de/insights/powercli-automating-vmware-tools-and-hardware-upgrades/ schema: /nerd/schema/posts.json markdown: /de/insights/powercli-automating-vmware-tools-and-hardware-upgrades.mdspec: title: VMware Tools und Hardware-Upgrades automatisieren date: 2017-07-24 author: dario-doerflinger locale: de summary: >- Vor ein paar Jahren habe ich mich in einer grossen Umgebung mit dem VMware Update Manager herumgeschlagen. Rund 1000 VMs sollten neue VMware Tools und eine neue VM-Version bekommen. capabilities: [automation] vendors: [vmware] series: scripting migrated: 2026-08-24 translationReviewed: false draft: false sections: - body: | Vor ein paar Jahren habe ich mich in einer grossen Umgebung mit dem VMware Update Manager herumgeschlagen. Rund 1000 VMs sollten die neuesten VMware Tools und die aktuelle VM-Version bekommen, also die Hardware. Der VUM schaffte das nicht und blieb mitten im Job stehen. Weil dafür Shutdowns und Reboots nötig sind, hatten wir nur ein kleines Zeitfenster. Nach einem erfolglosen Versuch mit dem VUM haben wir es gescriptet. Das ursprüngliche Script wurde 2009 irgendwo veröffentlicht, die Quelle steht im Script. Wir haben es übernommen und ein paar Dinge ergänzt, etwa einen Snapshot vor der Installation auf einer Linux-VM. Kürzlich habe ich es auf die aktuelle VM-Version gehoben, also 13 aus vSphere 6.5. Update: Dieses Script liegt inzwischen auf [GitHub](https://github.com/virtualFrog/PowerCLI-Scripts). - heading:

Das Script

body: | ```powershell ##################################################################################################################### # Author: Bechtle Schweiz AG, Dario Doerflinger (c) 2015-2017 # Skript: Update_VMs_1.0.4.ps1 # Datum: 24.07.2017 # Version: 1.0.4 # Original Author: AFokkema: http://ict-freak.nl/2009/07/15/powercli-upgrading-vhardware-to-vsphere-part-2-vms/ # Changelog: # - Improved Readability and added a general variables section # - Addedd functionality to upgrade VM Version 7 VMs # - Added Snapshot Mechanism to enable Linux Tools Upgrade # - Added functionality to upgrade VM Versions to 11 # - Added functionality to upgrade VM Versions to 13 (12 is only for Desktop products) # - Changed Add-Snapin to Import Module (not relevant for PowerCLI 6.5.1) # # Summary: This script will upgrade the VMWare Tools level and the hardware level from VMs ##################################################################################################################### clear Write-Host " " Write-Host " " Write-Host "######################## Update_VMs_1.0.4.ps1 ##########################" Write-Host " " Write-Host " this script updates VMware Tools und hardware." Write-Host " " Write-Host "######################################################################" Write-Host " " Import-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null # This script adds some helper functions and sets the appearance. #"C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts\Initialize-PowerCliEnvironment.ps1" # Variables $vCenter = Read-Host "Enter your vCenter servername" #$Folder = Read-Host "Enter the name of the folder where the VMs are stored" $timestamp = Get-Date -format "yyyyMMdd-HH.mm" # Note: enter the csv file without extension: $csvfile = "c:\tmp\$timestamp-vminfo.csv" $logFile = "c:\tmp\vm-update.log" #Rotate the Logfile if (Test-Path $logFile) { if (Test-Path c:\tmp\old_vm-update.log) { Remove-Item -Path c:\tmp\old_vm-update.log -Force -Confirm:$false } Rename-Item -Path $logfile -NewName old_vm-update.log -Force -Confirm:$false } #LogFunction: Standard at Coop! function LogWrite { #Aufruf: LogWrite "Tobi ist doof" "INFO" "1" Param([string]$logString, [string]$logLevel, [string]$priority) $nowDate = Get-Date -Format dd.MM.yyyy $nowTime = Get-Date -Format HH:mm:ss if ($logLevel -eq "EMPTY") { Add-Content $logFile -value "$logstring" Write-Host $logString } else { Add-Content $logFile -value "[$logLevel][Prio: $priority][$nowDate][$nowTime] - $logString" Write-Host "[$logLevel][Prio: $priority][$nowDate][$nowTime] - $logString" } } ################################################################ # Einlesen der Cred fuer vCenter und ESXi Server # ################################################################ #$vcCred = C:\vm-scripts\Get-myCredential.ps1 butob C:\vm-scripts\credentials #$esxCred = C:\vm-scripts\Get-myCredential.ps1 root C:\vm-scripts\host-credential ############################################################### # Prompt for Credentials # ################################################################ $vcCred = $host.ui.PromptForCredential("VCENTER LOGIN", "Provide VCENTER credentials (administrator privileges)", "", "") #$esxCred = $host.ui.PromptForCredential("ESX HOST LOGIN", "Provide ESX host credentials (probably root)", "root", "") Function Make-Snapshot($vm) { $snapshot = New-Snapshot -VM $vm -Name "BeforeUpgradeVMware" -Description "Snapshot taken before Tools and Hardware was updated" -Confirm:$false } Function Delete-Snap() { get-vm | get-snapshot -Name "BeforeUpgradeVMware" | Remove-Snapshot -Confirm:$false # $snapshot = Get-Snapshot -Name "BeforeUpgradeVMware" -VM $vm # Remove-Snapshot -Snapshot $snapshot -Confirm:$false } Function VM-Selection { $sourcetype = Read-Host "Do you want to upgrade AllVMs, a VM, Folder, ResourcePool or from a VMfile?" if($sourcetype -eq "AllVMs") { $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs" #$vms = Get-VM | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name $vms = Get-VM | Get-View | Where-Object {-not $_.config.template} | Select Name } else { $sourcename = Read-Host "Give the name of the object or inputfile (full path) you want to upgrade" if($sourcetype -eq "VM") { $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs" #$vms = Get-VM $sourcename | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name $vms = Get-VM $sourcename | Get-View | Where-Object {-not $_.config.template} | Select Name } elseif($sourcetype -eq "Folder") { $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs" #$vms = Get-Folder $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name $vms = Get-Folder $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template} | Select Name } elseif($sourcetype -eq "ResourcePool") { $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs" #$vms = Get-ResourcePool $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name $vms = Get-ResourcePool $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template} | Select Name } elseif(($sourcetype -eq "VMfile") -and ((Test-Path -path $sourcename) -eq $True)) { $abort = Read-Host "You've chosen $sourcetype with this file: $sourcename, this is your last chance to abort by pressing +C. Press 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-08" } | 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 is not an exact match of AllVMs, VM, Folder, ResourcePool or VMfile, or the VMfile does not exist. Exit the script by pressing +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 +C to quit the script or press to continue" LogWrite "PowerOn Error detected on $vm" "ERROR" "1" [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 +C to quit the script or press to continue" LogWrite "PowerOff Error detected on $vm" "ERROR" "1" [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 +C to quit the script or press to continue" LogWrite "VMware Tools Error detected on $vm" "ERROR" "1" } return $vmTools } Function Check-VMHardwareVersion($vm) { $vmView = get-VM $vm | Get-View $vmVersion = $vmView.Config.Version $v7 = "vmx-07" $v8 = "vmx-08" $v9 = "vmx-09" $v10 = "vmx-10" $v11 = "vmx-11" $v13 = "vmx-13" if ($vmVersion -eq $v8) { $vmHardware = "Old" } elseif($vmVersion -eq $v7) { $vmHardware = "Old" } elseif($vmVersion -eq $v9) { $vmHardware = "Old" } elseif($vmVersion -eq $v10) { $vmHardware = "Old" } elseif($vmVersion -eq $v11) { $vmHardware = "Old" } elseif($vmVersion -eq $v13) { $vmHardware = "Ok" } else { $vmHardware = "ERROR" LogWrite "Hardware Version Error detected on $vm" "ERROR" "1" [console]::ForegroundColor = "Red" Read-Host "The Hardware version of $vm is not set to $v7 or $v8 or $v9 or $v10 or $v11 or $v13. This is unusual. Press +C to quit the script or press to continue" [console]::ResetColor() } return $vmHardware } Function Upgrade-VMHardware($vm) { $vmview = Get-VM $vm | Get-View $vmVersion = $vmView.Config.Version $v7 = "vmx-07" $v8 = "vmx-08" $v9 = "vmx-09" $v10 = "vmx-10" $v11 = "vmx-11" $v13 = "vmx-13" if ($vmVersion -eq $v7) { Write-Host "Version 7 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null } if ($vmVersion -eq $v8) { Write-Host "Version 8 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null } if ($vmVersion -eq $v9) { Write-Host "Version 9 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null } if ($vmVersion -eq $v10) { Write-Host "Version 10 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null } if ($vmVersion -eq $v11) { Write-Host "Version 10 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null } } 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 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 do { sleep 10 Write-Host "Checking ToolsStatus $vm now" $vmToolsStatus = Check-ToolsStatus $vm }until($vmToolsStatus -eq "OK") PowerOff-VM $vm PowerOn-VM $vm } else { LogWrite "Linux / Windows (no tools installed) detected: $vm" "WARNING" "1" # ToDo: If the guest is running windows but tools notrunning/notinstalled it might be an option to invoke the installation through powershell. # Options are then Invoke-VMScript cmdlet or through windows installer: msiexec-i "D: \ VMware Tools64.msi" ADDLOCAL = ALL REMOVE = Audio, Hgfs, VMXNet, WYSE, GuestSDK, VICFSDK, VAssertSDK / qn # 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 Write-Host "$vm is a $family with tools status $vmToolsStatus. We are going to do the upgrade, but we'll take a snapshot beforehand" if ($vmToolsStatus -ne "NotInstalled") { Make-Snapshot $vm Get-Date Get-VMGuest $vm | Update-Tools -NoReboot do { sleep 10 Write-Host "Checking ToolsStatus $vm now" $vmToolsStatus = Check-ToolsStatus $vm }until($vmToolsStatus -eq "OK") PowerOff-VM $vm PowerOn-VM $vm } } } 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." } } } Connect-VIServer -Server $vcenter -Credential $vcCred -WarningAction SilentlyContinue | out-null Write-Host "connecting to $vcenter" $vms = VM-Selection CreateHWList $vms $csvfile foreach($item in $vms) { $vm = $item.Name Write-Host "Test $vm" CheckAndUpgradeTools $vm CheckAndUpgrade $vm } CreateHWList $vms $csvfile # $toggle = Read-Host "Would you like me to remove the snapshots taken on Linux VMs? (yes/no)" # if ($toggle -eq "yes") # { # Get-VM | Delete-Snap # } Disconnect-VIServer -Confirm:$false ``` - heading:

Voraussetzungen

body: | Du brauchst PowerCLI, klar. Das Schöne an diesem Script: Du hast mehrere Wege, festzulegen, welche VMs es anfassen soll. - Eine Textdatei mit den Anzeigenamen der VMs, Zeile für Zeile - Einen Ordner oder Resource Pool, in dem die VMs liegen - Einen VM-Namen - Oder einfach alle VMs https://youtu.be/lq1vJ20\_QLI Wenn du Fragen hast, melde dich auf Twitter oder schreib einen Kommentar.status: corpus: 267 alsoLike: - {ref: posts/vmware-explore-las-vegas-hackathon-2025, score: 1.00} - {ref: posts/vmware-hackathon-2024-project, score: 1.00} - {ref: solutions/vmware/vmware-cloud-foundation/addon/application-services, score: 0.60}
{ "apiVersion": "soultec.ch/v1", "kind": "Post", "metadata": { "name": "powercli-automating-vmware-tools-and-hardware-upgrades", "locale": "de", "labels": { "author": "dario-doerflinger", "series": "scripting", "capability/automation": "1.78", "vendor/vmware": "0.88" }, "annotations": { "source": "blog-content/posts/de/powercli-automating-vmware-tools-and-hardware-upgrades.md", "route": "/de/insights/powercli-automating-vmware-tools-and-hardware-upgrades/", "schema": "/nerd/schema/posts.json", "markdown": "/de/insights/powercli-automating-vmware-tools-and-hardware-upgrades.md" } }, "spec": { "title": "VMware Tools und Hardware-Upgrades automatisieren", "date": "2017-07-24", "author": "dario-doerflinger", "locale": "de", "summary": "Vor ein paar Jahren habe ich mich in einer grossen Umgebung mit dem VMware Update Manager herumgeschlagen. Rund 1000 VMs sollten neue VMware Tools und eine neue VM-Version bekommen.", "capabilities": [ "automation" ], "vendors": [ "vmware" ], "series": "scripting", "migrated": "2026-08-24", "translationReviewed": false, "draft": false }, "sections": [ { "body": "Vor ein paar Jahren habe ich mich in einer grossen Umgebung mit dem VMware Update Manager herumgeschlagen. Rund 1000 VMs sollten die neuesten VMware Tools und die aktuelle VM-Version bekommen, also die Hardware. Der VUM schaffte das nicht und blieb mitten im Job stehen. Weil dafür Shutdowns und Reboots nötig sind, hatten wir nur ein kleines Zeitfenster. Nach einem erfolglosen Versuch mit dem VUM haben wir es gescriptet.\n\nDas ursprüngliche Script wurde 2009 irgendwo veröffentlicht, die Quelle steht im Script. Wir haben es übernommen und ein paar Dinge ergänzt, etwa einen Snapshot vor der Installation auf einer Linux-VM. Kürzlich habe ich es auf die aktuelle VM-Version gehoben, also 13 aus vSphere 6.5.\n\nUpdate: Dieses Script liegt inzwischen auf [GitHub](https://github.com/virtualFrog/PowerCLI-Scripts)." }, { "heading": "

Das Script

",
"body": "```powershell\n#####################################################################################################################\n# Author: Bechtle Schweiz AG, Dario Doerflinger (c) 2015-2017\n# Skript: Update_VMs_1.0.4.ps1\n# Datum: 24.07.2017\n# Version: 1.0.4\n# Original Author: AFokkema: http://ict-freak.nl/2009/07/15/powercli-upgrading-vhardware-to-vsphere-part-2-vms/\n# Changelog:\n# - Improved Readability and added a general variables section\n# - Addedd functionality to upgrade VM Version 7 VMs\n# - Added Snapshot Mechanism to enable Linux Tools Upgrade\n# - Added functionality to upgrade VM Versions to 11\n# - Added functionality to upgrade VM Versions to 13 (12 is only for Desktop products)\n# - Changed Add-Snapin to Import Module (not relevant for PowerCLI 6.5.1)\n#\n# Summary: This script will upgrade the VMWare Tools level and the hardware level from VMs\n#####################################################################################################################\nclear\nWrite-Host \" \"\nWrite-Host \" \"\nWrite-Host \"######################## Update_VMs_1.0.4.ps1 ##########################\"\nWrite-Host \" \"\nWrite-Host \" this script updates VMware Tools und hardware.\"\nWrite-Host \" \"\nWrite-Host \"######################################################################\"\nWrite-Host \" \"\n\nImport-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null\n# This script adds some helper functions and sets the appearance.\n#\"C:\\Program Files (x86)\\VMware\\Infrastructure\\vSphere PowerCLI\\Scripts\\Initialize-PowerCliEnvironment.ps1\"\n\n# Variables\n$vCenter = Read-Host \"Enter your vCenter servername\"\n#$Folder = Read-Host \"Enter the name of the folder where the VMs are stored\"\n$timestamp = Get-Date -format \"yyyyMMdd-HH.mm\"\n# Note: enter the csv file without extension:\n$csvfile = \"c:\\tmp\\$timestamp-vminfo.csv\"\n$logFile = \"c:\\tmp\\vm-update.log\"\n\n#Rotate the Logfile\nif (Test-Path $logFile)\n{\n if (Test-Path c:\\tmp\\old_vm-update.log)\n {\n Remove-Item -Path c:\\tmp\\old_vm-update.log -Force -Confirm:$false\n }\n Rename-Item -Path $logfile -NewName old_vm-update.log -Force -Confirm:$false\n}\n\n#LogFunction: Standard at Coop!\nfunction LogWrite\n{\n #Aufruf: LogWrite \"Tobi ist doof\" \"INFO\" \"1\"\n Param([string]$logString, [string]$logLevel, [string]$priority)\n $nowDate = Get-Date -Format dd.MM.yyyy\n $nowTime = Get-Date -Format HH:mm:ss\n\n if ($logLevel -eq \"EMPTY\")\n {\n Add-Content $logFile -value \"$logstring\"\n Write-Host $logString\n } else {\n Add-Content $logFile -value \"[$logLevel][Prio: $priority][$nowDate][$nowTime] - $logString\"\n Write-Host \"[$logLevel][Prio: $priority][$nowDate][$nowTime] - $logString\"\n\n }\n\n}\n\n################################################################\n# Einlesen der Cred fuer vCenter und ESXi Server #\n################################################################\n#$vcCred = C:\\vm-scripts\\Get-myCredential.ps1 butob C:\\vm-scripts\\credentials\n#$esxCred = C:\\vm-scripts\\Get-myCredential.ps1 root C:\\vm-scripts\\host-credential\n\n###############################################################\n# Prompt for Credentials #\n################################################################\n$vcCred = $host.ui.PromptForCredential(\"VCENTER LOGIN\", \"Provide VCENTER credentials (administrator privileges)\", \"\", \"\")\n#$esxCred = $host.ui.PromptForCredential(\"ESX HOST LOGIN\", \"Provide ESX host credentials (probably root)\", \"root\", \"\")\n\nFunction Make-Snapshot($vm)\n{\n $snapshot = New-Snapshot -VM $vm -Name \"BeforeUpgradeVMware\" -Description \"Snapshot taken before Tools and Hardware was updated\" -Confirm:$false\n\n}\n\nFunction Delete-Snap()\n{\n get-vm | get-snapshot -Name \"BeforeUpgradeVMware\" | Remove-Snapshot -Confirm:$false\n # $snapshot = Get-Snapshot -Name \"BeforeUpgradeVMware\" -VM $vm\n # Remove-Snapshot -Snapshot $snapshot -Confirm:$false\n}\n\nFunction VM-Selection\n{\n $sourcetype = Read-Host \"Do you want to upgrade AllVMs, a VM, Folder, ResourcePool or from a VMfile?\"\n if($sourcetype -eq \"AllVMs\")\n {\n $abort = Read-Host \"You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs\"\n #$vms = Get-VM | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq \"vmx-08\" } | Select Name\n $vms = Get-VM | Get-View | Where-Object {-not $_.config.template} | Select Name\n }\n else\n {\n $sourcename = Read-Host \"Give the name of the object or inputfile (full path) you want to upgrade\"\n if($sourcetype -eq \"VM\")\n {\n $abort = Read-Host \"You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs\"\n #$vms = Get-VM $sourcename | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq \"vmx-08\" } | Select Name\n $vms = Get-VM $sourcename | Get-View | Where-Object {-not $_.config.template} | Select Name\n }\n elseif($sourcetype -eq \"Folder\")\n {\n $abort = Read-Host \"You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs\"\n #$vms = Get-Folder $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq \"vmx-08\" } | Select Name\n $vms = Get-Folder $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template} | Select Name\n }\n elseif($sourcetype -eq \"ResourcePool\")\n {\n $abort = Read-Host \"You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs\"\n #$vms = Get-ResourcePool $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq \"vmx-08\" } | Select Name\n $vms = Get-ResourcePool $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template} | Select Name\n }\n elseif(($sourcetype -eq \"VMfile\") -and ((Test-Path -path $sourcename) -eq $True))\n {\n $abort = Read-Host \"You've chosen $sourcetype with this file: $sourcename, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs\"\n #$list = Get-Content $sourcename | Foreach-Object {Get-VM $_ | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq \"vmx-08\" } | Select Name }\n $list = Get-Content $sourcename | Foreach-Object {Get-VM $_ | Get-View | Where-Object {-not $_.config.template} | Select Name }\n $vms = $list\n }\n else\n {\n Write-Host \"$sourcetype is not an exact match of AllVMs, VM, Folder, ResourcePool or VMfile, or the VMfile does not exist. Exit the script by pressing +C and try again.\"\n }\n }\n return $vms\n}\n\nFunction PowerOn-VM($vm)\n{\n Start-VM -VM $vm -Confirm:$false -RunAsync | Out-Null\n Write-Host \"$vm is starting!\" -ForegroundColor Yellow\n sleep 10\n\n do\n {\n $vmview = get-VM $vm | Get-View\n $getvm = Get-VM $vm\n $powerstate = $getvm.PowerState\n $toolsstatus = $vmview.Guest.ToolsStatus\n\n Write-Host \"$vm is starting, powerstate is $powerstate and toolsstatus is $toolsstatus!\" -ForegroundColor Yellow\n sleep 5\n #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\n\n }until(($powerstate -match \"PoweredOn\") -and (($toolsstatus -match \"toolsOld\") -or ($toolsstatus -match \"toolsOk\") -or ($toolsstatus -match \"toolsNotInstalled\")))\n\n if (($toolsstatus -match \"toolsOk\") -or ($toolsstatus -match \"toolsOld\"))\n {\n $Startup = \"OK\"\n Write-Host \"$vm is started and has ToolsStatus $toolsstatus\"\n }\n else\n {\n $Startup = \"ERROR\"\n [console]::ForegroundColor = \"Red\"\n Read-Host \"The ToolsStatus of $vm is $toolsstatus. This is unusual. Press +C to quit the script or press to continue\"\n LogWrite \"PowerOn Error detected on $vm\" \"ERROR\" \"1\"\n [console]::ResetColor()\n }\n return $Startup\n}\n\nFunction PowerOff-VM($vm)\n{\n Shutdown-VMGuest -VM $vm -Confirm:$false | Out-Null\n Write-Host \"$vm is stopping!\" -ForegroundColor Yellow\n sleep 10\n\n do\n {\n $vmview = Get-VM $vm | Get-View\n $getvm = Get-VM $vm\n $powerstate = $getvm.PowerState\n $toolsstatus = $vmview.Guest.ToolsStatus\n\n Write-Host \"$vm is stopping with powerstate $powerstate and toolsStatus $toolsstatus!\" -ForegroundColor Yellow\n sleep 5\n\n }until($powerstate -match \"PoweredOff\")\n\n if (($powerstate -match \"PoweredOff\") -and (($toolsstatus -match \"toolsNotRunning\") -or ($toolsstatus -match \"toolsNotInstalled\")))\n {\n $Shutdown = \"OK\"\n Write-Host \"$vm is powered-off\"\n }\n else\n {\n $Shutdown = \"ERROR\"\n [console]::ForegroundColor = \"Red\"\n Read-Host \"The ToolsStatus of $vm is $toolsstatus. This is unusual. Press +C to quit the script or press to continue\"\n LogWrite \"PowerOff Error detected on $vm\" \"ERROR\" \"1\"\n [console]::ResetColor()\n }\n return $Shutdown\n}\n\nFunction Check-ToolsStatus($vm)\n{\n $vmview = get-VM $vm | Get-View\n $status = $vmview.Guest.ToolsStatus\n\n if ($status -match \"toolsOld\")\n {\n $vmTools = \"Old\"\n }\n elseif($status -match \"toolsNotRunning\")\n {\n $vmTools = \"NotRunning\"\n }\n elseif($status -match \"toolsNotInstalled\")\n {\n $vmTools = \"NotInstalled\"\n }\n elseif($status -match \"toolsOK\")\n {\n $vmTools = \"OK\"\n }\n else\n {\n $vmTools = \"ERROR\"\n Read-Host \"The ToolsStatus of $vm is $vmTools. Press +C to quit the script or press to continue\"\n LogWrite \"VMware Tools Error detected on $vm\" \"ERROR\" \"1\"\n }\n return $vmTools\n}\n\nFunction Check-VMHardwareVersion($vm)\n{\n $vmView = get-VM $vm | Get-View\n $vmVersion = $vmView.Config.Version\n $v7 = \"vmx-07\"\n $v8 = \"vmx-08\"\n $v9 = \"vmx-09\"\n $v10 = \"vmx-10\"\n $v11 = \"vmx-11\"\n $v13 = \"vmx-13\"\n if ($vmVersion -eq $v8)\n {\n $vmHardware = \"Old\"\n }\n elseif($vmVersion -eq $v7)\n {\n $vmHardware = \"Old\"\n }\n elseif($vmVersion -eq $v9)\n {\n $vmHardware = \"Old\"\n }\n elseif($vmVersion -eq $v10)\n {\n $vmHardware = \"Old\"\n }\n elseif($vmVersion -eq $v11)\n {\n $vmHardware = \"Old\"\n }\n elseif($vmVersion -eq $v13)\n {\n $vmHardware = \"Ok\"\n }\n else\n {\n $vmHardware = \"ERROR\"\n LogWrite \"Hardware Version Error detected on $vm\" \"ERROR\" \"1\"\n [console]::ForegroundColor = \"Red\"\n Read-Host \"The Hardware version of $vm is not set to $v7 or $v8 or $v9 or $v10 or $v11 or $v13. This is unusual. Press +C to quit the script or press to continue\"\n [console]::ResetColor()\n }\n return $vmHardware\n}\n\nFunction Upgrade-VMHardware($vm)\n{\n $vmview = Get-VM $vm | Get-View\n $vmVersion = $vmView.Config.Version\n $v7 = \"vmx-07\"\n $v8 = \"vmx-08\"\n $v9 = \"vmx-09\"\n $v10 = \"vmx-10\"\n $v11 = \"vmx-11\"\n $v13 = \"vmx-13\"\n\n if ($vmVersion -eq $v7)\n {\n Write-Host \"Version 7 detected\" -ForegroundColor Red\n\n # Update Hardware\n Write-Host \"Upgrading Hardware on\" $vm -ForegroundColor Yellow\n Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null\n }\n\n if ($vmVersion -eq $v8)\n {\n Write-Host \"Version 8 detected\" -ForegroundColor Red\n\n # Update Hardware\n Write-Host \"Upgrading Hardware on\" $vm -ForegroundColor Yellow\n Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null\n }\n\n if ($vmVersion -eq $v9)\n {\n Write-Host \"Version 9 detected\" -ForegroundColor Red\n\n # Update Hardware\n Write-Host \"Upgrading Hardware on\" $vm -ForegroundColor Yellow\n Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null\n }\n\n if ($vmVersion -eq $v10)\n {\n Write-Host \"Version 10 detected\" -ForegroundColor Red\n\n # Update Hardware\n Write-Host \"Upgrading Hardware on\" $vm -ForegroundColor Yellow\n Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null\n }\n\n if ($vmVersion -eq $v11)\n {\n Write-Host \"Version 10 detected\" -ForegroundColor Red\n\n # Update Hardware\n Write-Host \"Upgrading Hardware on\" $vm -ForegroundColor Yellow\n Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null\n }\n}\n\nFunction CreateHWList($vms, $csvfile)\n{\n # The setup for this hwlist comes from http://www.warmetal.nl/powerclicsvvminfo\n Write-Host \"Creating a CSV File with VM info\" -ForegroundColor Yellow\n\n $MyCol = @()\n ForEach ($item in $vms)\n {\n $vm = $item.Name\n # Variable getvm is required, for some reason the $vm cannot be used to query the host and the IP-address\n $getvm = Get-VM $VM\n $vmview = Get-VM $VM | Get-View\n\n # VM has to be turned on to make sure all information can be recorded\n $powerstate = $getvm.PowerState\n if ($powerstate -ne \"PoweredOn\")\n {\n PowerOn-VM $vm\n }\n\n $vmnic = Get-NetworkAdapter -VM $VM\n $nicmac = Get-NetworkAdapter -VM $VM | ForEach-Object {$_.MacAddress}\n $nictype = Get-NetworkAdapter -VM $VM | ForEach-Object {$_.Type}\n $nicname = Get-NetworkAdapter -VM $VM | ForEach-Object {$_.NetworkName}\n $VMInfo = \"\" | Select VMName,NICCount,IPAddress,MacAddress,NICType,NetworkName,GuestRunningOS,PowerState,ToolsVersion,ToolsStatus,ToolsRunningStatus,HWLevel,VMHost\n $VMInfo.VMName = $vmview.Name\n $VMInfo.NICCount = $vmview.Guest.Net.Count\n $VMInfo.IPAddress = [String]$getvm.Guest.IPAddress\n $VMInfo.MacAddress = [String]$nicmac\n $VMInfo.NICType = [String]$nictype\n $VMInfo.NetworkName = [String]$nicname\n $VMInfo.GuestRunningOS = $vmview.Guest.GuestFullname\n $VMInfo.PowerState = $getvm.PowerState\n $VMInfo.ToolsVersion = $vmview.Guest.ToolsVersion\n $VMInfo.ToolsStatus = $vmview.Guest.ToolsStatus\n $VMInfo.ToolsRunningStatus = $vmview.Guest.ToolsRunningStatus\n $VMInfo.HWLevel = $vmview.Config.Version\n $VMInfo.VMHost = $getvm.VMHost\n $myCol += $VMInfo\n }\n\n if ((Test-Path -path $csvfile) -ne $True)\n {\n $myCol |Export-csv -NoTypeInformation $csvfile\n }\n else\n {\n $myCol |Export-csv -NoTypeInformation $csvfile-after.csv\n }\n}\n\nFunction CheckAndUpgradeTools($vm)\n{\n $vmview = Get-VM $VM | Get-View\n $family = $vmview.Guest.GuestFamily\n $vmToolsStatus = Check-ToolsStatus $vm\n\n if($vmToolsStatus -eq \"OK\")\n {\n Write-Host \"The VM tools are $vmToolsStatus on $vm\"\n }\n elseif(($family -eq \"windowsGuest\") -and ($vmToolsStatus -ne \"NotInstalled\"))\n {\n Write-Host \"The VM tools are $vmToolsStatus on $vm. Starting update/install now! This will take at few minutes.\" -ForegroundColor Red\n Get-Date\n Get-VMGuest $vm | Update-Tools -NoReboot\n do\n {\n sleep 10\n Write-Host \"Checking ToolsStatus $vm now\"\n $vmToolsStatus = Check-ToolsStatus $vm\n }until($vmToolsStatus -eq \"OK\")\n PowerOff-VM $vm\n PowerOn-VM $vm\n }\n else\n {\n LogWrite \"Linux / Windows (no tools installed) detected: $vm\" \"WARNING\" \"1\"\n # ToDo: If the guest is running windows but tools notrunning/notinstalled it might be an option to invoke the installation through powershell.\n # Options are then Invoke-VMScript cmdlet or through windows installer: msiexec-i \"D: \\ VMware Tools64.msi\" ADDLOCAL = ALL REMOVE = Audio, Hgfs, VMXNet, WYSE, GuestSDK, VICFSDK, VAssertSDK / qn\n # We're skipping all non-windows guest since automated installs are not supported\n # Write-Host \"$vm is a $family with tools status $vmToolsStatus. Therefore we're skipping this VM\" -ForegroundColor Red\n\n Write-Host \"$vm is a $family with tools status $vmToolsStatus. We are going to do the upgrade, but we'll take a snapshot beforehand\"\n if ($vmToolsStatus -ne \"NotInstalled\")\n {\n Make-Snapshot $vm\n Get-Date\n Get-VMGuest $vm | Update-Tools -NoReboot\n do\n {\n sleep 10\n Write-Host \"Checking ToolsStatus $vm now\"\n $vmToolsStatus = Check-ToolsStatus $vm\n }until($vmToolsStatus -eq \"OK\")\n PowerOff-VM $vm\n PowerOn-VM $vm\n\n }\n\n }\n}\n\nFunction CheckAndUpgrade($vm)\n{\n $vmHardware = Check-VMHardwareVersion $vm\n $vmToolsStatus = Check-ToolsStatus $vm\n\n if($vmHardware -eq \"OK\")\n {\n Write-Host \"The hardware level is $vmHardware on $vm\"\n }\n elseif($vmToolsStatus -eq \"OK\")\n {\n Write-Host \"The hardware level is $vmHardware on $vm.\" -ForegroundColor Red\n $PowerOffVM = PowerOff-VM $vm\n if($PowerOffVM -eq \"OK\")\n {\n Write-Host \"Starting upgrade hardware level on $vm.\"\n Upgrade-VMHardware $vm\n sleep 5\n PowerOn-VM $vm\n Write-Host $vm \"is up to date\" -ForegroundColor Green\n }\n else\n {\n Write-Host \"There is something wrong with the hardware level or the tools of $vm. Skipping $vm.\"\n }\n }\n}\n\nConnect-VIServer -Server $vcenter -Credential $vcCred -WarningAction SilentlyContinue | out-null\nWrite-Host \"connecting to $vcenter\"\n\n$vms = VM-Selection\nCreateHWList $vms $csvfile\nforeach($item in $vms)\n{\n $vm = $item.Name\n Write-Host \"Test $vm\"\n CheckAndUpgradeTools $vm\n CheckAndUpgrade $vm\n}\nCreateHWList $vms $csvfile\n# $toggle = Read-Host \"Would you like me to remove the snapshots taken on Linux VMs? (yes/no)\"\n# if ($toggle -eq \"yes\")\n# {\n# Get-VM | Delete-Snap\n# }\nDisconnect-VIServer -Confirm:$false\n```" }, { "heading": "

Voraussetzungen

",
"body": "Du brauchst PowerCLI, klar. Das Schöne an diesem Script: Du hast mehrere Wege, festzulegen, welche VMs es anfassen soll.\n\n- Eine Textdatei mit den Anzeigenamen der VMs, Zeile für Zeile\n- Einen Ordner oder Resource Pool, in dem die VMs liegen\n- Einen VM-Namen\n- Oder einfach alle VMs\n\nhttps://youtu.be/lq1vJ20\\_QLI\n\nWenn du Fragen hast, melde dich auf Twitter oder schreib einen Kommentar." } ], "status": { "corpus": 267, "alsoLike": [ { "ref": "posts/vmware-explore-las-vegas-hackathon-2025", "score": "1.00" }, { "ref": "posts/vmware-hackathon-2024-project", "score": "1.00" }, { "ref": "solutions/vmware/vmware-cloud-foundation/addon/application-services", "score": "0.60" } ] }}
apiVersion = "soultec.ch/v1"kind = "Post"[metadata]name = "powercli-automating-vmware-tools-and-hardware-upgrades"locale = "de"[metadata.labels]author = "dario-doerflinger"series = "scripting""capability/automation" = "1.78""vendor/vmware" = "0.88"[metadata.annotations]source = "blog-content/posts/de/powercli-automating-vmware-tools-and-hardware-upgrades.md"route = "/de/insights/powercli-automating-vmware-tools-and-hardware-upgrades/"schema = "/nerd/schema/posts.json"markdown = "/de/insights/powercli-automating-vmware-tools-and-hardware-upgrades.md"[spec]title = "VMware Tools und Hardware-Upgrades automatisieren"date = 2017-07-24author = "dario-doerflinger"locale = "de"summary = "Vor ein paar Jahren habe ich mich in einer grossen Umgebung mit dem VMware Update Manager herumgeschlagen. Rund 1000 VMs sollten neue VMware Tools und eine neue VM-Version bekommen."capabilities = ["automation"]vendors = ["vmware"]series = "scripting"migrated = 2026-08-24translationReviewed = falsedraft = false[[sections]]body = '''Vor ein paar Jahren habe ich mich in einer grossen Umgebung mit dem VMware Update Manager herumgeschlagen. Rund 1000 VMs sollten die neuesten VMware Tools und die aktuelle VM-Version bekommen, also die Hardware. Der VUM schaffte das nicht und blieb mitten im Job stehen. Weil dafür Shutdowns und Reboots nötig sind, hatten wir nur ein kleines Zeitfenster. Nach einem erfolglosen Versuch mit dem VUM haben wir es gescriptet.Das ursprüngliche Script wurde 2009 irgendwo veröffentlicht, die Quelle steht im Script. Wir haben es übernommen und ein paar Dinge ergänzt, etwa einen Snapshot vor der Installation auf einer Linux-VM. Kürzlich habe ich es auf die aktuelle VM-Version gehoben, also 13 aus vSphere 6.5.Update: Dieses Script liegt inzwischen auf [GitHub](https://github.com/virtualFrog/PowerCLI-Scripts).'''[[sections]]heading = "

Das Script

"
body = '''```powershell###################################################################################################################### Author: Bechtle Schweiz AG, Dario Doerflinger (c) 2015-2017# Skript: Update_VMs_1.0.4.ps1# Datum: 24.07.2017# Version: 1.0.4# Original Author: AFokkema: http://ict-freak.nl/2009/07/15/powercli-upgrading-vhardware-to-vsphere-part-2-vms/# Changelog:# - Improved Readability and added a general variables section# - Addedd functionality to upgrade VM Version 7 VMs# - Added Snapshot Mechanism to enable Linux Tools Upgrade# - Added functionality to upgrade VM Versions to 11# - Added functionality to upgrade VM Versions to 13 (12 is only for Desktop products)# - Changed Add-Snapin to Import Module (not relevant for PowerCLI 6.5.1)## Summary: This script will upgrade the VMWare Tools level and the hardware level from VMs#####################################################################################################################clearWrite-Host " "Write-Host " "Write-Host "######################## Update_VMs_1.0.4.ps1 ##########################"Write-Host " "Write-Host " this script updates VMware Tools und hardware."Write-Host " "Write-Host "######################################################################"Write-Host " "Import-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null# This script adds some helper functions and sets the appearance.#"C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts\Initialize-PowerCliEnvironment.ps1"# Variables$vCenter = Read-Host "Enter your vCenter servername"#$Folder = Read-Host "Enter the name of the folder where the VMs are stored"$timestamp = Get-Date -format "yyyyMMdd-HH.mm"# Note: enter the csv file without extension:$csvfile = "c:\tmp\$timestamp-vminfo.csv"$logFile = "c:\tmp\vm-update.log"#Rotate the Logfileif (Test-Path $logFile){ if (Test-Path c:\tmp\old_vm-update.log) { Remove-Item -Path c:\tmp\old_vm-update.log -Force -Confirm:$false } Rename-Item -Path $logfile -NewName old_vm-update.log -Force -Confirm:$false}#LogFunction: Standard at Coop!function LogWrite{ #Aufruf: LogWrite "Tobi ist doof" "INFO" "1" Param([string]$logString, [string]$logLevel, [string]$priority) $nowDate = Get-Date -Format dd.MM.yyyy $nowTime = Get-Date -Format HH:mm:ss if ($logLevel -eq "EMPTY") { Add-Content $logFile -value "$logstring" Write-Host $logString } else { Add-Content $logFile -value "[$logLevel][Prio: $priority][$nowDate][$nowTime] - $logString" Write-Host "[$logLevel][Prio: $priority][$nowDate][$nowTime] - $logString" }}################################################################# Einlesen der Cred fuer vCenter und ESXi Server ##################################################################$vcCred = C:\vm-scripts\Get-myCredential.ps1 butob C:\vm-scripts\credentials#$esxCred = C:\vm-scripts\Get-myCredential.ps1 root C:\vm-scripts\host-credential################################################################ Prompt for Credentials #################################################################$vcCred = $host.ui.PromptForCredential("VCENTER LOGIN", "Provide VCENTER credentials (administrator privileges)", "", "")#$esxCred = $host.ui.PromptForCredential("ESX HOST LOGIN", "Provide ESX host credentials (probably root)", "root", "")Function Make-Snapshot($vm){ $snapshot = New-Snapshot -VM $vm -Name "BeforeUpgradeVMware" -Description "Snapshot taken before Tools and Hardware was updated" -Confirm:$false}Function Delete-Snap(){ get-vm | get-snapshot -Name "BeforeUpgradeVMware" | Remove-Snapshot -Confirm:$false # $snapshot = Get-Snapshot -Name "BeforeUpgradeVMware" -VM $vm # Remove-Snapshot -Snapshot $snapshot -Confirm:$false}Function VM-Selection{ $sourcetype = Read-Host "Do you want to upgrade AllVMs, a VM, Folder, ResourcePool or from a VMfile?" if($sourcetype -eq "AllVMs") { $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs" #$vms = Get-VM | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name $vms = Get-VM | Get-View | Where-Object {-not $_.config.template} | Select Name } else { $sourcename = Read-Host "Give the name of the object or inputfile (full path) you want to upgrade" if($sourcetype -eq "VM") { $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs" #$vms = Get-VM $sourcename | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name $vms = Get-VM $sourcename | Get-View | Where-Object {-not $_.config.template} | Select Name } elseif($sourcetype -eq "Folder") { $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs" #$vms = Get-Folder $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name $vms = Get-Folder $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template} | Select Name } elseif($sourcetype -eq "ResourcePool") { $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs" #$vms = Get-ResourcePool $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name $vms = Get-ResourcePool $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template} | Select Name } elseif(($sourcetype -eq "VMfile") -and ((Test-Path -path $sourcename) -eq $True)) { $abort = Read-Host "You've chosen $sourcetype with this file: $sourcename, this is your last chance to abort by pressing +C. Press 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-08" } | 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 is not an exact match of AllVMs, VM, Folder, ResourcePool or VMfile, or the VMfile does not exist. Exit the script by pressing +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 +C to quit the script or press to continue" LogWrite "PowerOn Error detected on $vm" "ERROR" "1" [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 +C to quit the script or press to continue" LogWrite "PowerOff Error detected on $vm" "ERROR" "1" [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 +C to quit the script or press to continue" LogWrite "VMware Tools Error detected on $vm" "ERROR" "1" } return $vmTools}Function Check-VMHardwareVersion($vm){ $vmView = get-VM $vm | Get-View $vmVersion = $vmView.Config.Version $v7 = "vmx-07" $v8 = "vmx-08" $v9 = "vmx-09" $v10 = "vmx-10" $v11 = "vmx-11" $v13 = "vmx-13" if ($vmVersion -eq $v8) { $vmHardware = "Old" } elseif($vmVersion -eq $v7) { $vmHardware = "Old" } elseif($vmVersion -eq $v9) { $vmHardware = "Old" } elseif($vmVersion -eq $v10) { $vmHardware = "Old" } elseif($vmVersion -eq $v11) { $vmHardware = "Old" } elseif($vmVersion -eq $v13) { $vmHardware = "Ok" } else { $vmHardware = "ERROR" LogWrite "Hardware Version Error detected on $vm" "ERROR" "1" [console]::ForegroundColor = "Red" Read-Host "The Hardware version of $vm is not set to $v7 or $v8 or $v9 or $v10 or $v11 or $v13. This is unusual. Press +C to quit the script or press to continue" [console]::ResetColor() } return $vmHardware}Function Upgrade-VMHardware($vm){ $vmview = Get-VM $vm | Get-View $vmVersion = $vmView.Config.Version $v7 = "vmx-07" $v8 = "vmx-08" $v9 = "vmx-09" $v10 = "vmx-10" $v11 = "vmx-11" $v13 = "vmx-13" if ($vmVersion -eq $v7) { Write-Host "Version 7 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null } if ($vmVersion -eq $v8) { Write-Host "Version 8 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null } if ($vmVersion -eq $v9) { Write-Host "Version 9 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null } if ($vmVersion -eq $v10) { Write-Host "Version 10 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null } if ($vmVersion -eq $v11) { Write-Host "Version 10 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null }}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 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 do { sleep 10 Write-Host "Checking ToolsStatus $vm now" $vmToolsStatus = Check-ToolsStatus $vm }until($vmToolsStatus -eq "OK") PowerOff-VM $vm PowerOn-VM $vm } else { LogWrite "Linux / Windows (no tools installed) detected: $vm" "WARNING" "1" # ToDo: If the guest is running windows but tools notrunning/notinstalled it might be an option to invoke the installation through powershell. # Options are then Invoke-VMScript cmdlet or through windows installer: msiexec-i "D: \ VMware Tools64.msi" ADDLOCAL = ALL REMOVE = Audio, Hgfs, VMXNet, WYSE, GuestSDK, VICFSDK, VAssertSDK / qn # 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 Write-Host "$vm is a $family with tools status $vmToolsStatus. We are going to do the upgrade, but we'll take a snapshot beforehand" if ($vmToolsStatus -ne "NotInstalled") { Make-Snapshot $vm Get-Date Get-VMGuest $vm | Update-Tools -NoReboot do { sleep 10 Write-Host "Checking ToolsStatus $vm now" $vmToolsStatus = Check-ToolsStatus $vm }until($vmToolsStatus -eq "OK") PowerOff-VM $vm PowerOn-VM $vm } }}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." } }}Connect-VIServer -Server $vcenter -Credential $vcCred -WarningAction SilentlyContinue | out-nullWrite-Host "connecting to $vcenter"$vms = VM-SelectionCreateHWList $vms $csvfileforeach($item in $vms){ $vm = $item.Name Write-Host "Test $vm" CheckAndUpgradeTools $vm CheckAndUpgrade $vm}CreateHWList $vms $csvfile# $toggle = Read-Host "Would you like me to remove the snapshots taken on Linux VMs? (yes/no)"# if ($toggle -eq "yes")# {# Get-VM | Delete-Snap# }Disconnect-VIServer -Confirm:$false```'''[[sections]]heading = "

Voraussetzungen

"
body = '''Du brauchst PowerCLI, klar. Das Schöne an diesem Script: Du hast mehrere Wege, festzulegen, welche VMs es anfassen soll.- Eine Textdatei mit den Anzeigenamen der VMs, Zeile für Zeile- Einen Ordner oder Resource Pool, in dem die VMs liegen- Einen VM-Namen- Oder einfach alle VMshttps://youtu.be/lq1vJ20\_QLIWenn du Fragen hast, melde dich auf Twitter oder schreib einen Kommentar.'''[status]corpus = 267[[status.alsoLike]]ref = "posts/vmware-explore-las-vegas-hackathon-2025"score = "1.00"[[status.alsoLike]]ref = "posts/vmware-hackathon-2024-project"score = "1.00"[[status.alsoLike]]ref = "solutions/vmware/vmware-cloud-foundation/addon/application-services"score = "0.60"
<?xml version="1.0" encoding="UTF-8"?><manifest kind="Post"> <apiVersion>soultec.ch/v1</apiVersion> <metadata> <name>powercli-automating-vmware-tools-and-hardware-upgrades</name> <locale>de</locale> <labels> <author>dario-doerflinger</author> <series>scripting</series> <entry key="capability/automation">1.78</entry> <entry key="vendor/vmware">0.88</entry> </labels> <annotations> <source>blog-content/posts/de/powercli-automating-vmware-tools-and-hardware-upgrades.md</source> <route>/de/insights/powercli-automating-vmware-tools-and-hardware-upgrades/</route> <schema>/nerd/schema/posts.json</schema> <markdown>/de/insights/powercli-automating-vmware-tools-and-hardware-upgrades.md</markdown> </annotations> </metadata> <spec> <title>VMware Tools und Hardware-Upgrades automatisieren</title> <date>2017-07-24</date> <author>dario-doerflinger</author> <locale>de</locale> <summary>Vor ein paar Jahren habe ich mich in einer grossen Umgebung mit dem VMware Update Manager herumgeschlagen. Rund 1000 VMs sollten neue VMware Tools und eine neue VM-Version bekommen.</summary> <capabilities> <item>automation</item> </capabilities> <vendors> <item>vmware</item> </vendors> <series>scripting</series> <migrated>2026-08-24</migrated> <translationReviewed>false</translationReviewed> <draft>false</draft> </spec> <sections> <section> <body>Vor ein paar Jahren habe ich mich in einer grossen Umgebung mit dem VMware Update Manager herumgeschlagen. Rund 1000 VMs sollten die neuesten VMware Tools und die aktuelle VM-Version bekommen, also die Hardware. Der VUM schaffte das nicht und blieb mitten im Job stehen. Weil dafür Shutdowns und Reboots nötig sind, hatten wir nur ein kleines Zeitfenster. Nach einem erfolglosen Versuch mit dem VUM haben wir es gescriptet.Das ursprüngliche Script wurde 2009 irgendwo veröffentlicht, die Quelle steht im Script. Wir haben es übernommen und ein paar Dinge ergänzt, etwa einen Snapshot vor der Installation auf einer Linux-VM. Kürzlich habe ich es auf die aktuelle VM-Version gehoben, also 13 aus vSphere 6.5.Update: Dieses Script liegt inzwischen auf [GitHub](https://github.com/virtualFrog/PowerCLI-Scripts). </body> </section> <section> <heading>

Das Script

</heading>
<body>```powershell###################################################################################################################### Author: Bechtle Schweiz AG, Dario Doerflinger (c) 2015-2017# Skript: Update_VMs_1.0.4.ps1# Datum: 24.07.2017# Version: 1.0.4# Original Author: AFokkema: http://ict-freak.nl/2009/07/15/powercli-upgrading-vhardware-to-vsphere-part-2-vms/# Changelog:# - Improved Readability and added a general variables section# - Addedd functionality to upgrade VM Version 7 VMs# - Added Snapshot Mechanism to enable Linux Tools Upgrade# - Added functionality to upgrade VM Versions to 11# - Added functionality to upgrade VM Versions to 13 (12 is only for Desktop products)# - Changed Add-Snapin to Import Module (not relevant for PowerCLI 6.5.1)## Summary: This script will upgrade the VMWare Tools level and the hardware level from VMs#####################################################################################################################clearWrite-Host " "Write-Host " "Write-Host "######################## Update_VMs_1.0.4.ps1 ##########################"Write-Host " "Write-Host " this script updates VMware Tools und hardware."Write-Host " "Write-Host "######################################################################"Write-Host " "Import-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null# This script adds some helper functions and sets the appearance.#"C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts\Initialize-PowerCliEnvironment.ps1"# Variables$vCenter = Read-Host "Enter your vCenter servername"#$Folder = Read-Host "Enter the name of the folder where the VMs are stored"$timestamp = Get-Date -format "yyyyMMdd-HH.mm"# Note: enter the csv file without extension:$csvfile = "c:\tmp\$timestamp-vminfo.csv"$logFile = "c:\tmp\vm-update.log"#Rotate the Logfileif (Test-Path $logFile){ if (Test-Path c:\tmp\old_vm-update.log) { Remove-Item -Path c:\tmp\old_vm-update.log -Force -Confirm:$false } Rename-Item -Path $logfile -NewName old_vm-update.log -Force -Confirm:$false}#LogFunction: Standard at Coop!function LogWrite{ #Aufruf: LogWrite "Tobi ist doof" "INFO" "1" Param([string]$logString, [string]$logLevel, [string]$priority) $nowDate = Get-Date -Format dd.MM.yyyy $nowTime = Get-Date -Format HH:mm:ss if ($logLevel -eq "EMPTY") { Add-Content $logFile -value "$logstring" Write-Host $logString } else { Add-Content $logFile -value "[$logLevel][Prio: $priority][$nowDate][$nowTime] - $logString" Write-Host "[$logLevel][Prio: $priority][$nowDate][$nowTime] - $logString" }}################################################################# Einlesen der Cred fuer vCenter und ESXi Server ##################################################################$vcCred = C:\vm-scripts\Get-myCredential.ps1 butob C:\vm-scripts\credentials#$esxCred = C:\vm-scripts\Get-myCredential.ps1 root C:\vm-scripts\host-credential################################################################ Prompt for Credentials #################################################################$vcCred = $host.ui.PromptForCredential("VCENTER LOGIN", "Provide VCENTER credentials (administrator privileges)", "", "")#$esxCred = $host.ui.PromptForCredential("ESX HOST LOGIN", "Provide ESX host credentials (probably root)", "root", "")Function Make-Snapshot($vm){ $snapshot = New-Snapshot -VM $vm -Name "BeforeUpgradeVMware" -Description "Snapshot taken before Tools and Hardware was updated" -Confirm:$false}Function Delete-Snap(){ get-vm | get-snapshot -Name "BeforeUpgradeVMware" | Remove-Snapshot -Confirm:$false # $snapshot = Get-Snapshot -Name "BeforeUpgradeVMware" -VM $vm # Remove-Snapshot -Snapshot $snapshot -Confirm:$false}Function VM-Selection{ $sourcetype = Read-Host "Do you want to upgrade AllVMs, a VM, Folder, ResourcePool or from a VMfile?" if($sourcetype -eq "AllVMs") { $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs" #$vms = Get-VM | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name $vms = Get-VM | Get-View | Where-Object {-not $_.config.template} | Select Name } else { $sourcename = Read-Host "Give the name of the object or inputfile (full path) you want to upgrade" if($sourcetype -eq "VM") { $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs" #$vms = Get-VM $sourcename | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name $vms = Get-VM $sourcename | Get-View | Where-Object {-not $_.config.template} | Select Name } elseif($sourcetype -eq "Folder") { $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs" #$vms = Get-Folder $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name $vms = Get-Folder $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template} | Select Name } elseif($sourcetype -eq "ResourcePool") { $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press to continue selecting old hardware VMs" #$vms = Get-ResourcePool $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name $vms = Get-ResourcePool $sourcename | Get-VM | Get-View | Where-Object {-not $_.config.template} | Select Name } elseif(($sourcetype -eq "VMfile") -and ((Test-Path -path $sourcename) -eq $True)) { $abort = Read-Host "You've chosen $sourcetype with this file: $sourcename, this is your last chance to abort by pressing +C. Press 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-08" } | 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 is not an exact match of AllVMs, VM, Folder, ResourcePool or VMfile, or the VMfile does not exist. Exit the script by pressing +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 +C to quit the script or press to continue" LogWrite "PowerOn Error detected on $vm" "ERROR" "1" [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 +C to quit the script or press to continue" LogWrite "PowerOff Error detected on $vm" "ERROR" "1" [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 +C to quit the script or press to continue" LogWrite "VMware Tools Error detected on $vm" "ERROR" "1" } return $vmTools}Function Check-VMHardwareVersion($vm){ $vmView = get-VM $vm | Get-View $vmVersion = $vmView.Config.Version $v7 = "vmx-07" $v8 = "vmx-08" $v9 = "vmx-09" $v10 = "vmx-10" $v11 = "vmx-11" $v13 = "vmx-13" if ($vmVersion -eq $v8) { $vmHardware = "Old" } elseif($vmVersion -eq $v7) { $vmHardware = "Old" } elseif($vmVersion -eq $v9) { $vmHardware = "Old" } elseif($vmVersion -eq $v10) { $vmHardware = "Old" } elseif($vmVersion -eq $v11) { $vmHardware = "Old" } elseif($vmVersion -eq $v13) { $vmHardware = "Ok" } else { $vmHardware = "ERROR" LogWrite "Hardware Version Error detected on $vm" "ERROR" "1" [console]::ForegroundColor = "Red" Read-Host "The Hardware version of $vm is not set to $v7 or $v8 or $v9 or $v10 or $v11 or $v13. This is unusual. Press +C to quit the script or press to continue" [console]::ResetColor() } return $vmHardware}Function Upgrade-VMHardware($vm){ $vmview = Get-VM $vm | Get-View $vmVersion = $vmView.Config.Version $v7 = "vmx-07" $v8 = "vmx-08" $v9 = "vmx-09" $v10 = "vmx-10" $v11 = "vmx-11" $v13 = "vmx-13" if ($vmVersion -eq $v7) { Write-Host "Version 7 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null } if ($vmVersion -eq $v8) { Write-Host "Version 8 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null } if ($vmVersion -eq $v9) { Write-Host "Version 9 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null } if ($vmVersion -eq $v10) { Write-Host "Version 10 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null } if ($vmVersion -eq $v11) { Write-Host "Version 10 detected" -ForegroundColor Red # Update Hardware Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null }}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 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 do { sleep 10 Write-Host "Checking ToolsStatus $vm now" $vmToolsStatus = Check-ToolsStatus $vm }until($vmToolsStatus -eq "OK") PowerOff-VM $vm PowerOn-VM $vm } else { LogWrite "Linux / Windows (no tools installed) detected: $vm" "WARNING" "1" # ToDo: If the guest is running windows but tools notrunning/notinstalled it might be an option to invoke the installation through powershell. # Options are then Invoke-VMScript cmdlet or through windows installer: msiexec-i "D: \ VMware Tools64.msi" ADDLOCAL = ALL REMOVE = Audio, Hgfs, VMXNet, WYSE, GuestSDK, VICFSDK, VAssertSDK / qn # 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 Write-Host "$vm is a $family with tools status $vmToolsStatus. We are going to do the upgrade, but we'll take a snapshot beforehand" if ($vmToolsStatus -ne "NotInstalled") { Make-Snapshot $vm Get-Date Get-VMGuest $vm | Update-Tools -NoReboot do { sleep 10 Write-Host "Checking ToolsStatus $vm now" $vmToolsStatus = Check-ToolsStatus $vm }until($vmToolsStatus -eq "OK") PowerOff-VM $vm PowerOn-VM $vm } }}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." } }}Connect-VIServer -Server $vcenter -Credential $vcCred -WarningAction SilentlyContinue | out-nullWrite-Host "connecting to $vcenter"$vms = VM-SelectionCreateHWList $vms $csvfileforeach($item in $vms){ $vm = $item.Name Write-Host "Test $vm" CheckAndUpgradeTools $vm CheckAndUpgrade $vm}CreateHWList $vms $csvfile# $toggle = Read-Host "Would you like me to remove the snapshots taken on Linux VMs? (yes/no)"# if ($toggle -eq "yes")# {# Get-VM | Delete-Snap# }Disconnect-VIServer -Confirm:$false``` </body> </section> <section> <heading>

Voraussetzungen

</heading>
<body>Du brauchst PowerCLI, klar. Das Schöne an diesem Script: Du hast mehrere Wege, festzulegen, welche VMs es anfassen soll.- Eine Textdatei mit den Anzeigenamen der VMs, Zeile für Zeile- Einen Ordner oder Resource Pool, in dem die VMs liegen- Einen VM-Namen- Oder einfach alle VMshttps://youtu.be/lq1vJ20\_QLIWenn du Fragen hast, melde dich auf Twitter oder schreib einen Kommentar. </body> </section> </sections> <status> <corpus>267</corpus> <alsoLike> <item> <ref>posts/vmware-explore-las-vegas-hackathon-2025</ref> <score>1.00</score> </item> <item> <ref>posts/vmware-hackathon-2024-project</ref> <score>1.00</score> </item> <item> <ref>solutions/vmware/vmware-cloud-foundation/addon/application-services</ref> <score>0.60</score> </item> </alsoLike> </status></manifest>
Scripting · 2017-07-24

VMware Tools und Hardware-Upgrades automatisieren

Vor ein paar Jahren habe ich mich in einer grossen Umgebung mit dem VMware Update Manager herumgeschlagen. Rund 1000 VMs sollten neue VMware Tools und eine neue VM-Version bekommen.

2017-07-24Datum
Dario DörflingerAutor
11Min. Lesezeit
Themen Automation 1.78
Hersteller VMware 0.88

Dieser Beitrag ist von 2017. Er bleibt online, weil er nach wie vor nachgefragt wird, beschreibt aber einen Produktstand von damals.

Vor ein paar Jahren habe ich mich in einer grossen Umgebung mit dem VMware Update Manager herumgeschlagen. Rund 1000 VMs sollten die neuesten VMware Tools und die aktuelle VM-Version bekommen, also die Hardware. Der VUM schaffte das nicht und blieb mitten im Job stehen. Weil dafür Shutdowns und Reboots nötig sind, hatten wir nur ein kleines Zeitfenster. Nach einem erfolglosen Versuch mit dem VUM haben wir es gescriptet.

Das ursprüngliche Script wurde 2009 irgendwo veröffentlicht, die Quelle steht im Script. Wir haben es übernommen und ein paar Dinge ergänzt, etwa einen Snapshot vor der Installation auf einer Linux-VM. Kürzlich habe ich es auf die aktuelle VM-Version gehoben, also 13 aus vSphere 6.5.

Update: Dieses Script liegt inzwischen auf GitHub.

Das Script

#####################################################################################################################
# Author:           Bechtle Schweiz AG, Dario Doerflinger (c) 2015-2017
# Skript:           Update_VMs_1.0.4.ps1
# Datum:            24.07.2017
# Version:          1.0.4
# Original Author:  AFokkema: http://ict-freak.nl/2009/07/15/powercli-upgrading-vhardware-to-vsphere-part-2-vms/
# Changelog:
#                   - Improved Readability and added a general variables section
#                   - Addedd functionality to upgrade VM Version 7 VMs
#                   - Added Snapshot Mechanism to enable Linux Tools Upgrade
#                   - Added functionality to upgrade VM Versions to 11
#                   - Added functionality to upgrade VM Versions to 13 (12 is only for Desktop products)
#                   - Changed Add-Snapin to Import Module (not relevant for PowerCLI 6.5.1)
#
# Summary:          This script will upgrade the VMWare Tools level and the hardware level from VMs
#####################################################################################################################
clear
Write-Host " "
Write-Host " "
Write-Host "######################## Update_VMs_1.0.4.ps1 ##########################"
Write-Host " "
Write-Host "            this script updates  VMware Tools und hardware."
Write-Host " "
Write-Host "######################################################################"
Write-Host " "

Import-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue | Out-Null
# This script adds some helper functions and sets the appearance.
#"C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts\Initialize-PowerCliEnvironment.ps1"

# Variables
$vCenter = Read-Host "Enter your vCenter servername"
#$Folder = Read-Host "Enter the name of the folder where the VMs are stored"
$timestamp = Get-Date -format "yyyyMMdd-HH.mm"
# Note: enter the csv file without extension:
$csvfile = "c:\tmp\$timestamp-vminfo.csv"
$logFile = "c:\tmp\vm-update.log"

#Rotate the Logfile
if (Test-Path $logFile)
{
    if (Test-Path c:\tmp\old_vm-update.log)
    {
        Remove-Item -Path c:\tmp\old_vm-update.log -Force -Confirm:$false
    }
    Rename-Item -Path $logfile -NewName old_vm-update.log -Force -Confirm:$false
}

#LogFunction: Standard at Coop!
function LogWrite
{
    #Aufruf: LogWrite "Tobi ist doof" "INFO" "1"
    Param([string]$logString, [string]$logLevel, [string]$priority)
    $nowDate = Get-Date -Format dd.MM.yyyy
    $nowTime = Get-Date -Format HH:mm:ss

    if ($logLevel -eq "EMPTY")
    {
        Add-Content $logFile -value "$logstring"
        Write-Host $logString
    } else {
        Add-Content $logFile -value "[$logLevel][Prio: $priority][$nowDate][$nowTime] - $logString"
        Write-Host "[$logLevel][Prio: $priority][$nowDate][$nowTime] - $logString"

    }

}

################################################################
#       Einlesen der Cred fuer vCenter und ESXi Server          #
################################################################
#$vcCred = C:\vm-scripts\Get-myCredential.ps1 butob C:\vm-scripts\credentials
#$esxCred = C:\vm-scripts\Get-myCredential.ps1 root C:\vm-scripts\host-credential

###############################################################
#                  Prompt for Credentials                      #
################################################################
$vcCred = $host.ui.PromptForCredential("VCENTER LOGIN", "Provide VCENTER credentials (administrator privileges)", "", "")
#$esxCred = $host.ui.PromptForCredential("ESX HOST LOGIN", "Provide ESX host credentials (probably root)", "root", "")

Function Make-Snapshot($vm)
{
  $snapshot = New-Snapshot -VM $vm -Name "BeforeUpgradeVMware" -Description "Snapshot taken before Tools and Hardware was updated" -Confirm:$false

}

Function Delete-Snap()
{
  get-vm | get-snapshot -Name "BeforeUpgradeVMware" | Remove-Snapshot -Confirm:$false
  # $snapshot = Get-Snapshot -Name "BeforeUpgradeVMware" -VM $vm
  # Remove-Snapshot -Snapshot $snapshot -Confirm:$false
}

Function VM-Selection
{
   $sourcetype = Read-Host "Do you want to upgrade AllVMs, a VM, Folder, ResourcePool or from a VMfile?"
   if($sourcetype -eq "AllVMs")
   {
      $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press  to continue selecting old hardware VMs"
      #$vms = Get-VM | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name
      $vms = Get-VM | Get-View | Where-Object {-not $_.config.template} | Select Name
   }
   else
   {
      $sourcename = Read-Host "Give the name of the object or inputfile (full path) you want to upgrade"
      if($sourcetype -eq "VM")
      {
        $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press  to continue selecting old hardware VMs"
        #$vms = Get-VM $sourcename | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name
        $vms = Get-VM $sourcename | Get-View | Where-Object {-not $_.config.template} | Select Name
      }
      elseif($sourcetype -eq "Folder")
      {
        $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press  to continue selecting old hardware VMs"
        #$vms = Get-Folder $sourcename | Get-VM  | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name
        $vms = Get-Folder $sourcename | Get-VM  | Get-View | Where-Object {-not $_.config.template} | Select Name
      }
      elseif($sourcetype -eq "ResourcePool")
      {
        $abort = Read-Host "You've chosen $sourcetype, this is your last chance to abort by pressing +C. Press  to continue selecting old hardware VMs"
        #$vms = Get-ResourcePool $sourcename | Get-VM  | Get-View | Where-Object {-not $_.config.template -and $_.Config.Version -eq "vmx-08" } | Select Name
        $vms = Get-ResourcePool $sourcename | Get-VM  | Get-View | Where-Object {-not $_.config.template} | Select Name
      }
      elseif(($sourcetype -eq "VMfile") -and ((Test-Path -path $sourcename) -eq $True))
      {
        $abort = Read-Host "You've chosen $sourcetype with this file: $sourcename, this is your last chance to abort by pressing +C. Press  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-08" } | 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 is not an exact match of AllVMs, VM, Folder, ResourcePool or VMfile, or the VMfile does not exist. Exit the script by pressing +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 +C to quit the script or press  to continue"
      LogWrite "PowerOn Error detected on $vm" "ERROR" "1"
      [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 +C to quit the script or press  to continue"
      LogWrite "PowerOff Error detected on $vm" "ERROR" "1"
      [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 +C to quit the script or press  to continue"
      LogWrite "VMware Tools Error detected on $vm" "ERROR" "1"
    }
   return $vmTools
}

Function Check-VMHardwareVersion($vm)
{
    $vmView = get-VM $vm | Get-View
    $vmVersion = $vmView.Config.Version
    $v7 = "vmx-07"
    $v8 = "vmx-08"
    $v9 = "vmx-09"
    $v10 = "vmx-10"
    $v11 = "vmx-11"
    $v13 = "vmx-13"
    if ($vmVersion -eq $v8)
    {
      $vmHardware = "Old"
    }
    elseif($vmVersion -eq $v7)
    {
      $vmHardware = "Old"
    }
    elseif($vmVersion -eq $v9)
    {
      $vmHardware = "Old"
    }
    elseif($vmVersion -eq $v10)
    {
      $vmHardware = "Old"
    }
    elseif($vmVersion -eq $v11)
    {
      $vmHardware = "Old"
    }
    elseif($vmVersion -eq $v13)
    {
      $vmHardware = "Ok"
    }
    else
    {
      $vmHardware = "ERROR"
      LogWrite "Hardware Version Error detected on $vm" "ERROR" "1"
      [console]::ForegroundColor = "Red"
      Read-Host "The Hardware version of $vm is not set to $v7 or $v8 or $v9 or $v10 or $v11 or $v13. This is unusual. Press +C to quit the script or press  to continue"
      [console]::ResetColor()
    }
    return $vmHardware
}

Function Upgrade-VMHardware($vm)
{
  $vmview = Get-VM $vm | Get-View
  $vmVersion = $vmView.Config.Version
  $v7 = "vmx-07"
  $v8 = "vmx-08"
  $v9 = "vmx-09"
  $v10 = "vmx-10"
  $v11 = "vmx-11"
  $v13 = "vmx-13"

  if ($vmVersion -eq $v7)
  {
    Write-Host "Version 7 detected" -ForegroundColor Red

    # Update Hardware
    Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow
    Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null
  }

  if ($vmVersion -eq $v8)
  {
    Write-Host "Version 8 detected" -ForegroundColor Red

    # Update Hardware
    Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow
    Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null
  }

  if ($vmVersion -eq $v9)
  {
    Write-Host "Version 9 detected" -ForegroundColor Red

    # Update Hardware
    Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow
    Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null
  }

  if ($vmVersion -eq $v10)
  {
    Write-Host "Version 10 detected" -ForegroundColor Red

    # Update Hardware
    Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow
    Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null
  }

  if ($vmVersion -eq $v11)
  {
    Write-Host "Version 10 detected" -ForegroundColor Red

    # Update Hardware
    Write-Host "Upgrading Hardware on" $vm -ForegroundColor Yellow
    Get-View ($vmView.UpgradeVM_Task($v13)) | Out-Null
  }
}

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 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
    do
    {
      sleep 10
      Write-Host "Checking ToolsStatus $vm now"
      $vmToolsStatus = Check-ToolsStatus $vm
    }until($vmToolsStatus -eq "OK")
    PowerOff-VM $vm
    PowerOn-VM $vm
  }
  else
  {
    LogWrite "Linux / Windows (no tools installed) detected: $vm" "WARNING" "1"
    # ToDo: If the guest is running windows but tools notrunning/notinstalled it might be an option to invoke the installation through powershell.
    # Options are then Invoke-VMScript cmdlet or through windows installer: msiexec-i "D: \ VMware Tools64.msi" ADDLOCAL = ALL REMOVE = Audio, Hgfs, VMXNet, WYSE, GuestSDK, VICFSDK, VAssertSDK / qn
    # 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

    Write-Host "$vm is a $family with tools status $vmToolsStatus. We are going to do the upgrade, but we'll take a snapshot beforehand"
    if ($vmToolsStatus -ne "NotInstalled")
    {
      Make-Snapshot $vm
      Get-Date
      Get-VMGuest $vm | Update-Tools -NoReboot
      do
      {
        sleep 10
        Write-Host "Checking ToolsStatus $vm now"
        $vmToolsStatus = Check-ToolsStatus $vm
      }until($vmToolsStatus -eq "OK")
      PowerOff-VM $vm
      PowerOn-VM $vm

    }

  }
}

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."
      }
  }
}

Connect-VIServer -Server $vcenter -Credential $vcCred -WarningAction SilentlyContinue | out-null
Write-Host "connecting to $vcenter"

$vms = VM-Selection
CreateHWList $vms $csvfile
foreach($item in $vms)
{
    $vm = $item.Name
    Write-Host "Test $vm"
    CheckAndUpgradeTools $vm
    CheckAndUpgrade $vm
}
CreateHWList $vms $csvfile
# $toggle = Read-Host "Would you like me to remove the snapshots taken on Linux VMs? (yes/no)"
# if ($toggle -eq "yes")
# {
#   Get-VM | Delete-Snap
# }
Disconnect-VIServer -Confirm:$false

Voraussetzungen

Du brauchst PowerCLI, klar. Das Schöne an diesem Script: Du hast mehrere Wege, festzulegen, welche VMs es anfassen soll.

  • Eine Textdatei mit den Anzeigenamen der VMs, Zeile für Zeile
  • Einen Ordner oder Resource Pool, in dem die VMs liegen
  • Einen VM-Namen
  • Oder einfach alle VMs

https://youtu.be/lq1vJ20\_QLI

Wenn du Fragen hast, melde dich auf Twitter oder schreib einen Kommentar.

Passt ausserdem