Compare content of text file with directory and move the common result

I have a textfile which contains the name of files that are missing in a certain destination folder. Therefore I try to compare it to our archivefolder. All the files that are in the list should be copied to a destinationfolder. If you have any suggestion, that would be helpful!

Here is an example:
#script to compare files and move the right collection

$files = Get-Content -Path d:\acdc.txt
$searchIn = Get-ChildItem -Path d:\acdc\

foreach ($file in $files)

{
if ($searchIn -contains $file)
{
copy-item -Path D:\a-folder
}

}

When you post code, sample data, console output or error messages please format it as code using the preformatted text button ( </> ). Simply place your cursor on an empty line, click the button and paste your code.

Thanks in advance

How to format code in PowerShell.org <---- Click :point_up_2:t4: :wink:

If you want to compare objects you can use

Please read the help completely including the examples to learn how to use it. :wink:

ok, I tried to do it with compare…still have a problem.
In the destination folder only the “base folder” is created, but the files are not copied into it.

#List with all the files that we need to copy to a target directory
$files = Get-Content -Path "H:\Skripte\SearchListDirectory.txt"

#archive directory with a backup of all files - we filter to get a smaller result - we need only the .xml files
$archiv = Get-ChildItem -path "K:\temp\zwma\20230215" -Exclude *.pdf,*_log.xml -name

#comapare the directory with the content of the file - the result need to be restored
$selection = Compare-Object -ReferenceObject $files -DifferenceObject $archiv -IncludeEqual | Where-Object {$_.SideIndicator -eq "=="} | select inputobject

# Compare-Object -ReferenceObject $files -DifferenceObject $archiv -IncludeEqual | Where-Object {$_.SideIndicator -eq "=="} | gm

#copy files from backup directory to target directory.

ForEach ($select in $selection) {
            
  Copy-Item -path "K:\temp\zwma\20230215\$($selct.basename)" -destination "K:\temp\zwma\NachSendenOIZ\$select" -Force
}

If you use the parameter -ExcludeDifferent you don’t need the Where-Object. :wink:

Copy-Item by default expects a folder path as destination. And If you don’t want to rename the file while copying it you don’t need a file name.

To debug your code you should use a few test files and output the variables you’re using to check if it’s what you think it is.

The property BaseName is the file name without its extension - this will very likely not work. :wink:

If $Select is an object with properties this might not be what you expect. :wink:

1 Like

Thanks for the input…I changed a few things/name and got still no results, but the errormessage is now helpful.
PS tries to copy the content of the list instead of the archive files. I switched the refereceObject and DifferenceObject but it didn’t help. How to I tell PS to tkae to files from $arichive?

#List with all the files that we need to copy to a target directory
$files = Get-Content -Path "H:\Skripte\SearchListDirectory.txt"

#archive directory with a backup of all files - we filter to get a smaller result - we need only the .xml files
$archiv = Get-ChildItem -path "K:\temp\zwma\20230215" -Exclude *.pdf,*_log.xml -name

#target directory
$destination = "K:\temp\zwma\restore\"

#$restoreFiles = Compare-Object -ReferenceObject $files -DifferenceObject $archiv -ExcludeDifferent -IncludeEqual| select inputobject
$restoreFiles = Compare-Object -ReferenceObject $archiv -DifferenceObject $files -ExcludeDifferent -IncludeEqual| select inputobject

#copy files from backup directory to target directory.

ForEach ($restoreFile in $restoreFiles) {
        
      
       # copy files to destination folder
       Copy-Item $restoreFile -Destination $destination
              
       
}

Here is the error message -it’s in German - but you can clearly see that it tries to access H:\drive which is the source of the list. - Thanks for some additional input;-)
PS H:> H:\Skripte\compareCopyNew.ps1
Copy-Item : Der Pfad “H:@{InputObject=3010_007317562_189.xml}” kann nicht gefunden werden, da er nicht vorhanden ist.
In H:\Skripte\compareCopyNew.ps1:27 Zeichen:8

  •    Copy-Item $restoreFile -Destination $destination
    
  •    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : ObjectNotFound: (H:@{InputObject=3010_007317562_189.xml}:String) [Copy-Item], ItemNotFoundException
    • FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand

Hi Olaf,
found a soluten…

#Source Directory non-filtered
$PfadFROM = "K:\temp\zwma\20230215\"

#target directory
$destination = "K:\temp\zwma\NachSendenOIZ\"

#List with all the files that we need to copy to a target directory
$files = Get-Content -Path "K:\temp\zwma\SearchListDirectory.txt"

#### DEBUG - Ausgabe aller Filenamen von der Liste ####
#Write-host "Liste: "
#foreach ($filename in $files) {
    #Write-host $filename
#}

#archive directory with a backup of all files - we filter to get a smaller result - we need only the .xml files
$archiv = Get-ChildItem -path "K:\temp\zwma\20230215\" -Exclude *.pdf,*_log.xml -name
#Write-Host $archiv

#### DEBUG - Ausgeben aller Filenamen im Ordner (gefilteret)
#Write-host "Ordner Files: "
#foreach ($archivdatei in $archiv) {
    #Write-host $archivdatei
#}


##Unterschiede herausssuchen (und nur Name ausgeben)
#Write-Output "comparison"
$restoreFiles = Compare-Object -ReferenceObject $files -DifferenceObject $archiv -ExcludeDifferent -IncludeEqual | Select Object -ExpandProperty InputObject



#FĂĽr jeden treffer
ForEach ($restoreFile in $restoreFiles) {
    ##### Debug - Alle treffer ausgeben ####
    #Write-Host $restoreFile


    # Pfad FROM zusammenstellen
    $FullFileNameWithPathFROM =  $PfadFROM + $restoreFile
    #Write-Host "FROM" $FullFileNameWithPathFROM
    # Pfad TO zusammenstellen
    $FullFileNameWithPathTO =  $destination + $restoreFile
    #Write-Host "TO" $FullFileNameWithPathTO

    Copy-Item $FullFileNameWithPathFROM -Destination $FullFileNameWithPathTO      
}

Thank you very much! Have a nice weekend! Cheers :clinking_glasses:
:clinking_glasses:

Wow … you’re overcomplicating this a lot. :wink:

You may use -passThru to actually get the file system objects.

$files = Get-Content -Path "H:\Skripte\SearchListDirectory.txt"
$archiv = Get-ChildItem -path "K:\temp\zwma\20230215" -Exclude *.pdf,*_log.xml -name
$destination = "K:\temp\zwma\restore\"

$restoreFiles = 
    Compare-Object -ReferenceObject $archiv -DifferenceObject $files -ExcludeDifferent -IncludeEqual -PassThru

ForEach ($restoreFile in $restoreFiles) {
    # if you have code not doing what you expect you start with outputting the variables you use.
    $restoreFile.FullName
    Copy-Item $restoreFile.FullName -Destination $destination
}

No problem — me too. :wink: :de: