none
Filtering files across multiple drives will only select from last drive if I add a filter statement. RRS feed

  • Question

  • I am trying to write a script to do the following:

    1) list all type 3 logical disks

    2) For each type 3 logical disk, list all files recursively, filtering to exclude multiple paths, and filtered to only find files older than X days. 

    I have working code to list all items in any pre-specified path with all the filtering I want here:

    Get-ChildItem -recurse -path C:\ | Where-Object {($_.FullName -notlike 'C:\Windows\*') -and ($_.FullName -notlike 'c:\Program*\*') -and ($_.FullName -notlike 'C:\PerfLogs\*') -and ($_.FullName -notlike 'C:\Platform\*') -and ($_.FullName -notlike 'C:\Users\*\AppData\*')}  | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-5)} | where { !$_.PSisContainer }| select FullName, LastWriteTime, Length | Out-File C:\Temp\Files.txt

    I have a second line of working code that properly loops through all logical disks of type 3 and outputs *all* present files. 

    GET-WMIOBJECT –query "SELECT * from win32_logicaldisk where DriveType = '3'" | Select-Object -property DeviceID | ForEach-Object {Get-ChildItem -recurse -path $_.DeviceID} | where { !$_.PSisContainer } | select FullName, LastWriteTime, Length | Out-File C:\Temp\Files.txt

    Where I am having trouble is combining the two, if I add the filtering from line 1, it will output *nearly* what I want. In my instance, I have Drives C and E that match the criteria, and it will output the targeted contents of E, but nothing from C. I am unsure if it is either Ignoring drive C entirely, or if it is simply acting on the last item found in the wmi object query. Any help sticking these 2 lines together would be appreciated. 

    Here is my currently broken code:

    GET-WMIOBJECT –query "SELECT * from win32_logicaldisk where DriveType = '3'" | Select-Object -property DeviceID | ForEach-Object {Get-ChildItem -recurse -path $_.DeviceID | Where-Object {($_.FullName -notlike 'C:\Windows\*') -and ($_.FullName -notlike 'c:\Program*\*') -and ($_.FullName -notlike 'C:\PerfLogs\*') -and ($_.FullName -notlike 'C:\Platform\*') -and ($_.FullName -notlike 'C:\Users\*\AppData\*')}  | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-5)}} | where { !$_.PSisContainer } | select FullName, LastWriteTime, Length | Out-File C:\Temp\Files.txt

    Thanks in advance for any pointers!

    Tuesday, November 21, 2017 9:19 PM

Answers

  • You need to refrain from placing everything on one line.  It is impossible to read, hard to debug and serves no purpose. '

    $exclude = '^C:\\Windows\\|^c:\\Program.*\\|^C:\\PerfLogs\\|^C:\\Platform\\|^C:\\Users\\*\\AppData\'
    # '
    Get-WmiObject win32_logicaldisk -filter 'DriveType=3' | ForEach-Object { Get-ChildItem $_.DeviceID -File -recurse | Where-Object { $_.Fullname -notmatch $exclude -and $_.LastWriteTime -lt (Get-Date).AddDays(-5) } } | Select-Object FullName, LastWriteTime, Length | Out-File C:\Temp\Files.txt


    \_(ツ)_/




    • Edited by jrv Tuesday, November 21, 2017 9:45 PM
    • Marked as answer by Swat1234 Tuesday, November 21, 2017 10:04 PM
    Tuesday, November 21, 2017 9:44 PM

All replies

  • You need to refrain from placing everything on one line.  It is impossible to read, hard to debug and serves no purpose. '

    $exclude = '^C:\\Windows\\|^c:\\Program.*\\|^C:\\PerfLogs\\|^C:\\Platform\\|^C:\\Users\\*\\AppData\'
    # '
    Get-WmiObject win32_logicaldisk -filter 'DriveType=3' | ForEach-Object { Get-ChildItem $_.DeviceID -File -recurse | Where-Object { $_.Fullname -notmatch $exclude -and $_.LastWriteTime -lt (Get-Date).AddDays(-5) } } | Select-Object FullName, LastWriteTime, Length | Out-File C:\Temp\Files.txt


    \_(ツ)_/




    • Edited by jrv Tuesday, November 21, 2017 9:45 PM
    • Marked as answer by Swat1234 Tuesday, November 21, 2017 10:04 PM
    Tuesday, November 21, 2017 9:44 PM
  • This would be even faster:

    $exclude = 'Windows','Program*','PerfLogs','Platform'
    #' get-psdrive -PSProvider FileSystem | ForEach-Object { Get-ChildItem "$($_.root)\*" -File -recurse -Exclude $exclude| Where-Object { $_.Fullname -notmatch '^C:\\Users\\.*\\AppData\' #' -and $_.LastWriteTime -lt (Get-Date).AddDays(-5) } } | Select-Object FullName, LastWriteTime, Length | Out-File C:\Temp\Files.txt



    \_(ツ)_/



    • Edited by jrv Tuesday, November 21, 2017 9:59 PM
    Tuesday, November 21, 2017 9:58 PM
  • Thanks so much, I will avoid single line codes moving forward. 

    So it looks like I tripped up on escape characters then? 

    Tuesday, November 21, 2017 10:04 PM