Rammy Charles
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.Appl ication")
Set objNamespace = objOutlook.GetNamespace("M API")
Set objFolder = objNamespace.GetDefaultFol der(olFold erDeletedI tems)
Set colItems = objFolder.Items
Set colFilteredItems = colItems.Restrict("[UnRead ] = True")
For i = colFilteredItems.Count to 1 Step - 1
If DateDiff("m", colFilteredItems(i).Receiv edTime, 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).Receiv edTime, Now) > 6 Then
+ ~
Missing '(' after 'If' in if statement.
At line:11 char:22
+ If DateDiff("m", colFilteredItems(i).Receiv edTime, Now) > 6 Then
+ ~
Missing expression after ','.
At line:11 char:23
+ If DateDiff("m", colFilteredItems(i).Receiv edTime, Now) > 6 Then
+ ~~~~~~~~~~~~~~~~
Unexpected token 'colFilteredItems' in expression or statement.
At line:11 char:22
+ If DateDiff("m", colFilteredItems(i).Receiv edTime, Now) > 6 Then
+ ~
Missing closing ')' in expression.
At line:11 char:60
+ If DateDiff("m", colFilteredItems(i).Receiv edTime, Now) > 6 Then
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordE xception
+ FullyQualifiedErrorId : MissingOpenParenthesisAfte rKeyword
Const olFolderDeletedItems = 6
Set objOutlook = CreateObject("Outlook.Appl
Set objNamespace = objOutlook.GetNamespace("M
Set objFolder = objNamespace.GetDefaultFol
Set colItems = objFolder.Items
Set colFilteredItems = colItems.Restrict("[UnRead
For i = colFilteredItems.Count to 1 Step - 1
If DateDiff("m", colFilteredItems(i).Receiv
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).Receiv
+ ~
Missing '(' after 'If' in if statement.
At line:11 char:22
+ If DateDiff("m", colFilteredItems(i).Receiv
+ ~
Missing expression after ','.
At line:11 char:23
+ If DateDiff("m", colFilteredItems(i).Receiv
+ ~~~~~~~~~~~~~~~~
Unexpected token 'colFilteredItems' in expression or statement.
At line:11 char:22
+ If DateDiff("m", colFilteredItems(i).Receiv
+ ~
Missing closing ')' in expression.
At line:11 char:60
+ If DateDiff("m", colFilteredItems(i).Receiv
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordE
+ FullyQualifiedErrorId : MissingOpenParenthesisAfte
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"
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I am still getting this error message when I try to run.
At line:4 char:50
+ $colItems = $objOutlook.Session.GetDef aultFolder (olFolderD eletedItem s).Items
+ ~
Missing ')' in method call.
At line:4 char:50
+ $colItems = $objOutlook.Session.GetDef aultFolder (olFolderD eletedItem s).Items
+ ~~~~~~~~~~~~~~~~~~~~
Unexpected token 'olFolderDeletedItems' in expression or statement.
At line:4 char:70
+ $colItems = $objOutlook.Session.GetDef aultFolder (olFolderD eletedItem s).Items
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordE xception
+ FullyQualifiedErrorId : MissingEndParenthesisInMet hodCall
At line:4 char:50
+ $colItems = $objOutlook.Session.GetDef
+ ~
Missing ')' in method call.
At line:4 char:50
+ $colItems = $objOutlook.Session.GetDef
+ ~~~~~~~~~~~~~~~~~~~~
Unexpected token 'olFolderDeletedItems' in expression or statement.
At line:4 char:70
+ $colItems = $objOutlook.Session.GetDef
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordE
+ FullyQualifiedErrorId : MissingEndParenthesisInMet
have you tried Powershell script ? which has given by Qlemo?
ASKER
yes, I have. It gives me the above error (see attached).
ASKER
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() }
ASKER
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?
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.
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() }
}
ASKER
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() }
}
}
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() }
}
ASKER
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: (:) [], ParentContainsErrorRecordE xception
+ FullyQualifiedErrorId : UnexpectedToken
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: (:) [], ParentContainsErrorRecordE
+ FullyQualifiedErrorId : UnexpectedToken
ASKER
Additionally, is there anyway to do this directly from the Exchange server rather than targeting the Outlook application?
ASKER
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.GetDef aultFolder ('OlFolder DeletedIte ms').Items
$olddate = (Get-Date).AddMonths(-1).T oShortDate String()
$colItems.Restrict("[UnRea d] = True AND [ReceivedTime] <= '$olddate'") |
% { $_.Delete() }
}
$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.GetDef
$olddate = (Get-Date).AddMonths(-1).T
$colItems.Restrict("[UnRea
% { $_.Delete() }
}
ASKER
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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.