Lister les snapshots avec leur auteur

En production, avec une infrastructure importante gérée par plusieurs personnes, il n’est pas rare qu’on s’aperçoive que telle ou telle VM a un snapshot actif sans qu’on sache s’il est toujours nécessaire ou si on peut le supprimer. Le descriptif n’est pas toujours parlant, et il faut donc s’adresser à l’auteur du snapshot.
Cependant si lister les snapshots des VMs n’est pas compliqué (un simple « Get-VM | Get-Snapshot » renvoie le résultat), il manque une information importante dans ce que renvoie Get-Snapshot : l’auteur du snapshot.

On trouve de la littérature à ce sujet sur Internet, mais je n’ai jamais vraiment été satisfait de la façon dont c’était géré.

L’information de création des snapshots peut être trouvée dans l’historique des événements, via la commande Get-VIEvent.

Get-VIEvent -Type Info| where-object {$_.FullFormattedMessage.contains("Create virtual machine snapshot")}

Ce genre de commande renvoie tous les snapshots qui ont été créés. Mais certains ont été supprimés depuis.
Il est donc nécessaire de faire un rapprochement entre les résultats de Get-Snapshot et de Get-VIEvent pour obtenir les infos des snapshots encore actifs.
Pour cela, on peut se baser sur la date de création ($_.Created pour Get-Snapshot et $_.CreatedTime pour Get-VIEvent).

Cependant je me suis aperçu que je n’obtenais pas toujours le résultat escompté.

La date et l’heure renvoyées par Get-Snapshot différent parfois légèrement de celles renvoyées par Get-VIEvent. Je n’en ai pas vraiment identifié la cause, mais cela pourrait provenir d’une désynchronisation horaire entre le host et le vCenter, surtout avec un vCenter virtuel sous Windows (Microsoft ne garantit pas une haute précision de la synchro horaire via l’AD, voir https://support.microsoft.com/en-us/kb/939322).
Pour compenser ce problème, il faut prendre les événements intervenus quelques secondes avant ou quelques secondes après l’heure indiquée du snapshot.

De plus, il peut y avoir des cas de figure avec des snapshots relativement proches. Par exemple l’un lancé manuellement dès le début de la période de maintenance pour une opération spécifique, et un autre lancé automatiquement par l’outil de backup parce qu’il est justement supposé sauvegarder la VM dès le début de la plage de maintenance.
Avec ces snapshots proches, et vu qu’on prend une petite période de temps autour du snapshot, on pourrait trouver plusieurs événements semblant correspondre, sans qu’on puisse identifier d’après ces informations lequel a créé le snapshot encore actif.
C’est manuellement, au vu des infos remontées, qu’on pourra identifier le créateur du snapshot, en prenant en compte le nom et le descriptif de celui-ci (les outils automatiques saisissent des infos normalisées, un admin OS ne mettra pas le même commentaire qu’un admin DB, etc…).

lister-les-snapshots-avec-leur-auteur

Reste un problème que je n’ai pas encore résolu : comment identifier le créateur d’un snapshot tellement ancien que sa création ne figure plus dans l’historique des événements du vCenter ?
Un contournement : relever régulièrement les snapshots avec leur auteur, et conserver l’information.


Variables

Deux variables sont initialisées aux deux premières lignes.

$Delay : c’est le décallage horaire en secondes qu’on pourrait constater.

$Snapshots : il s’agit de la liste des snapshots à prendre en compte.
Elle est initialisée par une requête pour lister par exemple les snapshots d’une VM, des VMs d’un cluster, ou de toutes les VMs du vCenter.

$Snapshots = Get-VM NomVM | Get-Snapshot
$Snapshots = Get-Cluster NomCluster | Get-VM | Get-Snapshot
$Snapshots = Get-VM | Get-Snapshot

Script

$Delay = 5
$Snapshots = Get-VM | Get-Snapshot
$Result = @()
Foreach ($Snapshot in $Snapshots)
{
   $StartDateTime = $Snapshot.Created.AddSeconds(-$Delay)
   $EndDateTime = $Snapshot.Created.AddSeconds($Delay)
   $VIEvents = Get-VIEvent -Entity $Snapshot.VM -Type Info -Start $StartDateTime -Finish $EndDateTime | where-object {$_.FullFormattedMessage.contains("Create virtual machine snapshot")} | Select-Object UserNAme
   if (($VIEvents | Measure-Object).Count -gt 1)
   {
      $UserName = ""
      Foreach ($VIEvent in $VIEvents)
      {
         if ($UserName -eq "")
         {
            $UserName = $VIEvent.UserName
         }
         else
         {
            $UserName = $UserName + " or " + $VIEvent.UserName
         }
      }
   }
   else
   {
      if (($VIEvents | Measure-Object).Count -eq 1)
      {
          $UserName = $VIEvents.UserName
      }
      else
      {
          $UserName = "Unknown. Too old ?"
      }
   }
   $Result += $Snapshot | Select-Object Created, VM, @{Name="CreatedBy";Expression={$Username}}, Name, Description, PowerState, @{Name="SizeGB";Expression={([math]::round($_.SizeGB*10))/10}}
}
$Result | Format-Table * -Autosize

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *