adamsre Posted May 14, 2009 Share Posted May 14, 2009 Hey All, I've seen examples of finding the week number in a year, the number of days in a month, the id of the day of a week (0-6), but I have yet to see anyone request how to find what week number of a given month you're in based on the current date/time. I have a script that I need to execute on Saturdays during off hours, but based on the week number - in general 1-4 - it needs to do other jobs. To put it plainly, this is for an Exchange server that I want to dismount a given information store, perform maintenance on it, and then mount the store back. I have 4 storage groups, and would like to rotate through the groups based on the week number. I have the other scripts working to perform all of the above maintenance, but I just need a scheduler of sorts. The event scheduler in 2003 won't do what I need - in addition to my not being able to make the script detect what week its in. Pseudo Code: What week is it? Is it Saturday? Which Saturday is it? if Saturday #1, at 3:00 AM, dismount Storage_Group_1 Perform Maintenance Mount Storage_Group_1 if Saturday #2, at 3:00 AM, dismount Storage_Group_2 Perform Maintenance Mount Storage_Group_2 etc... I can use Windows Scheduler to run this on Saturdays, but I have the above just for error correction/detection. Thoughts? Link to comment Share on other sites More sharing options...
oMBRa Posted May 14, 2009 Share Posted May 14, 2009 if the day number is > 1 and < 8 1° week > 7 and < 15 2° week > 14 and < 22 3° week > 21 and < 32 4° week Link to comment Share on other sites More sharing options...
Developers Jos Posted May 14, 2009 Developers Share Posted May 14, 2009 (edited) #include <date.au3> ; check for saturday If @WDAY < 7 then Exit ; check saturday number in this month $SatWknr = 0 If @MDAY < 8 then $SatWknr = 1 ElseIf @MDAY < 15 then $SatWknr = 2 ElseIf @MDAY < 22 then $SatWknr = 3 ElseIf @MDAY < 29 then $SatWknr = 4 Else $SatWknr = 5 EndIf Edited May 14, 2009 by Jos SciTE4AutoIt3 Full installer Download page - Beta files Read before posting How to post scriptsource Forum etiquette Forum Rules Live for the present, Dream of the future, Learn from the past. Link to comment Share on other sites More sharing options...
CodyBarrett Posted May 14, 2009 Share Posted May 14, 2009 (edited) if the day number is > 1 and < 8 1° week> 7 and < 15 2° week> 14 and < 22 3° week> 21 and < 32 4° weeknot always... Edited May 14, 2009 by CodyBarrett [size="1"][font="Tahoma"][COMPLETED]-----[FAILED]-----[ONGOING]VolumeControl|Binary Converter|CPU Usage| Mouse Wrap |WinHide|Word Scrammbler|LOCKER|SCREEN FREEZE|Decisions Decisions|Version UDF|Recast Desktop Mask|TCP Multiclient EXAMPLE|BTCP|LANCR|UDP serverless|AIOCR|OECR|Recast Messenger|AU3C|Tik-Tak-Toe|Snakes & Ladders|BattleShips|TRON|SNAKE_____________________[u]I love the Helpfile it is my best friend.[/u][/font][/size] Link to comment Share on other sites More sharing options...
PsaltyDS Posted May 14, 2009 Share Posted May 14, 2009 Hey All, I've seen examples of finding the week number in a year, the number of days in a month, the id of the day of a week (0-6), but I have yet to see anyone request how to find what week number of a given month you're in based on the current date/time. I have a script that I need to execute on Saturdays during off hours, but based on the week number - in general 1-4 - it needs to do other jobs. To put it plainly, this is for an Exchange server that I want to dismount a given information store, perform maintenance on it, and then mount the store back. I have 4 storage groups, and would like to rotate through the groups based on the week number. I have the other scripts working to perform all of the above maintenance, but I just need a scheduler of sorts. The event scheduler in 2003 won't do what I need - in addition to my not being able to make the script detect what week its in. Pseudo Code: What week is it? Is it Saturday? Which Saturday is it? if Saturday #1, at 3:00 AM, dismount Storage_Group_1 Perform Maintenance Mount Storage_Group_1 if Saturday #2, at 3:00 AM, dismount Storage_Group_2 Perform Maintenance Mount Storage_Group_2 etc... I can use Windows Scheduler to run this on Saturdays, but I have the above just for error correction/detection. Like this: For $n = 1 To 31 $iWeek = Floor(($n - 1) / 7) + 1 ConsoleWrite($n & ": " & $iWeek & @LF) Next It's on you to figure out what to do with a fifth Saturday. Thoughts?Pinky: I think so, Brain. But how will we get the hippopotamus IN the tutu? Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
adamsre Posted May 15, 2009 Author Share Posted May 15, 2009 Pinky: I think so, Brain. But how will we get the hippopotamus IN the tutu? So... what are we going to do today, Brain?You guys rock. Thank you for your rapid responses - they gave me the direction I needed to head in. Link to comment Share on other sites More sharing options...
adamsre Posted May 15, 2009 Author Share Posted May 15, 2009 (edited) Here's the code I have thus far: expandcollapse popup#include <date.au3> $nowtime = StringReplace(_Now(),"/","") $nowtime = StringReplace($nowtime,":","") $nowtime = StringReplace($nowtime," ","") ; check for saturday If @WDAY < 7 then Exit ; check saturday number in this month $SatWknr = 0 If @MDAY < 8 then $SatWknr = 1 ElseIf @MDAY < 15 then $SatWknr = 2 ElseIf @MDAY < 22 then $SatWknr = 3 ElseIf @MDAY < 29 then $SatWknr = 4 Else $SatWknr = 5 EndIf ;msgBox(32, "Information", "This is Saturday #" & $SatWknr) AutoItSetOption("TrayIconHide", 1) Break(0) $USERNAME = "bubbagump" $DOMAIN = "domain.local" $PASSWORD = "Pa$$w0rd" $RUN = 0 ; run indicator ; retrieve the cycle from commandline If Not IsAdmin() Then ; retrieve the cycle from commandline If $CMDLINE[0] = 1 Then $RUN = $CMDLINE[1] If $RUN = 0 Then ; RunAsSet($USERNAME, $DOMAIN, $PASSWORD) RunAs($USERNAME,$DOMAIN,$PASSWORD,0,@ComSpec & " /c " & Chr(34) & @ScriptFullPath & Chr(34) & " 1",@TempDir,@SW_HIDE) If @error Then MsgBox(4096+32,@Error, "Error starting under admin mode") Exit EndIf EndIf If $SatWknr = 1 $SGroup = "Clay_Storage_1" $Store1 = "pub1" $Store2 = "S10L" $Store3 = "S11S_AES_CEB_CHE_CGE" $Store4 = "S12S_DIS_FIE_GPE_KHE" $Store5 = "S13S_LAE_LES_MRE_MBE" DismountDefragMount($SGroup, $Store1, $Store2, $Store3, $Store4, $Store5) EndIf If $SatWknr = 2 $SGroup = "Clay_Storage_2" $Store1 = "S20L" $Store2 = "S21S_MCE_OVE_OPE_PES_POE" $Store3 = "S22S_ROE_RVE_SBJ_SLE" $Store4 = "S23S_SPE_TBE_TES_WEC" $Store5 = "S24S_WES_BLC_GCJ" DismountDefragMount($SGroup, $Store1, $Store2, $Store3, $Store4, $Store5) EndIf If $SatWknr = 3 $SGroup = "Clay_Storage_3" $Store1 = "S30M" $Store2 = "S31S_LAJ_LSJ_OLS" $Store3 = "S32S_OPJ_WJH" $Store4 = "S33S_CHS_FIH" $Store5 = "S34S_KHS_MHS" DismountDefragMount($SGroup, $Store1, $Store2, $Store3, $Store4, $Store5) EndIf If $SatWknr = 4 $SGroup = "Clay_Storage_4" $Store1 = "S40M" $Store2 = "S41S_OPH_RHS" $Store3 = "S42_Admin" $Store4 = "S43_District_Office" $Store5 = "S44S_Temp" DismountDefragMount($SGroup, $Store1, $Store2, $Store3, $Store4, $Store5) EndIf If $SatWknr = 5 $SGroup = "Clay_Storage_3" $Store1 = "S30M" $Store2 = "S31S_LAJ_LSJ_OLS" $Store3 = "S32S_OPJ_WJH" $Store4 = "S33S_CHS_FIH" $Store5 = "S34S_KHS_MHS" DismountDefragMount($SGroup, $Store1, $Store2, $Store3, $Store4, $Store5) EndIf ;$SGroup = "Clay_Storage_4" ** for testing ;$Store1 = "S40M" ** for testing ;$Store2 = "S44S_Temp" ** for testing ;DismountDefragMount($SGroup, $Store1, $Store2) ** for testing Func DismountDefragMount($SGrp, $S1, $S2, $S3, $S4, $S5) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs dismount coexch01 " & $SGrp & " " & $S1, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "eseutil /d T:\EXCHSRVR\" & $SGrp & "\" & $S1 & ".edb /t T:\EXCHSRVR\" & $S1 & "_TEMP.edb > C:\defrag\"& $nowtime & "_" & $S1 & ".txt", "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs mount coexch01 " & $SGrp & " " & $S1, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs dismount coexch01 " & $SGrp & " " & $S2, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "eseutil /d T:\EXCHSRVR\" & $SGrp & "\" & $S2 & ".edb /t T:\EXCHSRVR\" & $S2 & "_TEMP.edb > C:\defrag\"& $nowtime & "_" & $S2 & ".txt", "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs mount coexch01 " & $SGrp & " " & $S2, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs dismount coexch01 " & $SGrp & " " & $S3, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "eseutil /d T:\EXCHSRVR\" & $SGrp & "\" & $S3 & ".edb /t T:\EXCHSRVR\" & $S3 & "_TEMP.edb > C:\defrag\"& $nowtime & "_" & $S3 & ".txt", "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs mount coexch01 " & $SGrp & " " & $S3, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs dismount coexch01 " & $SGrp & " " & $S4, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "eseutil /d T:\EXCHSRVR\" & $SGrp & "\" & $S4 & ".edb /t T:\EXCHSRVR\" & $S4 & "_TEMP.edb > C:\defrag\"& $nowtime & "_" & $S4 & ".txt", "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs mount coexch01 " & $SGrp & " " & $S4, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs dismount coexch01 " & $SGrp & " " & $S5, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "eseutil /d T:\EXCHSRVR\" & $SGrp & "\" & $S5 & ".edb /t T:\EXCHSRVR\" & $S5 & "_TEMP.edb > C:\defrag\"& $nowtime & "_" & $S5 & ".txt", "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs mount coexch01 " & $SGrp & " " & $S5, "", @SW_HIDE) EndFunc I'm certain this can be cleaned up substantially, so I'm open for suggestions. The code as-is works flawlessly, but I would like to change one thing. In my function, I have each command being run as a 'runwait'. The defrag has to wait until the dismount is complete, and the mount has to wait until the defrag is complete. However... I can have all 5 Information Stores performing defrag at the same time without issue, but they need to be aware of their own individual dismount and mount processes. Anyone have a suggestion as to how to dismount all 5 at the same time, and have each start a defrag as each dismount completes. The dismount is contigent on the sizes of the databases. Some of these are as small as 11gigs, and as large as 80 gigs, so the process times varies - as does the time to defrag each database. My thought - that just came to mind as I am writing this is to just shorten the function to a single statement, and have 5 function calls within each IF statement to each of the 5 databases. This *should* keep the databases independant of each other while still allowing them to be aware of their own individual dismounts, defrags, and mounts. If anyone has an easier way of doing this - feel free - I'm always open for constructive criticism. Thanks!! Edited May 15, 2009 by adamsre Link to comment Share on other sites More sharing options...
PsaltyDS Posted May 15, 2009 Share Posted May 15, 2009 (edited) Here's the code I have thus far: CODE#include <date.au3> $nowtime = StringReplace(_Now(),"/","") $nowtime = StringReplace($nowtime,":","") $nowtime = StringReplace($nowtime," ","") ; check for saturday If @WDAY < 7 then Exit ; check saturday number in this month $SatWknr = 0 If @MDAY < 8 then $SatWknr = 1 ElseIf @MDAY < 15 then $SatWknr = 2 ElseIf @MDAY < 22 then $SatWknr = 3 ElseIf @MDAY < 29 then $SatWknr = 4 Else $SatWknr = 5 EndIf ;msgBox(32, "Information", "This is Saturday #" & $SatWknr) AutoItSetOption("TrayIconHide", 1) Break(0) $USERNAME = "bubbagump" $DOMAIN = "domain.local" $PASSWORD = "Pa$$w0rd" $RUN = 0 ; run indicator ; retrieve the cycle from commandline If Not IsAdmin() Then ; retrieve the cycle from commandline If $CMDLINE[0] = 1 Then $RUN = $CMDLINE[1] If $RUN = 0 Then ; RunAsSet($USERNAME, $DOMAIN, $PASSWORD) RunAs($USERNAME,$DOMAIN,$PASSWORD,0,@ComSpec & " /c " & Chr(34) & @ScriptFullPath & Chr(34) & " 1",@TempDir,@SW_HIDE) If @error Then MsgBox(4096+32,@Error, "Error starting under admin mode") Exit EndIf EndIf If $SatWknr = 1 $SGroup = "Clay_Storage_1" $Store1 = "pub1" $Store2 = "S10L" $Store3 = "S11S_AES_CEB_CHE_CGE" $Store4 = "S12S_DIS_FIE_GPE_KHE" $Store5 = "S13S_LAE_LES_MRE_MBE" DismountDefragMount($SGroup, $Store1, $Store2, $Store3, $Store4, $Store5) EndIf If $SatWknr = 2 $SGroup = "Clay_Storage_2" $Store1 = "S20L" $Store2 = "S21S_MCE_OVE_OPE_PES_POE" $Store3 = "S22S_ROE_RVE_SBJ_SLE" $Store4 = "S23S_SPE_TBE_TES_WEC" $Store5 = "S24S_WES_BLC_GCJ" DismountDefragMount($SGroup, $Store1, $Store2, $Store3, $Store4, $Store5) EndIf If $SatWknr = 3 $SGroup = "Clay_Storage_3" $Store1 = "S30M" $Store2 = "S31S_LAJ_LSJ_OLS" $Store3 = "S32S_OPJ_WJH" $Store4 = "S33S_CHS_FIH" $Store5 = "S34S_KHS_MHS" DismountDefragMount($SGroup, $Store1, $Store2, $Store3, $Store4, $Store5) EndIf If $SatWknr = 4 $SGroup = "Clay_Storage_4" $Store1 = "S40M" $Store2 = "S41S_OPH_RHS" $Store3 = "S42_Admin" $Store4 = "S43_District_Office" $Store5 = "S44S_Temp" DismountDefragMount($SGroup, $Store1, $Store2, $Store3, $Store4, $Store5) EndIf If $SatWknr = 5 $SGroup = "Clay_Storage_3" $Store1 = "S30M" $Store2 = "S31S_LAJ_LSJ_OLS" $Store3 = "S32S_OPJ_WJH" $Store4 = "S33S_CHS_FIH" $Store5 = "S34S_KHS_MHS" DismountDefragMount($SGroup, $Store1, $Store2, $Store3, $Store4, $Store5) EndIf ;$SGroup = "Clay_Storage_4" ** for testing ;$Store1 = "S40M" ** for testing ;$Store2 = "S44S_Temp" ** for testing ;DismountDefragMount($SGroup, $Store1, $Store2) ** for testing Func DismountDefragMount($SGrp, $S1, $S2, $S3, $S4, $S5) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs dismount coexch01 " & $SGrp & " " & $S1, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "eseutil /d T:\EXCHSRVR\" & $SGrp & "\" & $S1 & ".edb /t T:\EXCHSRVR\" & $S1 & "_TEMP.edb > C:\defrag\"& $nowtime & "_" & $S1 & ".txt", "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs mount coexch01 " & $SGrp & " " & $S1, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs dismount coexch01 " & $SGrp & " " & $S2, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "eseutil /d T:\EXCHSRVR\" & $SGrp & "\" & $S2 & ".edb /t T:\EXCHSRVR\" & $S2 & "_TEMP.edb > C:\defrag\"& $nowtime & "_" & $S2 & ".txt", "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs mount coexch01 " & $SGrp & " " & $S2, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs dismount coexch01 " & $SGrp & " " & $S3, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "eseutil /d T:\EXCHSRVR\" & $SGrp & "\" & $S3 & ".edb /t T:\EXCHSRVR\" & $S3 & "_TEMP.edb > C:\defrag\"& $nowtime & "_" & $S3 & ".txt", "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs mount coexch01 " & $SGrp & " " & $S3, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs dismount coexch01 " & $SGrp & " " & $S4, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "eseutil /d T:\EXCHSRVR\" & $SGrp & "\" & $S4 & ".edb /t T:\EXCHSRVR\" & $S4 & "_TEMP.edb > C:\defrag\"& $nowtime & "_" & $S4 & ".txt", "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs mount coexch01 " & $SGrp & " " & $S4, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs dismount coexch01 " & $SGrp & " " & $S5, "", @SW_HIDE) RunWait(@ComSpec & " /c " & "eseutil /d T:\EXCHSRVR\" & $SGrp & "\" & $S5 & ".edb /t T:\EXCHSRVR\" & $S5 & "_TEMP.edb > C:\defrag\"& $nowtime & "_" & $S5 & ".txt", "", @SW_HIDE) RunWait(@ComSpec & " /c " & "cscript c:\Defrag\InfoStore.vbs mount coexch01 " & $SGrp & " " & $S5, "", @SW_HIDE) EndFuncI'm certain this can be cleaned up substantially, so I'm open for suggestions. The code as-is works flawlessly, but I would like to change one thing. In my function, I have each command being run as a 'runwait'. The defrag has to wait until the dismount is complete, and the mount has to wait until the defrag is complete. However... I can have all 5 Information Stores performing defrag at the same time without issue, but they need to be aware of their own individual dismount and mount processes. Anyone have a suggestion as to how to dismount all 5 at the same time, and have each start a defrag as each dismount completes. The dismount is contigent on the sizes of the databases. Some of these are as small as 11gigs, and as large as 80 gigs, so the process times varies - as does the time to defrag each database. My thought - that just came to mind as I am writing this is to just shorten the function to a single statement, and have 5 function calls within each IF statement to each of the 5 databases. This *should* keep the databases independant of each other while still allowing them to be aware of their own individual dismounts, defrags, and mounts. If anyone has an easier way of doing this - feel free - I'm always open for constructive criticism. Thanks!! This looked interesting and educational (for me) so I took a shot at how I would do this. I have a violent allergy to putting literal logon credentials in a script, so I took out the RunAs() stuff. Of course you could easily put that back in. I also get kind of OCD about logging everything, and prefer AutoIt's _FileWriteLog() UDF for the purpose. This demo uses a 2D array to hold the parameters, indexed by the week number, and two 1D arrays to track what step each store is on and the PIDs of the running processes. The single While/WEnd loops runs the whole thing: CODE#include <File.au3> ; check for saturday If @WDAY < 7 Then MsgBox(16, "Error", "It's not Saturday - no action taken.") Exit EndIf ; Verify admin If Not IsAdmin() Then MsgBox(16, "Error", "Must be an administrator.") Exit EndIf ; Init log file Global $nowtime = @YEAR & @MON & @MDAY & "_" & @HOUR & @MIN & @SEC Global $LogFile = "C:\defrag\" & $nowtime & "_Defrag.log", $sMsg If Not _FileWriteLog($LogFile, "Started defrag.") Then MsgBox(16, "Error", "Can't open log file for write.") Exit EndIf _FileWriteLog($LogFile, "Log file = " & $LogFile) _FileWriteLog($LogFile, "@ComputerName = " & @ComputerName & "; @UserName = " & @UserName) ; Get 1-based saturday number in this month (1 thru 5) Global $SatWknr = Floor((@MDAY - 1) / 7) + 1 _FileWriteLog($LogFile, "@MDAY = " & @MDAY & "; Saturday week number ($SatWknr) = " & $SatWknr) ; 2D array of work parameters: n = 1-based Saturday number ; [0][...] = First row not used (using 1-based index from $SatWknr) ; [n][0] = Group ; [n][1] thru [n][5] = Store1 thru Store5 names Global $avParams[6][6] = [["", "", "", "", "", ""], _ ["Clay_Storage_1", "pub1", "S10L", "S11S_AES_CEB_CHE_CGE", "S12S_DIS_FIE_GPE_KHE", "S13S_LAE_LES_MRE_MBE"], _ ["Clay_Storage_2", "S20L", "S21S_MCE_OVE_OPE_PES_POE", "S22S_ROE_RVE_SBJ_SLE", "S23S_SPE_TBE_TES_WEC", "S24S_WES_BLC_GCJ"], _ ["Clay_Storage_3", "S30M", "S31S_LAJ_LSJ_OLS", "S32S_OPJ_WJH", "S33S_CHS_FIH", "S34S_KHS_MHS"], _ ["Clay_Storage_4", "S40M", "S41S_OPH_RHS", "S42_Admin", "S43_District_Office", "S44S_Temp"], _ ["Clay_Storage_3", "S30M", "S31S_LAJ_LSJ_OLS", "S32S_OPJ_WJH", "S33S_CHS_FIH", "S34S_KHS_MHS"]] $sMsg = "Selected parameters: [" & $SatWknr & "][0] = " & $avParams[$SatWknr][0] & @CRLF For $s = 1 To 5 $sMsg &= @CRLF & @TAB & "[" & $SatWknr & "][" & $s & "] = " & $avParams[$SatWknr][$s] Next _FileWriteLog($LogFile, $sMsg) ; 1D array of steps (1-based index to match stores index from $avParams): ; "Dismount" = next step is Dismount ; "Defrag" = next step is Defrag ; "Mount" = next step is Mount ; "Finished" = This store is done Global $avStep[6] = [5, "Dismount", "Dismount", "Dismount", "Dismount", "Dismount"] ; 1D array of PIDs to monitor (1-based index to match stores index from $avParams): Global $avPID[6] = [5, 0, 0, 0, 0, 0] ; Create command lines to use Global $sInfoStoreDismount = @ComSpec & " /c cscript c:\Defrag\InfoStore.vbs dismount coexch01 " & $avParams[$SatWknr][0] Global $sEseUtilDefrag = @ComSpec & " /c " & "eseutil /d T:\EXCHSRVR\" & $avParams[$SatWknr][0] Global $sInfoStoreMount = @ComSpec & " /c cscript c:\Defrag\InfoStore.vbs mount coexch01 " & $avParams[$SatWknr][0] Global $sExtCmd ; Finished flag Global $f_Finished ; Global error count Global $iErrors = 0 ; Run all jobs for all stores While 1 $f_Finished = True ; Check each store for remaining tasks For $s = 1 To 5 Switch $avStep[$s] Case "Dismount" $f_Finished = False If $avPID[$s] = 0 Then ; Start dismount process $sExtCmd = $sInfoStoreDismount & " " & $avParams[$SatWknr][$s] $avPID[$s] = Run($sExtCmd, "", @SW_HIDE) If @error Then $iErrors += 1 _FileWriteLog($LogFile, "Error! Failed to start dismount process! $sExtCmd = " & $sExtCmd) MsgBox(16, "Error", "Failed to start dismount process!" & @CRLF & _ "$sExtCmd = " & $sExtCmd & @CRLF & _ "Processing for this store will not continue.") $avStep[$s] = "Finished" _FileWriteLog($LogFile, "Error! Processing will not continue for this store: " & $avParams[$SatWknr][$s]) Else _FileWriteLog($LogFile, "Started a dismount process; PID = " & $avPID[$s] & "; $sExtCmd = " & $sExtCmd) EndIf Else ; Dismount was running, check for done If ProcessExists($avPID[$s]) = 0 Then $avPID[$s] = 0 $avStep[$s] = "Defrag" _FileWriteLog($LogFile, "Finished dismount process for store: " & $avParams[$SatWknr][$s]) EndIf EndIf Case "Defrag" $f_Finished = False If $avPID[$s] = 0 Then ; Start defrag process $sDefragLog = "C:\defrag\" & $nowtime & "_Defrag_Store_" & $avParams[$SatWknr][$s] & ".log" $sExtCmd = $sEseUtilDefrag & " " & $avParams[$SatWknr][$s] & "\" & $avParams[$SatWknr][$s] & ".edb /t T:\EXCHSRVR\" & $avParams[$SatWknr][$s] & "_TEMP.edb > " & $sDefragLog $avPID[$s] = Run($sExtCmd, "", @SW_HIDE) If @error Then $iErrors += 1 _FileWriteLog($LogFile, "Error! Failed to start defrag process! $sExtCmd = " & $sExtCmd) MsgBox(16, "Error", "Failed to start defrag process!" & @CRLF & _ "$sExtCmd = " & $sExtCmd & @CRLF & _ "Processing for this store will not continue.") $avStep[$s] = "Finished" _FileWriteLog($LogFile, "Error! Processing will not continue for this store: " & $avParams[$SatWknr][$s]) Else _FileWriteLog($LogFile, "Started a defrag process; PID = " & $avPID[$s] & "; $sExtCmd = " & $sExtCmd) EndIf Else ; Defrag was running, check for done If ProcessExists($avPID[$s]) = 0 Then $avPID[$s] = 0 $avStep[$s] = "Mount" _FileWriteLog($LogFile, "Finished defrag process for store: " & $avParams[$SatWknr][$s]) EndIf EndIf Case "Mount" $f_Finished = False If $avPID[$s] = 0 Then ; Start mount process $sExtCmd = $sInfoStoreMount & " " & $avParams[$SatWknr][$s] $avPID[$s] = Run($sExtCmd, "", @SW_HIDE) If @error Then $iErrors += 1 _FileWriteLog($LogFile, "Error! Failed to start mount process! $sExtCmd = " & $sExtCmd) MsgBox(16, "Error", "Failed to start mount process!" & @CRLF & _ "$sExtCmd = " & $sExtCmd & @CRLF & _ "Processing for this store will not continue.") $avStep[$s] = "Finished" _FileWriteLog($LogFile, "Error! Processing will not continue for this store: " & $avParams[$SatWknr][$s]) Else _FileWriteLog($LogFile, "Started a mount process; PID = " & $avPID[$s] & "; $sExtCmd = " & $sExtCmd) EndIf Else ; Mount was running, check for done If ProcessExists($avPID[$s]) = 0 Then $avStep[$s] = "Finished" _FileWriteLog($LogFile, "Finished mount process for store: " & $avParams[$SatWknr][$s]) EndIf EndIf Case "Finished" If $avPID[$s] <> 0 Then $avPID[$s] = 0 _FileWriteLog($LogFile, "All processing finished for store: " & $avParams[$SatWknr][$s]) EndIf Case Else $iErrors += 1 _FileWriteLog($LogFile, "Error! Unhandled case: $avStep[" & $s & "] = " & $avStep[$s]) MsgBox(16, "Error", "Unhandled case: $avStep[" & $s & "] = " & $avStep[$s]) $avStep[$s] = "Finished" _FileWriteLog($LogFile, "Error! Processing will not continue for this store: " & $avParams[$SatWknr][$s]) EndSwitch Next ; If all stores are finished then exit If $f_Finished Then If $iErrors Then _FileWriteLog($LogFile, "Finished defrag processing on all stores. Errors occurred! Review all log files for details!") MsgBox(16, "Finished with Errors", "Finished defrag processing on all stores." & @CRLF & _ "Errors occurred! Review all log files for details!") Else _FileWriteLog($LogFile, "All stores finished processing. No errors starting processes. Review defrag logs for details.") MsgBox(64, "Finished Defrag", "Finished defrag processing on all stores." & @CRLF & _ "Review defrag log files for details.", 30) EndIf ExitLoop EndIf WEndObviously, it's not tested at all. But you get the idea of using arrays to track lists of things and step through them efficiently. Note that a single index variable ($s in the For/Next) selects everything needed for a given store from all three arrays. The While/WEnd loop continues until all processes for all stores are complete, but each store can run async from the others. Hope that helps you as much as it helped me going over it. I intend to get some use out of it myself. Edited May 15, 2009 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
oMBRa Posted May 15, 2009 Share Posted May 15, 2009 a bit off-topic, but, does the week for u start on sunday? Link to comment Share on other sites More sharing options...
CodyBarrett Posted May 15, 2009 Share Posted May 15, 2009 depends on your point of view... it could start on monday... [size="1"][font="Tahoma"][COMPLETED]-----[FAILED]-----[ONGOING]VolumeControl|Binary Converter|CPU Usage| Mouse Wrap |WinHide|Word Scrammbler|LOCKER|SCREEN FREEZE|Decisions Decisions|Version UDF|Recast Desktop Mask|TCP Multiclient EXAMPLE|BTCP|LANCR|UDP serverless|AIOCR|OECR|Recast Messenger|AU3C|Tik-Tak-Toe|Snakes & Ladders|BattleShips|TRON|SNAKE_____________________[u]I love the Helpfile it is my best friend.[/u][/font][/size] Link to comment Share on other sites More sharing options...
PsaltyDS Posted May 15, 2009 Share Posted May 15, 2009 a bit off-topic, but, does the week for u start on sunday?OP's topic was about getting the ordinal week number of the Saturday within the month, the day this defrag process was to run. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
adamsre Posted May 18, 2009 Author Share Posted May 18, 2009 (edited) This looked interesting and educational (for me) so I took a shot at how I would do this. I have a violent allergy to putting literal logon credentials in a script, so I took out the RunAs() stuff. Of course you could easily put that back in. I also get kind of OCD about logging everything, and prefer AutoIt's _FileWriteLog() UDF for the purpose. This demo uses a 2D array to hold the parameters, indexed by the week number, and two 1D arrays to track what step each store is on and the PIDs of the running processes. The single While/WEnd loops runs the whole thing: ** Obviously, it's not tested at all. But you get the idea of using arrays to track lists of things and step through them efficiently. Note that a single index variable ($s in the For/Next) selects everything needed for a given store from all three arrays. The While/WEnd loop continues until all processes for all stores are complete, but each store can run async from the others. Hope that helps you as much as it helped me going over it. I intend to get some use out of it myself. Very slick, Psalty! I had tried working with arrays a bit, but was only using a single dimensional array. I made a few mods to what you had, and it actually does allow the processes to work independently - which is precisely what I needed. I totally spaced the very simple @YEAR - @MONTH etc... lol... I just HAD to make that part more difficult then it needed to be. Obviously, I cannot take all of the stores down just to test a script, so I'm having to do a minor rewrite so I can test it with the few stores I do have available to be taken offline for testing. I do have to tweak a few things to get the syntax correct for the finicky ESEUTIL - that was one of the reasons I had the variables separated originally - the dismount was flawless. Started a dismount process; PID = 7548; $sExtCmd = C:\WINDOWS\system32\cmd.exe /c cscript c:\Defrag\InfoStore.vbs dismount coexch01 Clay_Storage_3 S30M but Started a defrag process; PID = 5788; $sExtCmd = C:\WINDOWS\system32\cmd.exe /c eseutil /d T:\EXCHSRVR\Clay_Storage_3 S30M\S30M.edb /t T:\EXCHSRVR\S30M_TEMP.edb > C:\defrag\20090518_091148_Defrag_Store_S30M.log doubled up the path to the database file - so just minor stuff like that was all I really had to work with. should have looked similar to: Started a defrag process; PID = 5788; $sExtCmd = C:\WINDOWS\system32\cmd.exe /c eseutil /d T:\EXCHSRVR\Clay_Storage_3\S30M.edb /t T:\EXCHSRVR\S30M_TEMP.edb > C:\defrag\20090518_091148_Defrag_Store_S30M.log This gives me a few fantastic ideas to work with - and you're right, I'll be very likely utilizing a modified version of this elsewhere within my network *grin*. Now I just need to figure out why the processes are hanging up and continuously forcing the cluster to failover to my other node when I run this thing, and I should be golden! I do have to agree with you on the logging aspect - I like to see what works, and what doesn't. Seeing something along the lines of: Microsoft(R) Exchange Server Database Utilities Version 6.5 Copyright (C) Microsoft Corporation. All Rights Reserved. Initiating DEFRAGMENTATION mode... Database: T:\EXCHSRVR\Clay_Storage_4\S40M.edb Streaming File: T:\EXCHSRVR\Clay_Storage_4\S40M.STM Temp. Database: T:\EXCHSRVR\S40M_TEMP.edb Temp. Streaming File: T:\EXCHSRVR\S40M_TEMP.STM Defragmentation Status (% complete) 0 10 20 30 40 50 60 70 80 90 100 |----|----|----|----|----|----|----|----|----|----| ................................................... Moving 'T:\EXCHSRVR\S40M_TEMP.edb' to 'T:\EXCHSRVR\Clay_Storage_4\S40M.edb'... DONE! Moving 'T:\EXCHSRVR\S40M_TEMP.STM' to 'T:\EXCHSRVR\Clay_Storage_4\S40M.stm'... DONE! Note: It is recommended that you immediately perform a full backup of this database. If you restore a backup made before the defragmentation, the database will be rolled back to the state it was in at the time of that backup. Operation completed successfully in 21.0 seconds. Always makes for a good Monday morning I am curious about how you're working with the process id's within this though - I was working with another author's personal mod as I didn't see much within the AutoIT docs about how to tell who the owner of a particular process was when you could potentially have 5 cmd.exe and 5 eseutil.exe processes running simultaneously (as it does in this example). Edited May 18, 2009 by adamsre Link to comment Share on other sites More sharing options...
adamsre Posted May 18, 2009 Author Share Posted May 18, 2009 (edited) Thought I would throw this in there as well for any other Exchange Admin: This is the script I stumbled across to Mount / Dismount / Delete Information Stores from the command-line. This is the VBS script that is referenced from within the AutoIT script in the off-chance anyone was interested. Props to the original author. expandcollapse popup' Name: StoreDB.VBS ' Purpose: To Mount, Dismount, or Delete a Mailbox Store (MDB) on Exchange Server ' 'Written by Leon Funnell 'email me at leon_funnell(At)hotmail(d0t)com '17/02/2005 ' ' quot = chr(34) Set iServer = CreateObject ("CDOEXM.ExchangeServer") Set iMDB = CreateObject ("CDOEXM.MailboxStoreDB") ' check command line GetArgs strMode,strComputerName,strSGName,strMDBName,CorrectSyntax If CorrectSyntax Then BindMailboxStore strComputerName,strSGName,strMDBName Select Case strMode Case "mount" WScript.echo "Mounting Database " & strMDBName & " in Storage Group " & strSGName & " on " & strComputerName iMDB.mount Case "dismount" WScript.echo "Dismounting Database " & strMDBName & " in Storage Group " & strSGName & " on " & strComputerName iMDB.dismount Case "delete" WScript.echo "Deleting Database " & strMDBName & " in Storage Group " & strSGName & " on " & strComputerName iMDB.DataSource.delete End Select ' Cleanup Set iServer = Nothing Set iMDB = Nothing Else DisplayHelp WScript.quit End If Sub BindMailboxStore (strComputerName,strSGName,strMDBName) ' Bind to the Exchange Server iServer.DataSource.Open strComputerName ' Build the first part of the URL to the MailboxStoreDB strTemp = "LDAP://" & iServer.DirectoryServer & "/" & "cn=" & strMDBName & "," ' Set variant array to the ExchangeServer.StorageGroups arrStGroup = iServer.StorageGroups ' Look in the StorageGroups array if the StorageGroup with strSGName exists If strSGName = "" Then ' Add last part to the URL to the MailboxStoreDB strMDBUrl = strTemp & iServer.StorageGroups(0) Else For i = 0 To UBound(arrStGroup) If InStr(1, UCase(arrStGroup(i)), UCase(strSGName)) <> 0 Then strMDBUrl = arrStGroup(i) End If Next If strMDBUrl <> "" Then ' Add last part to the URL to the MailboxStoreDB strMDBUrl = strTemp & strMDBUrl End If End If ' Bind to the MailboxStoreDB iMDB.DataSource.Open strMDBUrl ', , , adCreateOverwrite End Sub Sub GetArgs(strMode,strComputerName,strSGName,strMDBName,CorrectSyntax) Set Args = WScript.Arguments If args.count = 4 Then CorrectSyntax = True strMode = args(0) strComputerName = args(1) strSGName = args(2) strMDBName = args(3) Else CorrectSyntax = False End If Select Case lcase(strMode) Case "mount","dismount","delete" CorrectSyntax = True Case "/?","/help","?","help" CorrectSyntax = False End Select End Sub Sub DisplayHelp WScript.echo "Mounts, Dismounts, or Deletes a Mailbox Store on an Exchange 2000/2003 server" WScript.echo "" WScript.echo "cscript StoreDB.vbs /? or /Help ----------------------------------- Displays this help screen" WScript.echo "cscript StoreDB.vbs Mount Servername StorageGroupName MDBName ----- Mounts Database" WScript.echo "cscript StoreDB.vbs Dismount Servername StorageGroupName MDBName -- Dismounts Database" WScript.echo "cscript StoreDB.vbs Delete Servername StorageGroupName MDBName ---- Deletes Database" WScript.echo "" WScript.echo "" WScript.echo "Example:" WScript.echo "" WScript.echo "cscript StoreDB.vbs Mount SERVER1 ""&"First Storage Group""&" ""&"Mailbox Store (SERVER1)"" WScript.echo "" End Sub Edited May 18, 2009 by adamsre Link to comment Share on other sites More sharing options...
PsaltyDS Posted May 18, 2009 Share Posted May 18, 2009 I am curious about how you're working with the process id's within this though - I was working with another author's personal mod as I didn't see much within the AutoIT docs about how to tell who the owner of a particular process was when you could potentially have 5 cmd.exe and 5 eseutil.exe processes running simultaneously (as it does in this example).No attempt was made to deal with process ownership. The unique PID is simply stored in the array $avPID. Each time a new process was run for a given store, the PID was overwritten with the new one. The OS is responsible for making each PID unique, so you don't have to worry about duplicates. You can see this quickly by opening several CMD.exe windows and looking at the PIDs in the Processes tab of Task Manager. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
adamsre Posted May 19, 2009 Author Share Posted May 19, 2009 No attempt was made to deal with process ownership. The unique PID is simply stored in the array $avPID. Each time a new process was run for a given store, the PID was overwritten with the new one. The OS is responsible for making each PID unique, so you don't have to worry about duplicates. You can see this quickly by opening several CMD.exe windows and looking at the PIDs in the Processes tab of Task Manager. Aye - I think I may have asked the question incorrectly *grin*. What I meant was how was the $avPID grabbing the PID of the process it was spawning - I got into the mindset that you had to know the application's name (eseutil.exe for example) to be able to query the process for the PID. I was trying to discern how I could tell *which* eseutil.exe was performing maintenance on a particular store. I went back through your code and saw that you grabbed it as the process was spawning through the array - very slick. I learn something new every day. I greatly appreciate your feedback, help and assistance =) As with most scripts / programs, it always spawns new ideas and variations on something you've already done successfully - I suspect this one won't be much different Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now