DB25
Fresh Scripter
Registered: 2008-03-20
Posts: 14
|
Ok, this is what I have so far...what this does is:
close outlook copy the pst from location 1 to location 2
when you open outlook it asks for the path of the pst. - I need to have outlook automatically find the new location!! Once that is done it will be complete!!
Also for the relocate...I need to make the $newpstroot = \\server\share\and create the username folder to drop the pst in.
example... \\server\share\username\pstfile.pst
That would be \\server\share\ + @userid ???
Please help! I really appreciate it. Thanks!! :-)
Break On Dim $, $_ ; temp, throwaway var Dim $aPSTPaths[0] ; Array of PST paths Dim $aPSTKeys[0] ; Array of PST key paths Dim $RootPath ; registry root path Dim $WKey ; working key path Dim $EKey ; enumerated registry path Dim $TVal ; temp value for Dim $aIndex, $eIndex ; index pointers for array and enumeration Dim $MServer, $DName, $DProfile ; user data vars Dim $aMapped ; array of mapped network drives Dim $Drv, $NetFlag, $IsNet, $MoveFlag ; Drive letter enumerator, Network Only flag, IsNetwork flag, Move Flag Dim $PSTName, $PSTPath ; name & Path of current PST file Dim $NewPSTName, $NewPSTPath ; name of renamed PST file or new Path Dim $NewPSTRoot ; path of new PST path, when moving instead of renaming Dim $LogPath ; UNC path where logs are written $ = SetOption('Explicit', 'On') $ = SetOption('WrapAtEOL', 'On') $ = SetOption('NoVarsInStrings', 'On') $ = SetOption('NoMacrosInStrings', 'On') ; # # # # # START OF CUSTOM PARAMETERS # # # # # $NetFlag = 0 ; only process network PST files if 1 $MoveFlag = 1 ; Move files if 1, otherwise disassociate and rename $LogPath = '\\server\share\' ; UNC path where renamed PST file locations are logged $NewPSTRoot = '\\server\share\' ; UNC or mapped drive ; # # # # # END OF CUSTOM PARAMETERS # # # # # $RootPath = 'HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles' ; get list of mapped drives $aMapped = WMIMappedDrives() $DProfile = ReadValue($RootPath, 'DefaultProfile') $WKey = $RootPath + '\' + $DProfile + '\' $MServer = ReadValue($WKey + '13dbb0c8aa05101a9bb000aa002fc45a', '001e6602') $DName = UtoA(ReadValue($WKey + '13dbb0c8aa05101a9bb000aa002fc45a', '001f3001')) ; find the PST files associated with this profile - need to enumerate each subkey and find the 001f6700 value $eIndex = 0 $aIndex = -1 $EKey = EnumKey($WKey, $eIndex) While Not @ERROR $TVal = UtoA(ReadValue($WKey + $EKey, '001f6700')) If $TVal $aIndex = $aIndex + 1 ReDim Preserve $aPSTPaths[$aIndex] ReDim Preserve $aPSTKeys[$aIndex] $aPSTPaths[$aIndex] = $TVal $aPSTKeys[$aIndex] = $WKey + $EKey EndIf $eIndex = $eIndex + 1 $EKey = EnumKey($WKey, $eIndex) Loop ; Exit if nothing to do If $aIndex < 0 'No PST files are registered for user ' $DName ' - exiting!' ? ? Exit 0 EndIf ? ? 'Preparing for Mail Archiving on ' @WKSTA ' for user ' $DName ? ; now have all needed info ; - terminate Outlook if it is running ; - delete the PST registry keys ; - rename the PST files ; terminate Outlook $ = Split(WMIProcessList('outlook.exe')[0], ',')[1] If Not @ERROR ' Closing Outlook...' ? $ = WMIProcessKill($) ; terminate Outlook Sleep 3 ; wait for Outlook to close open files EndIf ; Enumerate the PST files that are registered in Outlook For $ = 0 to UBound($aPSTPaths) $IsNet = -1 ; Default to Not Network, will be 0 or more if network PSTs are found $Drv = Left($aPSTPaths[$], 2) ; drive letter where PST is stored $_ = InStrRev($aPSTPaths[$], '\') $PSTName = SubStr($aPSTPaths[$], $_ + 1) ; get name part $PSTPath = Left($aPSTPaths[$], $_) ; get path part ; determine if the PST is on a network drive. For $_ = 0 to UBound($aMapped) If $aMapped[$_][0] = $Drv $IsNet = $_ ; is network! EndIf Next ; Decide if this file should be processed - NetFlag=0 for all, or NetFlag=1 AND IsNet >= 0 If Not $NetFlag Or $NetFlag And $IsNet >= 0 ; Display the PST name ' ' Left($Drv + $PSTName + ' ', 25) '- ' If $MoveFlag ; Relocate the file to a user-specific folder on a common share $NewPSTPath = $NewPSTRoot 'move' Move $PSTPath + $PSTName $NewPSTPath + $PSTName ; re-associate the PST registry key with the new location '; reassociate' $_ = AtoU($NewPSTPath + $PSTName) $_ = WriteValue($aPSTKeys[$], '001f6700-0', $_, 'REG_BINARY') ; convert local to UNC for logging If $IsNet = -1 If Left($NewPSTPath, 1) = '\' $aPSTPaths[$] = $NewPSTPath + $PSTName Else $aPSTPaths[$] = '\\' + @WKSTA + '\' + Left($aPSTPaths[$], 1) + Chr(36) + SubStr($NewPSTPath, 3) + $PSTName EndIf Else If Left($NewPSTPath, 1) <> '\' $aPSTPaths[$] = $aMapped[$IsNet][1] + SubStr($NewPSTPath, 3) + $PSTName EndIf EndIf Else ; Disassociate by deleting the registry key 'Disassociate' $_ = DelTree($aPSTKeys[$]) ; Rename the file $NewPSTName = @USERID + '_' + Join(Split(Join(Split($PSTName, ' '), '_'), '.pst'), '.stp') '; move' Move $PSTPath + $PSTName $PSTPath + $NewPSTName ; convert local to UNC for logging If $IsNet = -1 ; local $aPSTPaths[$] = '\\' + @WKSTA + '\' + Left($aPSTPaths[$], 1) + Chr(36) + SubStr($PSTPath, 3) + $NewPSTName Else $aPSTPaths[$] = $aMapped[$IsNet][1] + SubStr($PSTPath, 3) + $NewPSTName EndIf EndIf ; write log for processed PST files - these files will be processed offline to move the ; renamed PST files to a central folder for processing '; write log' $_ = RedirectOutput($LogPath + '\' + @WKSTA + '_PST.txt') $aPSTPaths[$] ? $_ = RedirectOutput('') ' - Done!' ? EndIf Next Exit 0 ; convert Unicode strings to ASCII Function UtoA($_String) ; return if string is empty If Not $_String Exit 0 EndIf Dim $_S, $_I ; temp string, index pointer ; get each character pair as hex and convert to ASCII character For $_I = 1 to Len($_String) Step 4 $_S = $_S + Chr(Val('&' + SubStr($_String, $_I, 2))) Next $UtoA = $_S Exit 0 EndFunction Function AtoU($_String) Dim $_S, $_I ; temp string, index pointer ; get each ASCII character and convert to hex words For $_I = 1 to Len($_String) $_S = $_S + Right('00' + DecToHex(Asc(SubStr($_String, $_I, 1))), 2) + '00' Next $AtoU = LCase($_S) + '0000' Exit 0 EndFunction ;; ;;====================================================================== ;; ;;FUNCTION TimeDiff() ;; ;;AUTHOR Glenn Barnas ;; ;;VERSION 2.2 / 2007/10/14 ;; Modified to increase accuracy, permit fracional second calculations ;; 2.1 / 2007/03/17 ;; added "now" and "today" options for both start and end times ;; 2.0 / 2006/11/20 ;; Changes for code efficiency; added defaults for midnight ;; ;;ACTION Calculates the time difference between two given date/time strings ;; ;;SYNTAX TimeDiff(Start [, End] [, Format] [, MSec]) ;; ;;PARAMETERS Start - REQUIRED, String value representing the start timestamp ;; Format yyyy/mm/dd hh:mm:ss ;; ;; End - OPTIONAL, Defaults to "now" ;; String value representing the ending time ;; Format yyyy/mm/dd hh:mm:ss ;; Can be the special value "now" for the current date/time, or "today" ;; for midnight of the current day. ;; ;; When the time value is not specified, it defaults to 00:00:00.000 (midnight) ;; ;; Format - OPTIONAL, one of: ;; "m" - return minutes ;; "h" - return hours ;; "d" - return days ;; "y" - return years ;; When a format value is specified, it returns the fractional part (ie 0.5 days for 12 hours). ;; ;; MSec - OPTIONAL, True if the fractional seconds should be returned. Default ;; is false, returning whole seconds, to maintain compatibility with earlier versions. ;; MSec only affects the return of fractional seconds, not fractional parts of other time formats. ;; ;;REMARKS Returns a value representing the difference in time between two date/time ;; strings. Assumes that "Start" is in the past, but will properly return a ;; negative value if it is in the future. ;; ;;RETURNS Double - difference between Start and End timestamps in seconds ;; ;;DEPENDENCIES None ;; ;;TESTED WITH Kix 4.2+, NT4, W2K, WXP, W2K3 ;; ;;EXAMPLES If TimeDiff(GetFileTime('SomeFile.txt'), 'now', 'h') > 48 ;; "File is more than 2 days old!" ? ;; EndIf ; Function TimeDiff($_Start, OPTIONAL $_End, OPTIONAL $_Fmt, OPTIONAL $_MSec) Dim $_, $_SDate, $a_Start, $_EDate, $a_End, $_Duration ; Check for special START parameters Select Case $_Start = 'now' $_Start = @DATE + ' ' + @TIME + '.' + @MSECS Case $_START = 'today' $_Start = @DATE + ' 00:00:00.000' EndSelect ; Check for special END parameters Select Case $_End = 'now' Or $_End = '' $_End = @DATE + ' ' + @TIME + '.' + @MSECS Case $_End = 'today' $_End = @DATE + ' 00:00:00.000' EndSelect ; Validate parameters ; Parameters passed are "yyyy/mm/dd hh:mm:ss[.sss]" - make sure the default time is added $a_Start = Split(Join(Split(Join(Split($_Start + ' 00:00:00.000', '/'), ' '), ':'), ' '), ' ', 6) If UBound($a_Start) <> 5 Exit 87 EndIf ; bad start time parameter For $_ = 0 to 5 $a_Start[$_] = CDbl($a_Start[$_]) ; convert to numeric values Next $a_End = Split(Join(Split(Join(Split($_End + ' 00:00:00.000', '/'), ' '), ':'), ' '), ' ', 6) If UBound($a_End) <> 5 Exit 87 EndIf ; bad start time parameter For $_ = 0 to 5 $a_End[$_] = CDbl($a_End[$_]) ; convert to numeric values Next ; Convert dates to Days, then convert to seconds and add the time value If $a_Start[1] < 3 $a_Start[1] = $a_Start[1] + 12 $a_Start[0] = $a_Start[0] - 1 EndIf $_SDate = $a_Start[2] + ( 153 * $a_Start[1] - 457 ) / 5 + 365 * $a_Start[0] + $a_Start[0] / 4 - $a_Start[0] / 100 + $a_Start[0] / 400 - 306 $_SDate = CDbl($_SDate) * 86400.0 $_SDate = $_SDate + $a_Start[3] * 3600 + $a_Start[4] * 60 + $a_Start[5] If $a_End[1] < 3 $a_End[1] = $a_End[1] + 12 $a_End[0] = $a_End[0] - 1 EndIf $_EDate = $a_End[2] + ( 153 * $a_End[1] - 457 ) / 5 + 365 * $a_End[0] + $a_End[0] / 4 - $a_End[0] / 100 + $a_End[0] / 400 - 306 $_EDate = CDbl($_EDate) * 86400.0 $_EDate = $_EDate + $a_End[3] * 3600 + $a_End[4] * 60 + $a_End[5] ; Get the duration between the timestamps $_Duration = CDbl($_EDate - $_SDate) ; Trim fractional seconds if the MSec flag wasn't set ; Value returned is whole seconds If Not $_MSec $_Duration = CInt($_Duration) EndIf ; Return data as a Double - seconds (default), hours, minutes, days, or years Select Case $_Fmt = 'm' ; minutes $TimeDiff = $_Duration / 60.0 Case $_Fmt = 'h' ; hours $TimeDiff = $_Duration / 3600.0 Case $_Fmt = 'd' ; days $TimeDiff = $_Duration / 86400.0 Case $_Fmt = 'y' ; years $TimeDiff = $_Duration / 31536000.0 Case 1 $TimeDiff = $_Duration EndSelect Exit 0 EndFunction ;; ;;====================================================================== ;; ;;FUNCTION WMIMappedDrives() ;; ;;ACTION Return a list of mapped drives from a computer ;; ;;AUTHOR Glenn Barnas ;; ;;VERSION 1.0 / 2008/03/24 ;; ;;SYNTAX WMIMappedDrives([, AuthPtr]) ;; ;;PARAMETERS AuthPtr - OPTIONAL - pre-authenticated WMI object pointer ;; Use WMIAuthentication() udf to create the AuthPtr value ;; AuthPtr is not needed if user has admin rights ;; ;;REMARKS By default, returns a detailed list of all processes from the local computer. An ;; alternate computer can be specified, as can a specific process. When specifying ;; processes, you can use a name (cmd.exe) or process ID. If you specify a name, all ;; processeses matching that name will be returned, while specifying a PID will return ;; exactly one element that matches that process (if it was found) ;; If no match is found, the function exits with status 2 (file not found) ;; ;;RETURNS Array of drive letter / UNC Path arrays ;; ;;DEPENDENCIES WMI, ;; ;;TESTED WITH W2K, WXP, W2K3, Vista, x64 ;; ;;EXAMPLES ; Function WMIMappedDrives(OPTIONAL $_pAuth) Dim $_objWMIService, $_colItems, $_objItem ; WMI object vars Dim $_Line ; line string Dim $_aTmp[0], $_I ; return array, index Dim $_ ; temp var $_I = -1 ; If a pre-authenticated WMI object pointer was provided, use it, otherwise create a new object pointer If $_pAuth $_objWMIService = $_pAuth Else $_objWMIService = GetObject('winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2') If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf EndIf ; get the collection of process objects $_colItems = $_objWMIService.ExecQuery("Select * from Win32_MappedLogicalDisk",,48) If @ERROR $_colItems = 0 Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf ; Enumerate the collection of process data For Each $_objItem in $_colItems $_I = $_I + 1 ReDim Preserve $_aTmp[$_I] $_aTmp[$_I] = $_objItem.Name, $_objItem.ProviderName Next ; return the array, close the collection, and gripe if no items were found $WMIMappedDrives = $_aTmp $_colItems = 0 Exit 0 EndFunction ;; ;;====================================================================== ;; ;;FUNCTION WMIProcessKill() ;; ;;ACTION Terminates a specific process by numeric PID ;; ;;AUTHOR Glenn Barnas ;; ;;VERSION 1.0 / 2007/10/20 ;; ;;SYNTAX WMIProcessKill(Process [, Computer] [, AuthPtr]) ;; ;;PARAMETERS Process - PID of process to terminate ;; ;; Computer - OPTIONAL, Name of computer to target ;; ;; AuthPtr - OPTIONAL - pre-authenticated WMI object pointer ;; Use WMIAuthentication() udf to create the AuthPtr value ;; AuthPtr is not needed if user has admin rights ;; ;;REMARKS Terminates the process after verifying it exists ;; ;;RETURNS 1 (success) or 0 (failure) ;; ;;DEPENDENCIES WMI ;; ;;TESTED WITH W2K, WXP, W2K3, Vista, x64 ;; ;;EXAMPLES ; Function WMIProcessKill($_Process, Optional $_Computer, OPTIONAL $_pAuth) Dim $_objWMIService, $_colItems, $_objItem ; WMI object vars Dim $_ ; temp var Dim $_Err ; error code ; Must be a single numeric value to terminate If Val($_Process) <> $_Process $WMIProcessKill = 0 Exit 87 EndIf ; insure a properly formatted computer name, default to local computer is not specified $_Computer = IIf(Not $_Computer, '.', Join(Split($_Computer,'\'),'')) ; If a pre-authenticated WMI object pointer was provided, use it, otherwise create a new object pointer If $_pAuth $_objWMIService = $_pAuth Else $_objWMIService = GetObject('winmgmts:{impersonationLevel=impersonate}!\\' + $_Computer + '\root\cimv2') If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf EndIf ; get the collection of process objects $_colItems = $_objWMIService.ExecQuery("Select * from Win32_Process Where ProcessID=" + '"' + $_Process + '"',,48) If @ERROR $_colItems = 0 Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf $_Err = 2 ; prepare for not found ; Enumerate the collection of process data For Each $_objItem in $_colItems $_ = $_objItem.Terminate $_Err = @ERROR Next $_colItems = 0 ; return appropriate values $WMIProcessKill = Not $_Err Exit $_Err EndFunction ;; ;;====================================================================== ;; ;;FUNCTION WMIProcessList() ;; ;;ACTION Return a list of process info from a computer ;; ;;AUTHOR Glenn Barnas ;; ;;VERSION 1.0 / 2007/10/12 ;; Written as a replacement for PSList(), which uses SysInternals PSList.exe ;; ;;SYNTAX WMIProcessList([Process] [, Computer] [, AuthPtr]) ;; ;;PARAMETERS Process - return information about a specific process (group) by name ;; or individual process ID (PID) ;; ;; Computer - OPTIONAL, Name of computer to query ;; ;; AuthPtr - OPTIONAL - pre-authenticated WMI object pointer ;; Use WMIAuthentication() udf to create the AuthPtr value ;; AuthPtr is not needed if user has admin rights ;; ;;REMARKS By default, returns a detailed list of all processes from the local computer. An ;; alternate computer can be specified, as can a specific process. When specifying ;; processes, you can use a name (cmd.exe) or process ID. If you specify a name, all ;; processeses matching that name will be returned, while specifying a PID will return ;; exactly one element that matches that process (if it was found) ;; If no match is found, the function exits with status 2 (file not found) ;; ;;RETURNS Array of comma-delimited values, one element per process: ;; Process Name ;; Process ID (PID) ;; Thread Count ;; Handle Count ;; Memory Usage (Bytes) ;; User Time D:HH:MM:SS.sss format ;; Kernel Time D:HH:MM:SS.sss format ;; Elapsed Time D:HH:MM:SS.sss format ;; ;;DEPENDENCIES WMI, TimeDiff() external UDF ;; ;;TESTED WITH W2K, WXP, W2K3, Vista, x64 ;; ;;EXAMPLES ; Function WMIProcessList(OPTIONAL $_Process, Optional $_Computer, OPTIONAL $_pAuth) Dim $_objWMIService, $_colItems, $_objItem ; WMI object vars Dim $_Line ; line string Dim $_aTmp[0], $_I ; return array, index Dim $_ ; temp var Dim $_BTime, $_CTime ; boot and current times from target system $_I = -1 ; insure a properly formatted computer name, default to local computer is not specified $_Computer = IIf(Not $_Computer, '.', Join(Split($_Computer,'\'),'')) ; If a pre-authenticated WMI object pointer was provided, use it, otherwise create a new object pointer If $_pAuth $_objWMIService = $_pAuth Else $_objWMIService = GetObject('winmgmts:{impersonationLevel=impersonate}!\\' + $_Computer + '\root\cimv2') If @ERROR Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf EndIf ; Get the current and boot times from the client system $_colItems = $_objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48) For Each $_objItem in $_colItems $_BTime = $_objItem.LastBootUpTime ; host-local boot time $_CTime = $_objItem.LocalDateTime ; host-local current time Next $_colItems = 0 ; convert to a normalized time string $_CTime = SubStr($_CTime, 1,4) + '/' + SubStr($_CTime, 5,2) + '/' +SubStr($_CTime, 7,2) + ' ' + SubStr($_CTime, 9,2) + ':' + SubStr($_CTime, 11,2) + ':' + SubStr($_CTime, 13,6) ; get the collection of process objects $_colItems = $_objWMIService.ExecQuery("Select * from Win32_Process",,48) If @ERROR $_colItems = 0 Exit Val('&' + Right(DecToHex(@ERROR), 4)) EndIf ; Enumerate the collection of process data For Each $_objItem in $_colItems ; add the data to the array if no process is specified, or if a specific process name or ID is specified If Not $_Process Or $_Process = $_objItem.Name Or $_Process = $_objItem.ProcessID $_Line = $_objItem.Name $_Line = $_Line + ',' + $_objItem.ProcessID $_Line = $_Line + ',' + $_objItem.Priority $_Line = $_Line + ',' + $_objItem.ThreadCount $_Line = $_Line + ',' + $_objItem.HandleCount $_Line = $_Line + ',' + $_objItem.WorkingSetSize ; convert the following to d:hh:mm:ss.sss format $_Line = $_Line + ',' + _WMIPLTC(CDbl($_objItem.UserModeTime) * 0.0000001) $_Line = $_Line + ',' + _WMIPLTC(CDbl($_objItem.KernelModeTime) * 0.0000001) ; Use the system boot time if creation date is not set $_ = IIf($_objItem.CreationDate , $_objItem.CreationDate, $_BTime) ; calculate elapsed time and convert to d:hh:mm:ss.sss format $_Line = $_Line + ',' + _WMIPLTC(_WMIPLET($_, $_CTime)) ; Update the array $_I = $_I + 1 ReDim Preserve $_aTmp[$_I] $_aTmp[$_I] = $_Line EndIf Next ; return the array, close the collection, and gripe if no items were found $WMIProcessList = $_aTmp $_colItems = 0 If $_Process And $_I < 0 Exit 1911 EndIf Exit 0 EndFunction ; support function to calculate elapsed time as Seconds ; Dependent on TimeDiff UDF! Function _WMIPLET($_Time, $_CTime) Dim $_CurrentTime ; Break into Date and Time parts, including 3 decimal points $_Time = SubStr($_Time, 1,4) + '/' + SubStr($_Time, 5,2) + '/' +SubStr($_Time, 7,2) + ' ' + SubStr($_Time, 9,2) + ':' + SubStr($_Time, 11,2) + ':' + SubStr($_Time, 13,6) ; return the value with 3 decimal places $_WMIPLET = TimeDiff($_Time, $_CTime, '', 1); FormatNumber(, 3, -1, 0, 0) Exit 0 EndFunction ; support function to conver the time value (100ns units) to D:H:M:S.s format Function _WMIPLTC($_Units) Dim $_D, $_H, $_M, $_S ; day, hour, minute, & second values ; Find d/h/m and subtract result from units $_D = Int($_Units / 86400) $_Units = $_Units - $_D * 86400 $_H = Int($_Units/3600) $_Units = $_Units - $_H * 3600 $_M = Int($_Units/60) $_S = FormatNumber($_Units - $_M * 60, 3, -1, 0, 0) ; return a time string $_WMIPLTC = '' + $_D + ':' + $_H + ':' + $_M + ':' + $_S Exit 0 EndFunction
|