Question Backup de VM HyperV hébergées dans un cluster

Plus d'informations
il y a 13 ans 9 mois #12523 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 :p )

[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.

Plus d'informations
il y a 13 ans 9 mois #12526 par xyz
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.

Plus d'informations
il y a 13 ans 9 mois #12530 par Zedd
Un brin en effet.. rattage de copier coller, merci de m'avoir averti

Cdt,

Zedd

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 13 ans 9 mois #12535 par Zedd
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 :p

Le tout reste fonctionnel, avec une ptite 20ene de lignes en moins.

Cdt,

Zedd

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 13 ans 9 mois #12538 par xyz
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]
@\&quot;
Présence des fichiers suivants (SI VHD UNIQUEMENT, LE NOM EST EN DOUBLE) :

$VHDFileName
$VHDFileImage

\&quot;@ &gt;&gt; $Journal
[/code:1]

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.042 secondes
Propulsé par Kunena