laidback01 Posted January 28, 2008 Share Posted January 28, 2008 (edited) This is my first useful script. Its in use at our facility. Thanks belongs to autoit, the forums, and the people who answered my questions. I used code from the Help File, Koshy John's hd maintenance script, and someone else's DiskMax. Script is still really rather young, and not complete - hence the v0.3, but it's a work in progress, and maybe someone else can get some use out of it. again thanks, and I will post more at time goes on. expandcollapse popup#cs ********** Preventative Maintenance System Written By: Jack 16 Jan 2008 Call this program from command line as such: <path>\pms.exe <choice> the content you put after the command line is optional, if you put nothing, the system will bring up a GUI and run interactively. If, however, you give it a number 0 to 16, it will perform various functions. In Binary: Decimal: 0 0 0 0 0 0 =0 Leftmost column is Bit1 and rightmost column is Bit5, the others follow accordingly. 0 0 0 0 0 1 =1 A "1" in a column is a "Yes" or "Affirmative". A "0" in a column is a "No" or Negative 0 0 0 0 1 0 =2 bit0 is for GUI 0 0 0 0 1 1 =3 bit1 is for Defrag 0 0 0 1 0 0 =4 bit2 is for DiskClean 0 0 0 1 0 1 =5 bit3 is for UserClean 0 0 0 1 1 0 =6 bit4 is for WindowsUpdates 0 0 0 1 1 1 =7 bit5 is for PageFile 0 0 1 0 0 0 =8 0 0 1 0 0 1 =9 0 0 1 0 1 0 =10 0 0 1 0 1 1 =11 and so on... please determine the right combo on your own. 0 1 1 1 1 1 =95; No GUI, do everything else (basically silent operation) 1 0 0 0 0 0 =96 ; you might as well just double click the exe, as it's the same result - run the GUI, select nothing. 1 1 1 1 1 1 =127 ; don't exceed 127, it'll just drop to 127. This means run the GUI and preselect everything. #ce ********** #cs ********** INCLUDES, OPTIONS & VARIABLES #ce ********** #include <GUIConstants.au3> #include <Array.au3> Opt("TrayIconHide", 1) Opt("RunErrorsFatal", 0) ; Don't really need this script quitting because Run or RunWait freaked out. Opt("TrayIconDebug", 0) Opt('MustDeclareVars', 1) Global $version="PMS v0.3", $scrollText[16], $scrollPos=0, $needReboot=0 Global $svr="\\autoit", $share="\PMS", $user="user", $pass="pass" Global $localLog=@TempDir ; For the case that the machine this script runs on is not able to log to the autoit server. Global $REG_pageFileLoc="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management", $REG_pageFileName="PagingFiles" ; page file key information Global $localDriveLetter="T:" ; T: is one we don't use much in KRMC... so why not wink.gif Global $hdd="c:", $choice[6], $drivemapped=0 ; IF YOU MODIFIY THIS ARRAY, YOU NEED TO MODIFY THE SELECT STATEMENT BELOW AND CREATE CORRESPONDING FUNCTIONS... Global $choices[6][3] = [["Gui",0,0],["Clean Temp Files, Recycle Bin",0,0],["Set Virtual Memory Correctly",0,0],["Clean User Profiles",0,0],["Windows Updates - Broken",0,0],["Run Defrag (generally takes a long time)",0,0]] Global Const $arrayend = 5 ; the array starts at 0 always. Make sure you change this to 1 less than your max size if you change the amount of options. Global $count ; needed this for the handles and setting GUICtrlSetOnEvent for the checkboxes Global Const $test = 0 ; set to 0 to have script actually do anything besides mount/umount drives and some logging. Global $pfkeyloc="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" ; Paging File Registry Keys Global $pfkeyname="PagingFiles" ; Paging File Registry Keys Local $mem="", $pagefilesize=0, $i=0, $buffer=0 ; Check for XP First of all. if @OSVersion <> "WIN_XP" Then MsgBox(0,"Damn!","Sorry, I can't support anything but Windows XP so far...") Exit endif ; Read the first argument from the command line if $cmdline[0] > 0 Then ; Check to see that there is at least one arg. $buffer = $cmdline[1] ; because we cannot modify $cmdline if StringRegExp($buffer,"^\d+$") then ; this tests for positive integers if ( $buffer > 127) Then $buffer = 127 ; keep it sane EndIf $choice = bin($buffer) ; retrieve the array for $i=0 to $arrayend $choices[$i][1]=$choice[$i] ; modify the main array accordingly Next Else logthis("Use a number between 1 and 127", $localLog) exit endif EndIf ; Maybe later check for more than one $cmdline argument, and use those for something else handy. ; However, if it's just clicked on from the icon, start the gui, but just wait for the user. if $cmdline[0]=0 Then $choices[0][1]=1 for $i=1 to $arrayend ; starting from 1 because the "gui" is a func that's marked int the array as well, perhaps not the best way to do this... $choices[$i][1]=0 ; default them all. Next EndIf ; map the drives - so we can log and do windows updates mapAutoIT($localDriveLetter) if $choices[0][1] Then gui() unMapAutoIT($localDriveLetter) Else doFuncs() ; split out to a function because it's reuseable that way. endif ; close drives.. no need to leave these on the user's PC. unMapAutoIT($localDriveLetter) #cs ********** Functions #ce ********** Func gui() Local $windowW = 700 Local $windowH = 400 Local $mainWindow, $okbutton Opt("GUIOnEventMode",1) $mainWindow = GUICreate("Preventive Maintenance System", $windowW, $windowH) GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked") GUICtrlCreateLabel("Check your choices, then click 'Do Selected'.", 5, 10) $okbutton = GUICtrlCreateButton("Do Selected",($windowW-75),($windowH-30),70) GUICtrlSetOnEvent($okbutton,"OKButton") for $count = 1 to $arrayend ; Go from 1 because we don't want to display a checkbox for "gui" & use Global $count because of limitation of GUICtrlSetOnEvent ; capture the ControlID into the same array for later use. $choices[$count][2]= GUICtrlCreateCheckbox($choices[$count][0], 5, ($count*25)+5) GUICtrlSetOnEvent(-1, "changestate") if $choices[$count][1]=1 Then GUICtrlSetState(-1,$GUI_CHECKED) EndIf ; create state chage calls... Next Global $guiText = GUICtrlCreateEdit("",$windowW/2,5,$windowW/2-7,$windowH-40, BitOr($ES_MULTILINE,$ES_READONLY)) GUISetState(@SW_SHOW) logThis("Gui Initialized") while 1 Sleep(1000) WEnd EndFunc Func changestate() ; Rotten error checking... look this over better later. Local $i=0 ; ControlID is @GUI_CTRLID for $i=1 to $arrayend if $choices[$i][2] = @GUI_CTRLID Then if $choices[$i][1] Then $choices[$i][1] = 0 Else $choices[$i][1] = 1 EndIf EndIf Next EndFunc Func logThis($text) local $log,$loc,$success=0,$error=0 ; location of logfile. if $choices[0][1] Then ; see if the GUI is initialized. updateGUI($text) EndIf if $drivemapped Then $loc = $localDriveLetter&"\logs\" $log = FileOpen ( $loc & @ComputerName & ".log", 1 ) $success=FileWrite($log, $text& " | " & @HOUR & ":" & @MIN &" "& @MON &"/"& @MDAY &"/"& @YEAR & @CRLF) if $success <> 1 Then $error=1 EndIf FileClose($log) EndIf if $drivemapped=0 OR $error<>0 then $loc = $localLog&"\" $log = FileOpen ( $loc & @ComputerName & ".log", 1 ) $success=FileWrite($log, $text &" "& @HOUR & ":" & @MIN &" "& @MON &"/"& @MDAY &"/"& @YEAR & @CRLF) if $success <> 1 Then MsgBox(0,"","Cannot log remotely or locally... something is really screwed up here.") EndIf FileClose($log) EndIf EndFunc Func updateGUI($text) local $updatetxt = "" if $scrollpos < 15 AND $scrollpos > 0 then $scrollpos = $scrollpos + 1 $scrolltext[$scrollpos] = $text elseif $scrollpos = 0 Then $scrolltext[$scrollpos] = $text $scrollpos = $scrollpos + 1 Elseif $scrollpos >= 15 then _ArrayPush ($scrolltext, $text ,0 ) endif for $i = 0 to $scrollpos $updatetxt = $updatetxt&$scrolltext[$i]&@CRLF Next GUICtrlSetData($guiText,$updatetxt) EndFunc Func mapAutoIT($driveLetter) Local $success=0,$error=0 $success = DriveMapAdd($driveletter,$svr&$share,0,$user,$pass) $error = @error Select case $success=1 AND $error=0 $drivemapped=1 case $error=1 $success = DriveMapAdd($driveletter,$svr&$share,0); sometimes it gets screwy if you try to hand it credentials all the time. $error=@error if $success=1 AND $error=0 then $drivemapped=1 else MsgBox(0,"","Cannot map drive: Undefined / Other error. @extended set with Windows API return", 2) EndIf case $error=2 MsgBox(0,"","Cannot map drive: Access to the remote share was denied", 2) case $error=3 MsgBox(0,"","Cannot map drive: The device is already assigned", 2) case $error=4 MsgBox(0,"","Cannot map drive: Invalid device name", 2) case $error=5 MsgBox(0,"","Cannot map drive: Invalid remote share", 2) case $error=6 MsgBox(0,"","Cannot map drive: Invalid password", 2) EndSelect EndFunc Func unMapAutoIT($driveLetter) local $val=0 $val = DriveMapDel($driveletter) $drivemapped=0 EndFunc Func bin($decimal) local $retVal[6], $startVal=String($decimal), $work, $work2 ; very limited - only goes to decimal(127) - 6 "columns" ; good enough for this run though.. for $i = 5 to 0 step -1 $retVal[$i] = Int(Mod($decimal,2)) $decimal = $decimal / 2 next return $retVal EndFunc Func OKButton() ;MsgBox(0,"GUI Event","OK Clicked...") ; read thru the $choices array and find out which ones are checked and run those functions... DoFuncs() EndFunc Func CLOSEClicked() unMapAutoIT($localDriveLetter) Exit EndFunc Func DoFuncs() Local $success=0, $count, $hddfound, $return[10] for $i = 1 to $arrayend ;MsgBox(0,"Stuff",$choices[$i][0]) if $choices[$i][1] Then Select ;cleanTempFiles case $choices[$i][0] = $choices[1][0] ; Variable name in position 1,0 of $choices, this case: "Clean Temp Files, Recycle Bin". Done this way to keep you from ;cleantempfiles() ; needing to change select choices when you change the names in the $choices array. logThis("Called: cleanTempFiles()") if $test Then MsgBox(0,"Would do:","cleanTempFiles()") Else $success = cleanTempFiles($hdd) endif if $success Then logThis("cleanTempFiles() Successful") ElseIf $test=1 Then logThis("In TEST mode, nothing actually done...") ElseIf ($success=0 AND $test=0) Then logThis("Broken: cleanTempFiles(), please repair.") EndIf ;setVirtualMem case $choices[$i][0] = $choices[2][0] logThis("Called: setVirtualMem()") if $test Then MsgBox(0,"Would do:","setVirtualMem()") Else ; Get size of available memory. Do formula: ; The recommended size is 2.5 times your RAM size, and my choice is to set the Initial Size and Maximum Size values equal, to get a fixed size swap file ; We'll follow this till 4G in size for a swap file... past that's it a pain for windows to address the file size. $mem = MemGetStats() $pagefilesize = int(($mem[1] * 2.5) / 1000) $success = setVirtualMem($hdd, $pagefilesize) endif if $success Then logThis("setVirtualMem() Successful") elseif $test=1 Then logThis("In TEST mode, nothing actually done...") ElseIf ($success=0 AND $test=0) Then logThis("Broken: setVirtualMem(), please repair.") EndIf ;cleanUserProfiles case $choices[$i][0] = $choices[3][0] logThis("Called: cleanUserProfiles()") if $test Then MsgBox(0,"Would do:","cleanUserProfiles()") Else $success = cleanUserProfiles($hdd) endif if $success Then logThis("cleanUserProfiles() Successful") elseif $test=1 Then logThis("In TEST mode, nothing actually done...") ElseIf ($success=0 AND $test=0) Then logThis("Broken: cleanUserProfiles(), please repair.") EndIf ;doUpdates case $choices[$i][0] = $choices[4][0] logThis("Called: doUpdates()") if $test Then MsgBox(0,"Would do:","doUpdates()") Else $success = doUpdates() endif if $success Then logThis("doUpdates() Successful") elseif $test=1 Then logThis("In TEST mode, nothing actually done...") ElseIf ($success=0 AND $test=0) Then logThis("Broken: doUpdates(), please repair.") EndIf ;defrag case $choices[$i][0] = $choices[5][0] logThis("Called: defrag()") if $test Then MsgBox(0,"Would do:","defrag()") Else ; just in case there's more than one drive... $hddfound=DriveGetDrive("FIXED") If NOT @error Then logThis("Found " & $hddfound[0] & " drives") For $count = 1 to $hddfound[0] $return[$i]=defrag($hddfound[$count]) Next EndIf ; kind of a hack to see if it was successful or not... for $count = 1 to $return[0] ; array end $success = 1 $success = $return[$i] * $success Next endif if $success Then logThis("defrag() Successful") elseif $test=1 Then logThis("In TEST mode, nothing actually done...") ElseIf ($success=0 AND $test=0) Then logThis("Broken defrag(), please repair.") EndIf case Else MsgBox (0, "Whoops", "Next time try to fix the select statement...") EndSelect EndIf next EndFunc Func defrag($drive) local $process="", $count=0, $success=0, $remainder if IsAdmin() then if FileExists(@SystemDir&"\defrag.exe") Then $process=Run("defrag -f "&$drive,"",@SW_HIDE) logThis("Starting & Running Defrag on "&$drive) While ProcessExists($process) Sleep(1000) $count=$count+1 $remainder = mod($count,30) if $remainder = 0 Then ; repeat message every 30 secs... logThis("Defrag is still running on "&$drive&". Current time in seconds: "&$count) EndIf Wend logThis("Defrag complete; total runtime: "&($count/60)&" minutes") $success=1 Else logThis("Defrag not found") EndIf Else logThis("You need to be an admin to run defrag on drives...") EndIf return $success EndFunc Func doUpdates() return 0 EndFunc Func cleanUserProfiles($hdrive) ;finding user directories Local $i = 0, $find, $success $find = FileFindFirstFile($hdrive&"\Documents and Settings\*") If $find <> -1 Then While 1 $i = $i + 1 If $i > 75 Then logThis(" Warning: Only first 75 users are processed.") Return EndIf $user = FileFindNextFile($find) If @error = 1 Then ExitLoop If StringInStr(FileGetAttrib($hdrive&"\Documents and Settings\"&$user)&FileGetAttrib($hdrive&"\Users\"&$user),"D") = 0 Or $user = "." Or $user = ".." Or $user = "All Users" Or $user = "Local Settings" Or $user = "Default User" Or $user = "Public" Or $user = "Default" Or $user = "LocalService" Or $user = "NetworkService" Then ContinueLoop logThis(" Scanning "&$user&"'s account...") logThis("Clearing history...") rd($hdrive&"\Documents and Settings\"&$user&"\Local Settings\History") logThis("Cleared history.") logThis("Deleting temporary files...") rd($hdrive&"\Documents and Settings\"&$user&"\Local Settings\Temp") logThis("Deleted temporary files.") logThis("Emptying temporary internet files folder...") rd($hdrive&"\Documents and Settings\"&$user&"\Local Settings\Temporary Internet Files") logThis("Emptied temporary internet files folder.") logThis("Clearing cookies...") rd($hdrive&"\Documents and Settings\"&$user&"\Cookies") logThis("Cleared cookies.") logThis("Clearing recently opened documents list...") rd($hdrive&"\Documents and Settings\"&$user&"\Recent") rd($hdrive&"\Documents and Settings\"&$user&"\Application Data\Microsoft\Office\Recent") logThis("Cleared recently opened documents list.") WEnd FileClose($find) $success =1 EndIf return 1 EndFunc Func cleanTempFiles($drive) Local $file, $search, $verify, $v1, $v2, $size, $v3, $return, $folder logThis("Cleaning Temporary Files from " & $drive) ; Empty RecycleBin from $drive logThis("Emptying RecycleBin for "&$drive) $v1 = FileRecycleEmpty($drive&"\") ; If we profide no drive letter, this will empt recycle bins from all drives. if $v1 = 0 Then logThis ("Empty RecycleBin failed for drive "&$drive&"\") EndIf ; Remove the crap in the \MSOCache directory logThis("Removing Files from "&$drive&"\MSOCache") $search = FileFindFirstFile($drive&"\MSOCache\*.*") If $search = -1 Then ; Dir is empty, move on... logThis("MSOCache empty, leaving.") $v2 = 1 Else DirRemove($drive&"\MSOCache",1) ; DO NOT MAKE TYPOS IN THIS AREA... $size = DirGetSize($drive&"\MSOCache",1) ; DirGetSize in extended mode returns an array, of which the second element is filecount: $array[1] = Files count if $size[1] = 0 Then $v2 = 1 Else $v2 = 0 EndIf EndIf FileClose($search) ; Remove the crap in the \Windows\Temp directory logThis("Removing Files from "&$drive&"\Windows\Temp") $search = FileFindFirstFile($drive&"\Windows\Temp\*.*") ; Finds Dirs and Files. If $search = -1 Then ; this should provide -1 on not finding \Windows as well. ; Dir is empty, move on... logThis("Windows Temp empty, leaving.") $v3 = 1 Else FileDelete($drive&"\Windows\Temp\*.*"); Removes only the top level files.. nothing else so far... Need to handle the dirs as well. EndIf FileClose($search); Close the filehandle as soon as you are done with it... ; check to see that dir is actually empty. $search = FileFindFirstFile($drive&"\Windows\Temp\*.*") ; Finds Dirs and Files. While 1 $folder = FileFindNextFile($search) If @error Then ExitLoop ; Delete \Windows\Temp\$folder and all subdirs and files DirRemove($drive&"\Windows\Temp\"&$folder, 1) WEnd FileClose($search); Close the filehandle as soon as you are done with it... $size = DirGetSize($drive&"\Windows\Temp",1) ; DirGetSize in extended mode returns an array, of which the second element is filecount: $array[1] = Files count if ($size[1] + $size[2]) = 0 Then ; Amount of files + Amount of dirs $v3 = 1 Else $v3 = 0 EndIf ; FEATURE ADD HERE!!! ; Remove Windows Updates log files from Windows dir. ; logThis("Removing Windows Updates clutter.") ; FEATURE ADD HERE!!! $verify = $v1 * $v2 * $v3 if $verify Then return 1 Else return 0 EndIf EndFunc Func setVirtualMem($hdd, $pfsize) local $success=0, $key="" ; max pagefile can be is 4G - we make one less than 4096 just to make sure we are safe. if $pfsize > 4095 Then $pfsize = 4095 endif logThis("Setting pagefile to: "&$pfsize) $key =""$hdd&"\pagefile.sys "&$pfsize&" "&$pfsize& $success = RegWrite($pfkeyloc, $pfkeyname, "REG_MULTI_SZ", $key) if $success Then logThis("Pagefile Set to: "&$pfsize) Else if $success = 0 Then Select case @error = -2 logThis("value type not supported") case @error = -1 logThis("unable to open requested value") case @error = 1 logThis("unable to open requested key") case @error = 2 logThis("unable to open requested main key") case @error = 3 logThis("unable to remote connect to the registry") EndSelect EndIf EndIf return $success EndFunc Func rd($dir,$loop = 0,$indent = " ") ; Recurse Directory If $loop > 50 Then Return If FileExists ($dir) = 0 Then Return FileDelete($dir&"\*") logThis($indent&"+ "&$dir) Local $file,$find $find = FileFindFirstFile ($dir&"\*") If $find <> -1 Then While 1 $file = FileFindNextFile ($find) If @error = 1 Then ExitLoop If $file = "." Or $file = ".." Then ContinueLoop If FileDelete($dir&"\"&$file) = 0 And DirRemove($dir&"\"&$file,1) = 0 Then rd($dir&"\"&$file,$loop+1,$indent&" ") WEnd FileClose($find) EndIf EndFunc Edited January 29, 2008 by laidback01 Link to comment Share on other sites More sharing options...
MetalSpongebob Posted January 28, 2008 Share Posted January 28, 2008 Man there is some error,I try to correct it ^^ Noob but ethical Link to comment Share on other sites More sharing options...
laidback01 Posted January 28, 2008 Author Share Posted January 28, 2008 (edited) Man there is some error,I try to correct it ^^You need to customize it for your environment - It logs what it does to a network server for later parsing and/or troubleshooting.Near the top, you'll see a line:Global $svr="\\autoit", $share="\PMS", $user="user", $pass="pass"change that to suit. Other than that, should be good to go. Edited January 29, 2008 by laidback01 Link to comment Share on other sites More sharing options...
laidback01 Posted January 31, 2008 Author Share Posted January 31, 2008 LOL, and here I thought this was a cool idea - being able to control whether or not the gui show up or not depending on command line args... Guess it's all been done and done better... before. Only one guy comments to say there's errors, heh, and only cause he didn't read the code. Must not have fit anyone's "gotta have it" needs... Oh well. Link to comment Share on other sites More sharing options...
DirtDBaK Posted January 31, 2008 Share Posted January 31, 2008 I hate it when noobs rebuild other members scripts [center][/center] Link to comment Share on other sites More sharing options...
JustinReno Posted January 31, 2008 Share Posted January 31, 2008 I think DiskMax was from Koshy John, and nice script. Link to comment Share on other sites More sharing options...
Nahuel Posted January 31, 2008 Share Posted January 31, 2008 I thought this was some script to help you deal with women with PMS Link to comment Share on other sites More sharing options...
JustinReno Posted January 31, 2008 Share Posted January 31, 2008 I thought this was some script to help you deal with women with PMS The sad face almost implies you were hoping? Link to comment Share on other sites More sharing options...
James Posted January 31, 2008 Share Posted January 31, 2008 Don't worry. Just keep working, maybe you can make it new and better! Blog - Seriously epic web hosting - Twitter - GitHub - Cachet HQ Link to comment Share on other sites More sharing options...
jvanegmond Posted January 31, 2008 Share Posted January 31, 2008 Man there is some error,I try to correct it ^^Your PMS has PMS. github.com/jvanegmond Link to comment Share on other sites More sharing options...
laidback01 Posted January 31, 2008 Author Share Posted January 31, 2008 (edited) Thanks for all the comments both positive and negative, I've learned much about the autoit community. Edited January 31, 2008 by laidback01 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