Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to find files modified by month and year.
Microsoft Scripting Guy, Ed Wilson, is here. I will admit it. I am not the best computer user in the world. In fact, when it comes to finding things on the Internet, the Scripting Wife often is faster than I am. In my office, often the Scripting Wife sits beside me and does whatever she does. At times, I will ask her to find something that I have wasted 15 minutes seeking, and she can find it almost immediately.
A case-in-point is Windows Search. I modified the indexing to include the full contents of my Windows PowerShell script files, and it works great. However, one thing I have not figured out used to be very easy in the Windows 95 days by using the old-fashioned Find utility—that is to find a file by date.
Here is the situation…
When the Scripting Wife and I were in Montreal, Canada last October, I remember writing some additional Windows PowerShell labs for the class. In fact, I spent each day teaching the class, the evenings with friends, and the nights writing new labs for the coming day’s class. After spending 15 minutes attempting to browse and search for these files, I finally gave up. I was unable to find my new lab files.
Use Windows PowerShell to find files by date
OK, so maybe I am not the world’s greatest computer user, but I know Windows PowerShell really well. The neat thing is that because I do know Windows PowerShell so well, I can compensate. For example, to find my missing lab files, I use the Get-ChildItem cmdlet and search my Data directory. In addition, although I cannot remember if the files have a .doc or the newer .docx file extension, it really does not matter. Because my Data folder is deeply nested, I need to do a recursive search. The following command returns all .doc and .docx files from the Data directory on my computer.
Get-ChildItem -Path C:\data -Recurse -Include *.doc,*.docx
The next thing is that I know I modified the file during the month of October in the year of 2011. The cool thing is that the LastWriteTime property is an instance of a System.DateTime object. The following script illustrates this.
PS C:\> Get-Item C:\fso\a.txt | gm -Name lastwritetime
TypeName: System.IO.FileInfo
Name MemberType Definition
---- ---------- ----------
LastWriteTime Property System.DateTime LastWriteTime {get;set;}
Because the LastWriteTime property is an object, it means that it has a number of different properties. These properties are shown here.
PS C:\> (Get-Item C:\fso\a.txt).lastwritetime | gm -MemberType property
TypeName: System.DateTime
Name MemberType Definition
---- ---------- ----------
Date Property System.DateTime Date {get;}
Day Property System.Int32 Day {get;}
DayOfWeek Property System.DayOfWeek DayOfWeek {get;}
DayOfYear Property System.Int32 DayOfYear {get;}
Hour Property System.Int32 Hour {get;}
Kind Property System.DateTimeKind Kind {get;}
Millisecond Property System.Int32 Millisecond {get;}
Minute Property System.Int32 Minute {get;}
Month Property System.Int32 Month {get;}
Second Property System.Int32 Second {get;}
Ticks Property System.Int64 Ticks {get;}
TimeOfDay Property System.TimeSpan TimeOfDay {get;}
Year Property System.Int32 Year {get;}
Based on the information detailed above, I can easily look at the month and the year that file modifications took place. Therefore, I need to use the Where-Object to examine the month and year properties of each file. This is a perfect place to use the “double-dotted” notation. The first dot returns a System.DateTime object. The second dot returns a specific property from that DateTime object. The following code first returns the month the file was last written, and the second example returns the year that the file was modified.
PS C:\> (Get-Item C:\fso\a.txt).lastwritetime.month
5
PS C:\> (Get-Item C:\fso\a.txt).lastwritetime.year
2012
Extract the specific properties to examine
By using the “double-dotted” technique that I discussed in the previous section, I can easily return only the files modified during October 2011. The trick is to use the $_ automatic variable to reference the current item in the Windows PowerShell pipeline as I pipe FileInfo objects from the Get-ChildItem cmdlet to the Where-Object cmdlet. In addition, because I need to find files modified in October, but I also need to find files that were modified in 2011, I need to use a compound Where-Object, and I need to use the –AND operator. This is because I want files that were modified in the month of October AND in the year of 2011. I could look for files that were either modified in the month of October OR were modified in the year of 2011, but that would not give me what I need. So here is the Where-Object I need to use:
Where-Object { $_.lastwritetime.month -eq 10 -AND $_.lastwritetime.year -eq 2011 }
The complete command is shown here:
Get-ChildItem -Path C:\data -Recurse -Include *.doc,*.docx |
Where-Object { $_.lastwritetime.month -eq 10 -AND $_.lastwritetime.year -eq 2011 }
The command and the output associated with the command are shown in the image that follows.
The command is actually pretty fast. On my laptop, it takes a little more than six seconds to return the files I need. I used the following command to determine that bit of information:
PS C:\> measure-command {Get-ChildItem -Path C:\data -Recurse -Include *.doc,*.docx
? { $_.lastwritetime.month -eq 10 -AND $_.lastwritetime.year -eq 2011 }}
Days : 0
Hours : 0
Minutes : 0
Seconds : 6
Milliseconds : 147
Ticks : 61477502
TotalDays : 7.11545162037037E-05
TotalHours : 0.00170770838888889
TotalMinutes : 0.102462503333333
TotalSeconds : 6.1477502
TotalMilliseconds : 6147.7502
So how many files is that? Well, it is more than 46,000 files. The following command tells me that:
PS C:\> Get-ChildItem -Path C:\data -Recurse | Measure-Object
Count : 46425
Average :
Sum :
Maximum :
Minimum :
Property :
So what is my point?
If you get really good with Windows PowerShell, you improve more than just your system admin skills. Personally, I use Windows PowerShell every day; and these days, I do not do that much actual system administration. I love the Windows Search tool, and I am certain it could help me find files that I modified in October of last year. But it actually took me less than a minute to whip out the command, and it worked the very first time I ran it. Not only that, but the command is pretty fast as well. So given that I can find stuff in less than a minute, it does not really pay for me to spend hours trying to find out how to search by “date modified.” Windows PowerShell makes it easy. Join me tomorrow for more Windows PowerShell cool stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy