Jay
Jay

Reputation: 21

Accessing elements in an array

I have issue with looping through arrays that I am trying to understand.

I have an Array variable that stores the paths of some directories.

$collectorDirArray1 = @(Get-ChildItem -Path D:\APPS\Server* -Filter Data -Recurse -Directory).Fullname

$collectorDirArray1 returns this:

D:\Apps\Server
D:\Apps\Server1
D:\Apps\Server2

This foreach loops through the $collectorDirArray1 and gets all *.dat files that are 3 minutes or older.

foreach ($file in $collectorDirArray1) {
    $oldDats = @(Get-ChildItem -Path $collectorDirArray1 -Recurse -Filter "*.dat") | Where {$_.LastWriteTime -lt (get-date).AddMinutes(-3)}
}

$oldDats returns this:

    Directory: D:\APPS\Server\data

Mode                LastWriteTime     Length Name

-a---        2017-10-23   2:40 PM         18 test1.dat

    Directory: D:\APPS\Server2\data


Mode                LastWriteTime     Length Name

-a---        2017-10-17   4:22 PM         17 test2.dat

This foreach loops to get the LastWriteTime of each file in $oldDats array and sends the output to Write-Host.

foreach ($element in $oldDats) {
    $FileDate = $element.LastWriteTime
    Write-Host "The files that are 3 minutes old are: $oldDats the LastWriteTime is: $FileDate"
}

This returns:

The files that are 3 minutes old are: test1.dat test2.dat the LastWriteTime is: 10/23/2017 14:40:21
The files that are 3 minutes old are: test1.dat test2.dat the LastWriteTime is: 10/17/2017 16:22:03

I was expecting

The files that are 3 minutes old are: test1.dat the Last Write time is: 10/23/2017 14:40:21
The files that are 3 minutes old are: test2.dat the Last Write time is: 10/17/2017 16:22:03

If I directly access each element in the array ($oldDats[0] and $oldDats[1]) it returns each file name individually.

Why does the variable $oldDats hold both file names (test1.dat and test2.dat) instead of just the one (test1.dat)?

Upvotes: 0

Views: 2718

Answers (3)

Esperento57
Esperento57

Reputation: 17492

try this:

$maxdate=(get-date).AddMinutes(-3)
$Startdir="c:\temp"

Get-ChildItem $Startdir -file -Recurse -Filter "*.dat" | 
    where {$_.Directory -like "$Startdir\server*\data" -and $_.LastWriteTime -lt $maxdate} |
        %{"The files that are 3 minutes old are: {0} the Last Write time is: {1}" -f $_.Name, $_.LastWriteTime}

Upvotes: 0

Maximilian Burszley
Maximilian Burszley

Reputation: 19704

You are referring to the array instead of the element intended.

All of this can be simplified:

$Collection = Get-ChildItem -Path 'D:\APPS\Server*' -Filter '*.dat' -Recurse |
                Where-Object { $_.LastWriteTime -lt (Get-Date).AddMinutes(-3) } |
                ForEach-Object {
                  Write-Host 'This file is older than 3 minutes: {0}' -f $_.FullName
                  Write-Host 'The LastWriteTime is: {0}' -f $_.LastWriteTime
                  Return $_.FullName
                }

At the end of the command, your array will be stored in $Collection

Upvotes: 0

Bryce McDonald
Bryce McDonald

Reputation: 1870

You look to be mistakenly calling "OldDats" instead of "Element" in your ForEach loop. The code should look like this:

ForEach ($element in $oldDats){

    $FileDate = $element.LastWriteTime
    write-host "The files that are 3 minutes old are: $element the 
LastWriteTime is: $FileDate"}

When you are running your ForEach loop, the $oldDats is referring to the entire array, where as $element is referring to just the individual item this loop around in the array. Hope that helps!

Upvotes: 2

Related Questions