Membres: 1429  •  Messages: 46612  •  Sujets: 6155  •  Merci d'accueillir jumps, notre dernier membre.
Merci de vous connecter ou de vous inscrire.

Connexion avec identifiant, mot de passe et durée de la session
Recherche avancée  


Auteur Sujet: Script de récupération de données  (Lu 4205 fois)

0 Membres et 1 Invité sur ce sujet

Hors ligne Spip5

  • Grand Maître
  • *****
  • Messages: 1960
  • Karma: 1
  • Sexe: Homme
Script de récupération de données
« le: 05 février 2009 à 15:33:55 »
Bonjour à tous,

Il m'a été donné la directive suivante: rédiger un script pour sauvegarder automatiquement les données présentes sur X postes portables.

Dans la théorie, j'ai émis la première éventualité: à chaque connexion d'un utilisateur, lancer un script de connexion (via Active Directory) faisant une copie de tous les fichiers présents dans un répertoire donnée vers un serveur de sauvegarde.
Jusqu'ici, tout va bien. Un fichier .bat contenant
net use z: \\serveur\sauvegarde\%username%
xcopy c:\data z: /e /h /y /k
fera l'affaire.

Si à chaque ouverture de session les utilisateurs attendent 3 plombes que toutes les données se copient, ça ne va pas le faire. Il m'a donc été suggéré d'inclure une condition à la récupération des données: que seuls soient copiés les fichiers nouveaux ou modifiés depuis la dernière fois.
Là, ça va encore:
net use z: \\serveur\sauvegarde\%username%
xcopy c:\data z: /e /h /y /k /d

Mais en y réfléchissant, je me suis dit: si l'utilisateur a au 1er janvier 1Go de données récupérés, puis que 3 mois après il a supprimé localement ces données et les a remplacé par 1Go d'autre chose, le serveur lui conservera 2Go, ce qui n'est pas utile et risque rapidement de le surcharger.
Dès lors, comment faire pour que les fichiers présents sur le disque du serveur soient supprimés s'ils ne se trouvent plus sur le poste client ?
J'ignore s'il existe une telle commande. Peut-être un "if". Si oui, à quoi ressemblerait-il ?

Si une telle option n'était pas viable, je risquerai alors de me rabattre vers des logiciels consacrés et suis tout ouï à vos suggestions.

Merci d'avance pour vos réponses.

Hors ligne O-ERON

  • travailleur fou
  • Super modérateur
  • Grand Maître
  • *****
  • Messages: 4782
  • Karma: 0
  • Sexe: Homme
    • Codeweaver
Re : Script de récupération de données
« Réponse #1 le: 05 février 2009 à 18:11:25 »
déjà je passerais à un langage de script un peu plus évolué genre powershell
d'ailleurs en cherchant un peu, j'ai trouvé une fonction powershell qui permet de synchroniser deux dossiers
l'utilisation est assez spécifique mais tu pourra facilement l'adapter à tes besoins
[Sig removed by Admin: Total file size of all images in sig may not exceed 20 TB]

Hors ligne ferrari

  • Membre VIP
  • Grand Maître
  • *
  • Messages: 8161
  • Karma: 10
  • Sexe: Homme
Re : Script de récupération de données
« Réponse #2 le: 05 février 2009 à 21:56:55 »
j'en ai pas en tete mais il existe des outils de synchro dedie a l'usage que tu souhaites

Hors ligne Spip5

  • Grand Maître
  • *****
  • Messages: 1960
  • Karma: 1
  • Sexe: Homme
Re : Script de récupération de données
« Réponse #3 le: 06 février 2009 à 15:10:36 »
Merci pour vos réponses.

déjà je passerais à un langage de script un peu plus évolué genre powershell
Arg, je ne suis malheureusement pas développeur et ne connais pas grand chose à cela.

Citer
d'ailleurs en cherchant un peu, j'ai trouvé une fonction powershell qui permet de synchroniser deux dossiers
Excellent. Sans arriver à en faire autant, je peux quand même comprendre ce script en partie et il correspond effectivement à ce que je cherche à faire... dans les 2 premiers points de mon message initial. Reste toujours mon souhait "que les fichiers présents sur le disque du serveur soient supprimés s'ils ne se trouvent plus sur le poste client". A moins que j'ai mal lu, je crois que ton lien ne propose pas cela O-Eron.

Citation de: Ferrari
j'en ai pas en tete mais il existe des outils de synchro dedie a l'usage que tu souhaites
Mon souci est que je cherche si possible à ne pas déployer de logiciel sur les postes clients. Aussi, es-tu bien sûr qu'on trouve ce genre de programme ?

Hors ligne Spip5

  • Grand Maître
  • *****
  • Messages: 1960
  • Karma: 1
  • Sexe: Homme
Re : Script de récupération de données
« Réponse #4 le: 06 février 2009 à 15:38:02 »
Je viens d'avancer.

J'ai découvert la commande robocopy, présente dans le Windows Server 2003 Resource Kit Tools

Ma formule serait donc:
robocopy e:\monrepertoire d:\monbackup /mir /s /purge /r:0C'est le paramètre "/purge" qui fait toute la différence avec mon simple xcopy, puisqu'il supprime ce qui se trouve sur le serveur est n'est plus sur le poste client.



Mais, depuis hier, j'ai repensé à la chose.
Je me suis dit qu'il serait bien que les données ne soient supprimées du serveur si elles ne se trouvent plus sur le client qu'après un certain délai.
Car si un client détruit ses données localement, puis ouvre une nouvelle session, le serveur va répliquer la suppression !

De nouvelles pistes pour mon nouveau besoin ?

Merci d'avance pour vos réponses.
« Modifié: 06 février 2009 à 15:39:51 par Spip5 »

Hors ligne pilou055

  • Apprenti(e)
  • **
  • Messages: 100
  • Karma: 0
  • Sexe: Homme
    • Soluce ADSL
Re : Script de récupération de données
« Réponse #5 le: 06 février 2009 à 15:52:39 »
Là tu te pose trop de contraintes.
Pour les fichiers effacés récemment c'est le rôle des sauvegardes et corbeilles réseau.
C'est aussi le rôle de la corbeille locale dans ton cas.

Hors ligne O-ERON

  • travailleur fou
  • Super modérateur
  • Grand Maître
  • *****
  • Messages: 4782
  • Karma: 0
  • Sexe: Homme
    • Codeweaver
Re : Re : Script de récupération de données
« Réponse #6 le: 06 février 2009 à 17:54:35 »
déjà je passerais à un langage de script un peu plus évolué genre powershell
Arg, je ne suis malheureusement pas développeur et ne connais pas grand chose à cela.

Citer
d'ailleurs en cherchant un peu, j'ai trouvé une fonction powershell qui permet de synchroniser deux dossiers
Excellent. Sans arriver à en faire autant, je peux quand même comprendre ce script en partie et il correspond effectivement à ce que je cherche à faire... dans les 2 premiers points de mon message initial. Reste toujours mon souhait "que les fichiers présents sur le disque du serveur soient supprimés s'ils ne se trouvent plus sur le poste client". A moins que j'ai mal lu, je crois que ton lien ne propose pas cela O-Eron.

bah ça n'est pas un langage très compliqué, c'est fait pour être utilisé par les admins système, pas par des programmeurs
mais si tu n'a jamais utilisé de langage de script tu aura en effet un peu de mal

non, en effet, il ne propose pas d'effacer ce qui n'est plus présent
celà dit, ça n'est pas difficile à rajouter

pour le délais de suppression je rejoins pilou, trop compliqué
comment savoir quand un fichier a été supprimé ? il faudra garder dans une db (dans un fichier texte ou autre) la trace de la dernière fois que le logiciel de synchronisation a vu le fichier
[Sig removed by Admin: Total file size of all images in sig may not exceed 20 TB]

Hors ligne ferrari

  • Membre VIP
  • Grand Maître
  • *
  • Messages: 8161
  • Karma: 10
  • Sexe: Homme
Re : Script de récupération de données
« Réponse #7 le: 07 février 2009 à 16:31:57 »
pareil je rejoins pilou

Hors ligne Spip5

  • Grand Maître
  • *****
  • Messages: 1960
  • Karma: 1
  • Sexe: Homme
Re : Script de récupération de données
« Réponse #8 le: 10 février 2009 à 13:58:29 »
Merci à tous pour vos réponses.

J'ai suivi vos conseils et me suis orienté vers la suggestion d'O-eron d'utiliser powershell.

Voici le code vers lequel il m'a renvoyé:
function Get-SysInternals {

   param ( $sysIntDir="c:\sysint\" )
   
   if( !$sysIntDir.endsWith("\")) { $sysIntDir+="\" }
   $log = join-path $sysIntDir "changes.log"
   add-content -force $log -value "`n`n[$(get-date)]SysInternals sync has started"

      dir \\live.sysinternals.com\tools -recurse | foreach {

         $fileName = $_.name
         $localFile = join-path $sysIntDir $_.name                 
         $exist = test-path $localFile
         
         $msgNew = "new utility found: $fileName , downloading..."
         $msgUpdate = "file : $fileName  is newer, updating..."
         $msgNoChange = "nothing changed for: $fileName"
         

         if($exist){

            if($_.lastWriteTime -gt (get-item $localFile).lastWriteTime){
               copy-item $_.fullname $sysIntDir -force
               write-host $msgUpdate -fore yellow
               add-content -force $log -value $msgUpdate
            } else {
               add-content $log -force -value $msgNoChange
               write-host $msgNoChange
            }

          } else {

               if($_.extension -eq ".exe") {
                  write-host $msgNew -fore green
                  add-content -force $log -value $msgNew
               }

               copy-item $_.fullname $sysIntDir -force
         }
   }
}

J'ai beau le décortiquer dans tous les sens, je continue de me demander où y est indiqué le répertoire des données sources.

Quelqu'un pour m'aider ?

Hors ligne O-ERON

  • travailleur fou
  • Super modérateur
  • Grand Maître
  • *****
  • Messages: 4782
  • Karma: 0
  • Sexe: Homme
    • Codeweaver
Re : Script de récupération de données
« Réponse #9 le: 10 février 2009 à 14:17:25 »
err, à la 2ème ligne de code ;)
param ( $sysIntDir="c:\sysint\" )

comme je ne suis pas certain qu'on parle de la même "source", l'autre dossier se trouve à cette ligne :
dir \\live.sysinternals.com\tools -recurse | foreach {

pour en expliquer un peu plus, param récupère les paramètres passés en ligne de commande au script
on lui donne une valeur par défaut au cas où l'utilisateur ne fournit pas le paramètre

à la limite j'veux bien regarder ce soir pour le nettoyer et faire en sorte qu'il soit plus conforme à l'utilisation que tu veux en faire
« Modifié: 10 février 2009 à 14:22:13 par O-ERON »
[Sig removed by Admin: Total file size of all images in sig may not exceed 20 TB]

Hors ligne O-ERON

  • travailleur fou
  • Super modérateur
  • Grand Maître
  • *****
  • Messages: 4782
  • Karma: 0
  • Sexe: Homme
    • Codeweaver
Re : Script de récupération de données
« Réponse #10 le: 11 février 2009 à 00:09:56 »
un peu plus complexe à faire que prévu, par rapport au script d'exemple il faut traiter les sous-dossiers (un peu de récursivité et c'est bon) ainsi que la suppression des fichiers dans le répertoire de backup...
[Sig removed by Admin: Total file size of all images in sig may not exceed 20 TB]

Hors ligne Spip5

  • Grand Maître
  • *****
  • Messages: 1960
  • Karma: 1
  • Sexe: Homme
Re : Script de récupération de données
« Réponse #11 le: 11 février 2009 à 11:31:52 »
Salut Oeron et merci pour tes réponses.

err, à la 2ème ligne de code ;)
param ( $sysIntDir="c:\sysint\" )
Je ne vois pas l'erreur :( . Ici me semble simplement indiqué le répertoire cible.
Pourrais-tu expliciter le bug ?

Citer
comme je ne suis pas certain qu'on parle de la même "source", l'autre dossier se trouve à cette ligne :
dir \\live.sysinternals.com\tools -recurse | foreach {
Pour moi la source est le répertoire de sauvegarde sur le serveur. La source elle est le répertoire à sauver sur le client.
Si je comprends bien ton message, le rapport client-serveur est inversé dans le présent script:
La cible serait c:\sysint.
La source serait \\live.sysinternals.com\tools.
Est-ce bien ça ?

Citer
pour en expliquer un peu plus, param récupère les paramètres passés en ligne de commande au script
on lui donne une valeur par défaut au cas où l'utilisateur ne fournit pas le paramètre
Ca c'est bon, j'avais compris.



Mon idée du moment est la suivante:
- lister l'ensemble des fichiers présents sur le dossier à récupérer (c:\données).
- copier cette liste dans un document texte daté à la date du jour. Nous l'appellerons "liste.txt"
- chercher les différences de noms de fichier existant entre ce qui se trouve dans c:\données et le fichier "liste[date].txt" de J-7.
- Supprimer du serveur (\\serveur\sauvegarde\%username%) tout ce qui s'y trouve et qui ne figure pas dans le "liste[date].txt" de J-7



Voici ma suggestion, totalement incomplète, pour le script:
function Get-SysInternals { // Créer la fonction correspondant à la sauvegarde.

param ( $sysIntDir="\\serveur\sauvegarde\%username%$" ) // Définir la variable $sysIntDir.
param ( $dataDir="c:\donnees" ) // Définir la variable $dataDir
   
   if( !$sysIntDir.endsWith("\")) { $sysIntDir+="\" } // Créer le répertoire de sauvegarde s'il n'existe pas.
   $log = join-path $sysIntDir "changes.log"
   add-content -force $log -value "`n`n[$(get-date)]SysInternals sync has started"

      dir $dataDir -recurse | foreach > c:\donnees[date].txt { // liste les fichiers du client au jour J. Erreur à cette ligne: j'ignore comment insérer dans le nom d'un fichier la date du jour.

         $fileName = $_.name
         $localFile = join-path $sysIntDir $_.name                 
         $exist = test-path $localFile
         
         $msgDel = "Suppression des données obsolètes..." // Message de suppression des vieilles données sur le serveur.
$msgNew = "new utility found: $fileName , downloading..."
         $msgUpdate = "file : $fileName  is newer, updating..."
         $msgNoChange = "nothing changed for: $fileName"
         

         if($exist){

            if (c:\donnees[date].txt -gt c:\donnees[date-7].txt) { // Si les données du jour son différentes de celles d'il y a 7 jours. "-gt" correspond-il bien à cela ?
remove-item $dataDir *.* -recurse -force // supprimer tous les fichiers. J'ignore les paramètres pour spécifier ceux listés dans c:\donnees[date-7].txt mais qui ne se trouvent plus sur c:\donnees[date].txt
write-host $msgDel -fore red
add-content -force $log -value $msgDel
} else {
add-content $log -force -value $msgNoChange
write-host $msgNoChange

if($_.lastWriteTime -gt (get-item $localFile).lastWriteTime){ // a modifier pour que
               copy-item $_.fullname $sysIntDir -force
               write-host $msgUpdate -fore yellow
               add-content -force $log -value $msgUpdate
            } else {
               add-content $log -force -value $msgNoChange
               write-host $msgNoChange
            }

          } else {

               if($_.extension -eq ".exe") {
                  write-host $msgNew -fore green
                  add-content -force $log -value $msgNew
               }

               copy-item $_.fullname $sysIntDir -force
         }
   }
}

N'hésitez pas à me faire vos commentaire sur ce premier jet.
Tous les inconnus pour lesquels j'ai besoin d'aide sont sur des lignes avec des commentaires "//".
« Modifié: 11 février 2009 à 11:33:45 par Spip5 »

Hors ligne O-ERON

  • travailleur fou
  • Super modérateur
  • Grand Maître
  • *****
  • Messages: 4782
  • Karma: 0
  • Sexe: Homme
    • Codeweaver
Re : Re : Script de récupération de données
« Réponse #12 le: 11 février 2009 à 12:22:22 »
Citer
comme je ne suis pas certain qu'on parle de la même "source", l'autre dossier se trouve à cette ligne :
dir \\live.sysinternals.com\tools -recurse | foreach {
Pour moi la source est le répertoire de sauvegarde sur le serveur. La source elle est le répertoire à sauver sur le client.
Si je comprends bien ton message, le rapport client-serveur est inversé dans le présent script:
La cible serait c:\sysint.
La source serait \\live.sysinternals.com\tools.
Est-ce bien ça ?
c'est bien ça

Mon idée du moment est la suivante:
- lister l'ensemble des fichiers présents sur le dossier à récupérer (c:\données).
- copier cette liste dans un document texte daté à la date du jour. Nous l'appellerons "liste.txt"
- chercher les différences de noms de fichier existant entre ce qui se trouve dans c:\données et le fichier "liste[date].txt" de J-7.
- Supprimer du serveur (\\serveur\sauvegarde\%username%) tout ce qui s'y trouve et qui ne figure pas dans le "liste[date].txt" de J-7
pourquoi passser par une liste texte ? c'est autant garder ça dans un tableau en mémoire
attention aux dossiers et sous dossiers, il faut parcourir les fichiers 1 à 1
il faut aussi vérifier avec la date de dernière écriture du fichier, juste le nom ne suffit pas

pour info, en powershell les commentaires commencent par "#"
param s'utilise en 1x, en séparent les différents paramètres par des ","; par exemple Param($a, $b)
if( !$sysIntDir.endsWith("\")) { $sysIntDir+="\" } sert à rajouter si nécessaire un "\" à la fin du nom du répertoire
dir $dataDir -recurse | foreach > c:\donnees[date].txt la redirection vers un fichier texte est inutile, le résultat se trouve en mémoire, de plus la syntaxe n'est pas bonne, ça va planter direct au lancement :)
on compare les dates de modif directement entre dossier source et destination, pourquoi passer par un fichier temporaire ?
if (c:\donnees[date].txt -gt c:\donnees[date-7].txt) du coup cette ligne n'est plus bonne, elle comparait la date de dernière écriture entre les 2 fichiers, -gt correspond à greater càd plus grand que; autrement dit, si la date de dernière écriture du fichier source est plus grande que celle du fichier destination -> on copie

bon bah, je terminerai ma version, je crois que ça sera plus simple et plus rapide  :P

voilà rapidement la bonne structure:

fonction copie(source, destination)
pour chaque élément dans le dossier source
   si dossier
      vérifier qu'il existe dans la destination, sinon le créer
       appel récursif à fonction copie en rajoutant le dossier trouvé aux 2 chemins (source et destination)
       passer à l'élément suivant
   sinon
      si fichier existe dans dossier destination
         si date de modification fichier source > date modification fichier destination alors recopier le fichier de source dans destination en écrasant le fichier présent
      sinon copier le fichier dans le dossier de destination

après ça, tralala similaire pour effacer les fichiers (et dossier) présent dans destination mais pas dans source
« Modifié: 11 février 2009 à 12:30:00 par O-ERON »
[Sig removed by Admin: Total file size of all images in sig may not exceed 20 TB]

Hors ligne Spip5

  • Grand Maître
  • *****
  • Messages: 1960
  • Karma: 1
  • Sexe: Homme
Re : Script de récupération de données
« Réponse #13 le: 11 février 2009 à 13:23:43 »
Waaa, merci pour ta réponse détailléee O-Eron.

Je suis content de voir qu'on avance (ou plutôt que tu avances, enfin passons :lol:).

Pour la structure que tu suggères, elle correspond tout à fait à la première partie de ce que je souhaite faire: copier les données seulement si elles sont plus récentes.

Par contre pour la deuxième partie, celle qui va consister à supprimer du serveur les fichiers s'ils n'existent plus sur le client depuis 7 jours, j'ai du mal à comprendre comment tu peux arriver à le faire sans passer par un fichier de redirection, dans la mesure ou l'état du disque 7 jours avant ne peut être vu sur le moment par la machine, d'elle même, sans qu'elle en garde un historique (rôle attribué à ce fichier de redirection).

Enfin je te fais confiance et attends ton doux scripts dont le rêve bercera mes nuits.

Hors ligne O-ERON

  • travailleur fou
  • Super modérateur
  • Grand Maître
  • *****
  • Messages: 4782
  • Karma: 0
  • Sexe: Homme
    • Codeweaver
Re : Script de récupération de données
« Réponse #14 le: 11 février 2009 à 14:32:44 »
ah tu veux garder cette histoire de 7 jours quand même ?
oui, en effet, ça demande plus de réflexion alors  :?
j'ai horreur de passer par des fichiers plats (juste texte quoi) pour créer une espèce de DB

en tout cas la solution d'un fichier texte par synchronisation n'est pas bonne, en effet on peu synchroniser plusieurs fois par jour
ce qu'il faut c'est en seul endroit garder une liste des fichiers avec associé la date/heure de la dernière fois qu'on l'a vu
[Sig removed by Admin: Total file size of all images in sig may not exceed 20 TB]