The content of this document may be incorrect or outdated.
Print this article Edit this article
Office 2007 upgrade & autoarchive problems
Synopsis of problem:
Autoarchive quits working on users' mailboxes "all of a sudden". Investigation reveals that all messages have a single modified timestamp that does NOT coincide with an actual time of response or forwarding. Autoarchiving starts functioning as advertised *PAST* the modification timestamp. Manual archive does not work either, because it is based on the same settings.
Synopsis on how autoarchive works:
Autoarchive looks at the modify timestamp (found under "message properties") of each message. If the modify date is prior to the autoarchive date, the message is moved out from the active mailbox to the user's set archive pst file.
Presumably, the rationale of having modify vs. created/received date is that it updates the modified-stamp if you reply to or forward an old message, thereby keeping it "active".
Potential (conjectured) cause:
We suspect that when Office gets upgraded from one version to the other, it upgrades the .ost file from one format to the next. Updating the ost file probably resets the modify date on every message. Once you go online, it probably updates the main message store with the "new" modify timestamp, and therefore breaks autoarchive. Pst files work a bit differently than ost- pst updates do NOT change modify time, but ost updates do.
Another newly discovered interaction has to do with McAfee AV potentially scanning and touching modify time of certain messages.
Potential solution*:
When upgrading Outlook users' laptops- try to disable offline folders first. This requires a restart of Outlook. Then upgrade Outlook, then enable offline folders again... see if this avoids the problem to begin with. Again, those steps are:
1. Open Outlook, old version.
2. Disable offline folders and/or cached exchange mode if enabled.
3. Close outlook, wait 15 sec, reopen Outlook, wait 15 sec, close Outlook.
4. Upgrade.
5. Open Outlook, enable offline folders and/or cached exchange mode, have the user wait for the ost to populate.
*: This solution has not even been tried, let alone tested, but it seems to me that this is one of the only ways to work around the limitations.
Of course, given that we cannot predict who this will happen to, it is a lot of work to go through, with not very much to show for it after the fact.
Update:
As of June 13th, 2008, we are working on a script that will allow autoarchive based on receive date instead of modify date. More information as we proceed.
As of July 9th, 2008, we have a script that will allow autoarchiving of 1500 items or less based on receive date. More testing to follow.
As of November 3rd, our script is still unable to break the 1500 item barrier, active work on this script has been shelved until a later date.
As of November 18th, 2008, a breakthrough! We will post a copy of the script here shortly.
This script is intended to be run on NON-ECN MACHINES ONLY! This script is provided AS-IS as-is, with no implied warranty... Do not redistribute without the copyright notice at the header. If this script does what you need it to do, please drop us a thank-you email saying so!!
If you are using an ECN supported machine, please contact your site specialist instead of using this script.
Contents of script file ArchiveOutlookByReceivedDate.vbs
'
' This script scans through the Outlook mailbox,
' and moves items to the archive based on Received date.
'
'-------------------------------------------------------------------
'
' Copyright 2008, Purdue University, West Lafayette, Indiana, USA
'
' Author: Rex Bontrager
' Creation date: 2008 June 03
'
'-------------------------------------------------------------------
option explicit
RunWithCScript
Const olFolderCalendar = 9
Const olFolderContacts = 10
Const olFolderDeletedItems = 3
Const olFolderDrafts = 16
Const olFolderInbox = 6
Const olFolderJournal = 11
Const olFolderNotes = 12
Const olFolderOutbox = 4
Const olFolderSentMail = 5
Const olFolderTasks = 13
Const olPublicFoldersAllPublicFolders = 18
const iPrimaryExchangeMailbox = 0
Dim OutlookApp : Set OutlookApp = CreateObject("Outlook.Application")
CheckVersion
Dim myNameSpace : Set myNameSpace = OutlookApp.GetNamespace("MAPI")
Dim Mailboxes : Set Mailboxes = myNameSpace.Folders 'same as Stores
dim Stores : Set Stores = OutlookApp.Session.Stores 'same as Mailboxes
dim Store, oFrStore, oToStore, sFr, sTo, CutoffDate, gMoveCnt, BeforeCnt, rc1, rc2
dim olExchangeStoreType
olExchangeStoreType = array("PrimaryExchangeMailbox", _
"ExchangeMailbox", _
"ExchangePublicFolder", _
"NotExchange")
'--set defaults
sFr = ""
sTo = ""
CutoffDate = SetCutoffDate("6 months")
set oFrStore = nothing
set oToStore = nothing
'--parse args
if wscript.Arguments.Count>0 then sFr = wscript.Arguments(0)
if wscript.Arguments.Count>1 then sTo = wscript.Arguments(1)
if wscript.Arguments.Count>2 then CutoffDate = SetCutoffDate(wscript.Arguments(2))
if wscript.Arguments.Count>3 then Bomb "Too many arguments"
on error resume next
if sFr<>"" then set oFrStore=Stores(sFr)
rc1 = err.number
err.clear
if sTo<>"" then set oToStore=Stores(sTo)
rc2 = err.number
if rc1<>0 or rc2<>0 then
if rc1<>0 then say "Arg1 is not a valid mailbox: " & sFr
if rc2<>0 then say "Arg2 is not a valid archive store: " & sTo
say "Valid mailboxes/stores are:"
for each Store in Stores
say " " & Store.DisplayName
next
Bomb ""
end if
if not isDate(CutoffDate) then Bomb "Arg3 is not 'n days' or 'n months'"
on error goto 0
'--select defaults
if oFrStore is nothing or oToStore is nothing then
for each Store in Stores
with Store
'say ""
'say .DisplayName
'say "Application = " & .Application
'say "Class = " & .Class
'say "DisplayName = " & .DisplayName
'say "ExchangeStoreType = " & olExchangeStoreType(.ExchangeStoreType)
'say "FilePath = " & .FilePath
'say "IsCachedExchange = " & .IsCachedExchange
'say "IsDataFileStore = " & .IsDataFileStore
'say "IsInstantSearchEnabled = " & .IsInstantSearchEnabled
'say "IsOpen = " & .IsOpen
'say "Parent = " & .Parent
'say "PropertyAccessor = " & .PropertyAccessor
'say "Session = " & .Session
'say "StoreID = " & .StoreID
if (oFrStore is nothing) and .ExchangeStoreType=iPrimaryExchangeMailbox then
set oFrStore = Store
end if
if (oToStore is nothing) and .IsDataFileStore and inStr(Lcase(.DisplayName & .FilePath), "archive")>0 then
set oToStore = Store
end if
end with
next
end if
'--manually select
if oFrStore is nothing then
set oFrStore = SelectMailbox("Your ACTIVE MAILBOX could not be determined. Please select one:")
if oFrStore is nothing then
Bomb "Cannot determine your active mailbox -- terminating"
end if
end if
if oToStore is nothing then
set oToStore = SelectMailbox("Your ARCHIVE STORE could not be determined. Please select one:")
if oToStore is nothing then
Bomb "Cannot determine your archive store -- terminating"
end if
end if
'--confirm & process
if MsgBox("Ready to archive email that was received on or before " & FrmtDate(CutoffDate) & "." & vbLF & _
"Moving email from """ & oFrStore.DisplayName & """ to """ & oToStore.DisplayName & """" & vbLF & vbLF & _
"Continue?", vbYesNo, "Archive email?")=vbYes then
gMoveCnt = 0
do
BeforeCnt = gMoveCnt
DoTopFolder oFrStore.GetRootFolder, oToStore.GetRootFolder
say ">>> Total moved: " & gMoveCnt
loop until gMoveCnt=BeforeCnt
end if
'OutlookApp.Quit
set OutlookApp = nothing
'end main
sub DoTopFolder (oFrFolder, oToFolder)
if gMoveCnt=0 then
say ""
say "--------------------------------------------"
say " " & oFrFolder.Name
say "--------------------------------------------"
' say "addrbook=" & TopFolder.AddressBookName
' say "app =" & TopFolder.Application
' say "class =" & TopFolder.Class
' say "descrip =" & TopFolder.Description
' say "entryid =" & TopFolder.EntryID
' say "fldrpath=" & TopFolder.FolderPath
' say "inappfld=" & TopFolder.InAppFolderSyncObject
' say "name =" & TopFolder.Name
' say "parent =" & TopFolder.Parent
' say "session =" & TopFolder.Session
' say "storeid =" & TopFolder.StoreID
' say "unread =" & TopFolder.UnreadItemCount
end if
DoFolder oFrFolder.Folders("Inbox"), oToFolder, 1
end sub
sub DoFolder (oFrFolder, oToFolder, Level)
'
' oFrFolder is the "From" folder that is to be checked.
' oFrFolder changes with recursive invocations.
' oToFolder is the high-level destination folder that is
' to receive files and folders from oFrFolder.
' oToFolder is the same for all invocations.
' Level is the subpath depth in oFrFolder being
' processed.
'
dim subfolder, item, arItems, cnt, k
for each subfolder in oFrFolder.Folders
DoFolder subfolder, oToFolder, Level+1
next
'
' Since items are moved from the collection,
' we must collect all the candidate items
' before actually moving them. Otherwise,
' the collection loop gets messed up.
'
redim arItems(oFrFolder.Items.Count) 'index 1 = 1st item
cnt = 0
for each item in oFrFolder.Items
if isCandidate(item) then
cnt = cnt+1
set arItems(cnt) = item
end if
next
if cnt>0 then
say ">>> Folder """ & oFrFolder.Name & """ has " & oFrFolder.Items.Count & " items, moving " & cnt & " items"
end if
for k=1 to cnt
set item = arItems(k)
MoveItem oFrFolder, oToFolder, Level, item
next
end sub
function isCandidate (Item)
dim DT, Subj, rc, rs
on error resume next
''' .CreationTime
''' .ExpiryTime
''' .LastModificationTime
DT = Item.ReceivedTime
''' .ReminderTime
rc = err.number
rs = err.description
Subj = Item.Subject
on error goto 0
if rc<>0 or not isDate(DT) then
' say "Failed to get item's date, rc=" & rc & "=" & rs
' say " " & Subj
isCandidate = false
else
isCandidate = DT<CutoffDate
end if
end function
sub MoveItem (oFrFolder, oToFolder, Level, Item)
dim arFr, oTo, sLevelName, k
'--insure destination folder exists
set oTo = oToFolder
arFr = split(oFrFolder.FolderPath, "\")
for k=1 to Level
sLevelName = arFr(ubound(arFr)-Level+k)
on error resume next
oTo.Folders.Add sLevelName, olFolderInbox 'might already exist
on error goto 0
set oTo = oTo.Folders(sLevelName)
next
'--move item
gMoveCnt = gMoveCnt+1
say gMoveCnt & ": " & FrmtDate(Item.ReceivedTime) & " " & Item.Subject
on error resume next
Item.Move oTo
if err.number<>0 then
say " Move failed, rc=" & err.number & ": " & err.description
end if
on error goto 0
end sub
function SetCutoffDate (sInterval)
'
' sInterval can be "n days" or "n months". The space is optional.
' If valid, returns a DateValue. If invalid, returns null.
'
dim k, quan, unit
quan = 0
unit = ""
for k=1 to len(sInterval)
if not isNumeric(mid(sInterval,k,1)) then exit for
next
quan = left(sInterval,k-1)
unit = Lcase(left(trim(mid(sInterval,k)),1)) 'must be "d" or "m"
if isNumeric(quan) and (unit="d" or unit="m") then
SetCutoffDate = DateValue(DateAdd(unit, -CInt(quan), Now))
else
SetCutoffDate = null
end if
end function
function FrmtDate (Dval)
FrmtDate = right("0" & month(Dval),2) & "/" & right("0" & day(Dval),2) & "/" & year(Dval)
end function
function SelectMailbox (text)
dim indx, Store
set SelectMailbox = nothing
say text
indx = 0
for each Store in Stores
indx = indx+1
say indx & ": " & Store.DisplayName
next
wscript.StdOut.Write "Enter 1-" & Stores.Count & ": "
indx = wscript.StdIn.ReadLine
if isNumeric(indx) then
if CInt(indx)>=1 and CInt(indx)<=Stores.Count then
set SelectMailbox = Stores(CInt(indx))
end if
end if
end function
sub CheckVersion
dim ar
ar = split(OutlookApp.Version, ".")
if CInt(ar(0)) < 12 then
BombLine "This script requires Outlook 2007 or later"
wscript.quit 1
end if
end sub
sub RunWithCScript
'
' Insure that CScript (not WScript) is running
'
dim shell : set shell = CreateObject("wscript.shell")
dim sEngine : sEngine = mid(wscript.FullName,1+InStrRev(wscript.FullName, "\"))
dim sNewCmdLine, arg
if ucase(sEngine)="WSCRIPT.EXE" then
sNewCmdLine = """" & wscript.Path & "\CScript.exe"" //NoLogo """ & wscript.ScriptFullName & """"
for each arg in wscript.Arguments
sNewCmdLine = sNewCmdLine & " """ & arg & """"
next
shell.Run sNewCmdLine
wscript.Quit
end if
end sub
sub Bomb (text)
BombLine text
BombLine ""
BombLine "Syntax: " & wscript.ScriptName & " [mailboxName [archiveName [archiveAge]]]"
BombLine ""
BombLine " where"
BombLine " mailboxName = name of Outlook mailbox"
BombLine " archiveName = name of Outlook archive store"
BombLine " archiveAge = how old an item must be to be archived"
BombLine " (""n days"" or ""n months"")"
BombLine " (default = 6 months)"
OutlookApp.Quit
set OutlookApp = nothing
wscript.quit 1
end sub
sub BombLine (text)
wscript.StdErr.WriteLine wscript.ScriptName & ": " & text
end sub
sub say (text)
wscript.StdOut.WriteLine text
'wscript.StdErr.WriteLine text
end sub
Last Modified:
Aug 1, 2023 4:07 pm GMT-4
Created:
Jun 10, 2008 11:35 am GMT-4
by
admin
JumpURL: https://eng.purdue.edu/jump/b52c9