Clonage de machine virtuelle
< Technique | Virtualisation | VMware | PowerCLI
Sauter à la navigation
Sauter à la recherche
Ligne 281 : | Ligne 281 : | ||
===Script de clonage multiple=== | ===Script de clonage multiple=== | ||
Voici un exemple de script de clonage multiple s'appuyant sur le script <code>vmware_clone_VM.ps1</code> [[#Script|présenté plus haut]], d'une part, et le fichier <code>vms_list_to_clone.csv</code>, d'autre part : | Voici un exemple de script de clonage multiple s'appuyant sur le script <code>vmware_clone_VM.ps1</code> [[#Script|présenté plus haut]], d'une part, et le fichier <code>vms_list_to_clone.csv</code>, d'autre part : | ||
− | <syntaxhighlight lang="powershell" line highlight="7,9,11,13,57"> | + | <syntaxhighlight lang="powershell" line highlight="7,9,11,13,57,109-122,127"> |
#!/usr/bin/pwsh | #!/usr/bin/pwsh | ||
Ligne 439 : | Ligne 439 : | ||
*Ligne 57 : | *Ligne 57 : | ||
::Appel du script <code>vmware_clone_VM.ps1</code> précédemment présenté dans [[#Simple_clonage|la partie "Simple clonage" de cette page]]. | ::Appel du script <code>vmware_clone_VM.ps1</code> précédemment présenté dans [[#Simple_clonage|la partie "Simple clonage" de cette page]]. | ||
+ | *Lignes 109 à 122 : | ||
+ | ::Script personnalisé contenant les commandes à passer sur la VM | ||
+ | ::En l'occurrence, dans cet exemple, les commandes font les actions suivantes : | ||
+ | ::*Activation du service de supervision Zabbix | ||
+ | ::*Attente que le serveur MySQL soit bien lancé | ||
+ | ::*Réinitialisation de mots de passe de certains utilisateurs MySQL | ||
+ | ::*Renommage de la machine | ||
+ | ::*Changement d'adresse IP | ||
+ | ::*Réinitialisation des clés SSH | ||
+ | ::*Suppression de l'historique des commandes de l'utilisateur utilisé pour passer les commandes (effacement des mots de passe en clair) | ||
+ | *Ligne 127 | ||
+ | ::Réinitialisation du mot de passe de l'administrateur de la machine virtuelle |
Version du 25 janvier 2021 à 08:27
Sommaire
Présentation
Cette page a pour objet de montrer comment cloner des machines virtuelles à partir de PowerCLI.
Prérequis
- PowerShell installé
- Gestion des identifiants mise en place
- PowerCLI installé
Simple clonage
Script
Voici un script nommé vmware_clone_VM.ps1
qui permet de cloner une machine vers une autre :
#!/usr/bin/pwsh
# Penser à utiliser le script create_credentials.ps1 pour créer les credentials
<#
.SYNOPSIS
Script pour exporter une VM depuis le vCenter
.DESCRIPTION
Au préalable, enregistrer les credentials en lançant le script create_credentials.ps1
.PARAMETER VmNameSource
Le nom de la VM à cloner. (obligatoire)
.PARAMETER VmNameTarget
Le nom de la VM cible à créer par clonage. (obligatoire)
.PARAMETER VmHostNameTarget
Le nom de l'ESXi qui hébergera la VM cible. (faculatif)
Si absent, prendra la valeur de l'ESXi source.
.PARAMETER VmDatastoreNameTarget
Le nom du datastore qui hébergera la VM cible. (faculatif)
Si absent, prendra la valeur du datastore source.
Si fourni, doit correspondre à un datastore de l'ESXi $VmHostNameTarget.
.PARAMETER VmLocationTarget
Le dossier de VM dans lequel se trouvera la VM cible. (faculatif)
Seul le nom du dossier sans son arborescence est attendu.
Ainsi, si un nom de dossier existe plus d'une fois, le script s'arrêtera.
Si absent, prendra la valeur du dossier de VM source.
.PARAMETER VmDescriptionTarget
Description de la VM cible. (faculatif)
.PARAMETER DeleteTarget
Confirmation de la suppression de la VM cible avant clonage si elle existe. (faculatif)
Valeur possible : No ou Yes
Si Yes, la VM cible est définitivement supprimée.
Si No et si la VM cible n'existe pas, le script s'exécutera normalement et la VM cible sera créée.
Si No et si la VM cible existe déjà, le script se terminera immédiatement sans réaliser le clonage.
.EXAMPLE
./vmware_clone_VM.ps1 -DeleteTarget Yes myserver mybackupserver
.NOTES
Author: LE NUFF Jordan
Date: Jan 11, 2021
#>
## Définition des paramètres d'entrée
Param
(
[Parameter(Mandatory=$true, Position=0, HelpMessage="Nom de la VM source")]
[string]$VmNameSource,
[Parameter(Mandatory=$true, Position=1, HelpMessage="Nom de la VM cible")]
[string]$VmNameTarget,
[Parameter(Mandatory=$false, HelpMessage="ESXi cible")]
[string]$VmHostNameTarget,
[Parameter(Mandatory=$false, HelpMessage="Datastore cible")]
[string]$VmDatastoreNameTarget,
[Parameter(Mandatory=$false, HelpMessage="Dossier de VM cible")]
[string]$VmLocationTarget,
[Parameter(Mandatory=$false, HelpMessage="Description de VM cible")]
[string]$VmDescriptionTarget="",
[Parameter(Mandatory=$false, HelpMessage="Confirmation de la suppression de la VM cible : No ou Yes")]
[ValidateSet('No','Yes')]
[string]$DeleteTarget='No'
)
If ($VmNameSource -eq $VmNameTarget) {
Write-Host "La VM cible ne peut pas être la même que la VM source '$VmNameSource'. Fin du script."
exit
}
## Initialisation variables
# Dossier des identifiants
$CredsFileLocation="/data/scripts/.credentials"
# Adresse IP du vCenter
$UrlVcenter="vcenter01.groupegdb.local"
# Identifiant VMware à utiliser
$VmwareUser="expl@groupegdb.local"
# Construction du fichier d'identifiants à utiliser
$VcFileCreds=$($CredsFileLocation + "/" + $UrlVcenter + "_" + $VmwareUser + "_ps.xml")
# Importation des credentials
$VcCreds=Import-Clixml -Path $VcFileCreds
## Connection au VCenter
Connect-VIServer -Server $UrlVcenter -Credential $VcCreds | Out-Null
## Vérifications
# La VM source existe-t-elle ? Si non, fin du script
$VmSource=Get-VM -name $VmNameSource -ErrorAction SilentlyContinue
If (!$VmSource){
Write-Host "La VM source $VmNameSource n'existe pas. Fin du script."
exit
} ElseIf ($VmSource.Count -gt 1) {
Write-Host "La VM source $VmNameSource fournie existe plus d'une fois. VM source ambigüe. Fin du script."
exit
}
# La VM cible existe-t-elle ? Si oui et absence de la confirmation de la suppresion, fin du script
$VmTarget=Get-VM -name $VmNameTarget -ErrorAction SilentlyContinue
If ($VmTarget) {
If ($VmTarget.Count -gt 1) {
Write-Host "La VM cible $VmNameCible fournie existe plus d'une fois. VM cible ambigüe. Fin du script."
exit
} ElseIf ($DeleteTarget -eq 'No') {
Write-Host "La VM cible $VmNameTarget existe et sa suppression n'a pas été confirmée en entrée de ce script avec l'option '-DeleteTarget Yes'. Fin du script."
exit
}
If ( $VmTarget.PowerState -ne 'PoweredOff' )
{
$counter = 0
Shutdown-VMGuest $VmNameTarget -confirm:$false | Out-Null
do {
Start-Sleep -s 1
If ( $counter -ge 60 ) {
Write-Host "La VM cible $VmNameTarget n'est toujours pas éteinte après un délai de 60 secondes. Fin du script."
exit
}
$VmTarget = Get-VM $VmNameTarget
$status = $VmTarget.PowerState
$counter++
} until ($status -eq "PoweredOff")
}
}
# Si l'ESXi cible a été fourni, vérification de son existence
If ($VmHostNameTarget) {
$VmHostTarget=Get-VMhost -Name $VmHostNameTarget -ErrorAction SilentlyContinue
# Si inexistant, fin du script
If (!$VmHostTarget){
Write-Host "L'ESXi cible $VmHostNameTarget fourni n'existe pas. Fin du script."
exit
}
# Si l'ESXi n'a pas été fourni
} ElseIf (!$VmHostNameTarget) {
# Utilisation du même ESXi que la VM source
$VmHostTarget=Get-VMhost -VM $VmSource
}
# Si le datastore a été fourni, vérification de son existence
If ($VmDatastoreNameTarget) {
$VmDatastoreTarget=Get-Datastore -Name $VmDatastoreNameTarget -ErrorAction SilentlyContinue
# Si inexistant, fin du script
If (!$VmDatastoreTarget){
Write-Host "L'ESXi cible $VmDatastoreNameTarget fourni n'existe pas. Fin du script."
exit
# Si existant
}
# Si le datastore n'a pas été fourni
} ElseIf (!$VmHostNameTarget) {
# Utilisation du même ESXi que la VM source
$VmDatastoreTarget=Get-Datastore -VM $VmSource
}
# Si le datastore cible n'est pas accessible depuis l'ESXi cible, fin du script
If (!$(Get-Datastore -VMHost $VmHostTarget | Where-Object {$_ -eq $VmDatastoreTarget})){
Write-Host "Le datastore cible $VmDatastoreTarget n'est pas accessible depuis l'ESXi cible $VmHostTarget. Fin du script."
exit
}
# Si le dossier de VM cible a été fourni, vérification de son existence
If ($VmLocationTarget) {
$LocationTarget=Get-Folder -Name $VmLocationTarget -Type VM -ErrorAction SilentlyContinue
# Si inexistant, fin du script
If (!$LocationTarget){
Write-Host "Le dossier de VM cible $VmLocationTarget fourni n'existe pas. Fin du script."
exit
} ElseIf ($LocationTarget.Count -gt 1) {
Write-Host "Le dossier de VM cible $VmLocationTarget fourni existe plus d'une fois. Localisation cible ambigüe. Fin du script."
exit
}
# Si le dossier de VM cible n'a pas été fourni
} ElseIf (!$VmHostNameTarget) {
# Utilisation du même dossier de VM que la VM source
$LocationTarget=Get-Folder -Id $VmSource.FolderId
}
## Traitement
# Suppression de la VM cible
If ($VmTarget -And $DeleteTarget -eq 'Yes') {
Write-Host "Suppression de la VM cible $VmTarget"
Remove-VM -VM $VmTarget –DeletePermanently –confirm:$false
Write-Host "La VM $VmTarget a été supprimée avec succès."
}
# Clonage de la machine
If (New-VM -Name $VmNameTarget -VM $VmSource -VMHost $VmHostTarget -Datastore $VmDatastoreTarget -Location $LocationTarget -Description $VmDescriptionTarget) {
Write-Host "La VM $VmNameTarget a été clonée avec succès depuis la VM $VmSource. Fin du script."
} Else {
Write-Host "Une erreur est survenue lors du clonage de la VM $VmNameTarget depuis la VM $VmSource Fin du script."
exit
}
Disconnect-VIServer -Confirm:$false
Utilisation
L'utilisation de ce script se fait de la façon suivante :
./vmware_clone_VM.ps1 [-VmNameSource] <string[]> [-VmNameTarget] <string[]> [-VmHostNameTarget <String>] [-VmDatastoreNameTarget <String>] [-VmLocationTarget <String>] [-VmDescriptionTarget <String[""]>] [-DeleteTarget <String["No"|"Yes"]="No">]
Voici le détail des options :
VmNameSource
- Le nom de la VM à cloner. (obligatoire)
VmNameTarget
- Le nom de la VM cible à créer par clonage. (obligatoire)
VmHostNameTarget
- Le nom de l'ESXi qui hébergera la VM cible. (faculatif)
- Si absent, prendra la valeur de l'ESXi source.
- Le nom de l'ESXi qui hébergera la VM cible. (faculatif)
VmDatastoreNameTarget
- Le nom du datastore qui hébergera la VM cible. (faculatif)
- Si absent, prendra la valeur du datastore source.
- Si fourni, doit correspondre à un datastore de l'ESXi $VmHostNameTarget.
- Le nom du datastore qui hébergera la VM cible. (faculatif)
VmLocationTarget
- Le dossier de VM dans lequel se trouvera la VM cible. (faculatif)
- Seul le nom du dossier sans son arborescence est attendu.
- Ainsi, si un nom de dossier existe plus d'une fois, le script s'arrêtera.
- Si absent, prendra la valeur du dossier de VM source.
- Le dossier de VM dans lequel se trouvera la VM cible. (faculatif)
VmDescriptionTarget
- Description de la VM cible. (faculatif)
DeleteTarget
- Confirmation de la suppression de la VM cible avant clonage si elle existe. (faculatif)
- Valeur possible : No ou Yes
- Si Yes, la VM cible est définitivement supprimée.
- Si No et si la VM cible n'existe pas, le script s'exécutera normalement et la VM cible sera créée.
- Si No et si la VM cible existe déjà, le script se terminera immédiatement sans réaliser le clonage.
- Confirmation de la suppression de la VM cible avant clonage si elle existe. (faculatif)
Limitations
A ce jour, ce script possède des limitations liées aux noms qui existent en double.
Cela concerne les objets suivants :
- Machine Virtuelle
- Deux machines virtuelles peuvent porter le même nom. En revanche, leurs ID seront différents. Ce script se basant sur le nom d'une machine virtuelle, il tombera en erreur et s'arrêtera en cas de machine non-unique.
- Dossier de VM
- Un dossier de VM est défini par
- Un ID et nom
- Un ID de parent
- Ainsi, l'arborescence d'un dossier n'est pas inclus dans son nom. De ce fait, il n'est pas possible d'indiquer un chemin complet en entrée de ce script. De la même manière que pour les machines virtuelles, Deux dossiers de VM peuvent porter le même nom. Ainsi, le script tombera en erreur et s'arrêtera en cas de dossier de VM non-unique.
- Un dossier de VM est défini par
Clonage multiple
Prérequis
- Script
vmware_clone_VM.ps1
présenté plus haut - Fichier CSV contenant les informations nécessaires des machines à cloner
Fichier CSV
Voici un exemple de fichier CSV nommé vms_list_to_clone.csv
dont les champs sont séparés par des ;
:
Le fichier vmlist est manquant.
VmSource | VmHostnameSource | IpSource | GwSource | VmTarget | IpTarget | GwTarget | ESX | Datastore | Dossier | VLAN | Utilisateur | Description |
---|
Script de clonage multiple
Voici un exemple de script de clonage multiple s'appuyant sur le script vmware_clone_VM.ps1
présenté plus haut, d'une part, et le fichier vms_list_to_clone.csv
, d'autre part :
1 #!/usr/bin/pwsh
2
3 # Penser à utiliser le script create_credentials.ps1 pour créer les credentials
4
5 ## Initialisation variables
6 # Dossier des identifiants
7 $CredsFileLocation="/data/scripts/.credentials"
8 # Adresse du vCenter
9 $UrlVcenter="myvcenter.mydomain.com"
10 # Identifiant VMware à utiliser
11 $VmwareUser="myaccount@mydomain.com"
12 # Chemin du fichier CSV contenant les VMs à cloner
13 $CsvVmsPath="/data/scripts/vms_list_to_clone.csv"
14
15 Import-Csv $CsvVmsPath -Delimiter ";"| Foreach-Object {
16
17 Write-Host $_.VmTarget
18
19 # VM d'origine
20 $VmNameSource=$_.VmSource
21 $VmHostnameSource=$_.VmHostnameSource
22 $VmIpSource=$_.IpSource
23 $VmGwSource=$_.GwSource
24
25 # VM cible
26 $VmNameTarget=$_.VmTarget
27 $VmIpTarget=$_.IpTarget
28 $VmGwTarget=$_.GwTarget
29 $VmHostTarget=$_.ESX
30 $VmDatastoreTarget=$_.Datastore
31 $VmLocationTarget=$_.Dossier
32 $VmVlanNameTarget=$_.VLAN
33 $VmDescriptionTarget=$_.Description
34
35 # Utilisateur à utiliser
36 $VmUser=$_.Utilisateur
37 $UserTemplate="root" # <== A variabiliser
38
39 # Construction des fichiers d'identifiants à utiliser
40 $VcFileCreds=$($CredsFileLocation + "/" + $UrlVcenter + "_" + $VmwareUser + "_ps.xml")
41 $VmFileCredsSource=$($CredsFileLocation + "/" + $VmHostnameSource + "_" + $VmUser + "_ps.xml")
42 $FileCredsTemplate=$($CredsFileLocation + "/template_mysql_" + $UserTemplate + "_ps.xml")
43 $VmFileCredsTarget=$($CredsFileLocation + "/" + $VmNameTarget + "_" + $VmUser + "_ps.xml")
44
45 # Importation des credentials
46 $VcCreds=Import-Clixml -Path $VcFileCreds
47 $VmCredsSource=Import-Clixml -Path $VmFileCredsSource
48 $CredsTemplate=Import-Clixml -Path $FileCredsTemplate
49 $VmCredsTarget=Import-Clixml -Path $VmFileCredsTarget
50
51 # Récupération en clair du mot de passe de l'utilisateur cible
52 $PasswdTemplate=$CredsTemplate.GetNetworkCredential().Password
53 $PasswdTarget=$VmCredsTarget.GetNetworkCredential().Password
54
55 ## Pré-traitement
56 # Clonage de la VM
57 & /data/scripts/vmware_clone_VM.ps1 "$VmNameSource" $VmNameTarget -VmHostNameTarget $VmHostTarget -VmDatastoreNameTarget $VmDatastoreTarget -VmLocationTarget "$VmLocationTarget" -VmDescriptionTarget "$VmDescriptionTarget" -DeleteTarget Yes
58
59 ## Connection au VCenter
60 Connect-VIServer -Server $UrlVcenter -Credential $VcCreds | Out-Null
61
62 ## Vérifications
63 # La VM cible a-t-elle bien été créée ? Si non, fin du script
64 $VmTarget=Get-VM -name $VmNameTarget -ErrorAction SilentlyContinue
65 If (!$VmTarget){
66 Write-Host "La VM cible $VmNameTarget n'existe pas. Fin du script."
67 exit
68 } ElseIf ($VmTarget.Count -gt 1) {
69 Write-Host "La VM cible $VmNameTarget fournie existe plus d'une fois. VM cible ambigüe. Fin du script."
70 exit
71 }
72
73 # Le VLAN source est-il unique ? Si non, fin du script
74 $VmSource=Get-VM -name "$VmNameSource" -ErrorAction SilentlyContinue
75 $VmVlanSource=Get-VirtualPortGroup -VM $VmSource
76 If (!$VmVlanSource){
77 Write-Host "Il n'y a pas de VLAN source existant. Fin du script."
78 exit
79 } ElseIf ($VmVlanSource.Count -gt 1) {
80 Write-Host "Il existe plus d'un VLAN source. VLAN source ambigu. Fin du script."
81 exit
82 }
83
84 # Le VLAN cible existe-t-il ? Si non, fin du script
85 $VmVlanTarget=Get-VMHost -VM $VmTarget | Get-VirtualPortGroup -Name $VmVlanNameTarget
86 If (!$VmVlanTarget){
87 Write-Host "Le VLAN cible $VmVlanNameTarget n'existe pas. Fin du script."
88 exit
89 } ElseIf ($VmVlanTarget.Count -gt 1) {
90 Write-Host "Le VLAN cible $VmVlanNameTarget fourni existe plus d'une fois. VLAN cible ambigu. Fin du script."
91 exit
92 }
93
94 ## Traitement
95 # Déconnection de la carte réseau
96 $VmNicTarget=Get-NetworkAdapter -VM $VmTarget | Set-NetworkAdapter -StartConnected:$false –confirm:$false
97 If (!$VmNicTarget){
98 Write-Host "Une erreur s'est produite lors de la coniguration de la carte réseau en mode déconnecté au démarrage. Fin du script."
99 exit
100 }
101
102 # Allumage de la VM cible
103 If ($VmTarget.PowerState -eq 'PoweredOff') {
104 Start-VM -VM $VmTarget –confirm:$false | Wait-Tools | Out-Null
105 }
106
107 # Désactivation Zabbix, renommage des fichiers portant le nom de la machine, changement adresse IP, réinitialisation des clés SSH
108 $script=@"
109 systemctl enable zabbix-agent.service
110 sleep 10
111 export MYSQL_PWD=$PasswdTemplate
112 mysql -uroot -e "ALTER USER 'pma_user'@'192.168.0.40' IDENTIFIED BY '$PasswdTarget';"
113 mysql -uroot -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '$PasswdTarget';"
114 systemctl stop mysqld
115 sed -i -e 's/'$VmHostnameSource'/'$VmNameTarget'/g' /etc/hostname
116 sed -i -e 's/'$VmHostnameSource'/'$VmNameTarget'/g' /etc/zabbix/zabbix_agentd.conf
117 /usr/bin/sed -i -e 's/'$VmIpSource'/'$VmIpTarget'/g' /etc/sysconfig/network-scripts/ifcfg-ens192
118 /usr/bin/sed -i -e 's/'$VmGwSource'/'$VmGwTarget'/g' /etc/sysconfig/network-scripts/ifcfg-ens192
119 rm -rf /etc/ssh/ssh_host_*
120 ssh-keygen -A -q
121 rm -f /root/.ssh/*rsa*
122 >/root/.bash_history
123 "@
124 Invoke-VMScript -VM $VmTarget -ScriptType Bash -ScriptText $script -GuestCredential $VmCredsSource
125
126 # Mise à jour du mot de passe
127 Invoke-VMScript -VM $VmTarget -ScriptType Bash -ScriptText "echo $PasswdTarget | passwd --stdin $VmUser" -GuestCredential $VmCredsSource -ErrorAction SilentlyContinue
128
129 # Redémarrage de la machine cible
130 Restart-VMGuest -VM $VmTarget | Wait-Tools | Out-Null
131
132 # Changement de VLAN de la carte réseau
133 If ( $VmVlanSource -ne $VmVlanTarget ) {
134 If (!$(Set-NetworkAdapter -NetworkAdapter $VmNicTarget -Portgroup $VmVlanTarget –confirm:$false)) {
135 Write-Host "Une erreur s'est produite lors du changement de VLAN de la carte réseau. Fin du script."
136 exit
137 }
138 }
139
140 # Reconnection de la carte réseau
141 If (!$(Set-NetworkAdapter -NetworkAdapter $VmNicTarget -StartConnected:$true -Connected:$true –confirm:$false)) {
142 Write-Host "Une erreur s'est produite lors de la coniguration de la carte réseau en mode connecté en l'état et au démarrage. Fin du script."
143 exit
144 }
145 Disconnect-VIServer -Confirm:$false
146 }
Explications des options :
- Ligne 7 :
- Localisation du dossier contenant les identifiants précédemment créés avec le script create_credentials.ps1
- Ligne 9 et 11 :
- Adresse et identifiant du vCenter à utiliser
- Ligne 13 :
- Localisation du fichier CSV
vms_list_to_clone.csv
précédemment créé
- Localisation du fichier CSV
- Ligne 57 :
- Appel du script
vmware_clone_VM.ps1
précédemment présenté dans la partie "Simple clonage" de cette page.
- Appel du script
- Lignes 109 à 122 :
- Script personnalisé contenant les commandes à passer sur la VM
- En l'occurrence, dans cet exemple, les commandes font les actions suivantes :
- Activation du service de supervision Zabbix
- Attente que le serveur MySQL soit bien lancé
- Réinitialisation de mots de passe de certains utilisateurs MySQL
- Renommage de la machine
- Changement d'adresse IP
- Réinitialisation des clés SSH
- Suppression de l'historique des commandes de l'utilisateur utilisé pour passer les commandes (effacement des mots de passe en clair)
- Ligne 127
- Réinitialisation du mot de passe de l'administrateur de la machine virtuelle