Powershell: set .msg file date to date the mail was created.

Answered Powershell: set .msg file date to date the mail was created.

  • Sunday, February 03, 2013 9:25 PM
     
     
    Kind people.
    I've looked here: 
    And here:
    What I want is to drop & drag a message from Outlook to the filesystem.
    Next a powershell script which changes the creationdate of the file (in the explorer shown in the column [Date modified])
    to the date when the mail was made.
    I pinched the code from:
    Which in itself works well.
    And turned it into this:
    $olMailItemPath = "C:\msg\*"

      Write-Host $olMailItemPath
    $x =0
    $SourceFolders = Get-Item $olMailItemPath
    echo $SourceFolders . count
    $outlook = New-Object -comobject outlook.application
    $namespace = $outlook. GetNamespace( "MAPI")
     
    foreach ($_ in $SourceFolders )
        {
        $SourceFolder = $_
        Write-Host "SourceFolder is $SourceFolder "
        $SourceFiles = Get-ChildItem -path $SourceFolder -recurse -include *.msg    
        $SFCount = $SourceFiles. count
        Write-Host "Source File Count is $SFCount "
        $objDraftFolder = $outlook. Session .GetDefaultFolder( $olFolderDrafts )
        $objDeletedFolder = $outlook. Session .GetDefaultFolder( $olFolderDeletedItems )
        $colItems = $objDraftFolder. Items
        $FolderItemCount = $colItems. Count

        foreach ($_ in $SourceFiles )
            {
            $x ++
             Write-Host $x
            $MailItem = $_
             Write-Host "Mail Item is $MailItem "
            $olMailItem = $NameSpace. OpenSharedItem( $MailItem)
            $DateRecieved = $olMailItem. ReceivedTime
             Write-Host "Date Recieved is $DateRecieved "
            $Mailitem .CreationTime = $DateRecieved    # To show up in explorer (in column Date modified)
            }
        }
     

    Now wat bothers me is the last three lines i added.
    The last line invariable gives me: 
    Exception setting "CreationTime": "The process cannot access the file 'C:\msg\concrats.msg' because it is being used by another process." 
    This stomps me. Please help.
    Kind regards, Ad Weterings.



     

     


    WHS owner

All Replies

  • Sunday, February 03, 2013 10:08 PM
     
     

    You cannot change the creation time of a maiil message in Outlook.  Outlook owns the iitems and controls the dates.   Chnaging the message creation time would be problematic to Outlook.


    ¯\_(ツ)_/¯

  • Monday, February 04, 2013 11:27 AM
     
     

    The answer is in the error message: The other process is Outlook itself. Close Outlook after you droped the mailmessage into the filesystem.

    Regards

    Bernd

  • Monday, February 04, 2013 11:58 AM
    Moderator
     
     

    Use a regular expression (via select-string or get-content and -match) to find the creation time stamp in the msg file, and then use rename-item to change the file name.

    see

    get-help about_regular_expressions

    get-help about_comparison_operators

    get-help about rename-item

    Edit: 

     I think I misread the question.  After you get the creation time, you can set the modified time of the file by:

    $file = get-childitem <path to file>

    $file.lastwritetime = <creation timestamp of message>




    [string](0..33|%{[char][int](46+("686552495351636652556262185355647068516270555358646562655775 0645570").substring(($_*2),2))})-replace " "


  • Monday, February 04, 2013 5:41 PM
     
     

    Unfortunately what is missed here is that the OP is trying to change the creation time and not the time modified s stated.  

    See this:

    foreach ($_ in $SourceFiles )
            {
            $x ++
             Write-Host $x
            $MailItem = $_
             Write-Host "Mail Item is $MailItem "
            $olMailItem = $NameSpace. OpenSharedItem( $MailItem)
            $DateRecieved = $olMailItem. ReceivedTime
            Write-Host "Date Recieved is $DateRecieved "

            $Mailitem .CreationTime = $DateRecieved    # To show up in explorer (in column Date modified)
            }
        }

    the OP is also using Shell methods which my create conflicts.

    The code as posted cannot perform as desired due to a lack of understanding of the different between mail items and file items.  Outlook being open seems to never enter the picture.

    Either there is code missing or this script is unworkable.


    ¯\_(ツ)_/¯

  • Monday, February 04, 2013 6:11 PM
     
     

    The following lines are illegal and will not work:

    foreach($_ in $SourceFolders )
        {
        $SourceFolder = $_

    There is also a lot of adde4d spces throughout the code in places that will cause errors.


    ¯\_(ツ)_/¯


  • Monday, February 04, 2013 6:50 PM
     
      Has Code

    This bit of code:

        foreach($file in $SourceFiles){
             Write-Host "Mail Item is $file"
            $olMailItem = $NameSpace.OpenSharedItem($MailItem)
            $DateRecieved = $olMailItem.ReceivedTime
             Write-Host "Date Recieved is $DateRecieved "
            $file .CreationTime = $DateRecieved    # To show up in explorer (in column Date modified)
            }
        }

    seems to be trying to match a mail item with a file.  I see no matching.  The code enumerates the files and uses the file name to open the mail item. I see no way this can work.  I also see no reason to open the item  The timesstamps on an Outlook mail item are on the mailitem object and can be read without opening the item.

    I see no way any of this code can every have executed on any system.


    ¯\_(ツ)_/¯

    Thank you for looking at it so thoroughly.

    The original code is here:

    http://nukeitmike.com/blog/2012/07/17/import-msg-files-into-outlook-using-powershell/

    An I added the lines:

           $DateRecieved= $olMailItem. ReceivedTime
            Write-Host"Date Recieved is $DateRecieved"

           $Mailitem.CreationTime =$DateRecieved   # To show up in explorer (in column Date modified)

    So yes, i'm trying to get Outlook properties into the  file properties.

    Using the outlook related stuff (which i need to get the .RecieveTime),
    seems to lock the file which contains the .msg.

    So the question remains: how to go about it, something like this:??

    1. Remember filename with the correct time.

    2. Close everything. Clean up the objects.

    3. Open the file again (i have the filename now), and then set the .CreationTime of the file ?

    Seems a bit roundabout: i hoped to get rid of the lock outlook holds over this .msg file.


    I don't care i am a lemming. I-am-NOT-going.

  • Monday, February 04, 2013 6:59 PM
     
     

    One more thing:

    You do not really need to repair this code.

    What i'm looking for is:

    How do i set the date of the .msg file to the date the mail was send ?

    (Because otherwise it is the date of when the .msg file was created, which is of no interest to me, the other thing is.)


    I don't care i am a lemming. I-am-NOT-going.

  • Monday, February 04, 2013 7:02 PM
     
     Answered Has Code

    One thing to note is that when draging and dropping a mail item teh file name will be the subject + ".msg".   This will not match the mail item in Outlook.

    Dropping a mail file into a folder does NOT leave the file open in Outlook and it is avaiable for update.  The real issue here is that none of the code is functional. 

    When we use OPenSharedItem to open an external file the item must be closed.  This is accomplished by using the 'Close' method of the item.

    If this code is run numerous times it will leave a possible corrup copy of Outlook running which wil keep all files touched locked until the Outlook instance is killed.  It will be invisible outside of teh Task Manager.

    Here is a method for opening the files, getting the timestamp,closing the file then updating the file timestamp.  The script also correctly shuts outlook down.

    $SourceFolder='e:\test2\msg\*'
    $outlook = New-Object -comobject outlook.application
    $namespace = $outlook.GetNamespace('MAPI')
     
    # release references to COM object so it can close
    function ReleaseComObject($comobject){
        $ret=1
         do{
              $ret=[System.Runtime.Interopservices.Marshal]::ReleaseComObject($comobject)
         }while($ret -ne 0)
    }
     
    Write-Host "SourceFolder is $SourceFolder "
    $SourceFiles=Get-ChildItem -path $SourceFolder -recurse -include *.msg    
    Write-Host "Source File Count is $($SourceFiles.count)"
    foreach($file in $SourceFiles){
        Write-Host "Mail Item is $file"
        $mailItem=$NameSpace.OpenSharedItem($file)
        $DateRecieved=$mailItem.ReceivedTime
        Write-Host "Date Received is $DateRecieved"
        $mailItem.Close(1)
        ReleaseComObject $mailItem
        $file.LastWriteTime=$DateRecieved
    }
    ReleaseComObject $namespace
    $outlook.Quit()
    ReleaseComObject $outlook

    Outlook issues like this are much better solved by posting in the Outlook Developers forum.  Once you have a solution in C# or VB.Net it can be converted into PowerSHell more easily although many Interop bits will have to be learned by experience.

    If you are dragging and dropping from Outlook then it seems to me that placing the code into Outlook as VBA would be best.  Trap the drop and change the date when the file is dropped.  No need for an external script.


    ¯\_(ツ)_/¯


  • Wednesday, February 06, 2013 7:16 PM
     
     

    this does the trick. Thank you jrv.

    Now on to setting a whole slew of other properties...


    I don't care i am a lemming. I-am-NOT-going.