From 56afc579c0a937a0f8ba963299a995da5b2ef137 Mon Sep 17 00:00:00 2001 From: Nicolas Lang Date: Sun, 17 Dec 2023 01:18:44 +0100 Subject: [PATCH] =?UTF-8?q?Cr=C3=A9ation=20script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Backup Exec/tape_check.ps1 | 279 +++++++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 Backup Exec/tape_check.ps1 diff --git a/Backup Exec/tape_check.ps1 b/Backup Exec/tape_check.ps1 new file mode 100644 index 0000000..0364dc4 --- /dev/null +++ b/Backup Exec/tape_check.ps1 @@ -0,0 +1,279 @@ +#Script créé par Nicolas Lang - Sous licence CC-BY-SA +#https://nicolaslang.fr + +param( +[int]$joursprochains = 0 +) +#Ce paramètre vous permettra de choisir sur combien de jours vous souhaitez analyser les sauvegardes + +#Le serveur SMTP pour l'envoi du mail +$mailserver = "smtpserver.domain.local" +#L'expéditeur +$from = "moi@domain.local" +#Le / Les destinateurs +$to = @("moi@domain.local","lui@domain.local","eux@autredomaine.fr") + +#On démarre un fichier de log, utile en cas de problème +Start-Transcript C:\Temp\BECheck.txt -Force + + +#On essaie d'importer le module BEMCLI. S'il n'existe pas, alors on arrête le script +try +{ + Import-Module BEMCLI +} +catch +{ + Write-Output "Impossible d'importer le module BEMCLI" + throw("No BEMCLI") + exit +} + +#Un peu de texte pour alimenter le fichier de log +if ($joursprochains -ne 0) +{ + Write-Output "$((get-date).tolongtimestring()) : Vérification pour les $joursprochains prochains jours." +} + + +Write-Output "$((get-date).tolongtimestring()) : Récupération de l'objet de librairie" + +#On essaie d'obtenir l'objet de libraire. Si c'est impossible, on coupe. +try +{ + $librairie = Get-BERoboticLibraryDevice +} +catch +{ + Write-Output "$((get-date).tolongtimestring()) : Impossible de récupérer la libraire : $($Error[0])" + throw("Library error") + exit +} + +# On essaie ensuite de récuperer la liste des backups. Si une erreur se présente, on coupe. +try +{ + $listofjobs = Get-BEJob -JobType "Backup" +} +catch +{ + Write-Output "$((get-date).tolongtimestring()) : Impossible de récuperer les jobs : $($error[0])" + throw("Backup error") + exit +} + + + +#region inventaire + +#Lancement d'un inventaire. Si pas d'inventaire... et bien... la aussi, on coupe. +try +{ + $inventory = Submit-BEInventoryJob -RoboticLibraryDevice $librairie +} +catch +{ + Write-Output "$((get-date).tolongtimestring()) : Une erreur s'est produite durant le lancement de l'inventaire : $($Error[0])" + throw("Inventory error") + exit + +} +#Attente du lancement du job d'inventaire + +#L'outil BEMCLI est assez mal concu sur certains points. Il y a un décallage entre le lancement de l'inventaire et sa détection dans les jobs actifs. +#Nous devons donc attendre que l'inventaire déclenché précedemment soit détecté et actif. + +Write-Output "Attente du lancement du job`n" +do +{ + try + { + $jobcheck = Get-BEActiveJobDetail + } + catch + { + Write-host -NoNewline "-" + } + $jobfinished = Get-BEJobHistory -FromStartTime (get-date).Date | Where-Object {$_.name -eq $($inventory.name)} + + + Start-Sleep -Seconds 10 + Write-Host -NoNewline "-" +} +until($jobcheck.Name -eq $inventory.Name -or $jobfinished -ne $null) +Write-host " " + +#Couleurs jolies pour patienter. Oui. Comme ça. + +$i = 1 +$z = 15 +Write-Host $(" " * $((get-host).ui.rawui.buffersize.width)) -BackgroundColor 15 +Write-Host "Attente de la fin du job d'inventaire" +Write-Host $(" " * $((get-host).ui.rawui.buffersize.width)) -BackgroundColor 15 + +do { + + if ($i % $((get-host).UI.RawUI.BufferSize.Width) -eq 0) + { + if ($z -eq 0){$z = 16} + $z-- + Write-host " " -BackgroundColor $z + } + else + { + + Write-Host -NoNewline " " -BackgroundColor $z + } + $i++ + Start-Sleep -Seconds 1 + $endofjob = Get-BEJobHistory -FromStartTime (get-date).Date | Where-Object {$_.name -eq $($inventory.name)} +}while ($endofjob -eq $null) + +#Si le job n'est pas en succès, on coupe la et on avertit. Sinon, on continue. + +if ($endofjob.JobStatus -ne "Succeeded") +{ + Write-Output "$((get-date).tolongtimestring()) : Fin de l'inventaire." + Send-MailMessage -From $from -To $to -SmtpServer $mailserver -Subject "Erreur durant l'inventaire" -Body [string]($endofjob | ConvertTo-Html) -BodyAsHtml + Stop-Transcript + throw("ERREUR DURANT L'INVENTAIRE") + Exit +} + Write-Output "$((get-date).tolongtimestring()) : Fin de l'inventaire." + + +#endregion + + + +#Récupération du pool de media géré par BE. Nous recalculons à l'aide d'une propriété dynamique la date car elle est au format texte. +#Nous en aurons besoin au format DateTime pour pouvoir faire le tri. + +Write-output "$((get-date).tolongtimestring()) : Récupération des médias gérés par BE." +try +{ + $mediapool = (get-bemedia) | Select-Object Name,AllocatedDate,@{Name = "Date ajoutable";Expression = {Get-date $_.AppendableUntilDate}} | Sort-Object "date ajoutable" -Descending +} +catch +{ + Write-output "$((get-date).tolongtimestring()) : Erreur lors de la récupération du pool de médias : $($error[0])" +} + + +#Récupération du contenu de l'autoloader. +Write-output "$((get-date).tolongtimestring()) : Récupération du contenu de l'autoloader." +try +{ + $slots = Get-BERoboticLibrarySlot -RoboticLibraryDevice $librairie -IsCleaningSlot $false +} +catch +{ + Write-output "$((get-date).tolongtimestring()) : Erreur lors de la récupération des slots de la librairie : $($Error[0])" +} + + +#Récupération des jobs dont le prochain démarrage est entre aujourd'hui et le nombre de jours précisé. +$jobrunningtoday = $listofjobs | Where-Object {($_.nextstartdate.date -ge (get-date).Date -and $_.nextstartdate.date -le (get-date).AddDays($joursprochains).Date)} | Select-Object Name,Storage,nextStartDate + +if ($jobrunningtoday -eq $null) +{ + Write-output "$((get-date).tolongtimestring()) : Aucune sauvegarde detectée. Fin du script" + throw("No backup") + exit +} + + +$tapedefinitions = New-Object System.Collections.ArrayList +$validtapes = New-Object System.Collections.ArrayList +$analysed = @() + +# Dans la liste des jobs qui seront lancés, nous récupérons l'emplacement utilisé dans la librairie et vérifions le nombre de cassettes sur lequel nous pouvons écrire. +foreach ($job in $jobrunningtoday) +{ + if ($job.storage -notin $analysed) + { + $analysed += $job.storage + $slots = Get-BERoboticLibrarySlot -RoboticLibraryPartition $job.storage + foreach ($tape in $slots) + { + try { + $writedate = $($($mediapool | Where-Object {$_.name -eq $tape.media})."date ajoutable" | Sort-Object -Property "date ajoutable" -Descending) | Select-Object -First 1 -ErrorAction Stop + } + catch + { + Write-Host "Pas de date d'écriture sur une cassette" + $writedate = get-date "01/01/2001" + } + $tapedefinitions.Add([PSCUSTOMOBJECT]@{ + "Media" = $tape.Media + "Slot" = $tape.SlotNumber + "Storage" = $job.storage + "Ecrasable" = $writedate + }) | Out-Null + } + try + { + $toadd = $($tapedefinitions | Where-Object {$_.storage -eq $job.storage -and $_.ecrasable -lt $job.nextstartdate -and $_.media -and $_.media -ne $null}) + foreach ($addit in $toadd) + { + $validtapes.add($addit) | Out-Null + } + } + catch + { + Write-output "$((get-date).tolongtimestring()) : Détection d'une erreur sur l'ajout de $($toadd.media) dans la liste des cassettes valides" + } + + } + + + +} +$groupedjobs = $jobrunningtoday | Group-Object Storage +$groupedtapes = $validtapes | Group-Object Storage +$errorarray = New-Object System.Collections.ArrayList + +# En fonction de si l'on a le nombre précis de cassettes necessaires pour les sauvegardes (Ex : 2 backups a faire et 2 cassettes à disposition), +# nous affichons un message d'alerte. +# Si c'est un nombre inférieur, nous affichons une erreur +foreach ($line in $groupedjobs) +{ + $oktapes = $($groupedtapes | Where-Object {$_.name -eq $line.name}) + if ($line.count -gt $oktapes.count) + { + $errorarray.Add([PSCUSTOMOBJECT]@{ + "Niveau" = "DANGER" + "Erreur" = "$($line.count) sauvegardes ($($line.Group.name)) dans les logements $($line.name), mais seulement $($oktapes.Count) disponible(s) $($oktapes.group.media)" + }) + } + elseif ($line.count -eq $oktapes.count) + { + $errorarray.Add([PSCUSTOMOBJECT]@{ + "Niveau" = "Avertissement" + "Erreur" = "Juste assez de cassettes disponibles en écriture dans les logements $($line.name) pour faire la/les sauvegarde(s) $($line.Group.name). Si une sauvegarde demande plus d'une cassette, une sera bloquée en attente de média!" + }) + } + +} + +#Et nous envoyons le mail avec toutes les informations nécessaires +$body = "" +$subject = "Liste des cassettes" +$priority = "Normal" +if ($errorarray.Count -gt 0) +{ + $subject = "!!DANGER SUR LES PROCHAINES SAUVEGARDES!!" + $priority = "High" + $body += $errorarray | ConvertTo-Html + $body += " +"*5 +} + $choosein = $mediapool | Where-object {$_.name -notin $tapedefinitions.media} | Sort-Object "Date ajoutable" + + $body += "Liste des cartouches triées par date d'écrasement +" + $body += $choosein | Select-Object Name,"Date ajoutable" | ConvertTo-Html + Send-MailMessage -SmtpServer $mailserver -From $from -To $to -Body $body -BodyAsHtml -Subject $subject -Encoding UTF8 -Priority $priority + + +Stop-Transcript \ No newline at end of file