Macchine virtuali (VMware): individuare gli aggiornamenti da eseguire con PowerShell

| |

Metti uno o più vCenter con una quantità importante di macchine sotto gestione, metti anche la costante necessità di tenere in ordine le versioni dei VMware Tools e della Compatibility (spesso più spartanamente conosciuta come HW Version) e ora condisci il tutto con il fatto che almeno via GUI non sia così immediato farsi tirare fuori le macchine che necessitano di almeno uno dei due aggiornamenti. Mi ci sono ritrovato a litigare non molto tempo fa quando abbiamo riorganizzato in azienda la gestione di chi fa cosa e su quali macchine.

Per fortuna avere PowerShell e il modulo CLI di VMware a portata di mano può togliere molto rapidamente le castagne dal fuoco, ed è esattamente quello che ho fatto. Ti spiego rapidamente come perché immagino possa tornarti utile (e parlo anche a me del futuro quando avrò bisogno di ripescare lo script magari perso nei meandri delle mie cartelle).

Hai tutto, vero?

Diciamo che provo a dare per scontato che tu abbia già a bordo macchina PowerShell 7 (vedi learn.microsoft.com/it-it/powershell/scripting/install/installing-powershell-on-windows?view=powershell-7.4) e che sia installato già il modulo di amministrazione VMware (PowerCLI) ma, se così non fosse, la cosa è assai semplice:

Install-Module VMware.PowerCLI -Scope CurrentUser

Una volta installato non ti resta che iniziare il collegamento verso il tuo vCenter, perciò:

Connect-VIServer -Server vcenter.contoso.com

Se l’autenticazione viene effettuata tramite SAML non dovrai fare altro perché evidentemente arriverai da un PC di dominio collegato con il tuo utente, diversamente dovrai specificare nome utente e password per effettuare il collegamento da riga di comando (ma è cosa che già ti dirà il modulo PowerCLI). Una volta connesso potrai finalmente utilizzare i comandi previsti dal modulo, li trovi raccolti sulla documentazione ufficiale di VMware: developer.vmware.com/docs/15315/GUID-3E36F4EA-3742-48BA-BB4B-7E0A2EAAE83E.html.

Lo script

Prima te li mostro (i file – come tu stesso noterai – sono due), poi te li spiego:


# Retrieve the status (and the version) of the VMware Tools and the Hardware Version (Compatibility) of all VMs powered on
# GSolone, 2023
# Credits
# https://communities.vmware.com/t5/VMware-vSphere-Discussions/How-to-check-VMware-Tools-status-of-VM-use-PowerCLI/td-p/2278893
# https://blogs.vmware.com/PowerCLI/2018/09/discovering-vms-with-specific-vmware-tools-versions.html
Set-Variable ProgressPreference Continue
$arr_VMStats = @()
$ProcessedCount = 0
# Creates a variable that contains VMs which are in the PoweredOn state
$VMList = Get-VM | Where { $_.PowerState -eq "PoweredOn" }
$TotalVM = $VMList.Count
# Names of VMs that will not be shutdown or powered off (example: $VMExclusionList = "vm1","vm2","vm3")
$VMExclusionList = ""
# Loops through the variable an object at a time
Foreach ( $VM in $VMList ) {
# Checks if the name of the current VM is in the ExclusionList and skips if it is
If ( $VMExclusionList -notcontains $VM.Name ) {
$ProcessedCount++
$PercentComplete = (($ProcessedCount / $TotalVM) * 100)
Write-Progress -Activity "Processing $VM" -Status "$ProcessedCount out of $TotalVM completed ($($PercentComplete.ToString('0.00'))%)" -PercentComplete $PercentComplete
# Retrieve the status (and the version) of the VMware Tools and the Hardware Version
$arr_VMStats += New-Object -TypeName PSObject -Property $([ordered]@{
VM = $VM.Name
# PowerState = $VM.PowerState
# OSFullName = $VM.Guest.OSFullName
HWVersion = $VM.HardwareVersion
ToolsStatus = ($VM | Get-View).Guest.ToolsStatus
ToolsVersion = $VM.Guest.ToolsVersion
})
}
}
$arr_VMStats | Sort-Object VM | Out-Host


# Retrieve the status (and the version) of the VMware Tools and the Hardware Version (Compatibility) of all VMs powered on
# GSolone, 2023
# Credits
# https://communities.vmware.com/t5/VMware-vSphere-Discussions/How-to-check-VMware-Tools-status-of-VM-use-PowerCLI/td-p/2278893
# https://blogs.vmware.com/PowerCLI/2018/09/discovering-vms-with-specific-vmware-tools-versions.html
# Changes:
# 18/10/23- Improve: I show what updates there are to be made only if there is at least one within the array.
Set-Variable ProgressPreference Continue
$arr_VMStats = @()
$ProcessedCount = 0
# Creates a variable that contains VMs which are in the PoweredOn state
$VMList = Get-VM | Where { $_.PowerState -eq "PoweredOn" }
$TotalVM = $VMList.Count
# Names of VMs that will not be shutdown or powered off (example: $VMExclusionList = "vm1","vm2","vm3")
$VMExclusionList = ""
# Loops through the variable an object at a time
Foreach ( $VM in $VMList ) {
# Checks if the name of the current VM is in the ExclusionList and skips if it is
If ( $VMExclusionList -notcontains $VM.Name ) {
$ProcessedCount++
$PercentComplete = (($ProcessedCount / $TotalVM) * 100)
Write-Progress -Activity "Processing $VM" -Status "$ProcessedCount out of $TotalVM completed ($($PercentComplete.ToString('0.00'))%)" -PercentComplete $PercentComplete
# Retrieve the status (and the version) of the VMware Tools and the Hardware Version
$arr_VMStats += New-Object -TypeName PSObject -Property $([ordered]@{
VM = $VM.Name
# PowerState = $VM.PowerState
# OSFullName = $VM.Guest.OSFullName
HWVersion = $VM.HardwareVersion
ToolsStatus = ($VM | Get-View).Guest.ToolsStatus
ToolsVersion = $VM.Guest.ToolsVersion
})
}
}
$arr_VMStats | Sort-Object VM | Out-Host
$csvVMfound = @()
Import-Csv -Path "$PSScriptRoot\updateVMlist.csv" | Foreach {
$VMname = $_.vm
$VMfound = $arr_VMStats | Where-Object { $_.VM -eq $VMname }
if ($VMfound) {
if ($VMfound.ToolsStatus -eq "toolsOld" -or $VMfound.HWVersion -ne "vmx-19") {
$csvVMfound += $VMfound
}
}
}
if ($csvVMfound.Length -gt 0) {
Write-Host "`nSearch updates available in the CSV list ($PSScriptRoot\updateVMlist.csv)" -f "Yellow"
$csvVMfound | Sort-Object VM | Out-Host
} else {
Write-Host "`n✔️ No updates to manage in the CSV list ($PSScriptRoot\updateVMlist.csv)`n" -f "Green"
}

Parti dal presupposto che il secondo file è un po’ un “bonus“, un ulteriore livello di puntacazzismo per cercare di ottenere risultati attinenti alla specifica esigenza di prendermi cura solo di una parte delle macchine che girano sul vCenter (e non quindi di tutte, perché sarebbe un po’ too much). Ti spiego il tutto rapidamente e ti ricordo che questo script non funzionerà mai se prima non hai installato il modulo adatto ed effettuato la connessione come spiegato nel paragrafo precedente.

Macchine virtuali (VMware): individuare gli aggiornamenti da eseguire via PowerShell 1

  • Lo script prenderà in esame tutte le macchine virtuali che troverà a patto che queste siano accese ($VMList = Get-VM | Where { $_.PowerState -eq "PoweredOn" }), lo faccio perché spesso capita di tenere in vita (seppur spente) macchine che presto andranno in dismissione e/o verranno cancellate. Potrebbe quindi essere inutile perderci tempo ma sentiti ovviamente libero di togliere la condizione di Where dallo script nel caso in cui volessi analizzare tutte – ma proprio tutte – le VM disponibili.
  • Potrai escludere una o più macchine a tuo piacimento dall’analisi a patto di dichiarare i loro nomi all’interno della lista d’esclusione ($VMExclusionList = ""), nello script di default tale valore rimarrà vuoto.
  • Partirà così un ciclo che attraverserà ogni macchina trovata e tirerà fuori alcuni dati tra cui – appunto – lo stato dei Tools (se installati o no, e che versione) e della compatibilità:
$arr_VMStats += New-Object -TypeName PSObject -Property $([ordered]@{ 
            VM = $VM.Name
            # PowerState = $VM.PowerState
            # OSFullName = $VM.Guest.OSFullName
            HWVersion = $VM.HardwareVersion
            ToolsStatus = ($VM | Get-View).Guest.ToolsStatus
            ToolsVersion = $VM.Guest.ToolsVersion
        })

Sì, ho lasciato commentato lo stato della macchina in cui si trova la macchina e il nome completo del sistema operativo in uso perché iniziavo ad avere troppi dati potenzialmente inutili a video.
Sentiti libero di togliere i commenti e tirare fuori anche quei dati se ti servono)

Al termine del ciclo ti verranno restituiti i risultati in ordine per nome della macchina virtuale, tutti comodamente incolonnati per dare già il giusto colpo all’occhio ($arr_VMStats | Sort-Object VM | Out-Host).

Lo script finisce qui ed è esattamente come lo vedi da primo file su Gist.

La parte “bonus”

Si legga alla voce: mi pesano gli occhi e la voglio ancora più semplice.

Di tutte le macchine gestite dal vCenter io devo preoccuparmi e occuparmi di una parte di queste. Ho perciò creato un file CSV chiamato updateVMlist.csv che contiene una sola colonna con intestazione “vm” in cui ho specificato il nome delle macchine virtuali per le quali sono ufficialmente riconosciuto come baby sitter. Quel file CSV ospitato nella stessa identica cartella del file PS1 (quello dello script) verrà preso in esame per restituirmi a video ciò che c’è da fare.

Macchine virtuali (VMware): individuare gli aggiornamenti da eseguire via PowerShell

Nello specifico:

$csvVMfound = @()
Import-Csv -Path "$PSScriptRoot\updateVMlist.csv" | Foreach {
    $VMname = $_.vm
    $VMfound = $arr_VMStats | Where-Object { $_.VM -eq $VMname }

    if ($VMfound) {
        if ($VMfound.ToolsStatus -eq "toolsOld" -or $VMfound.HWVersion -ne "vmx-19") {
            $csvVMfound += $VMfound
        }
    }
}

if ($csvVMfound.Length -gt 0) {
    Write-Host "`nSearch updates available in the CSV list ($PSScriptRoot\updateVMlist.csv)" -f "Yellow"
    $csvVMfound | Sort-Object VM | Out-Host
} else {
    Write-Host "`n✔️ No updates to manage in the CSV list ($PSScriptRoot\updateVMlist.csv)`n" -f "Green"
}

Questo blocco di codice aggiuntivo prende le mie macchine virtuali, le confronta con quelle che ha precedentemente analizzato e mi restituisce a video il messaggio “No updates to manage in the CSV list” nel caso in cui non ci sia nulla da aggiornare (né VMware Tools, né Compatibility), diversamente mi mostrerà una lista di macchine che necessitano il mio intervento.

Occhio: c’è un passaggio in particolare che regola la questione Compatibility, questo:

if ($VMfound.ToolsStatus -eq "toolsOld" -or $VMfound.HWVersion -ne "vmx-19")

Quel valore vmx-19 è ciò che serve a me oggi che sto scrivendo e pubblicando l’articolo. Tra qualche tempo potrebbe essere necessario portarlo a vmx-20 e così via. Va da sé che trattandosi di una modifica così piccola e banale puoi farlo anche tu che stai leggendo questo articolo molto più in là nel tempo rispetto alla prima data di pubblicazione (o ultima di aggiornamento).

Gli script già belli e pronti si trovano entrambi su GitHub (Gist) e puoi scaricarli in un attimo, non dovrai fare altro che lanciare quello che desideri direttamente da finestra di PowerShell 7. Ricorda ovviamente che il secondo restituirà errore nel caso in cui non troverà il file CSV nella stessa posizione dello script PowerShell, come spiegato poco sopra.

Dubbi? Perplessità varie? Suggerimenti su come fare meglio?
L’area commenti è a tua totale disposizione e non morde certamente, approfittane! 🙃✌️

#KeepItSimple


Sfondo originale: eng.it/en/whats-on/newsroom/engineering-d-hub-is-vmware-cloud-verified

Correzioni, suggerimenti? Lascia un commento nell'apposita area qui di seguito o contattami privatamente.
Ti è piaciuto l'articolo? Offrimi un caffè! ☕ :-)

Condividi l'articolo con i tuoi contatti:
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Commenti
Inline Feedbacks
View all comments