Alors cette semaine je suis tombé sur un problème simple, savoir quelle version d’Hyper-V est présente sur le serveur. J’avais besoin de ce contrôle car selon la version d’Hyper-V j’aurai une création différente de ma VM. Par exemple une VM Linux n’a pas les mêmes besoins qu’une VM Windows Server 2012. Alors nous avons plusieurs solutions
La première est de vérifier la version du service de gestion d’ordinateurs virtuels
|
Get-Service -DisplayName *hy* |

Là on peut faire d’une pierre deux coups car on connaît la version d’Hyper-V et si le service est bien présent :
|
(Get-ItemProperty -Path "$env:SystemRoot\system32\vmms.exe").versioninfo | ft -AutoSize |

La seconde en WMI(celle que nous utiliserons ici) et de faire une requête au niveau classe Win32_operatingSystem puis je récupère par exemple la propriété versioninfo puis Version exemple ci-dessous :
|
Get-WmiObject -Class Win32_operatingSystem | select Version |

Ou aussi avec WinRm
|
Get-CimInstance CIM_operatingSystem | select Version |

Ensuite on peut en déduire par le numéro de version avec les 2 premiers chiffres :
Numéro | Version |
6.0 | Hyper-V 2008 |
6.1 | Hyper-V 2008 R2 |
6.2 | Hyper-V 2012 |
6.3 | Hyper-V 2012R2 |
10.0.10586 | Hyper-V 2016 ou Hyper-V Windows 10 |
Et bien oui on est sur la même version du noyau en Windows Server 2016 TP4 et Windows 10. Surprise 😛 . En fait c’est lié à la virtualisation imbriquer. J’explique ici pourquoi: Windows 10 Build 10565 : La virtualisation imbriquée

Moi dans le fond ça me ne dérange pas mais ça ne me dit pas tout ça si le rôle Hyper-V est installé. Je vais connaitre uniquement par cette méthode la version du système d’exploitation.
Bon là encore une fois je pourrais attaquer la classe WMI pour avoir l’information. Alors je pourrai utiliser la classe Win32_ServerFeature
|
Get-WmiObject -Class Win32_ServerFeature |select Name |

La seule chose c’est que la classe WMI Win32_ServerFeature n’existe pas sur Windows 10 et moi j’aime bien les scripts font papa maman 😀
Par contre on peut utiliser un test sur compteur de performance Hyper-V, et bien oui si le rôle n’est pas installé la classe WMI ne sera présente. Par exemple on peut utiliser la class Win32_PerfFormattedData_HvStats_HyperVHypervisor
Voilà un exemple pour une machine sans Hyper-V, nous avons un code retour d’erreur

Avec une machine avec Hyper-V

Là il va falloir dégainer le try et le catch :
|
try {Get-WmiObject -Class Win32_PerfFormattedData_HvStats_HyperVHypervisor -ErrorAction Stop} catch {write-host "Hyper-V not present"} |
Voilà deux exemples :
Hyper-V non présent :

Hyper-V présent :

J’ai ajouté trois tests. Avant l’exécution du code je vérifie si la machine est bien en ligne avec un Ping, ensuite les accès WMI sont bien possibles et pour finir on recherche si le compteur de performance Hyper-V est bien présent.
Pour le ping tout est expliqué ici:
Powershell teste de vérifications : Première partie Ping
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
<# .Synopsis Check HyperV version .DESCRIPTION Check HyperV version and if present .EXAMPLE Get-HyperVVersion localhost #> function Get-HyperVVersion { Param ( # Name of server Hyper-V $ServerName ) Begin { } Process { #Test of connectivity try { $connetion = Test-Connection -computername $ServerName -Count 1 -ErrorAction stop } catch [System.Net.NetworkInformation.PingException] { return "$ServerName offline" exit } try { $HPtest = Get-WmiObject -ComputerName $ServerName -Class Win32_PerfFormattedData_HvStats_HyperVHypervisor -ErrorAction Stop } #test if remote access is ok catch [System.UnauthorizedAccessException] { Return write-host "Not access" } #test if Hyper-V is present catch [System.Management.Automation.RuntimeException] { Return write-host "Hyper-V not present" } #Check hyper-V version $HpVer1 = (Get-WmiObject -ComputerName $ServerName -Class Win32_operatingSystem).Version $hpVer2 = $HpVer1.split(".") switch ($hpVer2[0]) { '10' { $Result = "W2K16" } '6' { switch ($hpVer2[1]) { '0' { $Result = "W2K8" } '1' { $Result = "W2K8R2" } '2' { $Result = "W2K12" } '3' { $Result = "W2K12R2" } } } } Return $Result } End { } } |
Exemple:
