mdwerne Posted February 10, 2009 Share Posted February 10, 2009 Hello, I have a script that searches for certian (specific) keys and if it finds them, deletes them. How might I clean up the script by using a "Wildcard" and maybe a loop through the key? Here is what I have...it works fine...but I was hoping to streamline it a bit. Thanks for any suggestions, -Mike CODE#NoTrayIcon If @OSArch = "X64" Then Exit EndIf $SCS1 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus") If @error <> 0 Then $SCS1 = "False" EndIf $SCS2 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus 10") If @error <> 0 Then $SCS2 = "False" EndIf $SCS3 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus 10.1") If @error <> 0 Then $SCS3 = "False" EndIf $SCS4 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus 10.2") If @error <> 0 Then $SCS4 = "False" EndIf If $SCS1 = "False" And $SCS2 = "False" And $SCS3 = "False" And $SCS4 = "False" Then $SCS = "False" Else $SCS = "True" EndIf $SEP = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus Outlook Protection") If @error <> 0 Then $SEP = "False" Else $SEP = "True" EndIf If $SCS = "False" And $SEP = "False" Then Exit ElseIf $SCS = "True" And $SEP = "False" Then RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus 10.2") RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus 10.1") RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus 10") RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus") Exit ElseIf $SCS = "False" And $SEP = "True" Then RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus Outlook Protection") Exit ElseIf $SCS = "True" And $SEP = "True" Then RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus") RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus 10") RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus 10.1") RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus 10.2") RegDelete("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions", "Symantec AntiVirus Outlook Protection") Exit EndIf One thing I tried was using StringRegExp and I don't think I have the syntax right. CODELocal $pattern = "Symantec [[:alnum:]]+" Local $regkey = RegRead("HKLM\SOFTWAR\Microsoft\Exchange\Client","Extensions") If StringRegExp($regkey, $pattern) Then MsgBox(64, "Info", "Key exists") Else MsgBox(16, "Error", "Key does not exist") EndIf Link to comment Share on other sites More sharing options...
Authenticity Posted February 10, 2009 Share Posted February 10, 2009 (edited) Isn't "Extensions" is a sub-key and not a value name? I believe you're reading a "(value not set)" REG_SZ value which might be just a zero length string. First confirm that the RegRead successfully read the value of the desired value name.Edit: You also got a typo :"SOFTWAR" (lol)$Key = RegRead("HKLM\SOFTWARE\Microsoft\Exchange\Client\Extensions","Exchange Extensions") MsgBox(0x40, 'Title', $Key) Edited February 10, 2009 by Authenticity Link to comment Share on other sites More sharing options...
mdwerne Posted February 10, 2009 Author Share Posted February 10, 2009 (edited) Isn't "Extensions" is a sub-key and not a value name? I believe you're reading a "(value not set)" REG_SZ value which might be just a zero length string. First confirm that the RegRead successfully read the value of the desired value name.Yep, your correct. Here is a modified version...but I still have the syntax very wrong. I have a very tough time with regular expressions. CODELocal $pattern = "Symantec [[:alnum:]]+" Local $regkey = RegRead("HKLM\SOFTWARE\Microsoft\Exchange\Client\Extensions","Default") If StringRegExp($regkey, $pattern) Then MsgBox(64, "Info", "Key exists") Else MsgBox(16, "Error", "Key does not exist") EndIf Edited February 10, 2009 by mdwerne Link to comment Share on other sites More sharing options...
Authenticity Posted February 10, 2009 Share Posted February 10, 2009 I can't really be of help if I don't know the content of the value name so what I do know is that you're telling the regex to check whether there is "Symantec" followed by a space " " and contains at least 1 digit after that... If you can give an example for a value name's value it'll help. Link to comment Share on other sites More sharing options...
mdwerne Posted February 10, 2009 Author Share Posted February 10, 2009 Sorry I'm not being clear enough. Instead of searching for the specific Symantec entry "Symantec Antivirus" (the value data makes no difference) I would like to find any value that contains the word "Symantec " and delete the whole value with its data. Does this help? As you can see in my first code box, I'm looking for each of my five Symantec names individually...I'm trying to change my code to loop through the key deleting each of the five, using some "Symantec *" wildcard. How can I do what I'm already doing more efficiently? That is my question. Thanks for the help, -Mike P.S. The "value data" of those values is a path to a dll that is fighting with the install of another application when Outlook runs. Link to comment Share on other sites More sharing options...
Authenticity Posted February 10, 2009 Share Posted February 10, 2009 (edited) $sKey = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions' $i = 1 While 1 $Key = RegEnumVal($sKey, $i) If @error = -1 Then ExitLoop If Not @error And StringRegExp($Key, 'Symantec[ ]?') Then RegDelete($sKey, $Key) ContinueLoop EndIf $i += 1 WEndEdit: pfff..., fixed my stupid mistake.Now this one will delete any key consisting of 'Symantec ' or 'Symantec' as well as 'asdSymantec 123' Edited February 10, 2009 by Authenticity Link to comment Share on other sites More sharing options...
mdwerne Posted February 10, 2009 Author Share Posted February 10, 2009 $sKey = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions' $i = 1 While 1 $Key = RegEnumVal($sKey, $i) If @error = -1 Then ExitLoop If Not @error And StringRegExp($Key, 'Symantec[ ]?') Then RegDelete($sKey, $Key) ContinueLoop EndIf $i += 1 WEnd Edit: pfff..., fixed my stupid mistake. Now this one will delete any key consisting of 'Symantec ' or 'Symantec' as well as 'asdSymantec 123'Thank you! This is exactly what I was looking for...nice, clean and simple enough for me to understand and implement. Have a great day!! -Mike Link to comment Share on other sites More sharing options...
mdwerne Posted February 11, 2009 Author Share Posted February 11, 2009 Based on Authenticity example, I "think" I simplified it even further. CODEIf @OSArch = "X64" Then Exit EndIf $sKey = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Client\Extensions' $i = 1 ;Loop through registry key ($sKey) looking for any "Symantec *" values. Delete if found. While 1 $Key = RegEnumVal($sKey, $i) If @error = -1 Then ExitLoop If Not @error And StringRegExp($Key, 'Symantec[ ]?') Then RegDelete($sKey, $Key) ContinueLoop EndIf $i += 1 WEnd $i = 1 $Key = RegEnumVal($sKey, $i) ;Check for absence of "Symantec *" values. If Not StringRegExp($Key, 'Symantec[ ]?') Then mgsbox(0,"result","keys gone") Else mgsbox(0,"result","keys not gone") EndIf Exit Link to comment Share on other sites More sharing options...
Archie Posted May 20, 2010 Share Posted May 20, 2010 Hi guys, I know that this thread is pretty old but i really hope someone picks up on it. I have been using AutoIT for a couple of years now but only in a very basic form (to automatically install software). I have now been given the task to regularly check when our Windows 2000 and 2003 servers have last had their windows updates installed on them (no, we don't have a WSUS server). The way i plan on doing this is by quering the registry to find the "last installed" update. What i want to do is write a query that searches the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ part of the registry for anything beginning with KB. Once i have those results, search the registry (above mentioned results) for the string values of "InstallDate" and ultimatley end up with the latest date. I know this seems like a long winded way but as i said, its part of a script that runs this task (along with a regread to show OS version and SP level) on 14 MS servers. Any help on this would be really appreciated. Archie Link to comment Share on other sites More sharing options...
zorphnog Posted May 20, 2010 Share Posted May 20, 2010 (edited) As long as the machines have been updated through the Windows Update Services, and not manually, this will show you the last update.$oSession = ObjCreate("Microsoft.Update.Session") If @error Then ConsoleWrite("Error creating session" & @CRLF) Exit EndIf $oSearcher = $oSession.CreateUpdateSearcher() $oHistoryColl = $oSearcher.QueryHistory(0, 1) For $iHistory In $oHistoryColl ConsoleWrite(" Title: " & $iHistory.Title & @CRLF) ConsoleWrite("Description: " & $iHistory.Description & @CRLF) ConsoleWrite(" Date: " & StringRegExpReplace($iHistory.Date, "([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})", "\1/\2/\3 \4:\5:\6") & @CRLF & @CRLF) NextOr for the full history:$oSession = ObjCreate("Microsoft.Update.Session") If @error Then ConsoleWrite("Error creating session" & @CRLF) Exit EndIf $oSearcher = $oSession.CreateUpdateSearcher() $iTotal = $oSearcher.GetTotalHistoryCount() ConsoleWrite("Total history events: " & $iTotal & @CRLF) $oHistoryColl = $oSearcher.QueryHistory(0, $iTotal) For $iHistory In $oHistoryColl ConsoleWrite(" Title: " & $iHistory.Title & @CRLF) ConsoleWrite("Description: " & $iHistory.Description & @CRLF) ConsoleWrite(" Date: " & StringRegExpReplace($iHistory.Date, "([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})", "\1/\2/\3 \4:\5:\6") & @CRLF & @CRLF) Next Edited May 20, 2010 by zorphnog Link to comment Share on other sites More sharing options...
Archie Posted May 21, 2010 Share Posted May 21, 2010 Hi zorphnog, Thanks for the speedy reply. I just wanted to ask a couple of questions first (and please excuse my ignorance). What is an Object in AutoIT and how can i interact with it. The other thing i wanted to ask was, how would i get the results from your script to "print to a file". While i dont need the full windows update history for what i want to achieve, i do have to have it. The only data i want to print to the file is along the lines of "Server X was last updated on dd/mm/yyyy" and possible the name (or KB number) of the last installed update. My script works in the following way: I have a file called server_list.ini In there, i have section 1 with the key value = to server 1, section 2 with the key value of server 2, etc etc My script reads the .ini file and runs a DriveMapAdd to the \ipc$ for each server (in order to authenticate using $username and $password variables taken from an InputBox ) and then performs a reg read to check OS ver and SP level (on each server). It does the above for 14 servers and writes the regread results to a file. Link to comment Share on other sites More sharing options...
zorphnog Posted May 21, 2010 Share Posted May 21, 2010 (edited) An object in AutoIt is a COM reference http://www.autoitscript.com/autoit3/docs/intro/ComRef.htm. A reference to a COM object allows you to get/set properties and perform it's methods. These properties and methods are unique to each COM object and you must refer to the COM API in order understand how to access and use the object. For this example I used a Windows Update Agent (WUA) API http://msdn.microsoft.com/en-us/library/aa387292%28VS.85%29.aspx. I'm not sure how familiar you are with AutoIt, but COM interfaces are a bit more complex than normal functions in AutoIt so it's not something that can be picked up easily.As far as making the results print to file, that's pretty simple. You can specify the servername/IP and authentication information in the ObjCreate function. I would store all your connection information (Servername/IP, Username, Password) in an array and then loop through the array for each connection to get the information. So something like this should do the trick.expandcollapse popup$sIniFile = "C:\server_list.ini " $aSections = IniReadSectionNames($sIniFile) If @error Then MsgBox(16, "ERROR", "Cannot read ini file") Exit EndIf Dim $aConnection[$aSections[0]][3] ; Create array for connection data $hOutfile = FileOpen("C:\ServerUpdates.txt", 2) ; Open new file in write mode For $i=0 To $aSections[0] - 1 $aConnection[$i][0] = IniRead($sIniFile, $aSections[$i+1], "server", 0) ; Get servername/IP $aConnection[$i][1] = InputBox($aConnection[$i][0], "Enter username:", "") ; Get username $aConnection[$i][2] = InputBox($aConnection[$i][0], "Enter password:", "", "*") ; Get password ; Enter code for ipc connection and registry reads here ; Get update information $oSession = ObjCreate("Microsoft.Update.Session", $aConnection[$i][0], $aConnection[$i][1], $aConnection[$i][2]) If @error Then MsgBox(16, "ERROR", "Error creating session for " & $aConnection[$i][0]) ContinueLoop EndIf $oSearcher = $oSession.CreateUpdateSearcher() $oHistoryColl = $oSearcher.QueryHistory(0, 1) For $iHistory In $oHistoryColl ; Write last update time and title to file FileWriteLine($hOutfile, "Server [" & $aConnection[$i][0] & "] was updated on " & _ StringRegExpReplace($iHistory.Date, "([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})", "\1/\2/\3 \4:\5:\6") & _ " [" & $iHistory.Title & "]") Next $oSession = 0 $oSearcher = 0 $oHistoryColl = 0 Next FileClose($hOutfile) Edited May 21, 2010 by zorphnog Link to comment Share on other sites More sharing options...
Archie Posted May 22, 2010 Share Posted May 22, 2010 Thanks for everything. So far this is what i have and most of it works but there are still some major glitches. The 1st problem i have is that for some reason, i can not pass through the admin user name and password properly (unless i am logged onto a machine with exactly the same username and password. The other problem i have is, if i connect to a server that has never had a windows update done on it, the entire script stops. I would like to have some sort of "this server has never been updated" report written to the history.txt file, and then continue through the ini file (getting update info from the other servers. Like i said, i am pretty stumped here and about to give up on the whole thing all together so any advice would be appriciated. Code is below: For $section = 1 to 14 Step +1 $host1 = IniRead("server_list.ini", $section, "key", "file not found") $host = String($host1);<------------------------ This took me ages to figure out!!! $Username1 = (InputBox("Login", "Please enter a username","", "", 200, 120)) $Username = "\" & $username1 $Password = (InputBox("Security Check", "Enter your password.", "", "*", 200, 120)) $oSession = ObjCreate("Microsoft.Update.Session", $host, $host & $username, $password) ;If @error Then ; ConsoleWrite("Error creating session" & @CRLF) ; Exit ;EndIf $oSearcher = $oSession.CreateUpdateSearcher() ;If @error Then ; ConsoleWrite("Error creating searcher" & @CRLF) ; Exit ;EndIf $iTotal = $oSearcher.GetTotalHistoryCount() ConsoleWrite("Total history events: " & $iTotal & @CRLF) $oHistoryColl = $oSearcher.QueryHistory(0, $iTotal) For $iHistory In $oHistoryColl FileWrite("temp.txt", $iHistory.Title & @CRLF) FileWrite("temp.txt", StringRegExpReplace($iHistory.Date, "([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})", "\1/\2/\3 \4:\5:\6") & @CRLF & @CRLF) Next MsgBox(0, "History", $oHistoryColl) $date =FileReadLine("temp.txt", 2) $patch = FileReadLine("temp.txt", 1) Filewrite("history.txt", "---------------------------" & @CRLF) FileWrite("history.txt", "The last installed update was " & $patch & @CRLF) Filewrite("history.txt", $host & " was last updated on " & $date & @CRLF) Filewrite("history.txt", "---------------------------" & @CRLF) FileDelete("temp.txt") Next MsgBox(64, "End", "Query Complete") Link to comment Share on other sites More sharing options...
Archie Posted May 23, 2010 Share Posted May 23, 2010 (edited) Ok, I have pretty got everything i want in the script now. The only problem i still have are: If any server has never been updated, the entire scripts stops at that point. The other problem is, if i am not logged onto a machine with exactly the same username and password that the servers have, the objcreate fails. For some reason, the $username and $password dont seem to get passed through (Even though a quick glance at net use shows a mapping to the IPC$ of each server. Here is what i have working at the moment (without $username and $password). expandcollapse popup;+++++++++++++++Delete previously run reports If FileExists(@ScriptDir &"\Full_history") Then DirRemove(@ScriptDir &"\Full_history", 1) EndIf if FileExists(@ScriptDir & "\history.txt") Then FileDelete(@ScriptDir & "\history.txt") EndIf ;+++++++++++++++Delete previously run reports DirCreate("Full_History") ;---------------Time stamp and username in report $file = FileOpen("history.txt", 1) If $file = -1 Then MsgBox(0, "Error", "Unable to open file.") Exit EndIf $date = @HOUR & ":" & @MIN & " on the " & @MDAY & "/" & @MON & "/" & @YEAR $Current_User = @UserName FileWrite($file, "This report was generated by " & $Current_User & " at " & $date & @CRLF) FileWrite($file, " " & @CRLF) FileWrite($file, "The latest Service pack for Windows 2003 server is Service Pack 2. The latest service pack for Windows 2000 is Service Pack 4" & @CRLF) FileWrite($file, " " & @CRLF) FileWrite($file, " " & @CRLF) FileWrite($file, " " & @CRLF) FileClose($file) ;---------------Time stamp and username in report ;-----------------Start of loop---------------------- For $section = 3 to 14 Step +1 ;*************Start of Windows OS and SP version read************* $host1 = IniRead("server_list.ini", $section, "key", "file not found") $host = String($host1) $WinVerPath = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" $reg_1 = "\\" & $host & "\" & $WinVerPath $ProductName = RegRead ($reg_1, "ProductName") $ServicePack = RegRead ($reg_1, "CSDVersion") $OS_Info = "Server " & $host & " is running " & $ProductName & " " & $ServicePack $oSession = ObjCreate("Microsoft.Update.Session", $host) ;If @error Then ; ConsoleWrite("Error creating session" & @CRLF) ; Exit ;EndIf $oSearcher = $oSession.CreateUpdateSearcher() ;If @error Then ; ConsoleWrite("Error creating searcher" & @CRLF) ; Exit ;EndIf $iTotal = $oSearcher.GetTotalHistoryCount() ConsoleWrite("Total history events: " & $iTotal & @CRLF) $oHistoryColl = $oSearcher.QueryHistory(0, $iTotal) For $iHistory In $oHistoryColl FileWrite("Full_History\" & $host & "_FullHistory.txt", $iHistory.Title & @CRLF) FileWrite("Full_History\" & $host & "_FullHistory.txt", StringRegExpReplace($iHistory.Date, "([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})", "\1/\2/\3 \4:\5:\6") & @CRLF & @CRLF) Next ;MsgBox(0, "History", $oHistoryColl) $date =FileReadLine("Full_History\" & $host & "_FullHistory.txt", 2) $patch = FileReadLine("Full_History\" & $host & "_FullHistory.txt", 1) Filewrite("history.txt", "---------------------------" & @CRLF) FileWrite("history.txt", $OS_Info & @CRLF) Filewrite("history.txt", $host & " was last updated on " & $date & @CRLF) FileWrite("history.txt", "The last installed update was " & $patch & @CRLF) Filewrite("history.txt", "---------------------------" & @CRLF) FileWrite("history.txt", " " & @CRLF) FileWrite("history.txt", " " & @CRLF) ;-----------------End of loop---------------------- Next $file = FileOpen("history.txt", 1) FileWrite("history.txt", "" & @CRLF) FileWrite("history.txt", "" & @CRLF) FileWrite("history.txt", "******************************* Report complete *******************************" & @CRLF) FileWrite("history.txt", "" & @CRLF) FileWrite("history.txt", "" & @CRLF) FileClose("history.txt") MsgBox(64, "Complete!", "The query has completed successfuly. You can view each server's full update history by looking in the folder " & @ScriptDir & "\Full_history") $File_Path = "history.txt" $Read_Report = MsgBox(68, "View Report","Would you like to view the summarised report?") If $Read_Report = 6 Then Run('Notepad.exe "' & $File_Path & '"', '', @SW_MAXIMIZE) EndIf Edited May 23, 2010 by Archie 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