Search code examples
powershellforeachpowershell-5.0

Variable being overwritten in ForEach loop - Powershell


I am trying to run the below code to import a list of directories from a .csv file (if chosen as a parameter) and then do a foreach loop to determined what files have been modified in the last XX days in the directories listed in the .csv file.

However it appears that the $modfiles variable is overwritten in each iteration as opposed to being appended.

The .csv being imported has 3 directories in it but my output only shows the relevant files from the last directory imported. Is their away to append $modfiles?

CSV Contents:

enter image description here

$importDirs = Import-Csv $importCsv
foreach ($importDir in $importDirs){
            $modfiles = Get-ChildItem -Path $importDir.Directory -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -ge $modDate }
}

Output:

enter image description here

Here is the entire script:

[CmdletBinding(DefaultParameterSetName='ManualDirectory')]
param (
    [Parameter(Mandatory = $true, ParameterSetName = 'ManualDirectory')]
    [System.String]
    $dir,

    [Parameter(Mandatory = $true, ParameterSetName = 'ImportDirectory')]
    [System.String]
    $importCsv,

    [Parameter(Mandatory=$true)]
    [int]$days,

    [switch]$exportCsv,

    [switch]$console

)

Process {
    #Clear-Host
    $totSize = 0
    $totFiles = 0
    $modDate = (Get-date).AddDays(-$days).Date
    If ($dir){
        $modfiles = Get-ChildItem -Path $dir -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -ge $modDate }
    }
    If ($importCsv){
        $importDirs = Import-Csv $importCsv
        foreach ($importDir in $importDirs){
            $modfiles = Get-ChildItem -Path $importDir.Directory -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -ge $modDate }
       }
    }
    If ($exportCsv){
        $modfiles | Select-Object -Property FullName, Length,LastWriteTime | Export-Csv -Path .\modFiles.csv -NoTypeInformation
    }
    foreach ($file in $modfiles){
        $totFiles = $totFiles + 1
        $totSize = $totSize + $file.Length
        If ($console -eq $true){
            Write-Host $file.FullName
        }
    }

    If ($totSize -lt 1MB){
        $outSize = $totSize/1KB
        $unit = "KB"
    }
    elseif (($totSize -ge 1MB) -and ($totSize -lt 1GB)){
        $outSize = $totSize/1MB
        $unit = "MB"   
    }
    elseif ($totSize -ge 1GB){
        $outSize = $totSize/1GB
        $unit = "GB" 
    } 

    $outRound = [math]::Round($outSize,2)
    Write-Host $totFiles "Files"
    Write-Host $outRound $unit
}

Solution

  • $importDirs = Import-Csv $importCsv
    foreach ($importDir in $importDirs){
                $modfiles = Get-ChildItem -Path $importDir.Directory -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -ge $modDate }
    }
    

    Each time you loop through $importDirs, you assign a value to $modfiles. Each iteration, you overwrite the values from previous iteration.

    If you need to keep a list of all the values, append the data by using

    $modfiles = $modfiles, (Get-Childitem ...)
    
    # or
    $modfiles += Get-ChildItem ...