RemoteWmiInfo

From AutoIt Wiki
Revision as of 18:54, 26 September 2009 by TMA-2 (talk | contribs) (Removed reference to internal AD stuff in a comment.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Script: remoteWMIInfo

Author: Jon Dunham

Description: Mostly-functioning example script for how to retrieve WMI information, as well as working with GUI controls. I currently use it a lot in my job, and works quite well at this point. It's commented sparingly thus far, but I'll try and and comment more of it for educational purposes. Please don't hesitate to contact me if you find problems with it or have ideas on improving its efficiency.

Notes: The Remote and Logoff buttons are disabled by default, as they're dependent on whether you have access to an internal LANDesk management suite URL (which is what I use specifically, it could also easily be changed to use WinVNC and the like), as well as the psShutdown tool. Also, bear this in mind:

"my code is a dog's code" - R. Beef Kazenzakis


; UDF
#include <date.au3>
#include <ie.au3>
#include <array.au3>
#include <misc.au3>
#include <guiStatusBar.au3>

; Standard
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <Constants.au3>

; -( remoteWmiInfo )--------------------
;
; © Jon Dunham 2009
;
; displays WMI and AD info including;
; 	0: Computer model
;	1: Serial Number & Asset (if found)
;	2: BIOS Version
;	3: total RAM
;	4: Operating system & service pack
;	5: MAC Address
;   6; private IP
;	7: current domain/user, including display name and SID (in a tooltip)
;	8: DefaultUserName, including display name and SID (in a tooltip)
;	9: time to connect in ms & ping
;  10: Bottom-level OU
;  11; IP address
;  12; wireless info from wirelessInfo.au3
;  13; active monitor model
;  14; active monitor serial (to some extent)
;  BLAH BLAH I'M NOT UPDATING THIS ANY MORE
;
; also uses psShutdown and LANDesk
;  for remoting convenience
;
; ======================================

Dim $compName, $go, $done
Global Const $version = "0.4.10"
Global $debug = 0
Global $pathSave = @MyDocumentsDir & "\remoteWmiInfo Queries\"

AutoItSetOption("TrayAutoPause", 0)
AutoItSetOption("GUICloseOnESC", 1)

;HotKeySet( "{ENTER}", "hotkey_enter" )
;HotKeySet( "{F1}", "aboutDiag" )

; make sure icons exist
DirCreate("Icons")
If Not FileExists("Icons\Dialog-Apply.ico") Then _
		FileInstall("Icons\Dialog-Apply.ico", "Icons\Dialog-Apply.ico")
If Not FileExists("Icons\Gnome-Document-Save.ico") Then _
		FileInstall("Icons\Gnome-Document-Save.ico", "Icons\Gnome-Document-Save.ico")
If Not FileExists("Icons\Gnome-Preferences-Desktop-Remote-Desktop.ico") Then _
		FileInstall("Icons\Gnome-Preferences-Desktop-Remote-Desktop.ico", "Icons\Gnome-Preferences-Desktop-Remote-Desktop.ico")
If Not FileExists("Icons\Gnome-Application-Exit.ico") Then _
		FileInstall("Icons\Gnome-Application-Exit.ico", "Icons\Gnome-Application-Exit.ico")


#Region ### START Koda GUI section ### Form=
$frmInfo = GUICreate("remoteWmiInfo " & $version, 337, 377, @DesktopWidth / 2, @DesktopHeight * 0.3)
$winSize = WinGetClientSize($frmInfo)
GUISetBkColor(0xEEEEEE)
GUISetIcon("Icons\Gnome-System-Search.ico")

;	Top Controls
$editComp = GUICtrlCreateInput(@ComputerName, 4, 30, 329, 21, $ES_UPPERCASE)

GUICtrlCreateIcon("Icons\Dialog-Apply.ico", -1, 4, 4, 21, 21)
$btnGo = GUICtrlCreateButton("Query", 27, 4, 45, 21, $BS_DEFPUSHBUTTON)
GUICtrlCreateIcon("Icons\Gnome-Document-Save.ico", -1, 74, 4, 21, 21)
$btnSave = GUICtrlCreateButton("Save", 97, 4, 45, 21)
GUICtrlCreateIcon("Icons\Gnome-Preferences-Desktop-Remote-Desktop.ico", -1, 144, 4, 21, 21)
$btnRC = GUICtrlCreateButton("Remote", 167, 4, 45, 21)
GUICtrlCreateIcon("Icons\Gnome-Application-Exit.ico", -1, 214, 4, 21, 21)
GUICtrlSetState($btnRC, $GUI_DISABLE)
$btnLO = GUICtrlCreateButton("Logoff", 237, 4, 45, 21)
GUICtrlSetState($btnLO, $GUI_DISABLE)
;$btnADQ = GUICtrlCreateButton( "dsQuery", 102, 29, 45, 21 )

$Tab1 = GUICtrlCreateTab(4, 56, 330, 297)
GUICtrlSetResizing($Tab1, $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)
$TabSheet1 = GUICtrlCreateTabItem("General")

;	Labels
GUICtrlCreateLabel("Model:", 12, 81, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("Serial / Asset:", 12, 105, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("BIOS Version:", 12, 129, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("Total RAM:", 12, 153, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("OS:", 12, 177, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("MAC:", 12, 201, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("IP:", 12, 225, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("OU:", 12, 249, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("Current User:", 12, 273, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("Default User:", 12, 297, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("Ping:", 12, 321, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)

;	Edit controls

$editModel = GUICtrlCreateInput("", 96, 81, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editSerial = GUICtrlCreateInput("", 96, 105, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editBIOS = GUICtrlCreateInput("", 96, 129, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editRAM = GUICtrlCreateInput("", 96, 153, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editOS = GUICtrlCreateInput("", 96, 177, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editMAC = GUICtrlCreateInput("", 96, 201, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editIP = GUICtrlCreateInput("", 96, 225, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editDN = GUICtrlCreateInput("", 96, 249, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editUser = GUICtrlCreateInput("", 96, 273, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editDefaultUser = GUICtrlCreateInput("", 96, 297, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editPing = GUICtrlCreateInput("", 96, 321, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))


;	Wireless info
$TabSheet2 = GUICtrlCreateTabItem("Wireless")

GUICtrlCreateLabel("SSID:", 12, 81, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("BSSID:", 12, 105, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("Signal:", 12, 129, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("Noise:", 12, 153, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("Channel:", 12, 177, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)

;	Edits

$editSSID = GUICtrlCreateInput("", 96, 81, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editBSSID = GUICtrlCreateInput("", 96, 105, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editSignal = GUICtrlCreateInput("", 96, 129, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editNoise = GUICtrlCreateInput("", 96, 153, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editChannel = GUICtrlCreateInput("", 96, 177, 228, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))

;	Misc info (incl. monitor)
$TabSheet3 = GUICtrlCreateTabItem("Misc")

$Group1 = GUICtrlCreateGroup("Monitor", 12, 86, 313, 102)
GUICtrlCreateLabel("Model:", 20, 106, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("Serial:", 20, 130, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("Description:", 20, 154, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
$editDmName = GUICtrlCreateInput("", 96, 106, 212, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editDmSerial = GUICtrlCreateInput("", 96, 130, 212, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editDmDesc = GUICtrlCreateInput("", 96, 154, 212, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))

$Group2 = GUICtrlCreateGroup("Software", 12, 190, 313, 102)
GUICtrlCreateLabel("IE:", 20, 210, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("Java RE:", 20, 234, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
GUICtrlCreateLabel("LANDesk:", 20, 258, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
$editVerIE = GUICtrlCreateInput("", 96, 210, 212, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editVerJava = GUICtrlCreateInput("", 96, 234, 212, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))
$editLD = GUICtrlCreateInput("", 96, 258, 212, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))

; default printer

GUICtrlCreateLabel("Printer:", 20, 300, 70, 17)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
$editPrinter = GUICtrlCreateInput("", 96, 300, 212, 22, BitOR($ES_AUTOHSCROLL, $ES_READONLY))

;	End tab section
GUICtrlCreateTabItem("")
GUISetState(@SW_SHOW)
;$background = GUICtrlCreatePic( "c:\temp\osxclonebg.jpg", 0, 0, 350, 274)

GUICtrlSetTip($btnGo, "Attempt to query the specified computer.")
GUICtrlSetTip($btnSave, "Save all fields to " & $pathSave & "COMPUTERNAME-" & @YEAR & @MON & @MDAY & ".txt")
GUICtrlSetTip($btnRC, "Start a remote control session with the specified computer.")
GUICtrlSetTip($btnLO, "Logoff the current user (please make sure nobody is using it before doing this!!!).")

$statusBar = _GUICtrlStatusBar_Create($frmInfo)
; try to make a dynamically-sized status size
Dim $StatusBar1_PartsWidth[2] = [StringLen(_NowTime(5) & " >") * 6.5, -1]
_GUICtrlStatusBar_SetParts($statusBar, $StatusBar1_PartsWidth)
_GUICtrlStatusBar_SetText($statusBar, _NowTime(5) & " >", 0)
_GUICtrlStatusBar_SetText($statusBar, "", 1)
_GUICtrlStatusBar_SetMinHeight($statusBar, 20)
#EndRegion ### END Koda GUI section ###

Dim $goState, $logoffCheck

While 1 ; main loop
	$guiMsg = GUIGetMsg()

	Select
		; Close window
		Case $guiMsg = $GUI_EVENT_CLOSE
			GUIDelete()
			Exit
			; Save info
		Case $guiMsg = $btnSave

			; Check that model field isn't blank
			If GUICtrlRead($editModel) <> "" Then
				Dim $stateWrite, $file

				If Not FileExists($pathSave) Then
					DirCreate($pathSave)
				EndIf

				; this needs to be updated for all fields
				$stateWrite = FileWrite($pathSave & GUICtrlRead($editComp) & "-" & @YEAR & @MON & @MDAY & ".txt", _
						"-( General )------------------------------" & @CRLF & _
						GUICtrlRead($editModel) & @CRLF & _
						GUICtrlRead($editSerial) & @CRLF & _
						GUICtrlRead($editBIOS) & @CRLF & _
						GUICtrlRead($editRAM) & @CRLF & _
						GUICtrlRead($editOS) & @CRLF & _
						GUICtrlRead($editMAC) & @CRLF & _
						GUICtrlRead($editIP) & @CRLF & _
						GUICtrlRead($editDN) & @CRLF & _
						GUICtrlRead($editUser) & @CRLF & _
						GUICtrlRead($editDefaultUser) & @CRLF & _
						GUICtrlRead($editPing) & @CRLF & _
						"-( Wireless )-----------------------------" & @CRLF & _
						GUICtrlRead($editSSID) & @CRLF & _
						GUICtrlRead($editBSSID) & @CRLF & _
						GUICtrlRead($editSignal) & @CRLF & _
						GUICtrlRead($editNoise) & @CRLF & _
						GUICtrlRead($editChannel) & @CRLF & _
						"-( Monitor )------------------------------" & @CRLF & _
						GUICtrlRead($editDmName) & @CRLF & _
						GUICtrlRead($editDmSerial) & @CRLF & _
						GUICtrlRead($editDmDesc))

				If $stateWrite Then
					upStatus("Info saved to [ " & $pathSave & GUICtrlRead($editComp) & "-" & @YEAR & @MON & @MDAY & ".txt ]")
				Else
					upStatus("Could not write file to [ " & $pathSave & GUICtrlRead($editComp) & "-" & @YEAR & @MON & @MDAY & ".txt ]", 1)
				EndIf

			Else
				upStatus("No data to write!", 1)
			EndIf

			; Start the WMI query
		Case $guiMsg = $btnGo
			GUISetState(@SW_DISABLE)
			$goState = _go()
			GUISetState(@SW_ENABLE)
			WinActivate($frmInfo)
			; Start a LANDesk remote session
		Case $guiMsg = $btnRC
			If GUICtrlRead($editComp) <> "" Then
				Select
					Case $goState = 1
						Dim $rcWin = _IECreate("http://landesk/RemoteSession.aspx?machine=" & _
							GUICtrlRead($editComp) & "&operation=rc", 0, 0)
						_IEQuit($rcWin)
						$goState = 0
					Case $goState = 2
						upStatus("Computer was not contactable.", 1)
					Case $goState = 0
						upStatus("Please query the computer first.", 1)
				EndSelect
			Else
				upStatus("Please enter a computer name.", 1)
			EndIf
			; Run the logoff process if user clicks 'Yes' to the msgbox
		Case $guiMsg = $btnLO
			If GUICtrlRead($editComp) <> "" And GUICtrlRead($editUser) <> "" Then
				$logoffCheck = MsgBox(51, "Remote WMI Info", "This will log off the current user: " & _
					_currentUser(GUICtrlRead($editComp)) & "." & @CRLF & @CRLF & "Have you checked " & _
					"that the computer is not in use?")
				If $logoffCheck = 6 Then
					ShellExecute("psTools\psshutdown.exe", "-o \\" & GUICtrlRead($editComp))
				EndIf
			Else
				MsgBox(0, "", "No computer entered or no user currently logged on.")
			EndIf
			#cs
				Case $guiMsg = $btnADQ
				if GUICtrlRead($editComp) <> "" Then
				ShellExecute( "rundll32", "dsquery,OpenQueryWindow" )
				WinWaitActive( "Find Users" )
				ControlCommand( "Find Users", "", 16897, "SelectString", 'Computers' )
				Sleep(2000)
				WinWait( "Find Computers" )
				ControlSetText( "Find Computers", "", 1224, GUICtrlRead($editComp) )
				ControlClick( "Find Computers", "", 16901 )
				EndIf
			#ce

	EndSelect

	Sleep(10)

WEnd ; <== main loop

Func _go()
	$compName = GUICtrlRead($editComp)

	; Populate the array with WMI info, if possible
	$info = _wmiInfo($compName)

	Select
		; Ping failed
		Case @error = 7
			upStatus($info, 1)
			guiFlash($editComp, 0xFF0000, 200)
			Return 2
			; Computername contained illegal characters
		Case @error = 8
			upStatus("Please enter a valid name.", 1)
			guiFlash($editComp, 0xFF0000, 200)
			Return 2
			; Unable to get WMI info from computer after successful ping (this shouldn't really happen ever)
		Case @error = 9
			upStatus("Unable to retrieve computer info after " & Round(@extended / 1000, 1) & "s.", 1)
			guiFlash($editComp, 0xFF0000, 200)
			Return 2
			; Everything OK? DISPLAY THE INFO THEN DAMN
		Case Not @error
			upStatus($compName & " queried in " & $info[5])
			If Not WinActive($frmInfo) Then
				WinFlash($frmInfo, "", 4, 250)
			Else
				guiFlash($editComp, 0x00FF00, 200)
			EndIf

			; general info
			GUICtrlSetData($editModel, $info[0])
			GUICtrlSetData($editSerial, $info[1] & " / " & $info[10])
			GUICtrlSetData($editBIOS, $info[2])
			GUICtrlSetData($editRAM, $info[3] & " GB")
			; Set field BkColor to red if below 1 GB
			If $info[3] < 0.98 Then
				GUICtrlSetBkColor($editRAM, 0xEECCCC)
			Else
				GUICtrlSetBkColor($editRAM, Default)
			EndIf
			GUICtrlSetData($editOS, $info[4])
			; Set field BkColor to red if not Windows XP
			If Not StringInStr($info[4], "XP") Then
				GUICtrlSetBkColor($editOS, 0xEECCCC)
			Else
				GUICtrlSetBkColor($editOS, Default)
			EndIf
			GUICtrlSetData($editMAC, $info[9])
			GUICtrlSetData($editDN, $info[8])
			GUICtrlSetData($editUser, $info[6]); & " (" & _ADDNToDisplayName($info[6]) & ")" )
			GUICtrlSetData($editDefaultUser, $info[7]); & " (" & _ADDNToDisplayName($info[7]) & ")" )
			GUICtrlSetData($editPing, $info[17])
			GUICtrlSetData($editIP, $info[11])

			; wireless
			GUICtrlSetData($editSSID, $info[12])
			GUICtrlSetData($editSignal, $info[13])
			GUICtrlSetData($editNoise, $info[14])
			GUICtrlSetData($editChannel, $info[15])
			GUICtrlSetData($editBSSID, $info[18])

			; misc
			GUICtrlSetData($editDmName, $info[19])
			GUICtrlSetData($editDmSerial, $info[20])
			GUICtrlSetData($editDmDesc, $info[21])
			GUICtrlSetData($editVerIE, $info[26])
			; Set field BkColor to red if below v7
			If StringLeft($info[26], 1) < 7 Then
				GUICtrlSetBkColor($editVerIE, 0xEECCCC)
			Else
				GUICtrlSetBkColor($editVerIE, Default)
			EndIf
			GUICtrlSetData($editVerJava, $info[27])
			; Set field BkColor to red if below v1.4
			If $info[27] < 1.4 Or $info[27] = "" Then
				GUICtrlSetBkColor($editVerJava, 0xEECCCC)
			Else
				GUICtrlSetBkColor($editVerJava, Default)
			EndIf
			GUICtrlSetData($editLD, $info[28])
			; Set field BkColor to red if below v1.4
			If $info[28] = "Not running." Then
				GUICtrlSetBkColor($editLD, 0xEECCCC)
			Else
				GUICtrlSetBkColor($editLD, Default)
			EndIf

			; printer
			GUICtrlSetData($editPrinter, $info[29])

			GUICtrlSetTip($editUser, $info[24], $info[22], 1)
			GUICtrlSetTip($editDefaultUser, $info[25], $info[23], 1)
	EndSelect

	Return 1

EndFunc   ;==>_go

Exit

Func _wmiInfo($compName)

	; seterror if the computername string contains illegal characters
	If Not _computerNameLegal($compName) Then
		SetError(8)
		Return
	EndIf

	; init object variables
	Dim $objWMIService, $objAccount
	Dim $colBios, $colCSP, $colLMC, $colOS, $colNic, $colSysEnc, $colDM
	Dim $dmEDID, $dmPNPDID, $dmName
	Dim $arrCU
	Dim $ping = Ping($compName, 1000)

	If @error Then
		Select
			Case @error = 1
				SetError(7)
				Return "Computer is offline."
			Case @error = 2
				SetError(7)
				Return "Computer is unreachable."
			Case @error = 3
				SetError(7)
				Return "Bad destination, please check the name."
			Case @error = 4
				SetError(7)
				Return "Problem contacting address."
		EndSelect
	EndIf

	; init arrays we'll return
	Dim $info[31], $mInfo, $infoW, $SID

	; get IP for no good damn reason
	TCPStartup()
	$info[11] = TCPNameToIP($compName)
	TCPShutdown()

	; start the response timer
	Dim $timer = TimerInit()

	; get the WIM object
	$objWMIService = ObjGet("winmgmts:\\" & $compName & "\root\cimv2")
	;$objRegistry = ObjGet("winmgmts:\\" & $compName & "\root\default:StdRegProv")
	If $debug Then ConsoleWrite("Time after WMI connection: " & TimerDiff($timer) & @CRLF)
	; get defaultusername & software versions from the registry
	$info[7] = RegRead("\\" & $compName & "\HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon", "DefaultUserName")
	$info[30] = RegRead("\\" & $compName & "\HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon", "DefaultDomainName")
	$info[26] = RegRead("\\" & $compName & "\HKLM\SOFTWARE\Microsoft\Internet Explorer", "Version")
	$info[27] = RegRead("\\" & $compName & "\HKLM\SOFTWARE\JavaSoft\Java Runtime Environment", "CurrentVersion")
	If $debug Then ConsoleWrite("Time after registry: " & TimerDiff($timer) & @CRLF)
	; check to see if the WMI object exists; if not, seterror and return
	; this check should now be deprecated due to the use of ping()
	If Not IsObj($objWMIService) Then
		SetError(9, TimerDiff($timer))
		Return
	EndIf

	$info[17] = Round($ping, -1) & "ms"

	; check if LD remote agent (issuser) is running
	$info[28] = _processExists("issuser.exe", $compName)

	If Not $info[28] Then
		$info[28] = "Not running."
	Else
		$info[28] = "Running (PID: " & $info[28] & ")"
	EndIf

	; execquery on all the info groups we'll need
	$colBios = $objWMIService.execquery("Select * From Win32_BIOS")
	$colSysEnc = $objWMIService.execquery("Select * From Win32_SystemEnclosure")
	$colCSP = $objWMIService.execquery("Select * from Win32_ComputerSystem")
	$colLMC = $objWMIService.execquery("Select * from Win32_LogicalMemoryConfiguration")
	$colOS = $objWMIService.execquery("Select * from Win32_OperatingSystem")
	$colNic = $objWMIService.execquery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")
	If $debug Then ConsoleWrite("Time after queries: " & TimerDiff($timer) & @CRLF)
	$info[8] = _extractOU(_getDN($compName))
	If $debug Then ConsoleWrite("Time after DN: " & TimerDiff($timer) & @CRLF)
	; get monitor info
	$mInfo = monitorInfo($compName)
	If $debug Then ConsoleWrite("Time after monitorInfo: " & TimerDiff($timer) & @CRLF)
	If IsArray($mInfo) Then
		$info[19] = $mInfo[0] ; model
		$info[20] = $mInfo[1] ; serial
		$info[21] = $mInfo[2] ; name
	Else
		$info[19] = "No valid EDID found."
	EndIf

	; grab computer model & current user
	For $objCSP In $colCSP
		$info[0] = StringStripWS($objCSP.Manufacturer, 2) & " " & $objCSP.Model
		$info[6] = $objCSP.UserName
	Next

	; get current user full name and description
	If $info[6] <> "" Then
		$arrCU = StringSplit($info[6], "\", 2)
		$objAccount = $objWMIService.Get('Win32_UserAccount.Name="' & $arrCU[1] & '",Domain="' & $arrCU[0] & '"')
		If IsObj($objAccount) Then
			$info[22] = $objAccount.FullName
			$info[24] = $objAccount.Description
			$SID = $objAccount.SID
		EndIf
	EndIf
	;if $debug Then ConsoleWrite( $arrCU[1] & " SID: " & $SID & @CRLF )

	; get default user full name and description
	$objAccount = $objWMIService.Get("Win32_UserAccount.Name='" & $info[7] & "',Domain='" & $info[30] & "'")
	If IsObj($objAccount) Then
		$info[23] = $objAccount.FullName
		$info[25] = $objAccount.Description
	EndIf

	; grab the serial and BIOS version
	For $objBios In $colBios
		$info[1] = $objBios.SerialNumber
		$info[2] = $objBios.SMBIOSBIOSVersion
	Next

	; grab the asset tag, if available (it will be on HP dc7900s and possibly others)
	For $objSysEnc In $colSysEnc
		$info[10] = $objSysEnc.SMBIOSAssetTag
	Next

	; set to N/A if it didn't exist for returning purposes
	If StringIsSpace($info[10]) Then $info[10] = "Asset tag not set"

	; grab RAM, convert to GB ('cause who the fuck has less than 1GB nowadays)
	For $objLMC In $colLMC
		$info[3] = Round($objLMC.TotalPhysicalMemory / 1048576, 2)
	Next

	; grab OS
	For $objOS In $colOS
		$info[4] = $objOS.Caption & " " & $objOS.CSDVersion
	Next

	; grab MAC
	For $objNic In $colNic
		$info[9] = $objNic.MACAddress
		; check if static IP or not, indicating QS or otherwise special-purpose machine
		$info[16] = $objNic.DHCPEnabled
		If $debug Then ConsoleWrite("DHCPEnabled: " & VarGetType($info[16]) & " | Length: " & StringLen($info[16]) & @LF)

	Next

	If $debug Then ConsoleWrite("Time after objWMI grabbing: " & TimerDiff($timer) & @CRLF)

	; get wireless info if available
	$infoW = wirelessInfo($compName)
	If $debug Then ConsoleWrite("Time after wireless stats: " & TimerDiff($timer) & @CRLF)

	; ssid
	$info[12] = $infoW[0]
	; signal
	$info[13] = $infoW[1]
	; noise
	$info[14] = $infoW[2]
	; channel
	$info[15] = $infoW[3]
	; BSSID
	$info[18] = $infoW[4]


	; Strip whitespace from end of model string, 'cause there's usually a lot
	$info[0] = StringStripWS($info[0], 2)

	; get the TOTAL query time now
	$info[5] = Round(TimerDiff($timer), -1) & "ms"

	If $SID Then _
			$info[29] = defPrinterInfo($SID, $compName)

	Return $info

EndFunc   ;==>_wmiInfo

Func _currentUser($compName)
	Dim $objWMIService
	Dim $colCSP
	Dim $user

	$objWMIService = ObjGet("winmgmts:\\" & $compName & "\root\cimv2")

	If Not IsObj($objWMIService) Then Return

	$colCSP = $objWMIService.execquery("Select * from Win32_ComputerSystem")

	For $objCSP In $colCSP
		$user = $objCSP.UserName
	Next

	Return $user

EndFunc   ;==>_currentUser

Func _getDN($compName)
	Dim $objTrans, $objDomain
	Const $ADS_NAME_TYPE_1779 = 1
	Const $ADS_NAME_INITTYPE_GC = 3
	Const $ADS_NAME_TYPE_NT4 = 3

	$objTranslate = ObjCreate("NameTranslate")
	$objDomain = ObjGet("LDAP://rootDse")
	If @error Then
		Return "Could not contact domain controller."
	EndIf

	$objTranslate.Init($ADS_NAME_INITTYPE_GC, "")
	$objTranslate.Set($ADS_NAME_TYPE_NT4, @LogonDomain & "\" & $compName & "$")
	$compDN = $objTranslate.Get($ADS_NAME_TYPE_1779)
	;Set DN to upper Case
	$compDN = StringUpper($compDN)

	Return $compDN

EndFunc   ;==>_getDN

Func upStatus($msg, $flash = 0, $color = 0x88DDCC)
	_GUICtrlStatusBar_SetText($statusBar, _NowTime(5) & " >", 0)
	_GUICtrlStatusBar_SetText($statusBar, $msg, 1)

	If $flash Then
		;for $i=0 to 3
		;	_GUICtrlStatusBar_SetBkColor($statusBar, $color)
		;	Sleep(500)
		;	_GUICtrlStatusBar_SetBkColor($statusBar, $CLR_DEFAULT)
		;	Sleep(500)
		;Next
	Else
		_GUICtrlStatusBar_SetBkColor($statusBar, $CLR_MONEYGREEN)
		Sleep(250)
		_GUICtrlStatusBar_SetBkColor($statusBar, $CLR_DEFAULT)
	EndIf
EndFunc   ;==>upStatus

Func _extractOU($DN)
	; We want to turn this
	; CN=compName,OU=Group3,OU=Group2,OU=Group1,DC=site,DC=com
	; into this
	; Group3
	;
	; HAHA THIS WAS SO EASY, THANKS StringSplit()
	If $DN = "Could not contact domain controller." Then Return $DN

	Dim $OU, $arrDN
	$arrDN = StringSplit($DN, ",", 2)
	$OU = StringTrimLeft($arrDN[1], 3)

	Return $OU
EndFunc   ;==>_extractOU

Func _displayName($logon)
	$objDomain = ObjGet("LDAP://rootDse")

	;$objDomain.

EndFunc   ;==>_displayName

Func _computerNameLegal($compName)
	Dim $i
	Const $illegalChars = StringToASCIIArray("`~!@#$ ^&*()=+[]{}\|;:',<>/?""")

	For $i = 0 To UBound($illegalChars) - 1
		If StringInStr($compName, Chr($illegalChars[$i])) Then
			; return 0 if computer name contains bad characters
			Return 0
		EndIf

	Next

	; return 1 if computer name is OK, in keeping with 1=success/0=failure autoit function return codes
	Return 1
EndFunc   ;==>_computerNameLegal

Func aboutDiag()
	GUISetState(@SW_DISABLE)
	MsgBox(64, "About", "remoteWmiInfo " & $version & @CR & _
			"© Jon Dunham 2009" & @CR & _
			"dunham.jon@gmail.com" & @CR & @CR)
	GUISetState(@SW_ENABLE)
	WinActivate($frmInfo)
EndFunc   ;==>aboutDiag

Func monitorInfo($compName = ".")
	; Dell serial - 78 characters in (without MX0 or CN0 prefix)
	; HP serial - 114 characters in
	; both models - 96 (192 hex) characters in
	;
	; this function runs assuming the computer has already been contacted,
	;  otherwise it will hang for ~82 seconds trying to contact the WMI service
	;
	Dim $colDM, $PNPDID, $EDID, $Name
	Dim $objWMIService = ObjGet("winmgmts:\\" & $compName & "\root\cimv2")
	$colDM = $objWMIService.execquery('SELECT * FROM Win32_DesktopMonitor WHERE PNPDeviceID IS NOT NULL')

	For $objDM In $colDM
		; this is the best scenario we want (powered on/connected).
		;  Generally all other DesktopMonitor.Availability = 8 (off-line)
		If $objDM.Availability = 3 Then 
			$PNPDID = $objDM.PNPDeviceID
			$Name = $objDM.Name
			$EDID = RegRead("\\" & $compName & "\HKLM\SYSTEM\CurrentControlSet\Enum\" & $PNPDID & "\Device Parameters", "EDID")
			If Not @error Then
				ExitLoop
			;if there isn't an EDID for this, continueloop and get it from the next monitor with a PNPDeviceID
			Else
				ContinueLoop 
			EndIf
		; this may or may not indicate the currently connected display device.
		;  Display status reporting seems to be sketchy at best with WMI
		Else
			$PNPDID = $objDM.PNPDeviceID
			$Name = $objDM.Name
			$EDID = RegRead("\\" & $compName & "\HKLM\SYSTEM\CurrentControlSet\Enum\" & $PNPDID & "\Device Parameters", "EDID")
			If Not @error Then
				ExitLoop
			Else
				ContinueLoop
			EndIf
		EndIf
	Next

	If $debug Then ConsoleWrite($Name & ": " & $objDM.Availability & " \ " & $PNPDID & @LF & @LF & $EDID & @LF)

	If Not IsBinary($EDID) Then
		SetError(1)
		Return @error
	EndIf

	Dim $info[3], $serial, $model

	$model = StringStripWS(StringMid(BinaryToString($EDID), 96, 12), 2)

	If $debug Then ConsoleWrite("Model: " & $model & @CRLF)

	Select
		Case StringLeft($model, 2) = "HP"
			If $debug Then ConsoleWrite("HP found" & @CRLF)
			$serial = StringMid(BinaryToString($EDID), 114, 10)
		Case StringLeft($model, 2) = "DE"
			If $debug Then ConsoleWrite("Dell found" & @CRLF)
			$serial = StringMid(BinaryToString($EDID), 78, 12)
			$serial = "[ MX0 | CN0 ]" & StringLeft($serial, 5) & "XXXXX" & StringRight($serial, 7)
		Case StringLeft($model, 2) = "LG"
			If $debug Then ConsoleWrite("LG found" & @CRLF)
			$serial = StringMid(BinaryToString($EDID), 114, 12) & " (may be the model)"
	EndSelect

	If $debug Then ConsoleWrite("Serial: " & $serial & @CRLF)

	$info[0] = $model
	$info[1] = $serial
	$info[2] = $Name

	Return $info
EndFunc   ;==>monitorInfo

Func _processExists($procName, $compName = ".")
	$oWMIService = ObjGet("winmgmts:\\" & $compName & "\root\CIMV2")

	If Not IsObj($oWMIService) Then
		SetError(1)
		Return
	EndIf

	Dim $handle, $colProc

	$cProc = $oWMIService.ExecQuery('SELECT * FROM Win32_Process WHERE Name = "' & $procName & '"')

	For $oProc In $cProc
		$handle = $oProc.Handle
	Next

	If $handle Then
		Return $handle
	Else
		Return 0
	EndIf
EndFunc   ;==>_processExists

Func guiFlash(ByRef $control, $color, $duration = 200, $times = 2, $tween = 0.4)
	$sleep1 = ($duration / $times) * $tween
	$sleep2 = ($duration / $times) * (1 - $tween)

	If $control <> "" Then
		If IsHWnd($control) Then
			For $i = 1 To $times
				GUISetBkColor($control, $color)
				Sleep($sleep1)
				GUISetBkColor($control, Default)
				Sleep($sleep2)
			Next
		Else
			For $i = 1 To $times
				GUICtrlSetBkColor($control, $color)
				Sleep($sleep1)
				GUICtrlSetBkColor($control, Default)
				Sleep($sleep2)
			Next
		EndIf
	Else
		Return 0
	EndIf

	Return 1
EndFunc   ;==>guiFlash

Func defPrinterInfo($SID, $compName = ".")
	$defPrintString = RegRead("\\" & $compName & "\HKU\" & $SID & "\Software\Microsoft\Windows NT\CurrentVersion\Windows", "Device")

	$info = StringSplit($defPrintString, ",", 2)
	$defPrinter = $info[0]

	Return $defPrinter
EndFunc   ;==>defPrinterInfo

Func wirelessInfo($strComputer = ".")

	Dim $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\WMI")

	; Was the computer contactable?
	If Not IsObj($objWMIService) Then
		Return 2
	EndIf

	Dim $SSID, $BSSID, $signal, $noise, $channel, $info[5]
	Dim $raw
	Const $channels[24] = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "40", "36", "44", "48", "52", _
		"56", "60", "64", "149", "153", "157", "161", "165"]
	Const $frequencies[24] = ["2412000", "2417000", "2422000", "2427000", "2432000", "2437000", "2442000", "2447000", _
	"2452000", "2457000", "2462000", "5200000", "5180000", "5220000", "5240000", "5260000", "5280000", "5300000", "5320000", _
	"5745000", "5765000", "5785000", "5805000", "5825000"]

	; Signal

	$colWifi = $objWMIService.ExecQuery("Select * From MSNdis_80211_ReceivedSignalStrength where Active = True")

	For $objWifi In $colWifi
		$signal = $objWifi.NDIS80211ReceivedSignalStrength & " dBm"
	Next

	; Noise

	$colWifi = $objWMIService.ExecQuery("SELECT * FROM Atheros5000_NoiseFloor where Active = True")

	For $objWifi In $colWifi
		$noise = -$objWifi.Value & " dBm"
	Next

	; SSID

	$colWifi = $objWMIService.ExecQuery("Select * From MSNdis_80211_ServiceSetIdentifier")

	For $objWifi In $colWifi
		$SSID = $objWifi.NDIS80211SSID
	Next

	For $i = 0 To UBound($SSID) - 1
		If $SSID[$i] < 32 Or $SSID[$i] > 127 Then
			$SSID[$i] = ""
		Else
			$SSID[$i] = Chr($SSID[$i])
		EndIf
	Next

	$SSID = _ArrayToString($SSID, "")

	; AP MAC

	$colWifi = $objWMIService.ExecQuery("Select * From MSNdis_80211_BaseServiceSetIdentifier WHERE Active = True")

	For $objWifi In $colWifi
		$BSSID = $objWifi.NDIS80211MacAddress
	Next

	For $i = 0 To UBound($BSSID) - 1
		$BSSID[$i] = Hex($BSSID[$i], 2)
	Next

	; Channel

	$colWifi = $objWMIService.ExecQuery("Select * From MSNdis_80211_Configuration WHERE Active = True")

	For $objWifi In $colWifi
		$raw = $objWifi.Ndis80211Config.DSConfig

		For $i = 0 To UBound($frequencies) - 1
			If $raw = $frequencies[$i] Then
				$channel = $channels[$i]
			EndIf
		Next

	Next

	; Formatting (use stringreplace($info[4], ":", "") to remove or replace colons in the AP MAC if desired)

	$BSSID = _ArrayToString($BSSID, ":")

	$info[0] = $SSID
	$info[1] = $signal
	$info[2] = $noise
	$info[3] = $channel
	$info[4] = $BSSID

	Return $info

EndFunc   ;==>wirelessInfo