Veeam et Powershell : état des jobs de sauvegardes sur les dernières 24 heures

Afin de me faciliter la tâche sur certains contrôles quotidiens, j’ai développé un script Powershell pour Veeam Backup & Replication me permettant d’afficher rapidement si il y a eu des échecs de sauvegarde durant les dernières 24 heures.

Ce script est plutôt simple et contrôle les sauvegardes de machines virtuelles VMware (supporte également Hyper-V il me semble) ainsi que les agents Veeam déployés sur des machines Windows. Veeam possède diverses commandes Powershell pour les divers types de sauvegarde qu’il propose (sauvegarde sur bande, par exemple) ; si il y a besoin de contrôler d’autres types de sauvegarde, alors il suffit simplement de réaliser une requête supplémentaire Get-VBRxSessionx sera évidemment remplacé par le type de sauvegarde.

J’ai testé ce script sur Veeam B&R version 9.5.

Add-PSSnapin VeeamPSSnapIn
Disconnect-VBRServer
$SrvList = @("backupsrv1","backupsrv2","veeamdev1","veeamdev2")
Write-Host "Veeam B&R Daily Checks Jobs Script"

function process{
param($type)
if($session.Result -eq "Failed"){
switch ($type){
"std" { $name = $session.Name ; $RetryList = $sessionList | Where { $_.Name -eq $name } }
"agent" { $job = Get-VBREPJob -ID $session.JobId ; $name = $job.Name ; $RetryList = $sessionAgentList | Where { $_.JobId -eq $session.JobId } }
}
$status = $session.Result
$st = $session.CreationTime
$et = $session.EndTime
$global:count+=1
echo "Job: $name"
echo "Status: $status"
echo "Start Time: $st"
echo "End Time: $et"
foreach($Retry in $RetryList){
if ($Retry.Result -ne "Failed"){
if ($Retry.State -ne "Running"){
$st = $Retry.CreationTime
$et = $Retry.EndTime
echo "Job $name finally succeeded."
echo "Start Time: $st"
echo "End Time: $et"
}
if ($Retry.State -eq "Running"){
echo "Job $name currently running."
}
}
}
}
}

foreach($UniqueSrv in $SrvList){
Write-Host "Processing server $UniqueSrv"
Connect-VBRServer -Server $UniqueSrv
$SessionList = Get-VBRBackupSession | ?{($_.EndTime -ge (Get-Date).AddHours(-24) -or $_.CreationTime -ge (Get-Date).AddHours(-24))}
$SessionAgentList = Get-VBREPSession | ?{($_.EndTime -ge (Get-Date).AddHours(-24) -or $_.CreationTime -ge (Get-Date).AddHours(-24))}
$global:count = 0
foreach($session in $SessionList){
process("std")
}
foreach($session in $SessionAgentList){
process("agent")
}
if ($global:count -eq 0){ Write-Host "No errors detected in the jobs for this server." }
Disconnect-VBRServer
}

Merci à smasterson d’avoir partagé un script complet de reporting Veeam en HTML, dont j’ai repris le pipe pour la condition des 24 dernières heures, mon premier développement de script fonctionnant autrement, cette syntaxe est plus propre. La documentation de Veeam étant ni claire ni complète et l’interface avec Powershell particulièrement catastrophique (propriétés, variables et retours différents entre deux objets pour rien, d’où l’usage de switch et gestion des états de fin de traitement anarchique : certaines sauvegardes s’arrêtent sans retour, d’autres en succès en fonction de leur type), j’ai donc dû m’y prendre à plusieurs fois avant de proposer un script fonctionnel.

Powershell : listing des objets ordinateur n’ayant pas donné signe de vie depuis un laps de temps

Dans la série « J’entretiens proprement mon ActiveDirectory », je vais vous proposer aujourd’hui un script vous permettant de lister dans un fichier CSV les objets Computer qui n’ont pas donné de signe de vie sur le domaine depuis un certain nombre de jours spécifié (par défaut dans ce script, 60).

Il est important de bien faire attention aux OU sur lesquelles nous souhaitons effectuer la recherche, afin d’éviter de supprimer des stations qui ne servent que ponctuellement ou qui ne sont positionnées sur le réseau que lors des campagnes de patchs par exemple. Il conviendra donc de modifier dans le script le paramètre SearchBase qui est passé lors de la requête ActiveDirectory.

$csvoutput = "$env:temp\orphan-computers.csv"
Write-Host "Orphan Computer objects listing script"
Write-Host "======================================"
Write-Host ""
Write-Host "This script will output to a file a list of Computer objects in the ActiveDirectory that haven't logged onto the domain for a specified number of days."
[int]$nbdays = Read-Host "Number of days before considering a Computer object orphan ? (default: 60)"
if ($nbdays -eq "") { $nbdays = 60 }
$today = Get-Date
$complist = Get-AdComputer -filter * -Properties LastLogonDate -SearchBase "OU=serveurs,DC=superdomaine,DC=com"
foreach ($computer in $complist) {
$lastlogondate = $computer.LastLogonDate
$fqdn = $computer.DNSHostName
if ($lastlogondate -eq $null) { Add-Content $csvoutput "$fqdn,'Object never logged on'" }
elseif ($lastlogondate.AddDays($nbdays) -lt $today) {
Add-Content $csvoutput "$fqdn,$lastlogondate"
}
}
Write-Host "All done. File is located in $env:temp."
explorer $env:temp

Les stations ont leur nom DNS et leur dernière date de communication avec le domaine de renseignées dans un fichier CSV écrit dans le répertoire des fichiers temporaires.

Powershell : liste des utilisateurs de tous les partages SMB d’un serveur

J’ai réalisé un script permettant de générer une liste d’utilisateurs des partages SMB d’un serveur, ce qui peut être pratique à des fins d’audit ou si l’on souhaite simplement contacter les utilisateurs d’un serveur de fichiers pour une maintenance par exemple.

Il existe bien l’instruction Get-SmbShare mais elle n’est disponible qu’à partir de 2012 R2 ! Afin de permettre une compatibilité avec les OS 2008 (qui seront par ailleurs bientôt plus maintenus 😱), j’ai utilisé la classe WMI Win32_share.

Le script fonctionne en plusieurs phases : tout d’abord, il liste les partages existants (tels qu’on peut les voir dans la console de Computer Management), puis liste leurs ACL et récupère les membres des groupes AD éventuellement positionnés pour n’obtenir au final que des identifiants utilisateur. Naturellement, il est nécessaire de lancer le script avec des droits d’administration sur la machine afin d’être sûr de pouvoir lire toutes les ACL et d’avoir les modules AD pour Powershell ; sans quoi il vous faudra vous résoudre à utiliser un Invoke-Command qui a de grandes chances d’être bloqué par le pare-feu.

function parse{
param($objectName)
$doneparsing = $false
for($i=0; $doneparsing -eq $false; $i++){
if ($i+1 -gt $parsedArray.Count) { Write-Host "Added user $objectName." ; $parsedArray.Add($objectName) > $null; $doneparsing = $true }
if ($parsedArray[$i] -eq $objectName){ $doneparsing = $true }
}
}

Write-Host "Share user ACL listing script"
Write-Host "============================="
Write-Host "This script will retrieve all the SMB shares and their ACLs with a 'MYDOMAIN' domain object filter to a file located in the temp folder."
$parsedArray = New-Object System.Collections.ArrayList
$sharelist = Get-WmiObject -Class Win32_Share
foreach($share in $shareList){
if ($share.Path -ne ""){
$aclList = (Get-Acl $share.Path).Access | Where-Object {$_.IdentityReference.ToString().Contains('MYDOMAIN') }
foreach ($acl in $aclList){
$objectName = $acl.IdentityReference.Value
$canoName = $objectName.ToString().SubString(9,$objectName.Length-9)
$objectType = Get-ADObject -Filter {CN -eq $canoName}
if ($objectType.ObjectClass -eq "user"){ parse($objectName) }
if ($objectType.ObjectClass -eq "group") {
Write-Host "Processing group $canoName..."
$PplInGrp = Get-ADGroupMember $canoName
foreach($ppl in $PplInGrp){ parse($ppl.SamAccountName) }
}
}
}
}
cd $env:temp
foreach ($line in $parsedArray){
Add-Content share-acl.txt $line }
Write-host "Done processing."