Estimating Folder Usage With PowerShell

This is an alternative to relying purely on the “date modified” of a directory. Offering a range for minimum/maximum age gives a small insight into how a directory is actually being used.

Issue

In my environment, there’s a particularly well used network drive that 2 levels down suddenly gets really wide. The width is attributed to teams and individuals creating new folders for different projects, or yearly iterations of projects. I suspect this isn’t a rare situation!

We were looking for a better handle on management of this area, ideally a quick way to estimate folder usage. That way, rarely used and older directories could be archived/removed. However, it’s not always obvious at first glance which directories are both old and rarely used. Some of our directories were created many years ago, but further down in them are still being used on an almost daily basis.

Approach

By finding the newest and oldest write/create times of files in a directory, we can then also calculate a minimum/maximum age range for the directory as a whole. I liked this approach because the size of the range itself also adds valuable information.  For instance, we found that some directories with content created over 7 years ago, were written to within the last few days. In contrast, there were also directories created a year ago, that appeared to have only been used for a period of 2 weeks.

I’m sure there are more accurate and in depth ways to estimate the usage of directories, but this approach yielded lots of useful information for very little time spent obtaining it.

Code

function Get-FolderAge {
  param(
    $Path = $pwd,
    [switch]$Recurse
  )

  if ($Recurse) {
    $Items = Get-ChildItem -Path $Path -Recurse
  }
  else {
    $Items = Get-ChildItem -Path $Path
  }

  $byCreateTime = $Items | sort -Property creationTime
  $byWriteTime = $Items | sort -Property lastWriteTime

  # items will be sorted in ascending order, so first will be oldest (max age) and last will be youngest (min   age)
  $Age = New-Object psobject -Property @{
    "Path" = $Path;
    "OldestCreateTime" = ($byCreateTime | select -First 1).creationTime;
    "OldestWriteTime" = ($byWriteTime | select -First 1).lastWriteTime;
    "NewestCreateTime" = ($byCreateTime | select -Last 1).creationTime;
    "NewestWriteTime" = ($byWriteTime | select -Last 1).lastWriteTime;
  }

  # figure out age range in days
  $ranges = @()
  $now = Get-Date
  foreach ($propName in $Age | Get-Member -MemberType NoteProperty) {
    if ($Age.$($propName.Name) -is [datetime]) {
      $ranges += New-TimeSpan -Start $Age.$($propName.Name) -End $now
    }
  }

  $Age | Add-Member -MemberType NoteProperty -Name MinimumAge -Value ($ranges | sort | select -First 1).Days
  $Age | Add-Member -MemberType NoteProperty -Name MaximumAge -Value ($ranges | sort | select -Last 1).Days

  Return $Age
}