Search code examples
powershellcsvimport-csv

How to select [n] Items from a CSV list to assign them to a variable and afterwards remove those items and save the file using PowerShell


I'm parsing a CSV file to get the names of folders which I need to copy to another location. Because there are hundreds of them, I need to select the first 10 or so and run the copy routine but to avoid copying them again I'm removing them from the list and saving the file.

I'll run this on a daily scheduled task to avoid having to wait for the folders to finish copying. I'm having a problem using the 'Select' and 'Skip' options in the code (see below), if I remove those lines the folders are copied (I'm using empty folders to test) but if I have them in, then nothing happens when I run this in PowerShell.

I looked around in other questions about similar issues but did not find anything that answers this particular issue selecting and skipping rows in the CSV.

$source_location = 'C:\Folders to Copy'
$folders_Needed = gci $source_location
Set-Location -Path $source_location
$Dest = 'C:\Transferred Folders'
$csv_name = 'C:\List of Folders.csv'
$csv_Import = Get-Content $csv_name


foreach($csv_n in $csv_Import | Select-Object -First 3){
    foreach ($folder_Tocopy in $folders_Needed){        
        if("$folder_Tocopy" -contains "$csv_n"){        
        Copy-Item -Path $folder_Tocopy -Destination $Dest -Recurse -Verbose        
        }
    }
    $csv_Import | Select-Object -Skip 3 | Out-File -FilePath $csv_name
}

Solution

  • It should work with skip/first as in your example, but I cannot really test it without your sample data. Also, it seems wrong that you write the same output to the csv file at every iteration of the loop. And I assume it's not a csv file but actually just a plain text file, a list of folders? Just folder names or full paths? (I assume the first.)

    Anyways, here is my suggested update to the script (see comments):

    $source_location = 'C:\Folders to Copy'
    $folders_Needed = Get-ChildItem $source_location
    $Dest = 'C:\Transferred Folders'
    $csv_name = 'C:\List of Folders.csv'
    $csv_Import = @(Get-Content $csv_name)
    # optional limit
    # set this to $csv_Import.Count if you want to copy all folders
    $limit = 10
    
    # loop over the csv entries
    for ($i = 0; $i -lt $csv_Import.Count -and $i -lt $limit; $i++) {
        # current line in the csv file
        $csv_n = $csv_Import[$i]
        # copy the folder(s) which name matches the csv entry
        $folders_Needed | where {$_.Name -eq $csv_n} | Copy-Item -Destination $Dest -Recurse -Verbose
        # update the csv file (skip all processed entries)
        $csv_Import | Select-Object -Skip ($i + 1) | Out-File -FilePath $csv_name
    }