#115190 - 2004-02-28 05:45 PM
WMIQuery + WMIAuthenticate = WMI_Auth_Query!
|
Glenn Barnas
KiX Supporter
   
Registered: 2003-01-28
Posts: 4401
Loc: New Jersey
|
Combined the functionality of Radimus' WMIQuery with Jens' WMIAuthenticate for a recent project - had to query non-domain systems with unique credentials. Here's the result.
It adds 2 optional args to the WMIQuery for the userID and Password. WMIAuthenticate code has basically replaced the original object creation code in WMIQuery, and it's varnames have been updated to match WMIQuery's use.
Thanks to the original code authors - I just joined the "peanut butter" with the "chocolate".
BLACK = Radimus' original code
BLUE = Jens' transplanted code (with vars renamed)
RED = Glenn's additions
Code:
;FUNCTION WMIQuery
;
;ACTION Queries WMI information from supported systems
;
;AUTHOR Radimus - Base code
; Jens Meyer (sealeopard@usa.net) - Authentication
; Glenn Barnas - merge base & authentication code
;
;CONTRIBUTORS kdyer, Shawn, And Howard
;
; gbarnas: expanded Loop & If statements (improve clarity while evaluating code)
; altered EXECUTE function for NoVarsInStrings support
; added SNVerify() for FRIT environment
; merged authentication support from Jens' fnWMIAuthenticate UDF
;
;VERSION 2.4.2
;
;DATE CREATED 12/22/2001
;
;DATE MODIFIED 09/23/2003
;DATE CONVERTED 02/26/2004
;
;KIXTART 4.x
;
;SYNTAX WMIQuery($what,$from,optional $computer,optional $where, optional $x, Optional $UID, Optional $Pwd)
;
;PARAMETERS $what
;
;
; $from
; - Win32 Collection
;
; optional $computer
; - defaults to local PC
;
; optional $where
; - addl parameter for a 'WHERE' clause. Used with $x
;
; optional $x
; - addl parameter for a 'WHERE' clause. Used with $Where
;
; optional $fUserID
; - User ID for when authentication is needed
;
; optional $fUserPW
; - User Password for when authentication is needed
;
;
;RETURNS Array
; @error 1 = Cannot create COM object on target PC
;
;REMARKS This is chage alters the return from the function into an ARRAY, where the previous version
; was a pipe '|' delimited string. If you are updating to this version, check your code closely
;
;DEPENDENCIES kix 4.x+, WMI
;
;EXAMPLE $make = WMIQuery("Manufacturer","Win32_ComputerSystem")[0]
; $modem = WMIQuery("Description","Win32_POTSModem",$remotePC,"Status","OK")[0]
; for each $stick in WMIQuery("Capacity","Win32_PhysicalMemory")
; ? val($stick) / 1048576
; next
;
;KIXTART BBS http://www.kixtart.org/board/ultimatebb.php?ubb=get_topic;f=12;t=000117
; http://download.microsoft.com/download/platformsdk/wmicore/1.5/W9XNT4/EN-US/wmicore.EXE
Function WMIQuery($sWhat, $sFrom, Optional $sComputer, Optional $sWhere, Optional $x, Optional $root, $sUserID, $sUserPW)
Dim $sQuery, $objEnum, $sValue, $sItem, $Tmp, $SystemSet
Dim $, $objInstance, $Dollar, $oCmd, $objLocator, $objWBEM
$Dollar = Chr(36)
If Not $sComputer
$sComputer = "."
EndIf
;if instr($sComputer,'\')
; $sComputer=Right($sComputer,instrrev($sComputer,'\'))
;Endif
$sComputer = SNVerify($sComputer, 1)
$root = trim($root) ; GAB added
if not $root
$root="\root\cimv2"
Endif
$sQuery = "Select " + $sWhat + " From "+ $sFrom
If $sWhere AND $x
$sQuery = $sQuery+" Where "+$sWhere+" = '"+$x+"'"
EndIf
; this is the original Object definition
; $SystemSet = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" + $sComputer + $root)
; Heavy mods here to integrate WMIAuthenticate() functionality =======================
; Jens' code has been transplanted, and integrated with appropriate varname changes
; check to see whether we're connecting to a local or remote computer
$sComputer = trim($sComputer)
select
case $sComputer = @WKSTA
$sComputer = '.'
case $sComputer
case 1
$sComputer='.'
endselect
select
case $sUserID and $sComputer <> '.'
; create locator object for connection to a remote computer
$objLocator = CreateObject('WbemScripting.SWbemLocator')
if @ERROR
exit @ERROR
endif
; create an credentialed (username/password provided) connection to a remote computer
$SystemSet = $objLocator.ConnectServer($sComputer, $root, $sUserID, $sUserPW)
if @ERROR
exit @ERROR
endif
; set the impersonation level
$SystemSet.Security_.ImpersonationLevel = 3
if @ERROR
exit @ERROR
endif
case 1
;set the impersonation level
$SystemSet = GetObject('winmgmts:{impersonationLevel=impersonate}!\\' + $sComputer + $root)
if @ERROR
exit @ERROR
endif
endselect
; original code resumes ==============================================================
If @ERROR
Exit Val("&" + Right(DecToHex(@ERROR), 4))
EndIf
$objEnum = $SystemSet.ExecQuery($sQuery)
If @ERROR
Exit Val("&" + Right(DecToHex(@ERROR), 4))
EndIf
For Each $objInstance in $objEnum
If $objInstance
$oCmd = $Dollar + 'sValue = ' + $Dollar + 'objInstance.' + $sWhat
$ = Execute($oCmd)
if VarType($sValue) & 8192
For Each $sItem in $sValue
$Tmp = $Tmp + '|' + Trim($sItem)
Next
else
$Tmp = $Tmp + '|' + Trim($svalue)
Endif
EndIf
Next
$WMIQuery = Split(SubStr($Tmp,2), '|')
Exit Val("&" + Right(DecToHex(@ERROR), 4))
EndFunction
_________________________
Actually I am a Rocket Scientist!
|
Top
|
|
|
|
#115199 - 2004-02-29 06:27 AM
Re: WMIQuery + WMIAuthenticate = WMI_Auth_Query!
|
Radimus
Moderator
   
Registered: 2000-01-06
Posts: 5187
Loc: Tampa, FL
|
If you haven't posted a seperate thread for this, I can integrate it. I did see a spot that could be integrated a touch better...
I don't know if this board software will allow me to edit the original post, but I'll give it a shot.
|
Top
|
|
|
|
#115200 - 2004-02-29 09:42 AM
Re: WMIQuery + WMIAuthenticate = WMI_Auth_Query!
|
Radimus
Moderator
   
Registered: 2000-01-06
Posts: 5187
Loc: Tampa, FL
|
wanna try this one...
Code:
FUNCTION WMIQuery($sWhat, $sFrom, Optional $sComputer, Optional $sWhere, Optional $x, Optional $root, Optional $sUserID, Optional $sUserPW)
Dim $sQuery, $objEnum, $sValue, $TMP, $SystemSet, $, $objInstance, $objLocator
if instr($sComputer,'\')
$sComputer = right($sComputer,instrrev($sComputer,'\'))
Endif
If Not $sComputer or $sComputer = @wksta
$sComputer = '.'
EndIf
if not $root
$root = '\root\cimv2'
Endif
$sQuery = 'Select ' + $sWhat + ' From '+ $sFrom
If $sWhere AND $x
$sQuery = $sQuery+' Where '+$sWhere+' = '"+$x+"'"
EndIf
if $sUserID and $sUserPW and $sComputer <> '.'
$objLocator = CreateObject('WbemScripting.SWbemLocator')
If @ERROR or not $objLocator Exit VAL("&"+Right(DecToHex(@ERROR),4)) EndIf
$SystemSet = $objLocator.ConnectServer($sComputer, $root, $sUserID, $sUserPW)
If @ERROR or not $SystemSet Exit VAL("&"+Right(DecToHex(@ERROR),4)) EndIf
$SystemSet.Security_.ImpersonationLevel = 3
else
$SystemSet = GetObject("winmgmts:{impersonationLevel=impersonate}!\\"+$sComputer+$root)
If @ERROR or not $SystemSet Exit VAL("&"+Right(DecToHex(@ERROR),4)) EndIf
Endif
$objEnum = $SystemSet.ExecQuery($sQuery)
If @ERROR or not $objEnum Exit VAL("&"+Right(DecToHex(@ERROR),4)) EndIf
For Each $objInstance in $objEnum
$=Execute(Chr(36) + 'sValue = ' + Chr(36) + 'objInstance.' + $sWhat)
$tmp = $tmp +'|' + iif(VarType($sValue) & 8192,join($sValue,'|',ubound($sValue)),$sValue)
Next
$WMIQuery = split(substr($tmp,2),'|')
Exit VAL("&"+Right(DecToHex(@ERROR),4))
ENDFUNCTION
Edited by Radimus (2004-02-29 09:44 AM)
|
Top
|
|
|
|
#115203 - 2004-02-29 04:26 PM
Re: WMIQuery + WMIAuthenticate = WMI_Auth_Query!
|
Radimus
Moderator
   
Registered: 2000-01-06
Posts: 5187
Loc: Tampa, FL
|
the weird hex @error statements were pointed out to me to convert WMI or COM error numbers into the equivalent Kix error code values.
personally, I;d just pull all the error trapping out, except for just before the the for each statement. I typically don't need to know why it failed, just that it did. since that I know that this UDF is pretty much 100% if there is a problem it is usually with the OS on the target machine. However, since putting in the authentication model, there is a point of failure, so that only leaves 1 possibly unnecessary statement, so it may as well be left in.
if It all works and tests out, I may Lonk it and strip all the vars down to 2 chars and make it completely unreadable, but more compact. I am quite proud of this line: $tmp = $tmp +'|' + iif(VarType($sValue) & 8192,join($sValue,'|',ubound($sValue)),$sValue)
|
Top
|
|
|
|
#115205 - 2004-02-29 05:46 PM
Re: WMIQuery + WMIAuthenticate = WMI_Auth_Query!
|
Radimus
Moderator
   
Registered: 2000-01-06
Posts: 5187
Loc: Tampa, FL
|
if instr($sComputer,'\') $sComputer = right($sComputer,instrrev($sComputer,'\')) Endif
could be replaced by
$sComputer = trim(join(split($sComputer,'\'),''))
and I screwed up this line...
$sQuery = $sQuery+" Where "+$sWhere+" = '"+$x+"'"
(this one works)
|
Top
|
|
|
|
#115207 - 2004-02-29 07:04 PM
Re: WMIQuery + WMIAuthenticate = WMI_Auth_Query!
|
Radimus
Moderator
   
Registered: 2000-01-06
Posts: 5187
Loc: Tampa, FL
|
this one is working for me...
Code:
FUNCTION WMIQuery($sWhat, $sFrom, Optional $sComputer, Optional $sWhere, Optional $x, Optional $root, Optional $sUserID, Optional $sUserPW) Dim $sQuery, $objEnum, $sValue, $TMP, $SystemSet, $, $objInstance, $objLocator
$sComputer = trim(join(split($sComputer,'\'),''))
; if instr($sComputer,'\') ; $sComputer = right($sComputer,instrrev($sComputer,'\')) ; Endif If Not $sComputer or $sComputer = @wksta $sComputer = '.' EndIf if not $root $root = '\root\cimv2' Endif $sQuery = 'Select ' + $sWhat + ' From '+ $sFrom If $sWhere AND $x $sQuery = $sQuery+" Where "+$sWhere+" = '"+$x+"'" EndIf if $sUserID and $sUserPW and $sComputer <> '.' $objLocator = CreateObject('WbemScripting.SWbemLocator') If @ERROR or not $objLocator Exit VAL("&"+Right(DecToHex(@ERROR),4)) EndIf $SystemSet = $objLocator.ConnectServer($sComputer, $root, $sUserID, $sUserPW) If @ERROR or not $SystemSet Exit VAL("&"+Right(DecToHex(@ERROR),4)) EndIf $SystemSet.Security_.ImpersonationLevel = 3 else $SystemSet = GetObject("winmgmts:{impersonationLevel=impersonate}!\\"+$sComputer+$root) If @ERROR or not $SystemSet Exit VAL("&"+Right(DecToHex(@ERROR),4)) EndIf Endif $objEnum = $SystemSet.ExecQuery($sQuery) If @ERROR or not $objEnum Exit VAL("&"+Right(DecToHex(@ERROR),4)) EndIf For Each $objInstance in $objEnum $=Execute(Chr(36) + 'sValue = ' + Chr(36) + 'objInstance.' + $sWhat) $tmp = $tmp +'|' + iif(VarType($sValue) & 8192,join($sValue,'|',ubound($sValue)),$sValue) Next $WMIQuery = split(substr($tmp,2),'|') Exit VAL("&"+Right(DecToHex(@ERROR),4)) ENDFUNCTION
|
Top
|
|
|
|
Moderator: Glenn Barnas, NTDOC, Arend_, Jochen, Radimus, Allen, ShaneEP, Ruud van Velsen, Mart
|
0 registered
and 194 anonymous users online.
|
|
|