Backup-PersonnalFolder - Sauvegarde de dossiers utilisateurs

CréationNicolas THOREZ 2019/11/28 14:13

Il y a des utilisateurs qui prennent l'habitude de garder des documents sur leur poste au lieu de les déposer dans un partage du serveur de fichiers. Cette manière de fonctionner est à proscrire car la sécurité des documents n'est pas garantie. Les administrateurs en charge de l'infrastructure n'ont aucune vision sur leur intégrité ni leur sauvegarde. Les habitudes ayant la vie dure, on est souvent amené à s'adapter à ce genre de comportement.

C'est dans cet optique que j'ai écris ce sript.

Son fonctionnement est assez simple :

  • Il crée une liste de PC à sauvegarder en ce basant sur l'interrogation de l'AD
  • Il teste les postes qui sont en ligne
  • Il récupère le nom du compte utilisateur connecté sur le poste
  • Il crée un ShadowCopy pour éviter les problèmes de copie de fichiers ouverts
  • Il copie les données d'un dossier spécifique vers un dossier réseaux
  • Enfin il crée un rapport quotidien

Les informations sont affichés en temps réel dans la console avec une coloration syntaxique, information en vert, avertissement en jaune et critique en rouge. Il inclut aussi la possibilité de création d'un rapport succin qui pourra être traité par un autre script renvoyant les informations dans Nagios.

Pour fonctionner, le script nécessite de stocker le mot de passe de l'administrateur de sauvegarde dans un fichier sécurisé.

Voir : Sécurisation d'un mot de passe

<#
.SYNOPSIS

    ███████╗██╗  ██╗██╗   ██╗██████╗ ██╗  ██╗ █████╗                 
    ██╔════╝██║  ██║╚██╗ ██╔╝██╔══██╗██║ ██╔╝██╔══██╗                
    ███████╗███████║ ╚████╔╝ ██████╔╝█████╔╝ ███████║                
    ╚════██║██╔══██║  ╚██╔╝  ██╔══██╗██╔═██╗ ██╔══██║                
    ███████║██║  ██║   ██║   ██║  ██║██║  ██╗██║  ██║                
    ╚══════╝╚═╝  ╚═╝   ╚═╝   ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝                
                                                                 
                ███████╗██╗   ██╗███████╗████████╗███████╗███╗   ███╗
                ██╔════╝╚██╗ ██╔╝██╔════╝╚══██╔══╝██╔════╝████╗ ████║
                ███████╗ ╚████╔╝ ███████╗   ██║   █████╗  ██╔████╔██║
                ╚════██║  ╚██╔╝  ╚════██║   ██║   ██╔══╝  ██║╚██╔╝██║
                ███████║   ██║   ███████║   ██║   ███████╗██║ ╚═╝ ██║
                ╚══════╝   ╚═╝   ╚══════╝   ╚═╝   ╚══════╝╚═╝     ╚═╝ 

#############################################################################################################
#                                                                                                           #
# Script de sauvegarde d'un dossier spécifique pour chaque utilisateur vers un dossier distant              #
#                                                                                                           #
# Par Nicolas THOREZ                                                                                        #
#                                                                                                           #
#############################################################################################################

.DESCRIPTION

Lance la sauvegarde du dossier utilisateur spécifié dans la variable $BackupRootFolder situé dans le profil utilisateur au chemin $SavedPath.
Cette sauvegarde est une copie miroir de ce dossier vers le même dossier dans le partage lié à chaque utilisateur sur un serveur distant $Partage.
Un fichier de log journalier est créé et contient toutes les traces de la sauvegarde. (Par défaut : C:\Scripts\BackupPersonnalFolder\Backup-AAAA-MM-JJ.log)

.PARAMETER ComputerName

Indique le ou les noms (séparé par des virgules (,)) des PC à sauvegarder. Si le paramètre n'est pas renseigner, la sauvegarde sera lancée sur tous les PC contenus dans les OU de recherche ($OUs).

.PARAMETER Verbose

Si le paramètre -Verbose est indiqué, les détails de la sauvegarde seront affichés dans la console.

.PARAMETER Nagios

Si le paramètre -Nagios est indiqué, un fichier de réponse pour un traitement par Nagios sera créé (Par défaut : C:\Scripts\BackupPersonnalFolder\SaveReport.dat).

.EXAMPLE

.\Backup-PersonnalFolder.ps1
Lance la sauvegarde sur tous les postes.

.EXAMPLE

.\Backup-PersonnalFolder.ps1 -Verbose
Lance la sauvegarde sur tous les postes en affichant les détails.

.EXAMPLE

.\Backup-PersonnalFolder.ps1 -ComputerName PC1,PC7
Lance la sauvegarde sur les postes PC1 et PC7

.NOTES

NOM :      Backup-PersonnalFolder.ps1
AUTEUR :   Nicolas THOREZ
VERSION :  2.0

HISTORIQUE :

0.0     2019-01-30      Début du projet

0.1     2019-01-30      Etude du script existant
                        Création du script de remplacement

0.2     2019-01-31      Ajout du paramètre PC pour ne sauvegarder qu'un PC (utile pour relancer une sauvegarde partiellement ratée)
                        Ajout du paramètre v pour avoir des détails supplémentaires (utile en cas d'analyse d'erreur de sauvegardes)

0.3     2019-01-31      Correction des erreurs lié au profil utilisateur ne correspondant pas au nom d'utilisateur
                        Correction des erreurs lié au blocage du pare-feu sur les postes distants

0.4     2019-01-31      Version de test

1.0     2019-01-31      Version mise en production

1.1     2019-01-31      Ajout du paramètre n pour créer un fichier de réponse pour Nagios (utile pour afficher une alerte dans Nagios en cas d'erreur)

1.2     2019-02-04      Ajout et traitements des codes d'erreurs 9 à 15
                        Ajout d'une suppression des anciens logs (la variable $Old indique l'âge maximum)

1.3     2019-02-05      Ajout de la gestion d'une liste d'ordinateurs pour l'argument -PC

1.3.1   2019-02-06      Modification de la gestion des erreurs en cas d'erreur inconnue

1.4     2019-03-26      Réécriture du mode verbeux

1.5     2019-04-08      Optimisation du code

1.6     2019-11-27      Modification du code pour utilisation de ShadowCopy

2.0     2019-11-28      Variabilisation des messages
						Ajout des commentaires manquants
						Optimisation du code
#>

# Paramètres d'entrée

Param (
	[String[]]$ComputerName = "All",
	[Switch]$Verbose,
	[Switch]$Nagios
)

#region Variables

# Date de la sauvegarde
$CheckDate = Get-Date -UFormat %Y-%m-%d

# Dossier de travail
$Path = "C:\Scripts\BackupPersonnalFolder"
# Fichier log général
$LogFile = "$Path\Backup-$CheckDate.log"
# Racine du dossier partagé de l'utilisateur acceuillant la sauvegarde
$BackupRootFolder = "Sauvegardes_Journalieres"
# Nom du fichier log spécifique à chaque utilisateur
$BackupLogFile = "Backup.log"
# Fichier de log spécifique à chaque utilisateur
$BackupLog = "$BackupRootFolder\$BackupLogFile"
# Initialisation du chemin de profil utilisateur
$UserProfilePath = ''
# Chemin pour la racine des destinations de sauvegardes
$Partage = "\\LBG-SMB-1\Partage_utilisateur"
# Dossier à sauvegarder dans les dossiers utilisateurs
$SavedPath = "Documents\$BackupRootFolder"
# Chemin du rapport Nagios
$Report = "$Path\SaveReport.dat"

# Initialisation de la quantité de postes sauvegardés
$PCSaved = 0
# Initialisation de la quantité de postes hors-ligne
$PCOffline = 0
# Initialisation de la quantité de postes avec des erreurs critiques
$PCWithError = 0
# Initialisation de la quantité de postes avec des avertissements
$PCWithWarn = 0
# Initialisation de la quantité de postes traités
$TotalPC = 0

# Age maximale des fichiers de log avant suppression
$Old = 7

# Domaine Active Directory
$Domaine = 'SHYRKA'
# FQDN pour le domaine
$FQDN = 'shyrka.sys'
# Liste des OU de recherche de postes pour l'inventaire des postes à traiter
$OUs = @(
	"OU=PC Fixe,OU=Ordinateurs,DC=SHYRKA,DC=SYS"
	"OU=PC Portable,OU=Ordinateurs,DC=SHYRKA,DC=SYS"
	"OU=Ordinateurs,OU=Direction,DC=SHYRKA,DC=SYS"
)
# Administrateur du domaine
$Admin = "$Domaine\BackupAdmin"
# Mot de passe (en version sécurisée)
$SecurePassword = Get-Content -Path "$Path\data.crypt" | ConvertTo-SecureString
# Identifiants pour le compte d'administration
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Admin, $SecurePassword

# Mise à jour des postes à traiter
If ($ComputerName -eq 'All')
{
	# Si on a indiquer tous les postes, on crée la liste à partir des postes de l'AD
	$ListPC = @()
	foreach ($OU in $OUs)
	{
		$ListPC += (Get-ADComputer -SearchBase $OU -Filter *).Name
	}
}
Else
{
	# Sinon, la liste des PC à traiter est indiquée par $ComputerName
	$ListPC = $ComputerName
}

#endregion Variables

#region Langue

##### En cas de traductions dans une autre langue, d'autres messages sont à modifiées entre les lignes 379 et 390 #####

$BackupSuccessful = "Sauvegarde réussie."
$CreatingLogFile = "Création du fichier log."
$CreatingNagiosReport = "Création du fichier de réponse pour Nagios."
$CriticalMessage = "Des erreurs critiques sont signalées. Merci de vérifier le fichier Backup.log dans le dossier de sauvegarde utilisateur."
$DeletingOldLogFiles = "Suppression des logs vieux de $Old jours."
$EndingTreatmentFor = "Fin de la sauvegarde de "
$EndOfGeneralTreatment = "Fin de la sauvegarde."
$ExistingLogFile = "Fichier log existant, inscription des nouvelles informations à la suite."
$GeneralBackupStart = "Début de la sauvegarde."
$StartingBackupOf = "Début de la sauvegarde de "
$StartingTreatmentOf = "Début de traitement de "
$TotalBackupedPCMessage = "Total des PC sauvegardés : "
$TotalCriticalMessage = "Total des sauvegardes en échec : "
$TotalPCMessage = "Total des PC traités : "
$TotalOffLineMessage = "Total des PC hors-ligne : "
$TotalWarningsMessage = "Total des sauvegardes avec des erreurs : "
$WarningMessage = "Des avertissements sont signalés. Merci de vérifier le fichier Backup.log dans le dossier de sauvegarde utilisateur."

##### En cas de traductions dans une autre langue, d'autres messages sont à modifiées entre les lignes 379 et 390 #####

#endregion Langue

#region Fonctions

# Fonction d'écriture du log général et d'affichage console (si -Verbose)
Function Add-Log()
{
	Param
	(
		# Type de Message
		[ValidateSet("INFO", "GOOD", "CRIT", "WARN", "UNKN")]
		[string]$Type,
		# Message à enregistrer et/ou afficher
		[string]$Message,
		# Switch pour demander de tracer une ligne (séparation) dans le log
		[switch]$Line
	)
	
	If ($Line)
	{
		# Si on a activer le switch -Line, on ajoute une ligne dans le fichier log un ligne
		If ($Verbose)
		{
			# Si -Verbose est activée, on affiche dans la console
			Write-Host "----------------------------------------------------------------------"
		}
		Add-Content -Path $LogFile -Value "----------------------------------------------------------------------"
	}
	Else
	{
		# Sinon, on traite le message
		$CheckTime = Get-Date -Format G
		If ($Verbose)
		{
			# Si -Verbose est activé, on affiche le message avec une certaine coloration syntaxique
			Switch ($Type)
			{
				"INFO"
				{
					$Color = "green"
				}
				"WARN"
				{
					$Color = "yellow"
				}
				"CRIT"
				{
					$Color = "red"
				}
				"UNKN"
				{
					$Color = "magenta"
				}
				default
				{
					$Color = "cyan"
				}
			}
			Write-Host "$CheckTime     " -NoNewline
			Write-Host "$type     " -NoNewline -ForegroundColor $Color
			Write-Host $Message
		}
		Add-Content -Path $LogFile -Value "$CheckTime     $Type     $Message"
	}
}

# Fonction de recherche de l'utilisateur connecté
Function Get-ConnectedUser($PC)
{
	# On interroge le poste
	$Name = (Get-WmiObject -ComputerName $PC -Class Win32_ComputerSystem -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -InformationAction SilentlyContinue).UserName
	If ($Name -notlike "$Domaine*")
	{
		# Si le retour ne commence pas par $Domaine, soit le poste est hors domaine, soit personne n'est connecté. On ignore donc.
		$Name = "n/a"
		Add-Log -Type "WARN" -Message "Aucun utilisateur connecté."
	}
	Else
	{
		# Sinon, on récupère le login de l'utilisateur
                $Pattern = $Domaine + '\'
		$Name = $Name.Replace("$Pattern", '')
		Add-Log -Type "INFO" -Message "Utilisateur $Name."
	}
	# On renvoie la réponse
	Return $Name
}

# Fonction de recherche du chemin du profil de l'utilisateur
Function Get-UserLocalPath
{
	Param (
		# Poste sur lequel faire la recherche
		[String]$PC,
		# Utilisateur pour lequel faire la recherche
		[String]$User
	)
	
	# On récupère le SID de l'utilisateur
	$SID = ([wmi]"win32_userAccount.Domain='$Domaine',Name='$User'").SID
	
	# ON interroge le PC distant pour connaître le chemin du profil utilisateur
	$LocalPath = (Get-WmiObject -ComputerName $PC -Class Win32_userprofile | Where-Object { $_.SID -eq $SID }).LocalPath
	
	# On renvoie la valeur
	Return $LocalPath
}

# Fonction de recherche de l'état de connexion du poste
Function Get-PCOnlineStatus($PC)
{
	# On interroge le PC via Get-WmiObject plutôt que par ping pour éviter les erreurs de pare-feu
	$OnlineTest = (Get-WmiObject -ComputerName $PC -Class Win32_ComputerSystem -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -InformationAction SilentlyContinue).Domain
	If ($OnlineTest -eq $FQDN)
	{
		# Si on récupère le $FQDN, le poste est en ligne et il répond
		Add-Log -Type "INFO" -Message "PC Online."
		Return $true
	}
	Else
	{
		# Sinon, soit il est hors-ligne, soit il ne répond pas, soit il est hors-domaine. Dans tous ces cas, on ignore.
		Add-Log -Type "WARN" -Message "PC Offline."
		Return $false
	}
}

# Fonction de sauvegarde
Function Run-Save
{
	Param
	(
		# Poste sur lequel sont les fichiers à sauvegarder
		[string]$PC,
		# Utilisateur pour lequel on doit sauvegarder les fichiers
		[String]$User
	)
	
	# Connexion au PC
	$Session = New-PSSession -ComputerName $PC -Credential $Credential
	
	# Récupération du chemin du profil utilisateur et formatage du chemin pour accès réseau
	$UserProfilePath = Get-UserLocalPath -PC $PC -User $User
	$UserProfilePath = $UserProfilePath.Replace(":", ":\ShadowCopy")
	
	# Définitions des dossiers pour la copie
	$Source = "$UserProfilePath\$SavedPath"
	$Destination = "$Partage\$User\$BackupRootFolder"
	
	# Création du fichier zip de la sauvegarde de la veille
	if (Test-Path -Path "$Partage\$User\$BackupRootFolder.zip")
	{
		Remove-Item -Path "$Partage\$User\$BackupRootFolder.zip" -Force | Out-Null
	}
	[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null
	[System.IO.Compression.ZipFile]::CreateFromDirectory("$Partage\$User\$BackupRootFolder", "$Partage\$User\$BackupRootFolder.zip")
	
	# Script de sauvegarde avec ShadowCopy depuis le poste utilisateur
	$ScriptCreateShadow = {
		Param (
			# Source des fichiers à sauvegarder
			$ScriptSource,
			# Destination de la sauvegarde
			$ScriptDestination,
			# Utilisateur avec droits d'administration pour les opérations nécessitant une élévation de droits
			$User,
			# Mot de passe de $User
			$Pass,
			# Fichier Backup local
			$LocalBackupLogFile
		)
		
		#region Langue pour locale
		
		$DeleteErrorMessage = "Impossible de supprimer :"
		$DeleteMessage = "Suppression de :"
		$FileIOnBackupMoreRecent = "Backup plus récent que la source :"
		$NewFileErrorMessage = "Impossible de copier :"
		$NewFileMessage = "Copie de :"
		$SameFile = "Fichier identique :"
		$UpdateErrorMessage = "Impossible de mettre à jour :"
		$UpdateMessage = "Mise à jour de :"
		
		#endregion Langue pour locale
		
		# Lettre du lecteur temporaire
		$Drive = "T"
                $DrivePath = "$Drive" + ':\'
		
                # Récupération de la lettre de disque système
                [string]$SystemDrive = (Get-ComputerInfo).OsSystemDrive + '\'
		# Création du ShadowCopy
		$ShadowCopy = (Get-WmiObject -List Win32_ShadowCopy).Create("$SystemDrive", "ClientAccessible")
		# Récupération de l'identifiant de ShadowCopy créé
		$ID = Get-WmiObject Win32_ShadowCopy | Where-Object { $_.ID -eq $ShadowCopy.ShadowID }
		# Formatage du chemin du ShadowCopy
		$CorrectPath = $ID.DeviceObject + "\"
		# Création du type d'objet [Custom.SymLink] pour le lien symbolique
		Try
		{
		    $Null = [Win32.SymLink]
		}
		Catch
		{
		    Add-Type @"
		        using System;
		        using System.Runtime.InteropServices;
  
		        namespace Win32
		        {
		            public class SymLink
		            {
		                [DllImport("kernel32.dll")]
		                public static extern bool CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, int dwFlags);
		            }
		        }
"@
		}
                
		# Création du lien symbolique
		[Win32.SymLink]::CreateSymbolicLink("C:\ShadowCopy", $CorrectPath, 1)
				
		# Identifiants pour l'élévation de droits
		$Cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $Pass
		
		# Création du lien local vers dossier distant
		New-PSDrive -Name "$Drive" -PSProvider FileSystem -Root $ScriptDestination -Credential $Cred | Out-Null
		
		##### Sauvegarde #####
		
		# Création du fichier de log spécifique à l'utilisateur
		If (Test-Path -Path "${Drive}:\$LocalBackupLogFile")
		{
			# Suppression de l'ancien avant création du nouveau
			Remove-Item -Path "${Drive}:\$LocalBackupLogFile"
		}
		New-Item -Path "$DrivePath" -Name "$LocalBackupLogFile" -ItemType File | Out-Null
		
		# Listes des fichiers
		$FileToBackup = Get-ChildItem -Path $ScriptSource -Recurse
		$FileInBackup = Get-ChildItem -Path "$DrivePath" -Recurse -Exclude "$LocalBackupLogFile"
		
		# Liste des fichiers à mettre à jour
		$FileToBackup | ForEach-Object {
			$FileFullName = $_.FullName
			$PrintName = $FileFullName.Replace("ShadowCopy\", '')
			$TestFile = ($_.FullName).Replace($ScriptSource, "${Drive}:")
			$TestFileType = (Get-Item -Path $TestFile).GetType().Name
			If ((Test-Path $TestFile) -and ($TestFileType -ne "DirectoryInfo"))
			{
				$SourceFileDate = Get-Date -Date (Get-ItemProperty -Path $FileFullName).LastWriteTime
				$DestinationFileDate = Get-Date -Date (Get-ItemProperty -Path $TestFile).LastWriteTime
				
				If ($SourceFileDate -gt $DestinationFileDate)
				{
					Try
					{
						Copy-Item -Path $FileFullName -Destination $TestFile
						$CheckDate = Get-Date -Format G
						Add-Content -Path "${Drive}:\$LocalBackupLogFile" -Value "$CheckDate    [GOOD]    $UpdateMessage $PrintName"
					}
					Catch
					{
						$CheckDate = Get-Date -Format G
						Add-Content -Path "${Drive}:\$LocalBackupLogFile" -Value "$CheckDate    [CRIT]    $UpdateErrorMessage $PrintName"
					}
				}
				
				If ($SourceFileDate -lt $DestinationFileDate)
				{
					$RecentFile = $TestFile.Replace("${Drive}:", $ScriptDestination)
					$CheckDate = Get-Date -Format G
					Add-Content -Path "${Drive}:\$LocalBackupLogFile" -Value "$CheckDate    [CRIT]    $FileIOnBackupMoreRecent $RecentFile"
				}
				
				If ($SourceFileDate -eq $DestinationFileDate)
				{
					$CheckDate = Get-Date -Format G
					Add-Content -Path "${Drive}:\$LocalBackupLogFile" -Value "$CheckDate    [INFO]    $SameFile $PrintName"
				}
			}
		}
		
		# Liste des fichiers à supprimer
		$FileInBackup | ForEach-Object {
			$FileFullName = $_.FullName
			$TestFile = $_.FullName.Replace($ScriptDestination, $ScriptSource)
			If (-not (Test-Path $TestFile))
			{
				Try
				{
					Remove-Item -Path $FileFullName -Force -Recurse 2> $Null
					$CheckDate = Get-Date -Format G
					Add-Content -Path "${Drive}:\$LocalBackupLogFile" -Value "$CheckDate    [GOOD]    $DeleteMessage $FileFullName"
				}
				Catch
				{
					$CheckDate = Get-Date -Format G
					Add-Content -Path "${Drive}:\$LocalBackupLogFile" -Value "$CheckDate    [WARN]    $DeleteErrorMessage $FileFullName"
				}
			}
		}
		
		# Liste des fichiers à ajouter
		$FileToBackup | ForEach-Object {
			$FileFullName = $_.FullName
			$TestFile = ($_.FullName).Replace($ScriptSource, "${Drive}:")
			$PrintName = $FileFullName.Replace("ShadowCopy\", '')
			If (-not (Test-Path $TestFile))
			{
				Try
				{
					Copy-Item -Path $FileFullName -Destination $TestFile
					$CheckDate = Get-Date -Format G
					Add-Content -Path "${Drive}:\$LocalBackupLogFile" -Value "$CheckDate    [GOOD]    $NewFileMessage $PrintName"
				}
				Catch
				{
					$CheckDate = Get-Date -Format G
					Add-Content -Path "${Drive}:\$LocalBackupLogFile" -Value "$CheckDate    [CRIT]    $NewFileErrorMessage $PrintName"
				}
			}
		}
		
		# Suppression du lien
		Remove-PSDrive -Name "$Drive" -Force
		
		# Suppression du lien de shadowcopy
		(Get-Item -Path C:\ShadowCopy).Delete() 
	}
	
	# Invocation du script de sauvegarde sur le poste utilisateur
	Invoke-Command -Session $Session -ArgumentList $Source, $Destination, $Admin, $SecurePassword, $BackupLogFile -ScriptBlock $ScriptCreateShadow
	
	# Déconnexion de poste
	Remove-PSSession -Session $Session
}

#endregion Fonctions

# Création du fichier log et suppression des anciens logs
If (Test-Path $LogFile)
{
	# Le fichier log du jour existe, on continue de l'utiliser
	Add-Log -Line
	Add-Log -Type "INFO" -Message $ExistingLogFile
	Add-Log -Type "INFO" -Message $GeneralBackupStart
	Add-Log -Line
}
Else
{
	# Le fichier log du jour n'existe pas. On le crée.
	New-Item -Path $LogFile > $null
	Add-Log -Type "INFO" -Message $CreatingLogFile
	# On supprime les anciens logs
	Get-ChildItem –Path $Path –Recurse | Where-Object CreationTime –lt (Get-Date).AddDays(- $Old) | Where-Object Name -like *.log | Remove-Item -Force > $null
	Add-Log -Type "INFO" -Message $DeletingOldLogFiles
	Add-Log -Type "INFO" -Message $GeneralBackupStart
	Add-Log -Line
}

# Traitement pour chaque poste dans la liste des postes à traiter
Foreach ($PC in $listPC)
{
	# On incrémente la quantité totale de postes traitées
	$TotalPC += 1
	$Message = $StartingTreatmentOf + "$PC."
	Add-Log -Type "INFO" -Message $Message
	
	# On teste si la machine est en ligne
	$OnlineStatus = Get-PCOnlineStatus($PC)
	
	# Si oui on continue le traitement
	If ($OnlineStatus -eq $true)
	{
		# On teste si un utilisateur est connecté
		$User = Get-ConnectedUser($PC)
		
		# Si oui, on lance la sauvegarde
		If ($User -notlike "n/a")
		{
			# Dédut du traitement
			$Message = $StartingBackupOf + "$PC."
			Add-log -Type "INFO" -Message $Message
			
			# Exécution de la sauvegarde
			Run-Save -PC $PC -User $User
			
			# Analyse du Log
			$Content = Get-Content -Path "$Partage\$User\$BackupLog"
			$WarnCount = ($Content | Where-Object {
					$_.Contains("WARN")
				}).Count
			$CritCount = ($Content | Where-Object {
					$_.Contains("CRIT")
				}).Count
			
			# Affichage du résultat
			If ($CritCount)
			{
				# Des alertes critiques sont signalées
				Add-Log -Type "CRIT" -Message $CriticalMessage
				$PCWithError++
			}
			Else
			{
				If ($WarnCount)
				{
					# Pas d'alerte critiques mais des avertissements sont signalés
					Add-Log -Type "WARN" -Message $WarningMessage
					$PCWithWarn++
				}
				Else
				{
					# Aucune anomalie signalée
					Add-Log -Type "GOOD" -Message $BackupSuccessful
				}
			}
			
			# Fin du traitement du poste
			$Message = $EndingTreatmentFor + "$PC."
			Add-Log -Type "INFO" -Message $Message
		}
	}
	Else
	{
		# Le PC est hors-ligne
		$PCOffline += 1
	}
}

# Fin de la sauvegarde
Add-Log -Line
Add-Log -Type "INFO" -Message $EndOfGeneralTreatment
Add-Log -Line

# Affichage des différents décomptes ($TotalPC, $PCSaved, $PCOffline, $PCWithWarn, $PCWithError)
$Message = $TotalPCMessage + "$TotalPC."
Add-Log -Type "INFO" -Message $Message
$Message = $TotalBackupedPCMessage + "$PCSaved."
Add-Log -Type "INFO" -Message $Message
$Message = $TotalOffLineMessage + "$PCOffline."
If ($PCOffline -gt 0)
{
	Add-Log -Type "WARN" -Message $Message
}
Else
{
	Add-Log -Type "INFO" -Message $Message
}
$Message = $TotalWarningsMessage + "$PCWithWarn."
If ($PCWithWarn -gt 0)
{
	Add-Log -Type "WARN" -Message $Message
}
Else
{
	Add-Log -Type "INFO" -Message $Message
}
$Message = $TotalCriticalMessage + "$PCWithError."
If ($PCWithError -gt 0)
{
	Add-Log -Type "CRIT" -Message $Message
}
Else
{
	Add-Log -Type "INFO" -Message $Message
}

# Création d'un fichier de réponse pour un traitement par Nagios
If ($Nagios)
{
	# On vérifie la présence d'un ancien rapport et si oui, on le détruit
	If (Test-Path -Path $Report)
	{
		Remove-Item -Path $Report -Force
	}
	
	# On crée un rapport vierge
	$TempVar = @{}
	$TempVar | Export-Csv -Path $Report -UseCulture
	
	# On ajoute les valeurs pour Nagios
	$ReportData = Import-Csv -Path $Report -UseCulture
	$ReportData | Add-Member -MemberType NoteProperty -Name "Total" -Value $TotalPC
	$ReportData | Add-Member -MemberType NoteProperty -Name "Saved" -Value $PCSaved
	$ReportData | Add-Member -MemberType NoteProperty -Name "Offline" -Value $PCOffline
	$ReportData | Add-Member -MemberType NoteProperty -Name "Warning" -Value $PCWithWarn
	$ReportData | Add-Member -MemberType NoteProperty -Name "Critical" -Value $PCWithError
	$ReportData | Export-Csv -Path $Report -UseCulture
	
	# Affichage des logs
	Add-Log -Line
	Add-Log -Type "INFO" -Message $CreatingNagiosReport
}

#######################################################################################
#                                                                                     #
# Vérification du fichier de réponse (SaveReport.dat) de Backup-PersonnalFolder       #
#                                                                                     #
# Par Nicolas THOREZ                                                                  #
#                                                                                     #
#######################################################################################

$Report = Import-Csv -Path 'C:\Scripts\BackupPersonnalFolder\SaveReport.dat' -Delimiter ';'

[int]$Total = $Report.Total
[int]$Saved = $Report.Saved
[int]$Offline = $Report.Offline
[int]$Warning = $Report.Warning
[int]$Critical = $Report.Critical

$Output = ''
$ExitCode = 3

If ($Critical -gt 0)
    {
        $Output = "Critical"
        $ExitCode = 2
    }
Elseif ($Warning -gt 0)
    {
        $Output = "Warning"
        $ExitCode = 1
    }
Elseif (($Warning -eq 0) -and ($Critical -eq 0))
    {
        $Output = "OK"
        $ExitCode = 0
    }
Else
    {
        Write-Host "Unknown - Error in SaveReport.dat, please check"
        exit $ExitCode
    }

Write-Host "$Output - Total : $Total, Saved : $Saved, Offline : $Offline, Warning : $Warning, Error : $Critical"
exit $ExitCode

Entrer votre commentaire. La syntaxe wiki est autorisée:
 
  • backuppersonnalfolder.txt
  • Dernière modification : 2021/03/05 16:12
  • de nekan