powershellmultiple-conditionsfile-search

Advance file search with powershell


I'm fairly new to Powershell and programming in general. I want to search files using Powershell having multiple conditions. I have managed to write this code

$Drives = Get-PSDrive -PSProvider 'FileSystem' 
$Filename= 'Result'
$IncludeExt= '*csv,*docx'
$StartDate= '11/1/20'
$EndDate= '1/26/21'

Get-ChildItem -Path $Drives.Root -Recurse  |Where-Object {$IncludeExt -match $_.Extension} |  Where-Object { $_.BaseName -match $Filename}  | Where-Object {$_.lastwritetime -ge $StartDate -AND $_.lastwritetime -le $EndDate} |

foreach{ 
$Item = $_.Basename
$Path = $_.FullName 
$Type = $_.Extension
$Age = $_.CreationTime


$Path | Select-Object `
    @{n="Name";e={$Item}},`        
    @{n="Created";e={$Age}},`
    @{n="filePath";e={$Path}},`
    @{n="Folder/File";e={if($Folder){"Folder"}else{$Type}}}` 

}| Export-Csv D:\FFNew.csv -NoTypeInformation

This works well when the all variables are mentioned. But how do I get this to work when

Case1: If $Filename is empty then it gives all the files with the mentioned extensions and files modified in Range of dates

Case2: If $IncludeExt is left empty then it gives all files with the $Filename mentioned, currently it gives only the folders and files modified in Range of dates

Case 3: If $Filename and $IncludeExt is left empty it gives all the files modified between the $StartDate and $EndDate


Solution

  • Pranay,

    [EDITED] Ok, here's the revised (exact) script with notes and sample output. Note: you'll have to change the items that are specific to my machine!

    $Drives     = Get-PSDrive -PSProvider 'FileSystem' 
    $Filename   = "*" #for all or "*partial name*"
    $IncludeExt = $Null #for no ext. or "*.csv","*.docx",etc...
    $StartDate  = '01/1/2020' #to ignore this use 1/1/1920
    #For latest date use below otherwise specify date.
    $EndDate    = (Get-Date).ToShortDateString() 
    
    #Note: below uses only 3rd drive in the array remove [2] for all.
    $GCIArgs = @{Path    = $Drives[2].Root
                 Recurse = $True
                }
    
    If ($Null -ne $IncludeExt) {
      $GCIArgs.Add("Include",$IncludeExt)
    }
    
    Get-ChildItem @GCIArgs   |
      Where-Object {($_.BaseName -Like $Filename)     -and 
                    ($_.lastwritetime -ge $StartDate) -and
                    ($_.lastwritetime -le $EndDate) } |
    
    foreach{ 
    
    $Item = $_.Basename
    $Path = $_.FullName 
    $Type = $_.Extension
    $Type = & {if($_.PSIsContainer){"Folder"}else{$_.Extension}}
    $Age  = $_.CreationTime
    
    
    $Path | Select-Object @{n="Name"       ;e={$Item}},        
                          @{n="Created"    ;e={$Age}} ,
                          @{n="filePath"   ;e={$Path}},
                          @{n="Folder/File";e={$Type}}  
     }  | Export-Csv -LiteralPath 'G:\BEKDocs\FFNew.csv' -NoTypeInformation 
    
    

    Notes:

    1. $IncludeExt is specified as $Null if it is not used and if used the list is like this ".csv",".docx"
    2. $Filename is specified as "*" for all filenames. Also changed the test from -match to -like so partial filenames should include *, e.g. "partial name".
    3. Notice I changed the location of the check for Extensions to use the -Include parameter of the Get-ChildItem vs checking in the Where-Object.
    4. Changed the piping of data to successive Where-Object clauses and replaced with -and operator, same effect and more efficient.
    5. Changed the test for Directories to use the PSIsContainer property, couldn't see where you were getting the value for $Folder.
    6. Removed the continuation characters from the Select-Object as the comma serves that purpose and is cleaner.

    Sample output on Single drive (per code shown above) with some lines hidden for space considerations but notice the last line number. enter image description here

    Sample output on all drives (code edited as per comment in code), again lines hidden for space but showing multiple drives and final line number. enter image description here HTH