Question
Backup de VM HyperV hébergées dans un cluster
- Zedd
- Auteur du sujet
- Hors Ligne
- Membre senior
-
Réduire
Plus d'informations
- Messages : 45
- Remerciements reçus 0
il y a 13 ans 9 mois #12523
par Zedd
Backup de VM HyperV hébergées dans un cluster a été créé par Zedd
Bonjour,
Après moultes recherches pour backuper mes machines virtuelles, j'en suis arrivé au script ci-dessous.
Je le partage donc si ça en intéresse certains, et bien sûr comme je suis une bille en powershell, si vous avez
des idées pour l'améliorer, n'hésitez pas !!
Voici ce que fait le script :
Prérequis : A l'endroit où se trouve le script, placer un fichier \"mailrecap.txt\" qui contient le ou les mails
des destinataires de notifications.
Avoir installé Hyperv.psd1 -> téléchargeable ici : pscodeplex.codeplex.com/
Avoir installé la fonction failover
Serveur SMTP : je me sers d'un SMTP interne, qui fait du relaying vers un SMTP externe -> Attention à VOTRE
configuration
Il retrouve le noeud où est la VM au moment de l'exécution du script (vive le cluster, le noeud n'est pas
forcément le même en cas de panne)
Il va tester la présence d'un snapshot (je n'aime pas travailler avec les snapshot, donc s'il y en a un, le
script m'averti et ne fait rien d'autre. Je gère le cas du snapshot à la main -> fusion, suppression, etc...)
Si la machine est éteinte, il m'averti et ne fait rien d'autre. Car il est possible que la VM soit
volontairement arrêtée pour maintenance ou autre.
Enfin, si la VM est allumée et que tout va bien, le script va stopper la VM, copier le VHD, puis redémarrer la VM.
Chaque condition fait l'objet d'un envoi de mail.
ATTENTION : Le nom de la VM à indiquer en début de script est celui visualisé dans le gestionnaire de cluster, pas celui visualisé dans le gestionnaire HyperV. (Eh oui, ils peuvent être différent, j'en ai fait l'expérience
)
[code:1]
####################################################
# Paramétrage
####################################################
# Paramétrage VM
$VMName = \"NVtestcluster\"
# Paramétrage Dossier
$Backup = \"C:\ClusterStorage\Volume2\Backup\$VMName\\"
$Journal = 'C:\Script_test\' + $VMName + '.txt'
#####Informations relative à l'envoi de mail
$expediteur = \"no-reply@mon_domaine.com\"
$serveur = \"mon_ip_locale\"
$SMTPAuthUsername = \"no-reply@domaine.local\"
$SMTPAuthPassword = \"mon_mot_de_passe\"
$SMTPclient = new-object System.Net.Mail.SmtpClient $serveur
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential($SMTPAuthUsername, $SMTPAuthPassword)
$Fichier = $Journal
#########################################################################################################
#Début du travail et création du nouveau journal
#########################################################################################################
\"Debut du travail le \" + (get-date).tostring(‘dd-MM-yyyy’) + \" à \" + (get-date).tostring(‘hh:mm:ss’) > $Journal
\"\" >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
\"\" >> $Journal
####################################################
# Import des différents modules
####################################################
#Import du module failover -> Ca permet d'interroger le cluster et pas un seul serveur physique
\"Import du module FailOver\" >> $Journal
Import-Module FailoverClusters
#Import du module Hyperv -> ca permet d'éteindre et d'allumer les machines sans SCVMM
\"Import du module HyperV\" >> $Journal
Import-Module \"C:\Program Files\modules\HyperV\Hyperv.psd1\"
\"\" >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
\"\" >> $Journal
####################################################
# Recherche du serveur qui heberge la VM dans le cluster
####################################################
\"Recherche du serveur qui heberge la VM dans le cluster à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
\"\" >> $Journal
$VMGroups = Get-ClusterGroup | ?{ $_ | Get-ClusterResource | ?{ $_.ResourceType -like \"Virtual Machine\" }}
$VM = $VMGroups | Where-Object {$_.Name -eq $VMName}
$ServerSource = $VM.ownernode.name
\"Serveur détenant la VM au moment de l'exécution du script : $ServerSource\" >> $Journal
\"\" >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
\"\" >> $Journal
####################################################
# Localisation du VHD et test de présence d'un AVHD
####################################################
\"Localisation du VHD et test de présence d'un AVHD à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
$VHDLocation = Get-VMDisk \"$VM\" -server \"$ServerSource\" | Where-Object {$_.DriveName -eq \"Disque Dur\"}
$VHDFileName = $VHDLocation.diskPath
$VHDFileImage = $VHDLocation.diskimage
\"Présence des fichiers suivants (SI VHD UNIQUEMENT, LE NOM EST EN DOUBLE) : \" >> $Journal
\"\" >> $Journal
\"$VHDFileName\" >> $Journal
\"$VHDFileImage\" >> $Journal
\"\" >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
\"\" >> $Journal
#Inscription en variable du chemin physique du VHD, volume 1 ou 2
if ($VHDFileName -like '*Volume1*')
{$Chemin = \"C:\ClusterStorage\Volume1\$VmName\\" }
else
{$Chemin = \"C:\ClusterStorage\Volume2\$VmName\\" }
\"\" >> $Journal
\"Chemin Physique de la VM : $Chemin\" >> $Journal
\"\" >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
\"\" >> $Journal
#########################################################################################################
#Envoi du mail au service Info signalant le AVHD
#########################################################################################################
\"Envoi du mail au service Info signalant le AVHD à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
if (($VHDFileName -like '*.avhd') -and ($VM | Where-Object {$_.State -eq \"Online\"}))
{
#La VM est allumée, un AVHD est présent, on ne fait rien au niveau du script de sauvegarde.
\"La VM est allumée, un AVHD est présent, on ne fait rien au niveau du script de sauvegarde.\" >> $Journal
$objet = \"HyperV - Sauvegarde de $VMName - Machine allumée ET AVHD le \" + [System.DateTime]::Now
$texte = \"La VM $VMName n'a pas été traitée, un fichier AVHD est présent\"
}
elseif (($VHDFileName -like '*.avhd') -and ($VM | Where-Object {$_.State -eq \"Offline\"}))
{
#La VM est éteinte, un AVHD est présent, on ne fait rien au niveau du script de sauvegarde.
\"La VM est éteinte, un AVHD est présent, on ne fait rien au niveau du script de sauvegarde.\" >> $Journal
$objet = \"HyperV - Sauvegarde de $VMName - Machine éteinte ET AVHD le \" + [System.DateTime]::Now
$texte = \"La VM $VMName n'a pas été traitée, un fichier AVHD est présent\"
}
elseif (($VHDFileName -like '*.vhd') -and ($VM | Where-Object {$_.State -eq \"Online\"}))
{
#Arret de l'original
\"Arret de la VM à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
shutdown-vm -vm \"$VM\" -server \"$ServerSource\" -force
\"\" >> $Journal
#########################################################################################################
#Début du clonage
\"Début de la copie du VHD à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
\"\" >> $Journal
xcopy $VHDFileName $Backup /Y >> $Journal
\"\" >> $Journal
\"Fin de la copie du VHD à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
\"\" >> $Journal
#########################################################################################################
#Redémarrage de l'original
\"Démarrage de la VM à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
start-vm -vm \"$VM\" -server \"$ServerSource\"
\"\" >> $Journal
\"\" >> $Journal
\"Fin du travail à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
$objet = \"HyperV - Sauvegarde de $VMName - Opération réussie le \" + [System.DateTime]::Now
$texte = \"La VM $VMName a été copiée. Vous trouverez le journal de Log en PJ.\"
}
elseif (($VHDFileName -like '*.vhd') -and ($VM | Where-Object {$_.State -eq \"Offline\"}))
{
#La VM est éteinte, peut-être volontairement, on ne fait rien au niveau du script de sauvegarde.
\"La VM est éteinte, peut-être volontairement, on ne fait rien au niveau du script de sauvegarde.\" >> $Journal
$objet = \"HyperV - Sauvegarde de $VMName - Machine Eteinte le \" + [System.DateTime]::Now
$texte = \"La VM $VMName est éteinte. La sauvegarde n'a pas eu lieu.\"
}
foreach ($email in ${C:\Script_test\mailrecap.txt}) {
$destinataire = $email
$message = new-object System.Net.Mail.MailMessage $expediteur, $destinataire, $objet, $texte
$attachment = new-object System.Net.Mail.Attachment $Journal
$message.Attachments.Add($attachment)
$SMTPclient.Send($message)
}
exit
[/code:1]
Cdt,
Zedd
Message édité par: Zedd, à: 13/08/12 16:59
Message édité par: Zedd, à: 13/08/12 21:44
Message édité par: Zedd, à: 14/08/12 12:53<br><br>Message édité par: Zedd, à: 14/08/12 13:13
Après moultes recherches pour backuper mes machines virtuelles, j'en suis arrivé au script ci-dessous.
Je le partage donc si ça en intéresse certains, et bien sûr comme je suis une bille en powershell, si vous avez
des idées pour l'améliorer, n'hésitez pas !!
Voici ce que fait le script :
Prérequis : A l'endroit où se trouve le script, placer un fichier \"mailrecap.txt\" qui contient le ou les mails
des destinataires de notifications.
Avoir installé Hyperv.psd1 -> téléchargeable ici : pscodeplex.codeplex.com/
Avoir installé la fonction failover
Serveur SMTP : je me sers d'un SMTP interne, qui fait du relaying vers un SMTP externe -> Attention à VOTRE
configuration
Il retrouve le noeud où est la VM au moment de l'exécution du script (vive le cluster, le noeud n'est pas
forcément le même en cas de panne)
Il va tester la présence d'un snapshot (je n'aime pas travailler avec les snapshot, donc s'il y en a un, le
script m'averti et ne fait rien d'autre. Je gère le cas du snapshot à la main -> fusion, suppression, etc...)
Si la machine est éteinte, il m'averti et ne fait rien d'autre. Car il est possible que la VM soit
volontairement arrêtée pour maintenance ou autre.
Enfin, si la VM est allumée et que tout va bien, le script va stopper la VM, copier le VHD, puis redémarrer la VM.
Chaque condition fait l'objet d'un envoi de mail.
ATTENTION : Le nom de la VM à indiquer en début de script est celui visualisé dans le gestionnaire de cluster, pas celui visualisé dans le gestionnaire HyperV. (Eh oui, ils peuvent être différent, j'en ai fait l'expérience
[code:1]
####################################################
# Paramétrage
####################################################
# Paramétrage VM
$VMName = \"NVtestcluster\"
# Paramétrage Dossier
$Backup = \"C:\ClusterStorage\Volume2\Backup\$VMName\\"
$Journal = 'C:\Script_test\' + $VMName + '.txt'
#####Informations relative à l'envoi de mail
$expediteur = \"no-reply@mon_domaine.com\"
$serveur = \"mon_ip_locale\"
$SMTPAuthUsername = \"no-reply@domaine.local\"
$SMTPAuthPassword = \"mon_mot_de_passe\"
$SMTPclient = new-object System.Net.Mail.SmtpClient $serveur
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential($SMTPAuthUsername, $SMTPAuthPassword)
$Fichier = $Journal
#########################################################################################################
#Début du travail et création du nouveau journal
#########################################################################################################
\"Debut du travail le \" + (get-date).tostring(‘dd-MM-yyyy’) + \" à \" + (get-date).tostring(‘hh:mm:ss’) > $Journal
\"\" >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
\"\" >> $Journal
####################################################
# Import des différents modules
####################################################
#Import du module failover -> Ca permet d'interroger le cluster et pas un seul serveur physique
\"Import du module FailOver\" >> $Journal
Import-Module FailoverClusters
#Import du module Hyperv -> ca permet d'éteindre et d'allumer les machines sans SCVMM
\"Import du module HyperV\" >> $Journal
Import-Module \"C:\Program Files\modules\HyperV\Hyperv.psd1\"
\"\" >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
\"\" >> $Journal
####################################################
# Recherche du serveur qui heberge la VM dans le cluster
####################################################
\"Recherche du serveur qui heberge la VM dans le cluster à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
\"\" >> $Journal
$VMGroups = Get-ClusterGroup | ?{ $_ | Get-ClusterResource | ?{ $_.ResourceType -like \"Virtual Machine\" }}
$VM = $VMGroups | Where-Object {$_.Name -eq $VMName}
$ServerSource = $VM.ownernode.name
\"Serveur détenant la VM au moment de l'exécution du script : $ServerSource\" >> $Journal
\"\" >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
\"\" >> $Journal
####################################################
# Localisation du VHD et test de présence d'un AVHD
####################################################
\"Localisation du VHD et test de présence d'un AVHD à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
$VHDLocation = Get-VMDisk \"$VM\" -server \"$ServerSource\" | Where-Object {$_.DriveName -eq \"Disque Dur\"}
$VHDFileName = $VHDLocation.diskPath
$VHDFileImage = $VHDLocation.diskimage
\"Présence des fichiers suivants (SI VHD UNIQUEMENT, LE NOM EST EN DOUBLE) : \" >> $Journal
\"\" >> $Journal
\"$VHDFileName\" >> $Journal
\"$VHDFileImage\" >> $Journal
\"\" >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
\"\" >> $Journal
#Inscription en variable du chemin physique du VHD, volume 1 ou 2
if ($VHDFileName -like '*Volume1*')
{$Chemin = \"C:\ClusterStorage\Volume1\$VmName\\" }
else
{$Chemin = \"C:\ClusterStorage\Volume2\$VmName\\" }
\"\" >> $Journal
\"Chemin Physique de la VM : $Chemin\" >> $Journal
\"\" >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
\"\" >> $Journal
#########################################################################################################
#Envoi du mail au service Info signalant le AVHD
#########################################################################################################
\"Envoi du mail au service Info signalant le AVHD à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
if (($VHDFileName -like '*.avhd') -and ($VM | Where-Object {$_.State -eq \"Online\"}))
{
#La VM est allumée, un AVHD est présent, on ne fait rien au niveau du script de sauvegarde.
\"La VM est allumée, un AVHD est présent, on ne fait rien au niveau du script de sauvegarde.\" >> $Journal
$objet = \"HyperV - Sauvegarde de $VMName - Machine allumée ET AVHD le \" + [System.DateTime]::Now
$texte = \"La VM $VMName n'a pas été traitée, un fichier AVHD est présent\"
}
elseif (($VHDFileName -like '*.avhd') -and ($VM | Where-Object {$_.State -eq \"Offline\"}))
{
#La VM est éteinte, un AVHD est présent, on ne fait rien au niveau du script de sauvegarde.
\"La VM est éteinte, un AVHD est présent, on ne fait rien au niveau du script de sauvegarde.\" >> $Journal
$objet = \"HyperV - Sauvegarde de $VMName - Machine éteinte ET AVHD le \" + [System.DateTime]::Now
$texte = \"La VM $VMName n'a pas été traitée, un fichier AVHD est présent\"
}
elseif (($VHDFileName -like '*.vhd') -and ($VM | Where-Object {$_.State -eq \"Online\"}))
{
#Arret de l'original
\"Arret de la VM à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
shutdown-vm -vm \"$VM\" -server \"$ServerSource\" -force
\"\" >> $Journal
#########################################################################################################
#Début du clonage
\"Début de la copie du VHD à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
\"\" >> $Journal
xcopy $VHDFileName $Backup /Y >> $Journal
\"\" >> $Journal
\"Fin de la copie du VHD à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
\"\" >> $Journal
#########################################################################################################
#Redémarrage de l'original
\"Démarrage de la VM à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
start-vm -vm \"$VM\" -server \"$ServerSource\"
\"\" >> $Journal
\"\" >> $Journal
\"Fin du travail à \" + (get-date).tostring(‘hh:mm:ss’) >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
\"
\" >> $Journal
$objet = \"HyperV - Sauvegarde de $VMName - Opération réussie le \" + [System.DateTime]::Now
$texte = \"La VM $VMName a été copiée. Vous trouverez le journal de Log en PJ.\"
}
elseif (($VHDFileName -like '*.vhd') -and ($VM | Where-Object {$_.State -eq \"Offline\"}))
{
#La VM est éteinte, peut-être volontairement, on ne fait rien au niveau du script de sauvegarde.
\"La VM est éteinte, peut-être volontairement, on ne fait rien au niveau du script de sauvegarde.\" >> $Journal
$objet = \"HyperV - Sauvegarde de $VMName - Machine Eteinte le \" + [System.DateTime]::Now
$texte = \"La VM $VMName est éteinte. La sauvegarde n'a pas eu lieu.\"
}
foreach ($email in ${C:\Script_test\mailrecap.txt}) {
$destinataire = $email
$message = new-object System.Net.Mail.MailMessage $expediteur, $destinataire, $objet, $texte
$attachment = new-object System.Net.Mail.Attachment $Journal
$message.Attachments.Add($attachment)
$SMTPclient.Send($message)
}
exit
[/code:1]
Cdt,
Zedd
Message édité par: Zedd, à: 13/08/12 16:59
Message édité par: Zedd, à: 13/08/12 21:44
Message édité par: Zedd, à: 14/08/12 12:53<br><br>Message édité par: Zedd, à: 14/08/12 13:13
Connexion ou Créer un compte pour participer à la conversation.
- xyz
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6311
- Remerciements reçus 69
il y a 13 ans 9 mois #12526
par xyz
Tutoriels PowerShell
Réponse de xyz sur le sujet Re:Backup de VM HyperV hébergées dans un cluster
Pas de pb avec la config email en début de ton script ?
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Zedd
- Auteur du sujet
- Hors Ligne
- Membre senior
-
Réduire
Plus d'informations
- Messages : 45
- Remerciements reçus 0
il y a 13 ans 9 mois #12530
par Zedd
Réponse de Zedd sur le sujet Re:Backup de VM HyperV hébergées dans un cluster
Un brin en effet.. rattage de copier coller, merci de m'avoir averti
Cdt,
Zedd
Cdt,
Zedd
Connexion ou Créer un compte pour participer à la conversation.
- Zedd
- Auteur du sujet
- Hors Ligne
- Membre senior
-
Réduire
Plus d'informations
- Messages : 45
- Remerciements reçus 0
il y a 13 ans 9 mois #12535
par Zedd
Réponse de Zedd sur le sujet Re:Backup de VM HyperV hébergées dans un cluster
Voila, une ptite retouche, ça fait un peu moins cochon, même si je suis sûr que les développeurs dans l'âme vont se tirer les cheuveux 
Le tout reste fonctionnel, avec une ptite 20ene de lignes en moins.
Cdt,
Zedd
Le tout reste fonctionnel, avec une ptite 20ene de lignes en moins.
Cdt,
Zedd
Connexion ou Créer un compte pour participer à la conversation.
- xyz
- Hors Ligne
- Modérateur
-
Réduire
Plus d'informations
- Messages : 6311
- Remerciements reçus 69
il y a 13 ans 9 mois #12538
par xyz
Tutoriels PowerShell
Réponse de xyz sur le sujet Re:Backup de VM HyperV hébergées dans un cluster
Tu devrais le poster dans le forum contribution, en y attachant le script, car certaines lignes sont interprétées par Joomla.
Deux remarques ;
Il est préférable de libérer les ressources de l'objet Attachement (cf. méthode Dispose())
Et le mieux eut été de ne pas mélanger le reporting/log d'avec le traitement à proprement dit. Mais pour un premier script tu peux le laisser en l'état.
une astuce : tu peux utilser `r`n pour insére un retour chariot dans une string.
Tu peux aussi utilser la construction suivante :
[code:1]
@\"
Présence des fichiers suivants (SI VHD UNIQUEMENT, LE NOM EST EN DOUBLE) :
$VHDFileName
$VHDFileImage
\"@ >> $Journal
[/code:1]
Deux remarques ;
Il est préférable de libérer les ressources de l'objet Attachement (cf. méthode Dispose())
Et le mieux eut été de ne pas mélanger le reporting/log d'avec le traitement à proprement dit. Mais pour un premier script tu peux le laisser en l'état.
une astuce : tu peux utilser `r`n pour insére un retour chariot dans une string.
Tu peux aussi utilser la construction suivante :
[code:1]
@\"
Présence des fichiers suivants (SI VHD UNIQUEMENT, LE NOM EST EN DOUBLE) :
$VHDFileName
$VHDFileImage
\"@ >> $Journal
[/code:1]
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
Temps de génération de la page : 0.045 secondes
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Entraide pour les débutants
- Backup de VM HyperV hébergées dans un cluster