Search code examples
powershellget-childitem

Improve Get-ChildItem funtion


I have the following script that searches a large directory for random files matching specific parameters. The script is very inefficient and has several Get-ChildItem requests. I know there must be a better way to do this, perhaps by piping instead of multiple separate Get-ChildItem requests.

#begin random image pull for set1

#find MAIN images within date range
$set1Images = GCI $archive -recurse -include @("*MAIN*jpg") -exclude ("*Silhouette*") | 
    Where-Object {($_.LastWriteTime -ge $dateRangeBegin -and $_.LastWriteTime -le $dateRangeEnd -and $_.FullName -like "*\A6*") -or ($_.LastWriteTime -ge $dateRangeBegin -and $_.LastWriteTime -le $dateRangeEnd -and $_.FullName -like "*\A8*")} |
        Get-Random -Count $count
            $set1Images | Copy-Item -Destination $set1
                Write-Host 'these are your images:' $set1Images -ForegroundColor Green



#begin random image pull for set2

#find MAIN images within date range
$set2Images = GCI $archive -recurse -include @("*MAIN*jpg") | 
    Where-Object {($_.LastWriteTime -ge $dateRangeBegin -and $_.LastWriteTime -le $dateRangeEnd -and $_.FullName -like "*\C*")} |
        Get-Random -Count $count
            $set2Images | Copy-Item -Destination $set2
                Write-Host 'these are your images:' $set2Images -ForegroundColor Green



#begin random image pull for set3

#find MAIN images within date range
$set3Images = GCI $archive -recurse -include @("*MAIN*jpg") | 
    Where-Object {($_.LastWriteTime -ge $dateRangeBegin -and $_.LastWriteTime -le $dateRangeEnd -and $_.FullName -like "*\D*")} |
        Get-Random -Count $count
            $set3Images | Copy-Item -Destination $set3
                Write-Host 'these are your images:' $set3Images -ForegroundColor Green

Can anyone help me come up with a clever way to reduce the number of Get-Childitem requests while still achieving the same goal of pulling random files meeting the parameters for each set?


Solution

  • If it is performance you are after, the quick and dirty is to do one full Get-ChildItem with the date range filtering, into a variable. Once you have the information in a variable, you can then perform the 3 separate queries against the variable which is in RAM and therefore will perform much faster. e.g.

    #Find ALL MAIN images within date range
    $AllImages = GCI $archive -Recurse -include @("*MAIN*jpg") | 
        Where-Object {($_.LastWriteTime -ge $dateRangeBegin -and $_.LastWriteTime -le $dateRangeEnd)
    
    #find MAIN images within date range not like '*Silhouette*'
    $set1Images = $AllImages | 
        Where-Object { $_.FullName -notlike '*Silhouette*' -and ($_.FullName -like "*\A6*" -or $_.FullName -like "*\A8*")} |
            Get-Random -Count $count
                $set1Images | Copy-Item -Destination $set1
                    Write-Host 'these are your images:' $set1Images -ForegroundColor Green
    
    #begin random image pull for set2
    
    #find MAIN images within date range
    $set2Images = $AllImages | 
        Where-Object { $_.FullName -like "*\C*" } |
            Get-Random -Count $count
                $set2Images | Copy-Item -Destination $set2
                    Write-Host 'these are your images:' $set2Images -ForegroundColor Green
    
    #begin random image pull for set3
    
    #find MAIN images within date range
    $set3Images = $AllImages | 
        Where-Object { $_.FullName -like "*\D*" } |
            Get-Random -Count $count
                $set3Images | Copy-Item -Destination $set3
                    Write-Host 'these are your images:' $set3Images -ForegroundColor Green