# ======================================================= # Fonction qui ecrit les messages sur la sortie standard # Usage : Write-OutputConsole ($theme) # ======================================================= function Write-OutputConsole($theme) { if ( $theme -eq "lancement") { write-Output "!-----------------------------------------------------------------------------!" Write-Output "! La Sauvegarde en local de Vos Documents et de Votre Bureau est en cours. !" Write-Output "! !" Write-Output "! !" Write-Output "! Les fichiers avec les extensions suivantes sont actuellement exclus: !" Write-Output "! .ogg.flac.mp3.wav.wma.aac.mpeg.ogm.avi.flv.wmv.mov.divx.xvid !" Write-Output "! !" Write-Output "! Fermer cette Fenêtre Annulera la Sauvegarde ! !" Write-Output "! !" Write-Output "------------------------------------------------------------------------------!" } if ( $theme -eq "lancementvol") { write-Output "!-----------------------------------------------------------------------------!" Write-Output "! La Sauvegarde sur Serveur distant de Vos Documents et de Votre Bureau !" Write-Output "! est en cours. !" Write-Output "! !" Write-Output "! Les fichiers avec les extensions suivantes sont actuellement exclus: !" Write-Output "! .ogg.flac.mp3.wav.wma.aac.mpeg.ogm.avi.flv.wmv.mov.divx.xvid !" Write-Output "! !" Write-Output "! Fermer cette Fenêtre Annulera la Sauvegarde ! !" Write-Output "! !" Write-Output "------------------------------------------------------------------------------!" } if ( $theme -eq "zipprob") { write-Output "!-------------------------------------------------------------------------------!" Write-Output "! La compression de la messagerie a echoué !" Write-Output "! !" Write-Output "! !" Write-Output "! Fermer cette Fenêtre Annulera la Sauvegarde ! !" Write-Output "! !" Write-Output "--------------------------------------------------------------------------------!" } if ( $theme -eq "nospace") { write-Output "!-------------------------------------------------------------------------------!" Write-Output "! Le Disque dur C Local n'a pas assez d'espace Libre !" Write-Output "! !" Write-Output "! La sauvegarde est annulée !" Write-Output "! Contactez votre administrateur. !" Write-Output "! !" Write-Output "--------------------------------------------------------------------------------!" } if ( $theme -eq "novoltaire") { Write-Output "!-------------------------------------------------------------------------------!" Write-Output "! Le Serveur de Sauvegarde est indiponible !" Write-Output "! !" Write-Output "! !" Write-Output "! La Sauvegarde distante est Annulée ! !" Write-Output "! !" Write-Output "--------------------------------------------------------------------------------!" } if ( $theme -eq "pasdeflagloc") { Write-Output "!-------------------------------------------------------------------------------!" Write-Output "! La Sauvegarde Locale de Vos Documents e tde Votre Bureau a déjà été lancée !" Write-Output "! !" Write-Output "! lors de ces dernières 24 heures !" Write-Output "! La Sauvegarde est donc annulée ! !" Write-Output "! !" Write-Output "--------------------------------------------------------------------------------!" } if ( $theme -eq "pasdeflagnet") { Write-Output "!-------------------------------------------------------------------------------!" Write-Output "! La Sauvegarde Réseau de Vos Documents et de Votre Bureau !" Write-Output "! a déjà été lancée !" Write-Output "! lors de ces dernières 24 heures !" Write-Output "! La Sauvegarde est donc annulée ! !" Write-Output "! !" Write-Output "--------------------------------------------------------------------------------!" } } # ======================================================= # Fonction qui envoie un email avec 2 attachements # ======================================================= function Send-EMail($argFrom, $argTo, $argtoCC, $argPriority, $argSubject, $argBody, $argAtt, $argSmtp) { $mail = New-Object System.Net.Mail.MailMessage $smtpClient = new-object system.net.mail.SmtpClient($argSmtp) $mail.Body = $argBody $mail.Subject = $argSubject $mail.priority = $argPriority $mail.From = $argFrom $mail.To.Add($argTo) if ($argtoCC) { $mail.CC.Add($argtoCC) } if (!($argAtt -eq $null)) { $att = new-object Net.Mail.Attachment $argAtt $mail.Attachments.Add($att) } $smtpClient.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials $smtpClient.Send($mail) $mail.Attachments.Dispose() $mail = $null $smtpClient = $null } # ======================================================================= # Fonction qui affiche une boite de dialogue qui se ferme automatiquement # ======================================================================= function DisplayMessageBox($argText, $argDelayDisplay, $argTitre, $argButton) { $job=Start-Job -ArgumentList $argText,$argDelayDisplay,$argTitre,$argButton -ScriptBlock { $a = new-object -comobject wscript.shell $a.popup($args[0],$args[1],$args[2],$args[3]) } return $job; } # ================================================================================================= # DESCRIPTION: Displays the attention message box & checks to see if the user clicks the ok button. # Affiche une boîte de dialogue fenêtrée # Prérequis [void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") # ================================================================================================= function Show-MessageBox([string] $Message,[string] $Titre="Attention !!", [String] $IconType="Warning",[String] $BtnType="Ok") { trap { switch ($_.Exception.GetType().FullName) { "System.Management.Automation.PSInvalidCastException" {$_.message;Break} "System.Management.Automation.RuntimeException" { Throw "Assurez-vous que l'assembly [System.Windows.Forms] est bien chargé." } default {Throw $_} }#switch }#trap return [Windows.Forms.MessageBox]::Show($Message,$Titre, $BtnType,$IconType) } function Show-QuestionBox([string] $Message,[string] $Titre="Question ??", [String] $IconType="Question",[String] $BtnType="YesNo") { trap { switch ($_.Exception.GetType().FullName) { "System.Management.Automation.PSInvalidCastException" {$_.message;Break} "System.Management.Automation.RuntimeException" { Throw "Assurez-vous que l'assembly [System.Windows.Forms] est bien chargé." } default {Throw $_} }#switch }#trap return [Windows.Forms.MessageBox]::Show($Message,$Titre,[Windows.Forms.MessageBoxButtons]::$BtnType, [Windows.Forms.MessageBoxIcon]::$IconType) } function Show-InfoBox([string] $Message,[string] $Titre="Pour votre Information !!", [String] $IconType="Information",[String] $BtnType="Ok") { trap { switch ($_.Exception.GetType().FullName) { "System.Management.Automation.PSInvalidCastException" {$_.message;Break} "System.Management.Automation.RuntimeException" { Throw "Assurez-vous que l'assembly [System.Windows.Forms] est bien chargé."} default {Throw $_} }#switch }#trap return [Windows.Forms.MessageBox]::Show($Message,$Titre, $BtnType,$IconType) } # ================================================= # Renvoi la Taille d'un repertoire en octets # ================================================= function Get-FolderSize() { param ([string]$root = $(resolve-path .)) gci -re $root | ?{ -not $_.PSIsContainer } | measure-object -sum -property Length } # ================================================= # Renvoi la Taille d'un fichier en octet # ================================================= function Get-FileSize($Path) { # On verifie si le path exist if(test-path $Path){ $colItems = (Get-ChildItem $Path) return $colItems.Length } else { return 0 } } # ================================================== # Renvoie la Taille d'un fichier en Go # ================================================== function Get-FileSizeGB($Path){ return ("{0:N2}" -f ((Get-FileSize $Path) /1GB)) } # =========================================================== # Nettoyage des Logs # =========================================================== function Delete-Logs($argDirectoryLogs,$argDelay){ $jour = [DateTime]::Today $lastMod = $jour.AddDays(-$argDelay) #Récupere la liste des fichiers logs antérieurs à la date $Files = get-childitem $argDirectoryLogs -include *.log -recurse | Where {$_.LastWriteTime -le "$lastMod"} if (!($Files -eq $null)) { foreach ($File in $Files) { write-host $File Remove-Item $File } } } # ========================================================================= # Fonction de récupération du mail utilisateur dans le fichier sur Voltaire # ========================================================================= function Get-Email { param ([string]$login,[string]$filelogs) Get-Content $filelogs | Where-Object { $_.split(";")[0] -match "$login"} | foreach {$_ -replace "^$login;", ""} } # ======================================================= # Fonction qui initialise le bon path de la messagerie # ======================================================= function Find-DirectoryMessagerie { param ([string]$pathDocsUserLocation) Set-Location $pathDocsUserLocation Get-ChildItem "./" | Where-Object {$_.Attributes -eq "Directory"} | Where-Object {$_.Name -match "^[M-m]essagerie$"} | foreach {$_.FullName} } # ========================================================================= # Fonctions relatives à la taille du disque C # ========================================================================= function Get-FreeSpaceCGB { return Get-WmiObject win32_logicaldisk -Filter "DriveType=3" | Where-Object {$_.DeviceID -eq "C:"} | ForEach-Object {[Math]::round($_.FreeSpace/1GB,2)} } function Get-FreeSpaceC { return Get-WmiObject win32_logicaldisk -Filter "DriveType=3" | Where-Object {$_.DeviceID -eq "C:"} | ForEach-Object {$_.FreeSpace} } function Get-SizeC { return Get-WmiObject win32_logicaldisk -Filter "DriveType=3" | Where-Object {$_.DeviceID -eq "C:"} | ForEach-Object {$_.Size} } function Get-SizeCGB { return Get-WmiObject win32_logicaldisk -Filter "DriveType=3" | Where-Object {$_.DeviceID -eq "C:"} | ForEach-Object {[Math]::round($_.Size/1GB,2)} } function espacedispo { $freespaceC = Get-WmiObject win32_logicaldisk -Filter "DriveType=3" | Where-Object {$_.DeviceID -eq "C:"} | ForEach-Object {$_.FreeSpace} $sizeC = Get-WmiObject win32_logicaldisk -Filter "DriveType=3" | Where-Object {$_.DeviceID -eq "C:"} | ForEach-Object {$_.Size} $freespaceCGB = Get-WmiObject win32_logicaldisk -Filter "DriveType=3" | Where-Object {$_.DeviceID -eq "C:"} | ForEach-Object {[Math]::round($_.FreeSpace / 1073741824,2)} $sizeCGB = Get-WmiObject win32_logicaldisk -Filter "DriveType=3" | Where-Object {$_.DeviceID -eq "C:"} | ForEach-Object {[Math]::round($_.Size / 1073741824,2)} $docspace = (Get-FolderSize $DocsUserLocation).Sum $burspace = (Get-FolderSize $BureauUserLocation).Sum $totaltoback = $burspace + $docspace $docspaceGB = [Math]::round($docspace/1GB,2) $totaltobackGB = [Math]::round($totaltoback/1GB,2) $spaceminfree = $totaltoback + 21474836480 echo $spaceminfree echo $freespaceCGB if ( $freespaceC -lt $spaceminfree ) { $greenflag = 1 } else { $greenflag = 0 } return $greenflag } function Kill-Process ($app) { if (Get-Process $app -ErrorAction silentlycontinue) { Get-Process $app | Stop-Process Start-Sleep -s 2 } } function Get-OS { return (Get-WmiObject -class Win32_OperatingSystem).Caption | foreach {$_ -replace " ", ""} } #======================================================= # Fonction qui défini laptop ou desktop # ======================================================= function Get-PCtype { return (Get-WmiObject -class Win32_computersystem).PCSystemType } $pctype = Get-PCtype if ($pctype -ne "2") {$fixe = "Oui"} else {$fixe = "Non"} # ======================================================= # Fonction qui écrit des indicateurs dans un fichier # ======================================================= function Set-Indicator($fichier) { #Si le fichier n'existe pas, je crée un nouveau fichier. if ((Test-Path $fichier) -ne "True") { New-Item -ItemType file -Path $indicateurs -Force } # Ajoute une ligne dans le fichier. # Les champs sont l'utilisateur, l'ordinateur, les 5 codes de sortie des commandes robocopy, les dates de debut et de fin, la taille en GB à copier à distance # et l'espace libre suffisant Oui ou Non Add-Content -Path $fichier -Value "$UserName;$ComputerName;$DocExitCode;$BurExitCode;$BurVolExitCode;$DocVolExitCode;$Tstart;$Tend;$sizetobackGB;$nospace" } # ======================================================= # Déclaration des variables globales # ======================================================= # Portable ou Fixe #$fixe = "Oui" # Serveur de backup $BackupServer = "CLUSTER_SYNOLOG" # Serveur de Backup FQDN $BackupServerfdqn = "CLUSTER_SYNOLOG.iut.local" # Répertoire partagé sur le serveur $ShareBackupServer = "Personnel\MonDossier" # Nom de l'ordinateur $ComputerName = $Env:COMPUTERNAME # Nom de la session $UserName = Enjalbert.S # Initialisation du jour de la semaine $numjour = Get-Date -UFormat %u # Initialisation du Jour de l'année $dayofyear = (get-date).dayofyear # Répertoire de sauvegarde sur le serveur aubrac $DirBackVol = "\\$BackupServerfdqn\$ShareBackupServer\$UserName" # Nom du repertoire de logs $NameDirectoryLogs = "logssauv" # Nom du repertoire de logs Local $NameDirectoryLogsLocal = "localogssauv" # Nom du serveur smtp $SmtpServerName = "relay.iut-rodez.fr" # Mail du support $toSupport = "support@iut-rodez.fr" # Emplacement du fichier de correspondance des emails (attention à ce qu'il ne soit pas modifié par des utilisateurs!) $filelogins = "\\$BackupServerfdqn\$ShareBackupServer\logssauv\login-email.csv" # Champ FROM des courriel if ((Test-Path $filelogins) -ne "True") { $mailfrom = "sauvegarde@iut-rodez.fr" } else { if (( Get-Content "$filelogins" | ? { $_ -match "$UserName" } ) -eq $Null ) { $mailfrom = "sauvegarde@iut-rodez.fr" } else { $mailfrom = Get-EMail $UserName $filelogins } } if ((Test-Path $filelogins) -ne "True") { $Toclient = "sauvegarde@iut-rodez.fr" } else { if (( Get-Content "$filelogins" | ? { $_ -match "$UserName" } ) -eq $Null ) { $Toclient = "sauvegarde@iut-rodez.fr" } else { $Toclient = Get-EMail $UserName $filelogins } } # Fichier des indicateurs sur Cluster_synolog $indicateurs = "\\$BackupServerfdqn\$ShareBackupServer\logssauv\indicateurs$dayofyear.txt" # Localisation du profil des utilisateurs (XP ou seven) $ProfileUserLocation = $Env:UserProfile $DirectoryBackup = "$ProfileUserLocation\Copie-Y" $NameDirectoryLogsVol = "$DirectoryBackup\Logssauv" $fichierflagnet = "$DirectoryBackup\flag-net.txt" $os = Get-OS #Liste des fichiers à exclure $FileExclude = "`"*.ogg`" `"*.flac`" `"*.mp3`" `"*.wav`" `"*.wma`" `"*.aac`" `"*.mpeg`" `"*.ogm`" `"*.avi`" `"*.flv`" `"*.wmv`" `"*.mov`" `"*.divx`" `"*.xvid`" " # Nom du fichier logs $NameDocVolLogs = "SavDocVol"+" {0:dddd dd MMM yyyy' - 'HH'h'mm}.log" -f (Get-Date) $DelayRetentionLogs = 8 $listJob = @() $ExitCode = @{ "16"="Erreur fatale lors de l'opération. Voir fichier de Log" "15"="Echec de la copie. Voir le fichier de Log." "14"="Echec de la copie. Voir le fichier de Log." "13"="Echec de la copie. Voir le fichier de Log." "12"="Echec de la copie. Voir le fichier de Log." "11"="Echec de la copie. Voir le fichier de Log." "10"="Echec de la copie. Voir le fichier de Log." "9"="Echec de la copie. Voir le fichier de Log." "8"="Echec de la copie. Plisieurs fichiers n'ont pas été copiés. Voir le fichier de Log." "7"="Copie OK. Certains fichiers présents et supplémentaires on généré une incohérence entre la source et la destination. Voir le fichier de Log." "6"="Copie OK. Certains fichiers et dossiers suplémentaires ont généré une incohérence entre la source et la destination. Voir le fichier de Log." "5"="Copie OK. Certains fichiers ont été copiés et d'autres ont généré une incohérence entre la source et la destination. Voir le fichier de Log." "4"="Copie OK. Une incohérence entre la source et la destination de la sauvegarde a été détectée. Voir le fichier de Log." "3"="Copie OK. Certains fichiers supplémentaires ont été copiés avec succès." "2"="Copie OK. Certains fichiers ou répertoires supplémentaires ont été détectés et copiés avec succès." "1"="Copie OK. Un ou plusieurs fichiers ont été copiés avec succès du répertoire source au répertoire de destination." "0"="Copie OK. Aucun changement. Le répertoire source était identique au répertoire de destination." } $mail = New-Object System.Net.Mail.MailMessage $killappli = @("outlook","excel","winword","powerpnt","msaccess","mspub","visio","thunderbird","soffice.bin") $SavDocVolLog = "$NameDirectoryLogsVol\$NameDocVolLogs" $resultatcopieloc = 0 $resultatcopienet = 0 $pasnecessaireloc = 0 $pasnecessairenet = 0 # FIN VARIABLES GLOBALES DEF ET INIT # ============================= # DEBUT DU PROGRAMME PRINCIPAL # ============================= # Chargement d'une librairie pour l'affichade de fenetre [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") # On tue les appli genantes foreach ($i in $killappli){ Kill-Process ($i) } Start-Sleep -s 2 # Détermination de l'endroit ou effectuer la sauvegarde # et la validation ou non de la sauvegarde précédente en local If (!(Test-Path "$NameDirectoryLogsVol")){ Set-Location "$DirectoryBackup" New-Item -ItemType Directory -Name "$NameDirectoryLogs" } $TimesStart = Get-date -Format 'dddd dd MMM yyyy' $HourStart = Get-Date -Format 'HH"h"mm' $Tstart = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' ## =============================================================== # SEQUENCE : COPIE RESEAU ## ================================================================ Write-OutputConsole("lancement") Start-Sleep -s 2 # Test de la disponibilité du serveur, on arrête le programme si le serveur est injoignable if ((!(Test-Connection -computer $BackupServer -Count 3 -quiet)) -or (!(Test-Connection -computer $BackupServerfdqn -Count 5 -quiet))) { Write-OutputConsole("nosynolog") Show-MessageBox ("Attention !!", "Le serveur de backup n'est pas joignable, la sauvegarde est annulée`nContactez votre administrateur.`n`nCliquez su OK pour Eteindre") exit } # Lancement de la copie Y CLUSTER_SYNOLOG vers Dossier Copie-Y sur Portable robocopy "$DirBackVol" "$DirectoryBackup" /MIR /R:3 /W:5 /XD $DirectoryExclude >> $SavDocVolLog $DocVolExitCode = $LASTEXITCODE if ($DocVolExitCode -lt 8){ # La sauvegarde Locale est réussie, on remet le fichier flag puis on compresse le tout dans le dossier du jour set-content -path "$fichierflagnet" -value "OK" $resultatcopienet = 1 } $TimesEnd = Get-date -Format 'dddd dd MMM yyyy' $HourEnd = Get-Date -Format 'HH"h"mm' $Tend = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' ## =============================================================== # 3EME SEQUENCE : INDICATEURS/NOTIFICATIONS # ================================================================ Delete-Logs $NameDirectoryLogsVol 8 if ($resultatcopienet -eq 1) { $messagecourriel = "Résultat de la sauvegarde : OK (démarrée le $TimesStart à $HourStart et terminée le $TimesEnd à $HourEnd)" $body = "Si la sauvegarde a déja été exécutée dans les 18h, elle n'est pas relancée." $toSupport = $null } else { $messagecourriel = "Un problème est survenu dans l'exécution de votre sauvegarde (démarrée le $TimesStart à $HourStart et terminée le $TimesEnd à $HourEnd)" $body = "Un problème est survenu dans l'exécution de la sauvegarde pour $UserName. survenu lors de la sauvegarde de Copie-Y démarrée le $TimesStart à $HourStart et terminée le $TimesEnd à $HourEnd.`n`nLes résultats de sauvegardes ont été les suivants :`n`nCopie-Y vers CLUSTER_SYNOLOG `n"+$ExitCode["$DocVolExitCode"]+"`n`Pour de plus amples détails, consultez le fichier log en pièce jointe." } If (!(Test-Path "$SavDocVolLog")){ $SavDocVolLog = $null } # Message aux utilisateurs Send-Email $mailfrom $Toclient $toSupport 'High' $messagecourriel $body $SavDocVolLog $SmtpServerName # TODO:verifier le lancement de la commande mail # INDICATEURS : # ------------ # Set-indicator($indicateurs) } { Exit }