Search code examples
powershellrecursioncomparemoveget-childitem

How I can compare two Directories in Powershell and move the items then older x days?


hi i want to compare two objects in Powershell. the objects are directories. For example:

$folderA = gci $source -Recurse
$folderB = gci $destination -Recurse

$diff = Compare-Object -ReferenceObject $folderA -DifferenceObject $folderB -PassThru | Where-Object {$_.SlideIndicator -eq "<="}

The first Problem is if folderB dont have elements then the object is null -.-

The second Problem is if I test it with two Directorys (folderA has 10000 pdf files xD) and folderB has only one test.txt (because if the folder empty then I get null and dont can compare).

My Idea is it that I can comapre folderA with folderB and move all (older then x Days files and Folder) to folderB. only folderA -> folderB

here is my full code:

#Vergleicht zwei Objekte und führt eine Aktion durch
function compareFiles($source,$destination,$days){

    Write-Host "compareFiles(): Es werden zwei Objekte miteinander verglichen"

    #Ermitellt wie alt die Daten sein müssen
    $lastwrite = (Get-Date).AddDays(-$days)

    #Enthält alle Elemente aus dem source Verzeichniss
    $folderA = Get-ChildItem $source -Recurse

    #Definiert eine Testdatei im Falle das Verzeichniss Destination leer ist
    $f = $destination +"\test.txt"

    #Prüft ob das Zielverzeichniss existiert
    if(!(Test-Path $destination -PathType Container)){

        #Erstellt das Zielverzeichniss
        New-Item -ItemType Container -Path $destination -Force 
        Write-Host "NEW FOLDER :" $destination

        #Erstellt die Testdatei im Zielverzeichnis
        New-Item -ItemType File -Path $f -Force
        Write-Host "NEW FILE :" $destination 

    }else{

        #Prüft ob das Zielverzeichniss leer ist
        if((Get-ChildItem $destination) -eq $null){

            #Erstellt die testdatei
            New-Item -ItemType File -Path $f -Force 
            Write-Host "NEW FILE :" $destination
        }
    }


    #Enthält alle Elemente aus dem destination Verzeichniss
    $folderB = Get-ChildItem $destination -Recurse

    #Gibt die Unterschiede zurück
    $diff = Compare-Object -ReferenceObject $folderA -DifferenceObject $folderB -PassThru | Where-Object {$_.SlideIndicator -eq "<="}
    Write-Host ""
    try{

        #Durchläuft alle Elemente in dem Compare Objekt (Unterschiede)
        foreach($element in $diff){

            #Gibt den Vollständigen Pfad von einem Element zurück
            $element_fullname = $element.FullName 

            #Erstellt ein Zielpfad für das Element
            $targetFile = $destination + $element.FullName.SubString($source.Length)

            #Prüft ob das Element ein Ordner ist
            if($element.PSIsContainer){

                #Erstellt einen Ordner 
                New-Item -ItemType Container -Path $targetFile -Force
                Write-Host "NEW FOLDER :" $element.FullName
            }
            else
            {
                #Prüft das Datum von einem Element mit dem definierten Datum ab 
                if($element.creationTime -le $lastwrite){

                    #Verschiebt das Element zum Zielpfad
                    #Move-Item $element.FullName -Destination $targetFile
                    Copy-Item $element.FullName -Destination $targetFile
                    Write-Host "COPY FILE : " $element.FullName
                }
            }
        }

    }catch{
        Write-Host "Es besteht kein Unterschied zwischen den Verzeichnissen!"
    }
}

Solution

  • I would simply use robocopy $source $destination /s /minage:$days for this, but since you say you want to learn how to do it yourself: it takes just 5 simple steps.

    1. Enumerate the files in the folder $source.
    2. Create the destination path for each file by replacing the $source part with $destination.
    3. Check if the LastWriteTime or CreationTime attribute of each file to see if was modified or created more than $days ago, depending on what you mean by "older".
    4. If the file is older, check if the directory part of the destination path exists, otherwise create it.
    5. Move the file to the destination path.

    If you want to exclude existing destination files, add a check for the destination path to step 3.