Résolu Déplacement de fichiers et copie d'arborescence selon critères

Plus d'informations
il y a 7 mois 1 semaine - il y a 7 mois 1 semaine #33757 par CUISINIER
Bonjour,
J'ai besoin de faire de la place sur nos serveurs de fichiers.
J'ai donc commencé à rédiger un script powershell, mais après plusieurs jours à m'arracher les cheveux, je demande un peu d'aide.

Je dois donc déplacer les fichiers d'un disque local vers un lecteur réseau mais :
  • je dois recréer l'arborescence des dossiers
  • je ne dois déplacer que les fichiers de plus de 5 ans
  • je dois exclure les fichiers dont l'extension est .bat ou .exe
  • je dois exclure deux dossiers (est leurs sous-dossiers) "D:\Informatique" et "D:\En cours\Important"
Voilà ce que j'ai réalisé jusqu'à présent :
# Chemin du dossier source
$sourceFolder = "D:\test"

# Chemin du dossier de destination
$destinationFolder = "D:\deplace_test"

# Exclure les extensions de fichiers spécifiées
$excludedExtensions = @("bat", "exe")

# Exclure les dossiers spécifiés
$excludedFolders = @("D:\Informatique", "D:\En cours\Important")

# Durée de rétention des fichiers en années
$retentionYears = 5

# Date actuelle
$currentDate = Get-Date

# Calculer la date de rétention
$retentionDate = $currentDate.AddYears(-$retentionYears)

# Fonction récursive pour déplacer les fichiers
function Move-OldFiles {
    param (
        [string]$source,
        [string]$destination
    )

    # Parcourir tous les fichiers dans le dossier source
    Get-ChildItem -Path $source | ForEach-Object {
        Write-Host "Traitement du fichier : $_.FullName"
        Write-Host "Date de dernière modification : $($_.LastWriteTime)"
        Write-Host "Date de rétention : $retentionDate"

        # Vérifier si le fichier est plus ancien que la date de rétention
        if ($_.LastWriteTime -lt $retentionDate) {
            # Résoudre le chemin canonique des dossiers exclus
            $resolvedExcludedFolders = $excludedFolders | ForEach-Object { (Resolve-Path $_).Path }

            # Vérifier les exclusions
            $isExcludedExtension = $excludedExtensions -contains $_.Extension
            $isExcludedFolder = $resolvedExcludedFolders -contains (Resolve-Path $_.FullName).Path

            if (-not $isExcludedExtension -and -not $isExcludedFolder) {
                # Construire le chemin de destination
                $destinationPath = Join-Path $destination $_.FullName.Substring($source.length + 1)

                # Créer le dossier de destination si nécessaire
                $null = New-Item -ItemType Directory -Path (Split-Path $destinationPath) -Force

                # Déplacer le fichier
                Move-Item $_.FullName -Destination $destinationPath -Force
            }
        }
    }

    # Appeler récursivement pour les sous-dossiers
    Get-ChildItem -Path $source -Directory | ForEach-Object {
        Move-OldFiles -source $_.FullName -destination $destination
    }
}

# Appeler la fonction pour démarrer le déplacement
Move-OldFiles -source $sourceFolder -destination $destinationFolder

Quand je l'utilise, tous les fichiers et dossiers sont déplacés sans prise en compte des conditions et exceptions...
J'ai dû faire une erreur quelque part, mais à force de scruter mon code et de le modifier dans tous les sens, mes yeux se croisent et je ne vois plus rien.

Un regard neuf pourrait-il m'offrir son aide ?
Dernière édition: il y a 7 mois 1 semaine par CUISINIER.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 7 mois 1 semaine #33761 par CUISINIER
J'ai fini par trouver par moi-même.
Je dépose ici la solution si ça intéresse quelqu'un :
# Chemin du dossier source
$sourceFolder = "D:\test"

# Chemin du dossier de destination (pour l'arborescence des dossiers)
$destinationFolderStructure = "D:\deplace_test"

# Exclure les extensions de fichiers spécifiées
$excludedExtensions = @("bat", "exe", "ps1")

# Dossiers à exclure complètement
$excludedFolders = @("D:\test\Informatique", "D:\test\En cours\Important")

# Durée de rétention des fichiers en années
$retentionYears = 5

# Date actuelle
$currentDate = Get-Date

# Calculer la date de rétention
$retentionDate = $currentDate.AddYears(-$retentionYears)

# Fonction récursive pour copier l'arborescence des dossiers
function Copy-FolderStructure {
    param (
        [string]$source,
        [string]$destination
    )

    # Vérifier si le dossier doit être exclu
    if ($excludedFolders -notcontains $source) {
        # Parcourir tous les éléments dans le dossier source
        Get-ChildItem -Path $source | ForEach-Object {
            Write-Host "Copie de l'élément : $_.FullName"

            # Construire le chemin de destination
            $destinationPath = Join-Path $destination $_.FullName.Substring($source.length + 1)

            # Créer le dossier de destination si nécessaire
            if ($_.PSIsContainer -eq $true) {
                $null = New-Item -ItemType Directory -Path $destinationPath -Force

                # Appeler récursivement pour les sous-dossiers
                Copy-FolderStructure -source $_.FullName -destination $destinationPath
            }
        }
    }
}

# Appeler la fonction pour copier l'arborescence des dossiers
Copy-FolderStructure -source $sourceFolder -destination $destinationFolderStructure

# Fonction récursive pour déplacer les fichiers selon les critères
function Move-OldFiles {
    param (
        [string]$source,
        [string]$destination
    )

    # Vérifier si le dossier doit être exclu
    if ($excludedFolders -notcontains $source) {
        # Parcourir tous les fichiers dans le dossier source
        Get-ChildItem -Path $source -File | ForEach-Object {
            Write-Host "Traitement du fichier : $_.FullName"
            Write-Host "Date de dernière modification : $($_.LastWriteTime)"
            Write-Host "Date de rétention : $retentionDate"

            # Vérifier si le fichier est plus ancien que la date de rétention
            if ($_.LastWriteTime -lt $retentionDate) {
                # Vérifier les exclusions
                $isExcludedExtension = $excludedExtensions -contains $_.Extension

                if (-not $isExcludedExtension) {
                    # Construire le chemin de destination pour les fichiers
                    $relativePath = $_.Directory.FullName.Substring($sourceFolder.length + 1)
                    $destinationPath = Join-Path $destinationFolderStructure $relativePath

                    # Créer le dossier de destination si nécessaire
                    $null = New-Item -ItemType Directory -Path $destinationPath -Force

                    # Déplacer le fichier
                    Move-Item $_.FullName -Destination $destinationPath -Force
                }
            }
        }

        # Appeler récursivement pour les sous-dossiers
        Get-ChildItem -Path $source -Directory | ForEach-Object {
            Move-OldFiles -source $_.FullName -destination $destinationFolderStructure
        }
    }
}

# Appeler la fonction pour déplacer les fichiers selon les critères
Move-OldFiles -source $sourceFolder -destination $destinationFolderStructure
Ce code déplace les fichiers de plus de 5 ans, dont l'extension n'est pas dans la liste ("bat", "exe", "ps1") et qui ne se trouvent pas dans les dossiers @("D:\test\Informatique", "D:\test\En cours\Important").

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 7 mois 1 semaine #33762 par Fabien
Bonjour,

Tu as été plus rapide que moi, lol.
Sinon pour ce genre de script avec des copies de plusieurs fichiers, j'utilise Robocopy qui gère bien les exceptions.

Fabien

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.102 secondes
Propulsé par Kunena