Search code examples
powershelloperator-precedence

Prioritizing "$_.Name" over "$_.LastAccessTime"


I created a script that allows me to search for and ignore directories from a Remove-Item statement, and the script works, but not necessarily to the extent I need it to.

Get-ChildItem -Path $Path |
  Where-Object {
    ($_.LastAccessTime -lt $Limit) -and
    -not ($_.PSIsContainer -eq $True -and $_.Name -contains ("2013","2014","2015"))
  } | Remove-Item -Force -Recurse -WhatIf

This script is currently finding and deleting all objects that

  1. Have not been accessed in the given time period

But what I need this script to do is find and delete all objects that

  1. Have not been accessed in the given time period AND
  2. Exclude directories that contain the name of "2013", "2014", or "2015".

I'm not arguing that the script "isn't working properly", but the thesis of my question is this:

How do I program this script to look at the directory name first, and then the last access date? I don't know where and how to tell this script that the $_.Name needs to take precedence over the $_.LastAccessTime -lt $Limit.


Solution

  • Currently the logic of your condition is this:

    Delete objects that were last accessed before $Limit and are not folders whose name contains the array ["2013","2014","2015"].

    The second condition is never true, because a string can never contain an array of strings.

    Also, the last modification time is stored in the LastWriteTime property.

    What you actually want is something like this:

    Where-Object {
      $_.LastWriteTime -lt $Limit -and
      -not ($_.PSIsContainer -and $_.Name -match '2013|2014|2015')
    }
    

    If the directory names consist only of the year and nothing else you could also use this:

    Where-Object {
      $_.LastWriteTime -lt $Limit -and
      -not ($_.PSIsContainer -and '2013','2014','2015' -contains $_.Name)
    }
    

    Note the reversed order of the last clause (array -contains value).