Comment créer une machine virtuelle Hyper-V avec PowerShell ?
Sommaire
I. Présentation
Ce chapitre aborde la création d'une machine virtuelle Hyper-V à partir d'un script PowerShell. Pour atteindre cet objectif, nous allons utiliser le module PowerShell nommé "Hyper-V" développé par Microsoft.
Dans un premier temps, nous allons apprendre à utiliser différentes commandes PowerShell pour créer et configurer la VM. Puis, nous verrons comment créer un script PowerShell pour personnaliser et faciliter la création de nouvelles VM.
II. Créer une VM Hyper-V avec Hyper-V
La première étape, si vous travaillez directement sur votre serveur, c'est d'ouvrir Windows PowerShell ISE pour rédiger votre script (ou saisissez directement les commandes dans la console). Nous allons créer une machine virtuelle avec les paramètres suivants :
- Nom : VM-W11
- RAM : 4 Go
- vCPU : 2
- Génération : 2
- Disque virtuel VHDX : 4 Go
- Média d'installation : D:\Win11_24H2_French_x64.iso
- Puce TPM virtuelle : oui
- Chemin de stockage de la VM : D:\Hyper-V
- Réseau virtuel : LAN-Physique
Ainsi, notre machine virtuelle sera créée avec ces paramètres et il ne restera plus qu'à la démarrer pour installer le système d'exploitation. Puisque de nombreuses commandes impliquent de préciser le nom de la VM, nous allons le stocker en mémoire dans une variable nommée "$Name". Ainsi, nous n'aurons qu'à appeler cette variable à chaque fois que nous devons préciser le nom de la VM.
$Name = "VM-W11"
La machine virtuelle créée sera préconfigurée pour accueillir Windows 11, notamment parce que sa configuration respecte les prérequis et que la puce vTPM sera activée.
A. New-VM : créer la machine virtuelle
Le cmdlet PowerShell "New-VM" contient plusieurs paramètres pour créer une VM et personnaliser sa configuration. Nous allons spécifier les paramètres suivants :
- -Name : le nom de la VM
- -MemoryStartupBytes : quantité de RAM à associer à la VM. Par exemple : "4GB" pour 4 Go (4096 Mo)
- -Generation : spécifier la génération de la VM (1 ou 2)
- -Path : chemin vers le répertoire dans lequel stocker la VM (un sous-répertoire avec le nom de la VM sera créé)
- -NewVHDPath : chemin complet vers le fichier ".vhdx" à créer pour le disque dur virtuel de la VM. Ici, nous allons reprendre le chemin dans lequel stocker la VM ("D:\Hyper-V") et créer un sous-répertoire nommé "Virtual Hard Disks" pour reproduire le comportement de l'assistant de création de VM Hyper-V. Le disque virtuel aura pour nom : le nom de la VM + l'extension VHDX.
- -NewVHDSizeBytes : taille du disque dur virtuel. Par exemple : "64GB" pour 64 Go.
- -SwitchName : nom du commutateur virtuel sur lequel connecter la carte réseau de la VM.
Ce qui donne la commande suivante :
New-VM -Name $Name -MemoryStartupBytes 4GB -Generation 2 -Path "D:\Hyper-V" -NewVHDPath "D:\Hyper-V\$Name\Virtual Hard Disks\$Name.vhdx" -NewVHDSizeBytes 64GB -SwitchName "LAN-Physique"
L'exécution de cette commande crée la VM immédiatement. Elle est éteinte et c'est une coquille vide, mais elle est présente dans l'inventaire des VM de l'Hyper-V.
D'autres paramètres sont disponibles pour cette commande, vous pouvez en savoir plus sur cette page :
Nous allons poursuivre la configuration avec d'autres commandes.
B. Associer une image ISO
Nous souhaitons installer le système d'exploitation Windows 11 à partir d'une image ISO située à l'emplacement suivant : "D:\Win11_24H2_French_x64.iso". Nous devons donc le déclarer dans les paramètres de la VM.
Pour cela, nous allons utiliser le cmdlet "Add-VMDvdDrive" de cette façon :
Add-VMDvdDrive -VMName $Name -Path "D:\Win11_24H2_French_x64.iso"
Nous devons également ajuster l'ordre de démarrage de la VM, afin de démarrer sur l'image ISO en priorité et ainsi effectuer l'installation de l'OS. Grâce au cmdlet "Set-VMFirmware" et à son paramètre "-BootOrder", nous allons ajuster la configuration afin de définir l'ordre suivant :
- Image ISO (DVD)
- Démarrage réseau
- Démarrage sur le disque dur
Ce qui donne la commande suivante :
Set-VMFirmware -VMName $Name -BootOrder $(Get-VMDvdDrive -VMname $Name), $(Get-VMNetworkAdapter -VMName $Name), $(Get-VMHardDiskDrive -VMName $Name)
Nous utilisons plusieurs commandes (Get-VMDvdDrive, Get-VMNetworkAdapter, et Get-VMHardDiskDrive) pour récupérer les informations de façon dynamiques. Grâce à cette configuration, d'une part, l'image ISO est associée au lecteur DVD virtuel de la VM, et d'autre part, l'ordre de démarrage est ajusté.
C. Définir le nombre de CPU virtuels
Notre souhait étant d'avoir 2 CPU virtuels sur la machine virtuelle, nous allons ajuster sa configuration avec le cmdlet "Set-VM". Voici la commande à exécuter :
Set-VM -Name $Name -ProcessorCount 2
Le cmdlet "Set-VM" sert à modifier certains paramètres d'une VM existante, ce qui est notre cas ici.
D'autres paramètres sont disponibles pour cette commande, vous pouvez en savoir plus sur cette page :
D. Activer le TPM virtuel sur la VM
La dernière étape consiste à activer le TPM virtuel sur la VM, sinon Windows 11 refusera de s'installer... Nous devons commencer par définir un "key protector" sur la VM via "Set-VMKeyProtector", afin de pouvoir activer le module vTPM via "Enable-VMTPM". Si vous exécutez seulement la seconde commande, une erreur sera retournée.
Set-VMKeyProtector -VMName $Name -NewLocalKeyProtector
Get-VM -Name $Name | Enable-VMTPM
E. Récapitulatif des commandes
La machine virtuelle est créée et sa configuration correspond à nos attentes. Il ne reste plus qu'à la démarrer et à effectuer l'installation du système. D'ailleurs, nous pourrions démarrer la VM via cette commande PowerShell :
Start-VM -VMName $Name
Pour finir, voici un récapitulatif des commandes exécutées :
# Nom de la VM
$Name = "VM-W11"
# Créer la VM
New-VM -Name $Name -MemoryStartupBytes 4GB -Generation 2 -Path "D:\Hyper-V" -NewVHDPath "D:\Hyper-V\$Name\Virtual Hard Disks\$Name.vhdx" -NewVHDSizeBytes 64GB -SwitchName "LAN-Physique"
# Définir l'image ISO dans le lecteur DVD de la VM
Add-VMDvdDrive -VMName $Name -Path "D:\Win11_24H2_French_x64.iso"
# Ajuster l'ordre de démarrage
Set-VMFirmware -VMName $Name -BootOrder $(Get-VMDvdDrive -VMname $Name), $(Get-VMNetworkAdapter -VMName $Name), $(Get-VMHardDiskDrive -VMName $Name)
# Modifier le nom de CPU virtuel
Set-VM -Name $Name -ProcessorCount 2
# Configurer la puce vTPM
Set-VMKeyProtector -VMName $Name -NewLocalKeyProtector
Get-VM -Name $Name | Enable-VMTPM
# Démarrer la VM
Start-VM -VMName $Name
III. Créer un script pour déployer plusieurs VM
Comme nous avons pu le constater, la création et la configuration d'une machine virtuelle avec PowerShell nécessite d'utiliser un ensemble de cmdlets PowerShell. Ceci est vrai même pour définir des paramètres basiques. Notre exemple précédent n'intègre pas la moindre vérification. Par exemple, avant de créer la VM, nous ne vérifions pas s'il existe déjà une VM avec le même nom.
Ainsi, je vous propose un script nommé "New-VMCustom.ps1" qui accepte plusieurs paramètres en entrée pour personnaliser la création d'une ou plusieurs VM. Il intègre plusieurs vérifications et vous pouvez l'adapter à votre convenance. Retrouvez ce script sur le GitHub IT-Connect :
Voici le code, à titre d'information.
<#
.SYNOPSIS
Créer une ou plusieurs machines virtuelles Hyper-V, avec les paramètres de base
.DESCRIPTION
Créer une ou plusieurs machines virtuelles Hyper-V, en spécifiant nom, RAM, CPU, image ISO,
Génération 1 ou 2, le switch virtuel, l'emplacement de la VM, la taille du disque et l'activation vTPM
.PARAMETER Name
Spécifier le nom de la VM. Par exemple : "VM-1"
.PARAMETER RAM
Spécifier la RAM statique à associer à la VM. Par exemple : "4GB" pour 4 Go
.PARAMETER CPU
Spécifier le nombre de CPU virtuel à associer à la VM. Par exemple : "2" pour 2 CPU virtuel
.PARAMETER ISO
Spécifier le chemin complet vers l'image ISO source pour l'installation.
Par exemple : "D:\Win11_24H2_French_x64.iso"
.PARAMETER Gen
Spécifier la génération de la VM : 1 ou 2
.PARAMETER Switch
Spécifier le nom du commutateur virtuel sur lequel connecter la VM (facultatif).
Le vSwitch doit exister car il y a une vérification au niveau du paramètre.
.PARAMETER VMPath
Spécifier le nom du répertoire dans lequel créer la VM. Par exemple : "D:\Hyper-V"
.PARAMETER VHDSize
Spécifier la taille du disque dur virtuel VHDX pour la VM. Par exemple : "64GB" pour un disque de 64 Go
.PARAMETER TPM
Indiquer si oui ($true) ou non ($false ou non configuré) il est nécessaire d'activer la puce vTPM sur la VM
.EXAMPLE
.\New-VMCustom.ps1 -Name "VM-1" -RAM 4GB -CPU 2 -ISO "D:\Win11_24H2_French_x64.iso" -Gen 2 -VMPath "D:\Hyper-V" -VHDSize 64GB -TPM $true -Switch "LAN-Physique"
#>
Param(
[Parameter(Mandatory=$true)][string]$Name,
[Parameter(Mandatory=$true)][int64]$RAM,
[Parameter(Mandatory=$true)][int64]$CPU,
[Parameter(Mandatory=$false)][string]$ISO,
[Parameter(Mandatory=$false)][ValidateRange(1,2)][int]$Gen = 2,
[Parameter(Mandatory=$false)][ValidateScript({$_ -in (Get-VMSwitch).Name})][string]$Switch,
[Parameter(Mandatory=$true)][ValidateScript({Test-Path $_})][string]$VMPath,
[Parameter(Mandatory=$true)][int64]$VHDSize,
[Parameter(Mandatory=$false)][boolean]$TPM
)
# La VM existe-elle déjà ?
$VMCheck = Get-VM -Name $Name -ErrorAction SilentlyContinue
# Si la VM n'existe pas et que le chemin ne correspond pas déjà à une autre VM, on lance la création
if(($VMCheck -eq $null) -and (-not (Test-Path "$VMPath\$Name"))){
# Affichage des informations
Write-Host "####################################" -ForegroundColor Yellow
Write-Host "# Nom de la VM : $Name" -ForegroundColor Green
Write-Host "# Mémoire vive : $($RAM/1MB) Mo" -ForegroundColor Green
Write-Host "# CPU virtuels : $CPU" -ForegroundColor Green
Write-Host "# Image ISO : $ISO" -ForegroundColor Green
Write-Host "# Génération : $Gen" -ForegroundColor Green
Write-Host "# Réseau virtuel : $Switch" -ForegroundColor Green
Write-Host "# Puce vTPM : $TPM" -ForegroundColor Green
Write-Host "# Stockage VM : $VMPath" -ForegroundColor Green
Write-Host "# Taille disque virtuel : $($VHDSize/1GB) Go" -ForegroundColor Green
Write-Host "####################################" -ForegroundColor Yellow
# Créer la VM avec le minimum de paramètres
try{
New-VM -Name $Name -MemoryStartupBytes $RAM -Generation $Gen -Path $VMPath `
-NewVHDPath "$VMPath\$Name\Virtual Hard Disks\$Name.vhdx" -NewVHDSizeBytes $VHDSize | Out-Null
Write-Host "> $Name - Machine virtuelle créée" -ForegroundColor Green
}catch{
Write-Host $_.Exception.Message -ForegroundColor Red
exit
}
# Ajouter une image ISO (si nécessaire) et ajuster l'ordre de boot
if(($ISO -ne "") -and ($ISO -ne " ") -and ($ISO -ne $null)) {
try{
Add-VMDvdDrive -VMName $Name -Path $ISO -ErrorAction Stop
Write-Host "> $Name - Image ISO associée au lecteur DVD" -ForegroundColor Green
}catch{
Write-Host $_.Exception.Message -ForegroundColor Red
}
Try{
Set-VMFirmware -VMName $Name -BootOrder $(Get-VMDvdDrive -VMname $Name), $(Get-VMNetworkAdapter -VMName $Name), $(Get-VMHardDiskDrive -VMName $Name) -ErrorAction Stop
Write-Host "> $Name - Ordre de démarrage configuré" -ForegroundColor Green
}catch{
Write-Host $_.Exception.Message -ForegroundColor Red
}
}
# Configurer le vCPU sur la VM
if($CPU -ne $null) {
Try{
Set-VM -Name $Name -ProcessorCount $CPU -ErrorAction Stop
Write-Host "> $Name - CPU virtuel configuré à $CPU" -ForegroundColor Green
}catch{
Write-Host $_.Exception.Message -ForegroundColor Red
}
}
# Activer la puce TPM sur la VM (si nécessaire)
if($TPM -eq $true){
Try{
Set-VMKeyProtector -VMName $Name -NewLocalKeyProtector -ErrorAction Stop
Get-VM -Name $Name | Enable-VMTPM -ErrorAction Stop
Write-Host "> $Name - Puce vTPM activée" -ForegroundColor Green
}catch{
Write-Host $_.Exception.Message -ForegroundColor Red
}
}
# Connecter la VM sur un réseau virtuel (si nécessaire)
if(($Switch -ne "") -and ($Switch -ne " ") -and ($Switch -ne $null)) {
Try{
Get-VM -Name $Name | Get-VMNetworkAdapter | Connect-VMNetworkAdapter -SwitchName $Switch
Write-Host "> $Name - Réseau connecté sur vSwitch $Switch" -ForegroundColor Green
}catch{
Write-Host $_.Exception.Message -ForegroundColor Red
}
}
Write-Host "####################################" -ForegroundColor Yellow
Write-Host ">> Machine virtuelle $Name créée avec succès !" -ForegroundColor Green
}else{
Write-Host "Opération annulée : la VM existe déjà ou il y a un conflit avec le répertoire cible !" -ForegroundColor Red
}
Pour créer une machine virtuelle identique à celle créée dans la première partie de l'article, il suffirait d'exécuter ceci :
.\New-VMCustom.ps1 -Name "VM-W11" -RAM 4GB -CPU 2 -ISO "D:\Win11_24H2_French_x64.iso" -Gen 2 -VMPath "D:\Hyper-V" -VHDSize 64GB -TPM $true -Switch "LAN-Physique"
Nous pourrions aussi créer 3 machines virtuelles (ou plus) en appelant plusieurs fois le script. Ces machines sont identiques, il n'y a que le nom qui est différent.
# Création de plusieurs machines virtuelles
$VMList = ("VM-W11-1","VM-W11-2","VM-W11-3")
Foreach($VM in $VMList){
New-VMCustom -Name $VM -RAM 4GB -CPU 2 -ISO "D:\Win11_24H2_French_x64.iso" -Gen 2 -VMPath "D:\Hyper-V" -VHDSize 64GB -TPM $true -Switch "LAN-Physique"
}
Ensuite, il sera nécessaire d'installer le système d'exploitation sur chaque VM.
Si vous avez besoin d'aide pour la compréhension de ce code PowerShell, vous pouvez vous aider de mon cours PowerShell :
IV. Conclusion
Voilà, vous savez désormais utiliser PowerShell pour créer une VM Hyper-V ! Il existe d'autres commandes PowerShell pour aller plus loin et modifier d'autres paramètres. Vous pouvez lister ces commandes de cette façon :
Get-Command -Module Hyper-V
Pour gagner beaucoup plus de temps, il peut s'avérer judicieux de créer une VM modèle prête à l'emploi sur laquelle un SYSPREP est appliqué. Pour, ensuite, copier le disque pour chaque nouvelle VM. Il n'y aurait que l'installation à terminer (à moins de pousser un fichier unattend.xml dans le disque virtuel directement, en amont).