As you might imagine, I work on a lot of different files throughout the week. Sometimes it is hard to keep everything straight. I'll want to return to script I was working on yesterday, but I can't remember what I called it. So I spend a few minutes searching and filtering until I find it. That takes too long. So why not create a simple PowerShell tool and load it into my profile?
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
First, I need a date to filter with. I want to find all files that were last modified yesterday.
$y = (Get-Date).AddDays(-1).Date
If I just used the AddDays method, I would get exactly 24 hours from now, including the time. But I want since midnight. That's what the Date property gets me. The value of $y is something like Thursday, March 19, 2015 12:00:00 AM. Now it is a simple matter of getting a directory listing and filtering with this date.
dir -file | where {$_.lastwritetime -ge $y} | Sort LastWriteTime
I need to make sure I sort the results but do so at the end so that PowerShell is sorting the filtered results.
Naturally I don't want to have to type that all the time. So here is a function to do the work for me.
#requires -version 3.0 Function Get-RecentFile { [cmdletbinding()] Param( [Parameter(Position=0)] #make sure path exists and it belongs to the FileSystem provider [ValidateScript({ if ((Test-Path -path $_) -AND ((Resolve-Path -path $_).Provider.Name -eq "FileSystem")) { $True } else { Throw "Verify path exists and is a FileSystem path." } })] [string]$Path = ".", [ValidateScript({$_ -ge 0})] [int]$Days = 1, [ValidateNotNullorEmpty()] [DateTime]$Since = (Get-Date).AddDays(-$Days).Date, [int]$Newest, [ValidateNotNullorEmpty()] [string]$Filter = "*" ) Write-Verbose -Message "Starting $($MyInvocation.Mycommand)" #get a full path path for verbose messages $Path = Resolve-Path -Path $Path Write-Verbose -Message "Getting files [$filter] from $path since $($Since.ToShortDateString())" #sort last $files = Dir -path $Path -filter $Filter -File | where {$_.LastWriteTime -ge $Since} | Sort LastWriteTime if ($Newest) { Write-Verbose -message "Getting $newest newest files" $files | Select-Object -last $Newest } else { $files } Write-Verbose -Message "Ending $($MyInvocation.Mycommand)" } #end function #define an optional alias Set-Alias -Name grf -Value Get-RecentFile
I set the default to find all files in the current folder last modified since yesterday. I also added an option to limit the results to the newest X number of files. My scripts folder has 10 years-worth of files so this is very helpful.
grf -Days 30 -filter *.txt -Newest 3
I even created an alias.
By the way, if you set the Days parameter to 0 you'll get files modified today. It also makes it easy to see what I've been working on.
get-recentfile -days 30 | group extension
I want to point out one other feature that you might find useful in your scripts. You'll notice that I use parameter validation a lot. If a validation test fails, PowerShell throws an exception. But sometimes you may want something a bit more elegant. In this function, I wanted to validate that the path existed and that it was a FileSystem path. A path like HKLM: would test as True but be invalid for the function's purpose.
Here's the validation attribute:
[ValidateScript({ if ((Test-Path -path $_) -AND ((Resolve-Path -path $_).Provider.Name -eq "FileSystem")) { $True } else { Throw "Verify path exists and is a FileSystem path." } })]
When you use ValidateScript, the scriptblock must return $True or $False. If it is $False then you get the typical exception. In this case, if the path passes my tests I can tell PowerShell it is OK ($True) and the function proceeds. But if the path fails my test I'm going to write my own error message.
As is often the case in PowerShell you have to consider who will be using your tools or script and how will they respond to errors.
The only thing I haven't done is include any comment based help, so I'll leave that to you. Enjoy!