Link to home
Start Free TrialLog in
Avatar of Rammy Charles
Rammy CharlesFlag for United States of America

asked on

PowerShell Script to Delete Unread Messages

I came across this script online that will delete all unread messages out of deleted items folder that are older than 6 months old.

Const olFolderDeletedItems = 6

 Set objOutlook = CreateObject("Outlook.Application")
 Set objNamespace = objOutlook.GetNamespace("MAPI")
 Set objFolder = objNamespace.GetDefaultFolder(olFolderDeletedItems)

 Set colItems = objFolder.Items
 Set colFilteredItems = colItems.Restrict("[UnRead] = True")

 For i = colFilteredItems.Count to 1 Step - 1
     If DateDiff("m", colFilteredItems(i).ReceivedTime, Now) > 6 Then
         colFilteredItems(i).Delete
     End If
 Next

However, I get the below error message when I try to run. Seems like a syntax issue but cannot sort it out. Any help would be appreciated.

At line:10 char:5
+  For i = colFilteredItems.Count to 1 Step - 1
+     ~
Missing opening '(' after keyword 'for'.
At line:11 char:8
+      If DateDiff("m", colFilteredItems(i).ReceivedTime, Now) > 6 Then
+        ~
Missing '(' after 'If' in if statement.
At line:11 char:22
+      If DateDiff("m", colFilteredItems(i).ReceivedTime, Now) > 6 Then
+                      ~
Missing expression after ','.
At line:11 char:23
+      If DateDiff("m", colFilteredItems(i).ReceivedTime, Now) > 6 Then
+                       ~~~~~~~~~~~~~~~~
Unexpected token 'colFilteredItems' in expression or statement.
At line:11 char:22
+      If DateDiff("m", colFilteredItems(i).ReceivedTime, Now) > 6 Then
+                      ~
Missing closing ')' in expression.
At line:11 char:60
+      If DateDiff("m", colFilteredItems(i).ReceivedTime, Now) > 6 Then
+                                                            ~
Unexpected token ')' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MissingOpenParenthesisAfterKeyword
Avatar of Qlemo
Qlemo
Flag of Germany image

This is VB Script code, no PowerShell ...
Agreed with Qlemo,

you need to use cscript to execute this VB script

save it as a .vbs format and run it from command prompt

CScript "C:\Name of the script file vbs"
SOLUTION
Avatar of Qlemo
Qlemo
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Rammy Charles

ASKER

I am still getting this error message when I try to run.

At line:4 char:50
+ $colItems = $objOutlook.Session.GetDefaultFolder(olFolderDeletedItems).Items
+                                                  ~
Missing ')' in method call.
At line:4 char:50
+ $colItems = $objOutlook.Session.GetDefaultFolder(olFolderDeletedItems).Items
+                                                  ~~~~~~~~~~~~~~~~~~~~
Unexpected token 'olFolderDeletedItems' in expression or statement.
At line:4 char:70
+ $colItems = $objOutlook.Session.GetDefaultFolder(olFolderDeletedItems).Items
+                                                                      ~
Unexpected token ')' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MissingEndParenthesisInMethodCall
have you tried Powershell script ? which has given by Qlemo?
yes, I have. It gives me the above error (see attached).
Small typo, but the script can be improved anyway, so:
$objOutlook = New-Object -Com Outlook.Application
$colItems = $objOutlook.Session.GetDefaultFolder('OlFolderDeletedItems').Items

$olddate = (Get-Date).AddMonths(-6).ToShortDateString()
$colItems.Restrict("[UnRead] = True AND [ReceivedTime] <= '$olddate'") |
  % { $_.Delete() }

Open in new window

Thanks. This seems to work great. However, I noticed that I had to runt it a few times to delete all of the unread emails older than 6 months. Seems like the script would quit before actually completing.

Also, to take this a step further, how can we execute this on a remote machine on the network or in the domain? I am assuming it would entail using the invoke-command?
The script itself has to run completely on the remote machine - there are no remote commands for any part of the script. So yes, you would have to run the script with Invoke-Command, which again requires you to have set up WinRM on each remote machine to allow connection and execution.
Client OS machines (W7 etc.) do not have WinRM set up by default, server OS do.
The manual way to enable WinRM is to run WinRM quickconfig once on each client.

The script might fail only because of one issue - the sequence of mails. Outlook is very delicate if you try to access moved or deleted mails in an order (that is the reason the VBS code starts with the last mail going towards the first one in the filter list).

This slight variation might help with that, and shows how to execute the code remotely.
Invoke-Command -Computer 'pc1', 'pc2'  -Script {
  $objOutlook = New-Object -Com Outlook.Application
  $colItems = $objOutlook.Session.GetDefaultFolder('OlFolderDeletedItems').Items

  $olddate = (Get-Date).AddMonths(-6).ToShortDateString()
  $filtered = $colItems.Restrict("[UnRead] = True AND [ReceivedTime] <= '$olddate'")
  $filtered |
    % { $_.Delete() }
  }

Open in new window

Thanks. It still looks like it is taking a few executions to get all of the messages. How can I have the script automatically run 3 or 4 times? Is there a way to loop the job "x" times?
In that case we should make it failsafe, similar to the original.
Invoke-Command -Computer 'pc1', 'pc2'  -Script {
  $objOutlook = New-Object -Com Outlook.Application
  $colItems = $objOutlook.Session.GetDefaultFolder('OlFolderDeletedItems').Items

  $olddate = (Get-Date).AddMonths(-6).ToShortDateString()
  $filtered = $colItems.Restrict("[UnRead] = True AND [ReceivedTime] <= '$olddate'")
  if ($filtered.Count)
  {
     foreach ($i in $filtered.count..1) { $filtered.Item($i).Delete() }
  }
}

Open in new window

This code could also work, as it processes a copy of the collation instead of the (changing) original collation of search results:
Invoke-Command -Computer 'pc1', 'pc2'  -Script {
  $objOutlook = New-Object -Com Outlook.Application
  $colItems = $objOutlook.Session.GetDefaultFolder('OlFolderDeletedItems').Items

  $olddate = (Get-Date).AddMonths(-6).ToShortDateString()
  $filtered = $colItems.Restrict("[UnRead] = True AND [ReceivedTime] <= '$olddate'")
  foreach ($mail in @($filtered) { $mail.Delete() }
}

Open in new window

Unfortunately neither of these scripts work.

This is the error message that I get

At line:6 char:34
+   foreach ($mail in @($filtered) { $mail.Delete() }
+                                  ~
Unexpected token '{' in expression or statement.
At line:6 char:33
+   foreach ($mail in @($filtered) { $mail.Delete() }
+                                 ~
Missing closing ')' after expression part of foreach loop.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnexpectedToken
Additionally, is there anyway to do this directly from the Exchange server rather than targeting the Outlook application?
So I tried executing the below script. It just hangs but does not execute on the remote PC. Any thoughts?

$ComputerName = Read-Host "Type he PC that you want to remove messages from:"
Invoke-Command -ComputerName $ComputerName -Credential (Get-Credential -Credential domain\user) -Script {
$objOutlook = New-Object -Com Outlook.Application
$colItems = $objOutlook.Session.GetDefaultFolder('OlFolderDeletedItems').Items

$olddate = (Get-Date).AddMonths(-1).ToShortDateString()
$colItems.Restrict("[UnRead] = True AND [ReceivedTime] <= '$olddate'") |
  % { $_.Delete() }
  }
I've requested that this question be closed as follows:

Accepted answer: 0 points for Narvaezj's comment #a40286827

for the following reason:

Closed due to lack of response
Sorry, didn't receive any notice about your posts.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial