Jump to content

Registry Wildcard


mdwerne
 Share

Recommended Posts

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.

CODE
Local $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

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 by Authenticity
Link to comment
Share on other sites

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.

CODE
Local $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 by mdwerne
Link to comment
Share on other sites

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

$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'

Edited by Authenticity
Link to comment
Share on other sites

$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

Based on Authenticity example, I "think" I simplified it even further.

CODE
If @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

  • 1 year later...

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

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)
Next

Or 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 by zorphnog
Link to comment
Share on other sites

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

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.

$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 by zorphnog
Link to comment
Share on other sites

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

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).

;+++++++++++++++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 by Archie
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...