Finding the most recent modification date of all files/subfolders in all top-level directories of a share with PowerShell

I have a shared directory tree on a Windows 2003 file server that has about 100GB worth of data in it. I need to find all top-level directories in this share where the last modification time for every file in every subfolder hasn't been modified sine 1/1/11. Essentially, I'm looking for shares that are abandoned.

The directory structure looks something like this:

-a
--a1
--a2
--a3
----a3_1

-b
--b1
--b2

-c
--c1
----c1_1

etc

What I want to do is find out if everything that's not a hidden file under a or b or c has a mod date before or after 1/1/11.

So far, I can find the mod times after a year for each file with this:

get-childitem "\\server\h$\shared" -recurse | where-object {$_.mode -notmatch "d"} |
where-object {$_.lastwritetime -lt [datetime]::parse("01/01/2011")}

What I don't know how to do is check each top level directory individually to see if all of the files contained within it are older than a year. Any ideas?


Solution 1:

I think you're asking to look at only file modification times. Not sure what you want to do about folders, which only contain sub-folders that haven't been modified in a year. I'm also not sure if by "each top level directory", you mean a, b, c or a, a1, a2...

The following looks at all directories, and only list them if they do not contain files written within the past year. Let me know if this produces the output you're looking for:

$shareName = "\\server\share"
$directories = Get-ChildItem -Recurse -Path $path | Where-Object { $_.psIsContainer -eq $true }

ForEach ( $d in $directories ) { 
    # Any children written in the past year?
    $recentWrites = Get-ChildItem $d.FullName | Where-Object { $_.LastWriteTime -gt $(Get-Date).AddYears(-1) } 
    If ( -not $recentWrites ) {
        $d.FullName
    }
}

Edit, per your comment. If you want get just the top-level directories which do not contain files modified in the past year, try the following. Note that on very deep/large shares, this may take some time to run.

$shareName = "\\server\share"
# Don't -recurse, just grab top-level directories
$directories = Get-ChildItem -Path $shareName | Where-Object { $_.psIsContainer -eq $true }
ForEach ( $d in $directories ) { 
    # Get any non-container children written in the past year
    $recentWrites = Get-ChildItem $d.FullName -recurse | Where-Object { $_.psIsContainer -eq $false -and $_.LastWriteTime -gt $(Get-Date).AddYears(-1) } 
    If ( -not $recentWrites ) {
        $d.FullName
    }
}