#79594 - 2003-03-02 12:26 AM
Problem with semisyncronous WMI query
|
Sealeopard
KiX Master
Registered: 2001-04-25
Posts: 11164
Loc: Boston, MA, USA
|
I've been testing the UDF below with KiXtart and I've found that it apparently does not support semisynchronous queries with WMI. Semisynchronous queries are faster and require less memory overhead on the queried computer. These queries are generated through a ExecQuery($query,'WQL',48) call.
When uncommenting the line that activates semisynchronous queries, the UDF still works without raising an error message. However, all array fields are empty even though the correct number of rows/columns are returned.
code:
; some test code first $events = ReadEventlog('Security',528,@WKSTA,'2003/03/01 00:00:00') ? ubound($events,1) ? ubound($events,2) for $a=0 to ubound($events,1) for $b=0 to ubound($events,2) ? 'Events['+$a+','+$b+'] = '+$events[$a,$b] next next $rc='SELECT TimeGenerated, User FROM Win32_NTLogEvent WHERE Logfile="System" AND TimeGenerated>="20030225000000.000000-300"' $events = ReadEventlog($rc) ? ubound($events,1) ? ubound($events,2) for $a=0 to ubound($events,1) for $b=0 to ubound($events,2) ? 'Events['+$a+','+$b+'] = '+$events[$a,$b] next next
; here's the UDF
;FUNCTION ReadEventlog() ; ;ACTION Retrieves events from the eventlog ; ;AUTHOR Jens Meyer ; ;VERSION 1.4 ; ;KIXTART VER 4.20 ; ;SYNTAX RETCODE = READEVENTLOG(EVENTLOG, EVENTID, OPTIONAL COMPUTER, OPTIONAL DATETIME, ; OPTIONAL USERNAME, OPTIONAL PASSWORD) ; ;PARAMETERS EVENTLOG ; Name of the eventlog, e.g. 'Security', 'System','Application' ; Alternatively, a custom WQL query can be provided. Date fields in ; a WQL query MUST be properly formatted as YYYY/MM/DD HH:MM:SS:000 ; ; EVENTID ; Optional Event ID number to be retrieved ; ; COMPUTER ; optional name of a remote computer which eventlog is to be queried. If no ; username/password is provided then the current users credentials will be ; used to connect to the remote event log. ; ; DATETIME ; optional date/time string denoting the start date of the events in ; the form of YYYY/MM/DD HH:MM:SS, YYY/MM/DD, or HH:MM:SS ; ; USERNAME ; optional username which will be used to connect to a remote computer ; ; PASSWORD ; optional password which will be used to connect to the remote computer ; ;RETURN array of events or empty string ; ;REMARKS returns a 2-dimensional array with the following columns. If custom WQL is ; used, then the SELECT part of the custom WQL determines the field assignments. ; ; Column 0 = Category ; Column 1 = CategoryString ; Column 2 = ComputerName ; Column 3 = Data ; Column 4 = EventCode ; Column 5 = EventIdentifier ; Column 6 = EventType ; Column 7 = InsertionStrings ; Column 8 = Logfile ; Column 9 = Message ; Column 10 = RecordNumber ; Column 11 = Source Name ; Column 12 = TimeGenerated ; Column 13 = TimeWritten ; Column 14 = Type ; Column 15 = User ; ;DEPENDENCIES WMI ; ;EXAMPLE $events = ReadEventlog('Security',528) ; $events = ReadEventlog('Security',528,,'COMPUTER') ; $events = ReadEventlog('Security',528,'2002/09/01 00:00:00','COMPUTER','Administrator','password') ; $events = ReadEventlog('SELECT TimeGenerated, User FROM Win32_NTLogEvent ; WHERE Logfile="Security" AND EventCode=528 AND ; TimeGenerated>="2002/09/01 00:00:00:000"' ; ;KIXTART BBS http://www.kixtart.org/cgi-bin/ultimatebb.cgi?ubb=get_topic&f=12&t=000270 ; function ReadEventlog($eventlog, optional $eventid, optional $computer, optional $datetime, optional $username, optional $password) dim $objLocator, $objWBEM, $objWMIResults, $namespace dim $event, $item, $wqlQuery, $eventarray dim $customwql, $customfields, $field dim $rownumber, $arrayrows, $arraycolumns, $columnnumber dim $byte, $datastring, $date, $time, $querydate, $querytime, $timezone dim $objWMIService, $colItems, $objItem
$namespace = 'root\CIMV2'
if trim($eventlog)='' exit 87 endif
; check to see whether we're connecting to a local or remote eventlog $computer=trim($computer) select case $computer=@WKSTA $computer='.' case $computer case 1 $computer='.' endselect
if $username and $computer<>'.' ; create locator object for connection to a remote computer $objLocator = CreateObject('WbemScripting.SWbemLocator') if @ERROR exit @ERROR endif ; create a (credentialed, if username/password provided) connection to a remote computer $objWBEM=$objLocator.ConnectServer($computer,$namespace,$username,$password) if @ERROR exit @ERROR endif ; set the impersonation level $objWBEM.Security_.ImpersonationLevel = 3 if @ERROR exit @ERROR endif else ;set the impersonation level and make sure we have security permissions if $eventlog='Security' $objWBEM=GetObject('winmgmts:{impersonationLevel=impersonate, (Security)}!\\'+$computer+'\'+$namespace) else $objWBEM=GetObject('winmgmts:{impersonationLevel=impersonate}!\\'+$computer+'\'+$namespace) endif if @ERROR exit @ERROR endif endif
; check to see whether we're looking for an event ID or if there's a custom query if left($eventlog,6)='select' $wqlquery=$eventlog $arraycolumns=trim(substr($wqlquery,instr($wqlquery,' ')+1,instr($wqlquery,'FROM')-instr($wqlquery,' ')-2)) if instr($arraycolumns,'*') $arraycolumns=16 $customwql=0 else $customfields=split(trim($arraycolumns),',') for $arraycolumns=0 to ubound($customfields) $customfields[$arraycolumns]=trim($customfields[$arraycolumns]) next $arraycolumns=ubound($customfields)+1 $customwql=1 endif else $customwql=0 $arraycolumns=16 $eventid=val($eventid) $wqlQuery="SELECT * FROM Win32_NTLogEvent WHERE Logfile='"+$eventlog+"' AND EventCode="+val($eventID)
if $datetime $colItems = $objWBEM.ExecQuery('Select CurrentTimeZone from Win32_ComputerSystem') if @ERROR exit @ERROR endif
for each $objItem in $colItems $timezone = $objItem.CurrentTimeZone next
$objWMIService = 0 $colItems = 0 $objItem = 0
$datetime=trim($datetime)
select case instr($datetime,' ') $date=left($datetime,instr($datetime,' ')-1) $time=substr($datetime,instr($datetime,' ')+1) case instr($datetime,'/') $date=$datetime $time='00:00:00' case instr($datetime,':') $date=@DATE $time=$datetime case 1 $date=@DATE $time=@TIME endselect if $date and $time $datetime=join(split($date,'/'),'')+join(split($time,':'),'')+'.000000'+$timezone else $datetime='' endif
$wqlQuery=$wqlQuery+' AND TimeGenerated>="'+$datetime+'"' endif endif
;------------------------------------------ ;| beginning of problematic code fragment | ;------------------------------------------
; the following line would not work ; $objWMIResults = $objWBEM.ExecQuery($wqlQuery,'WQL',48) ; this line would work ; $objWMIResults = $objWBEM.ExecQuery($wqlQuery,'WQL',0) ; this line would work $objWMIResults = $objWBEM.ExecQuery($wqlQuery)
;------------------------------------------ ;| end of problematic code fragment | ;------------------------------------------
if @ERROR exit @ERROR endif
$rownumber = 0 $columnnumber = 0 ; this is for semisyncronous queries $arrayrows=0 for each $event in $objWMIResults $arrayrows=$arrayrows+1 next ; otherwise, this could be used for non-semisynchronous queries ;$arrayrows = val($objWMIResults.Count)
if $arrayrows=0 $ReadEventlog='' return endif
redim $eventarray[$arrayrows-1,$arraycolumns-1]
for each $event in $objWMIResults $columnnumber = 0 for each $item in $event.Properties_ if $customwql=0 or ascan($customfields,$item.name)+1 select case $item.Name='Data' $datastring='' for each $byte in $event.Data if $byte=0 $byte=46 endif $datastring=$datastring+chr($byte) next $eventarray[$rownumber,$columnnumber]=$datastring case $item.name='InsertionStrings' $eventarray[$rownumber,$columnnumber]=join($item.Value,@CRLF) case $item.name='TimeGenerated' or $item.Name='TimeWritten' $time=left($item.Value,4)+'/'+substr($item.Value,5,2)+'/'+substr($item.Value,7,2)+' ' $time=$time+substr($item.Value,9,2)+':'+substr($item.Value,11,2)+':'+substr($item.Value,13,2) $eventarray[$rownumber,$columnnumber]=$time case 1 $eventarray[$rownumber,$columnnumber]=$item.Value endselect $columnnumber=$columnnumber+1 endif next $rownumber=$rownumber+1 next
$objWMIResults = 0 $objWBEM = 0 $objLocator = 0 $ReadEventlog = $eventarray exit 0
endfunction
[ 02. March 2003, 01:35: Message edited by: sealeopard ]
_________________________
There are two types of vessels, submarines and targets.
|
Top
|
|
|
|
Moderator: ShaneEP, Arend_, Jochen, Radimus, Glenn Barnas, Allen, Ruud van Velsen, Mart
|
0 registered
and 507 anonymous users online.
|
|
|