Processing .EML files with Select-String and SetCreationTime()

PowerShell Team

PowerShell Team

In our newsgroup Microsoft.Public.Windows.PowerShell, Steve Foster asked whether PowerShell could help him with a bunch of emails in .EML format.  Here was his query:

Got a bunch of emails (.EML) that have been copied around various places
with the result that their file timestamps bear no resemblance to the
dates in the emails.

It would be really helpful to extract the date from the headers in the
emails, and update the timestamps on the files accordingly.

It strikes me that this would be the sort of thing PowerShell ought to be
really good at – but could it do the job? And if so, how?

Remember that old TV game show where the participants would guess how many notes it took to Name That Tune?  Well:

I can code that script in 2 lines!

foreach ($record in Select-String ^Date: *.eml) {
  [System.IO.File]::SetCreationTime($Record.Path, [datetime]($record.line.substring(6)))

Ok so I didn’t count the trailing “}” as a line – sue me!  🙂



There are 2 lessons to draw here:

1) Select-String is NOT grep.  Here is an example to drive home that point:

PS> Select-String ^Date: *.eml |Get-Member -MemberType Property

   TypeName: Microsoft.PowerShell.Commands.MatchInfo

Name       MemberType Definition
—-       ———- ———-
Filename   Property   System.String Filename {get;}
IgnoreCase Property   System.Boolean IgnoreCase {get;set;}
Line       Property   System.String Line {get;set;}
LineNumber Property   System.Int32 LineNumber {get;set;}
Path       Property   System.String Path {get;set;}
Pattern    Property   System.String Pattern {get;set;}

PS> Select-String ^Date: *.eml |format-list *

IgnoreCase : True
LineNumber : 4
Line       : Date: Tue, 21 Nov 2006 09:30:19 -0800
Filename   : t1.eml
Path       : D:\Temp\t1.eml
Pattern    : ^Date:

IgnoreCase : True
LineNumber : 4
Line       : Date: Sat, 09 July 2005 09:30:19 -0800
Filename   : t3.eml
Path       : D:\Temp\t3.eml
Pattern    : ^Date:

2) .NET ROCKS.  Ok so we didn’t get around to shipping a cmdlet to change the times on a filename.  .NET provides this so the fact that we can access .NET means that you are not stuck waiting for us.  In this example we are using a static method on PATH.  Here is how you find out what other statics are available on that class:

PS> [System.IO.File] |Get-Member -Static

   TypeName: System.IO.File

Name                 MemberType Definition
—-                 ———- ———-
AppendAllText        Method     static System.Void AppendAllText(String ..
AppendText           Method     static System.IO.StreamWriter AppendText..
Copy                 Method     static System.Void Copy(String sourceFil..
Create               Method     static System.IO.FileStream Create(Strin..
CreateText           Method     static System.IO.StreamWriter CreateText..
Decrypt              Method     static System.Void Decrypt(String path)
Delete               Method     static System.Void Delete(String path)
Encrypt              Method     static System.Void Encrypt(String path)
Equals               Method     static System.Boolean Equals(Object objA..
Exists               Method     static System.Boolean Exists(String path)
GetAccessControl     Method     static System.Security.AccessControl.Fil..
GetAttributes        Method     static System.IO.FileAttributes GetAttri..
GetCreationTime      Method     static System.DateTime GetCreationTime(S..
GetCreationTimeUtc   Method     static System.DateTime GetCreationTimeUt..
GetLastAccessTime    Method     static System.DateTime GetLastAccessTime..
GetLastAccessTimeUtc Method     static System.DateTime GetLastAccessTime..
GetLastWriteTime     Method     static System.DateTime GetLastWriteTime(..
GetLastWriteTimeUtc  Method     static System.DateTime GetLastWriteTimeU..
Move                 Method     static System.Void Move(String sourceFil..
Open                 Method     static System.IO.FileStream Open(String ..
OpenRead             Method     static System.IO.FileStream OpenRead(Str..
OpenText             Method     static System.IO.StreamReader OpenText(S..
OpenWrite            Method     static System.IO.FileStream OpenWrite(St..
ReadAllBytes         Method     static System.Byte[] ReadAllBytes(String..
ReadAllLines         Method     static System.String[] ReadAllLines(Stri..
ReadAllText          Method     static System.String ReadAllText(String ..
ReferenceEquals      Method     static System.Boolean ReferenceEquals(Ob..
Replace              Method     static System.Void Replace(String source..
SetAccessControl     Method     static System.Void SetAccessControl(Stri..
SetAttributes        Method     static System.Void SetAttributes(String ..
SetCreationTime      Method     static System.Void SetCreationTime(Strin..
SetCreationTimeUtc   Method     static System.Void SetCreationTimeUtc(St..
SetLastAccessTime    Method     static System.Void SetLastAccessTime(Str..
SetLastAccessTimeUtc Method     static System.Void SetLastAccessTimeUtc(..
SetLastWriteTime     Method     static System.Void SetLastWriteTime(Stri..
SetLastWriteTimeUtc  Method     static System.Void SetLastWriteTimeUtc(S..
WriteAllBytes        Method     static System.Void WriteAllBytes(String ..
WriteAllLines        Method     static System.Void WriteAllLines(String ..
WriteAllText         Method     static System.Void WriteAllText(String p..


Jeffrey Snover [MSFT]
Windows PowerShell/MMC Architect
Visit the Windows PowerShell Team blog at:
Visit the Windows PowerShell ScriptCenter at:

PowerShell Team
PowerShell Team

Follow PowerShell Team   

No Comments.