Open-AudIT https://www.open-audit.org/phpBB3/ |
|
New "audit_domain" script https://www.open-audit.org/phpBB3/viewtopic.php?f=20&t=4081 |
Page 1 of 1 |
Author: | Mark [ Mon Jan 24, 2011 4:45 pm ] |
Post subject: | New "audit_domain" script |
Please feel free to give this a shot. Differences are -
test for connection before running "audit_windows" non-connecting machines are logged to output_err_file with the intention of inputting this into OAv2 (will happen later). varying debug levels - 0,1,2 can now audit a specific OU [code]' the number of audits to run concurrently number_of_audits = 10 debug_level = 1 ' the name and path of the audit script to use script_name = "c:\audit\audit_windows.vbs" ' set the below to your active directory domain ' format of LDAP://your.domain.org or LDAP://OU=group,DC=yourdomain,DC=org local_domain = "LDAP://your.domain.org" ' if operating_system has a value, ' restricts the audit to only systems with the specified operating system ' leave blank for all computers, regardless of OS operating_system = "Windows 2000 Professional" operating_system = "Windows 2000 Server" operating_system = "Windows XP" operating_system = "Windows Server 2003" operating_system = "Windows Vista" operating_system = "Windows 7" operating_system = "Windows Server 2008" operating_system = "Server" operating_system = "" ' if set, create an output file of all retrieved systems from active directory output_file = "" output_err_file = "error_pcs.txt" ' below we take any command line arguements ' to override the variables above, simply include them on the command line like submit_online=n Set objArgs = WScript.Arguments For Each strArg in objArgs argName = left(strArg,inStr(strArg,"=")-1) argValue = mid(strArg,inStr(strArg,"=")+1) select case argName case "output_file" output_file = argValue case "output_err_file" output_err_file = argValue case "operating_system" operating_system = argValue case "local_domain" local_domain = argValue case "script_name" script_name = argValue case "number_of_audits" number_of_audits = int(argValue) case "debug_level" debug_level = int(argValue) end select Next if (debug_level > 0) then wscript.echo "Arguements and Variables" wscript.echo "-------------------" wscript.echo "Debug Level: " & debug_level wscript.echo "Output File: " & output_file wscript.echo "Output Error File: " & output_err_file wscript.echo "Operating System: " & operating_system wscript.echo "Domain: " & local_domain wscript.echo "Audit Script Name: " & script_name wscript.echo "Number of concurrent audits: " & number_of_audits wscript.echo "-------------------" end if ' leave the below settings strComputer = "." const HKEY_CLASSES_ROOT = &H80000000 const HKEY_CURRENT_USER = &H80000001 const HKEY_LOCAL_MACHINE = &H80000002 const HKEY_USERS = &H80000003 const FOR_APPENDING = 8 const ADS_SCOPE_SUBTREE = 2 Const adOpenStatic = 3 set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") set objWMIService2 = GetObject("winmgmts:\\" & strComputer & "\root\WMI") set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv") set objShell = CreateObject("WScript.Shell") set objFSO = CreateObject("Scripting.FileSystemObject") set wshNetwork = WScript.CreateObject( "WScript.Network" ) set objlocalwmiservice = getobject("winmgmts:root\cimv2") set colitems = objlocalwmiservice.execquery("select * from win32_process",,48) for each objitem in colitems if instr (objitem.commandline, wscript.scriptname) <> 0 then current_pid = objitem.processid end if next if (debug_level > 0) then wscript.echo "Script Process ID: " & current_pid wscript.echo "-------------------" end if Set adoCommand = CreateObject("ADODB.Command") Set adoConnection = CreateObject("ADODB.Connection") adoConnection.Provider = "ADsDSOObject" adoConnection.Open "Active Directory Provider" Set adoCommand.ActiveConnection = adoConnection ' Search entire Active Directory domain. Set objRootDSE = GetObject("LDAP://RootDSE") strDNSDomain = objRootDSE.Get("defaultNamingContext") strBase = "<" & local_domain & ">" ' Filter on user objects. strFilter = "(&(objectCategory=computer))" ' Comma delimited list of attribute values to retrieve. strAttributes = "name, adspath, operatingSystem, operatingSystemVersion, operatingsystemservicepack" ' Construct the LDAP syntax query. strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree" if (debug_level > 1) then wscript.echo "Ldap Query: " & strQuery end if adoCommand.CommandText = strQuery adoCommand.Properties("Page Size") = 100 adoCommand.Properties("Timeout") = 30 adoCommand.Properties("Cache Results") = False adoCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE Set adoRecordset = CreateObject("ADODB.Recordset") Set adoRecordset.ActiveConnection = adoConnection adoRecordset.Properties("Page Size") = 100 adoRecordset.Properties("Timeout") = 30 'adoRecordset.Properties("Cache Results") = False adoRecordset.Properties("Searchscope") = ADS_SCOPE_SUBTREE ' Assign cursorType that allows forward and backward movement. adoRecordset.cursorType = adOpenStatic ' Run the query. adoRecordset.Source = strQuery adoRecordset.Open ' Display number of records. ' This positions the cursor at the end of the recordset. total_retrieved_computers = adoRecordset.RecordCount - 1 ' Move the cursor back to the beginning. ' The cursorType assignment allows this. adoRecordset.MoveFirst redim pc_array(total_retrieved_computers) ' set array to computer count redim err_array(5, total_retrieved_computers) ' set array to computer count if (debug_level > 0) then wscript.echo "-------------------" wscript.echo "number of systems retrieved from ldap: " & total_retrieved_computers wscript.echo "-------------------" end if all_count = 0 err_count = 0 if (debug_level > 0) then wscript.echo "Testing systems for connectivity." wscript.echo "-------------------" end if count = 0 Do Until adoRecordset.EOF count = count + 1 system_name = adoRecordset.fields("name").value computer_os = adoRecordset.fields("operatingSystem").value if ( ((len(operating_system) >= 0) AND (instr(computer_os, operating_system) > 0)) AND (instr(system_name, "DPWQBELL") = 0) AND (instr(system_name, "DPWCTX") = 0) ) then if (debug_level > 0) then wscript.echo system_name & " - matches OS filter" end if if (not isempty(adoRecordset.fields("operatingSystem").value)) then ad_operatingsystem = adoRecordset.fields("operatingSystem").value else ad_operatingsystem = "" end if if (not isempty(adoRecordset.fields("operatingSystemVersion").value)) then ad_os_version = adoRecordset.fields("operatingSystemVersion").value else ad_os_version = "" end if if (not isempty(adoRecordset.fields("operatingsystemservicepack").value)) then ad_servicepack = adoRecordset.fields("operatingsystemservicepack").value else ad_servicepack = "" end if if (not isempty(adoRecordset.fields("adspath").value)) then ad_ou = Mid(adoRecordset.fields("adspath").value, InStr(adoRecordset.fields("adspath").value, ",")+1, len(adoRecordset.fields("adspath").value)) else ad_ou = "" end if if (debug_level > 1) then wscript.echo system_name wscript.echo "Match On: " & operating_system wscript.echo "OS: " & computer_os wscript.echo "Formatted ADS Path: " & ad_ou wscript.echo "ServicePack: " & ad_servicepack wscript.echo "Version: " & ad_os_version end if strCommand = "%comspec% /c ping -n 3 -w 1000 " & system_name & "" Set objExecObject = objShell.Exec(strCommand) 'clears echo replies left in strText from the previous loop strText="" Do While Not objExecObject.StdOut.AtEndOfStream strText = objExecObject.StdOut.ReadAll() If Instr(strText, "Reply") > 0 Then If Err.Number > 0 then ' On, but returned an error. err_count = err_count + 1 err_array(1, err_count) = system_name err_array(2, err_count) = ad_operatingsystem err_array(3, err_count) = ad_servicepack err_array(4, err_count) = ad_ou if (debug_level >0) then wscript.echo space(len(system_name)) & " - cannot connect" end if else ' Available. all_count = all_count + 1 pc_array(all_count) = system_name ' feed computers into array if (debug_level >1) then wscript.echo space(len(system_name)) & " - can connect" end if num_running = HowMany while num_running > number_of_audits wscript.echo("processes running (" & num_running & ") greater than number wanted (" & number_of_audits & ")") wscript.echo("therefore - sleeping for 4 seconds.") wscript.sleep 4000 num_running = HowMany wend command1 = "cscript //nologo " & script_name & " " & pc_array(i) set sh1=wscript.createobject("wscript.shell") sh1.run command1, 6, false set sh1 = nothing num_running = HowMany end if 'flushes error code from the previous loop Err.Clear Else ' Unavailable. err_count = err_count + 1 err_array(1,err_count) = system_name err_array(2, err_count) = ad_operatingsystem err_array(3, err_count) = ad_servicepack err_array(4, err_count) = ad_ou err_array(5, err_count) = ad_os_version if (debug_level >0) then wscript.echo space(len(system_name)) & " - cannot connect" end if End If Loop else if (debug_level > 1) then wscript.echo " " & system_name & " - does not match OS filter" end if end if if (debug_level > 1) then wscript.echo "-------------------" end if adoRecordset.MoveNext loop ' Clean up. adoRecordset.Close adoConnection.Close if (debug_level > 0) then wscript.echo "-------------------" wscript.echo "number of systems retrieved from ldap: " & total_retrieved_computers wscript.echo "number of available matching systems: " & all_count wscript.echo "number of uncontactable matching systems: " & err_count wscript.echo "-------------------" end if redim Preserve pc_array(all_count) redim Preserve err_array(5, err_count) ' generates a text file of retrieved PCs if (output_file > "") then for i = 0 to ubound(pc_array) retrieved_from_ad = retrieved_from_ad & pc_array(i) & vbcrlf next set objTS = objFSO.OpenTextFile(output_file, FOR_APPENDING, True) objTS.Write retrieved_from_ad end if if (ubound(err_array,2) > 0) then ' todo ' send the output of each line of err_array to an input page from OAv2 result = "<?xml version=""1.0"" encoding=""ISO-8859-1""?>" & vbcrlf system_timestamp = Year(Now()) & "-" & Right("0" & Month(Now()),2) & "-" & Right("0" & Day(Now()),2) & " " & Right("0" & Hour(Now()),2) & ":" & Right("0" & Minute(Now()),2) & ":" & Right("0" & Second(Now()),2) for i = 1 to ubound(err_array,2) system_os_family = os_family(err_array(2,i)) system_os_icon = os_icon(err_array(2,i)) result = result & "<system>" & vbcrlf result = result & " <sys>" & vbcrlf result = result & " <system_timestamp>" & escape_xml(system_timestamp) & "</system_timestamp>" & vbcrlf result = result & " <system_hostname>" & escape_xml(err_array(1,i)) & "</system_hostname>" & vbcrlf result = result & " <system_domain>" & escape_xml(err_array(4,i)) & "</system_domain>" & vbcrlf result = result & " <system_type>system</system_type>" & vbcrlf result = result & " <system_os_icon>" & system_os_icon & "</system_os_icon>" & vbcrlf result = result & " <system_os_group>Windows</system_os_group>" & vbcrlf result = result & " <system_os_family>" & escape_xml(system_os_family) & "</system_os_family>" & vbcrlf result = result & " <system_os_name>" & escape_xml(err_array(2,i)) & "</system_os_name>" & vbcrlf result = result & " <system_os_version>" & escape_xml(err_array(5,i)) & "</system_os_version>" & vbcrlf result = result & " </sys>" & vbcrlf result = result & "</system>" & vbcrlf next ' generates a text file of PCs that we cannot connect to if (output_err_file > "") then set objTS = objFSO.OpenTextFile(output_err_file, FOR_APPENDING, True) objTS.Write result end if end if ' finish up wscript.quit() Function HowMany() Dim Proc1,Proc2,Proc3 CheckForHungWMI() Set Proc1 = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") Set Proc2 = Proc1.ExecQuery("select * from win32_process" ) HowMany=0 For Each Proc3 in Proc2 If LCase(Proc3.Caption) = "cscript.exe" Then HowMany=HowMany + 1 End If Next End Function Sub CheckForHungWMI() ' Get the current date in UTC format Set dtmStart = CreateObject("WbemScripting.SWbemDateTime") dtmStart.SetVarDate Now, True ' Subtract the script_timeout value dtmNew = DateAdd("s", (script_timeout * -1), dtmStart.GetVarDate(True)) ' Convert our dtmNew time back to UTC format, since that's the format needed for the WMIService query, below. Set dtmTarget = CreateObject("WbemScripting.SWbemDateTime") dtmTarget.SetVarDate dtmNew, True Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") ' Pull a list of all processes that are over (script_timeout) seconds old Set colProcesses = objWMIService.ExecQuery _ ("Select * from Win32_Process WHERE CreationDate < '" & dtmTarget & "'") For each objProcess in colProcesses ' Look for cscript.exe processes only if objProcess.Name = "cscript.exe" then ' Look for audit.vbs processes with the //Nologo cmd line option. ' NOTE: The //Nologo cmd line option should NOT be used to start the initial audit, or it will kill itself off after script_timeout seconds if InStr(objProcess.CommandLine, "//Nologo") and InStr(objProcess.CommandLine, "audit.vbs") then ' The command line looks something like this: "C:\WINDOWS\system32\cscript.exe" //Nologo audit.vbs S0259W11 ' Get the position of audit.vbs in the command line, and add 10 to get to the start of the workstation name position = InStr(objProcess.CommandLine, "audit.vbs") + 10 affectedComputer = Mid(objProcess.CommandLine,position) Echo("" & Now & "," & affectedComputer & " - Hung Process Killed. ") LogKilledAudit("Hung Process Killed for machine: " & affectedComputer) objProcess.Terminate end if end if Next End Sub Function LogKilledAudit(txt) on error resume next dim Today, YYYYmmdd, fp, txtarr, txtline, todaystr today=Now logfilename="killed_audits.log" todaystr=datepart("yyyy", today)&"/"&_ right("00"&datepart("m", today), 2)&"/"&_ right("00"&datepart("d", today), 2)&" "&_ right("00"&datepart("h", today), 2)&":"&_ right("00"&datepart("n", today), 2)&":"&_ right("00"&datepart("s", today), 2) Set objFSO = CreateObject("Scripting.FileSystemObject") set fp=objFSO.OpenTextFile(logfilename, 8, true) If err<>0 then wscript.echo err.number&" "&err.description txtarr=Split(txt, vbcrlf) txt="" For each txtline in txtarr txtline=trim(txtline) if txtline<>"" then txt=txt&todaystr&" - "&txtline&vbcrlf End if Next WScript.Echo(left(txt, len(txt)-2)) fp.write txt fp.Close set fp=Nothing LogKilledAudit=True End Function function os_family(os) if InStr(os, " 95") then os_family="Windows 95" if InStr(os, " 98") then os_family="Windows 98" if InStr(os, " NT") then os_family="Windows NT" if InStr(os, "2000") then os_family="Windows 2000" if InStr(os, " XP") then os_family="Windows XP" if InStr(os, "2003") then os_family="Windows 2003" if InStr(os, "Vista") then os_family="Windows Vista" if InStr(os, "2008") then os_family="Windows 2008" if InStr(os, "Windows 7") then os_family="Windows 7" end function function os_icon(os) if InStr(os, " 95") then os_icon="windows_old" if InStr(os, " 98") then os_icon="windows_old" if InStr(os, " NT") then os_icon="windows_old" if InStr(os, "2000") then os_icon="windows_old" if InStr(os, " XP") then os_icon="windows" if InStr(os, "2003") then os_icon="windows" if InStr(os, "Vista") then os_icon="windows" if InStr(os, "2008") then os_icon="windows_new" if InStr(os, "Windows 7") then os_icon="windows_new" end function function escape_xml(data) if IsNull(data) then escape_xml = "" else data = replace(data,"&","&") data = replace(data,"<","<") data = replace(data,">",">") data = replace(data,"""",""") data = replace(data,"'","'") data = trim(data) escape_xml = data end if end function[/code] |
Author: | jpa [ Tue Jan 25, 2011 2:38 am ] |
Post subject: | Re: New "audit_domain" script |
FYI the meat of the script is commented out: [code]num_running = HowMany while num_running > number_of_audits wscript.echo("processes running (" & num_running & ") greater than number wanted (" & number_of_audits & ")") wscript.echo("therefore - sleeping for 4 seconds.") wscript.sleep 4000 num_running = HowMany wend 'command1 = "cscript //nologo " & script_name & " " & pc_array(i) 'set sh1=wscript.createobject("wscript.shell") 'sh1.run command1, 6, false 'set sh1 = nothing num_running = HowMany[/code] |
Author: | jpa [ Tue Jan 25, 2011 3:16 am ] |
Post subject: | Re: New "audit_domain" script |
Tried it but I think you'll get complaints from those with larger infrastructure. The connectivity test penalty is pretty sizable. If you've got debug = 0 then I'd say most people would kill the cscript and open a bug saying nothing happens. |
Author: | Mark [ Tue Jan 25, 2011 8:40 am ] |
Post subject: | Re: New "audit_domain" script |
[quote]Tried it but I think you'll get complaints from those with larger infrastructure. The connectivity test penalty is pretty sizable. If you've got debug = 0 then I'd say most people would kill the cscript and open a bug saying nothing happens. Yeah - I think you're right. Maybe I should move the connectivity test into audit_windows, but if I do that I won't have the other AD attributes... (audit_windows just takes the PC name). Maybe I should just write an audit_active_directory script to get all info from AD and dump it into OAv2 ? It would be a completely seperate script... Thoughts ? |
Author: | user123 [ Wed Jan 26, 2011 12:07 am ] |
Post subject: | Re: New "audit_domain" script |
Hi, i just tried the new script. I got @ all machines (i have debug on) "- cant connect". What could we have done wrong? THX for your answer! |
Author: | jpa [ Wed Jan 26, 2011 10:45 am ] |
Post subject: | Re: New "audit_domain" script |
With this script the audited machines need to respond to ping requests. Try a manual ping. If they don't respond then you can't use this script. |
Author: | user123 [ Wed Jan 26, 2011 5:41 pm ] |
Post subject: | Re: New "audit_domain" script |
Hi, that is exactly the problem,the machines are accessible. There is no firewall active. |
Author: | jpa [ Fri Jan 28, 2011 3:18 am ] |
Post subject: | Re: New "audit_domain" script |
Try this and post the output. [code]system_name = "systemnamehere" strCommand = "%comspec% /c ping -n 3 -w 1000 " & system_name & "" set objShell = CreateObject("WScript.Shell") set objExecObject = objShell.Exec(strCommand) strText="" Do While Not objExecObject.StdOut.AtEndOfStream strText = objExecObject.StdOut.ReadAll() wscript.echo strText wscript.echo "Error: " & Err.Number Loop[/code] |
Author: | Mark [ Fri Jan 28, 2011 6:26 am ] |
Post subject: | Re: New "audit_domain" script |
I've fixed (removed the comments) from the original post - oops |
Author: | user123 [ Fri Jan 28, 2011 7:14 am ] |
Post subject: | Re: New "audit_domain" script |
Hi, there it is: [code]Ping SRVVMWSUSKAS.gs.darc.local [192.168.1.25] mit 32 Bytes Daten: Antwort von 192.168.1.25: Bytes=32 Zeit=1ms TTL=128 Antwort von 192.168.1.25: Bytes=32 Zeit=31ms TTL=128 Antwort von 192.168.1.25: Bytes=32 Zeit<1ms TTL=128 Ping-Statistik für 192.168.1.25: Pakete: Gesendet = 3, Empfangen = 3, Verloren = 0 (0% Verlust), Ca. Zeitangaben in Millisek.: Minimum = 0ms, Maximum = 31ms, Mittelwert = 10ms[/code] Ok, what now? |
Author: | snue [ Tue May 10, 2011 9:44 pm ] |
Post subject: | Re: New "audit_domain" script |
Hi, its a bit late, but ive run into the same problem and fixed it: "Reply" works only with the english version of ping/windows, so you have to change line 230 in audit_domain from If Instr(strText, "Reply") > 0 Then to If Instr(strText, "Antwort") > 0 Then Maybe Mark knows another way to check if the ping did work and will change it, but this workaround works for now. |
Author: | snue [ Tue May 10, 2011 10:04 pm ] |
Post subject: | Re: New "audit_domain" script |
Oh.. and another Issue i ran into, but this time couldnt solve it myself... the script every time has one computer less than there are actually in the ldap when "number of systems retrieved from ldap: " shows up - and everytime it wants to audit the last/missing one (if its 6, at the seventh, if its 4, at the fifth) it crashes with "Index out of range: 'all_count'", code: 800A0009 - line 244, unit 16 (at p from pc_array): pc_array(all_count) = system_name ' feed computers into array ive looked through the code (i dont have any idea of coding or vbs, just logical workthrough - but maybe i can help with this) and found this on line 154: ' Display number of records. ' This positions the cursor at the end of the recordset. total_retrieved_computers = adoRecordset.RecordCount - 1 maybe there is the error, as total_retrieved_computers seems to be wrong after this. |
Page 1 of 1 | All times are UTC + 10 hours |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |