LurchMan Posted May 3, 2010 Share Posted May 3, 2010 Hey everyone - I've got a simple script that pulls the name of every computer running Windows XP from AD, and then uses WMI to retrieve the Serial Number of each machine and check it against a specified serial number. The problem is that it runs really slow. There's about 600 computers that it pull, and if it hits one that is offline it takes a few extra seconds and when that's spread over 600 computer it slows it way down (about 30 mins to check all 600 computers). IF you have any ideas on how to speed this up at all, or any improvements I could make it would be appreciated. Thanks --LurchMan Code: #include <ADfunctions2.au3> Global $aComputers $sSN = StringUpper (InputBox ("Serial Number", "Please enter the serial number you are trying to locate:")) $msg = MsgBox(52, "Warning!", "This program can take up to 30 minuets or more to complete. Are you sure you wish to continue?") If $msg = 7 Then Exit MsgBox (64, "Continuing", "This program will be running in the background with no GUI...") $sOU = $strDNSDomain _ADGetObjectsInOU($aComputers,$sOU,"(&(&(&(&(&(objectCategory=Computer)(operatingSystem=Windows XP Professional))))))",2,"name") _ArraySort ($aComputers) ;~ _ArrayDisplay ($aComputers) For $i = 1 To UBound($aComputers) - 1 $colItems = "" If Ping ($aComputers[$i], 1000) > 0 Then $objWMIService = ObjGet("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" _ & $aComputers[$i] & "\root\cimv2") If IsObj ($objWMIService) Then $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_SystemEnclosure", "WQL", 0x10 + 0x20) If IsObj($colItems) Then For $objItem In $colItems If StringUpper($objItem.SerialNumber) = $sSN Then MsgBox (64, "Found It", "Computer Name: " & $aComputers[$i] & " | SN: " & $sSN) Exit EndIf Next EndIf EndIf EndIf Next MsgBox (64, "Not Found", "Could not find the serial number " & $sSN & " on the network.") Dating a girl is just like writing software. Everything's going to work just fine in the testing lab (dating), but as soon as you have contract with a customer (marriage), then your program (life) is going to be facing new situations you never expected. You'll be forced to patch the code (admit you're wrong) and then the code (wife) will just end up all bloated and unmaintainable in the end. Link to comment Share on other sites More sharing options...
spudw2k Posted May 3, 2010 Share Posted May 3, 2010 The biggest bottlenecks are going to be the Ping and the WMI Connection, which I'm not sure what you can do about that. You could make the query (potentially but unrealistically) more defined, and just a side note...Win32_SystemEnclosure may not always have the SerialNumber property. Try Win32_BIOS instead. untested: $colItems = $objWMIService.ExecQuery("SELECT SerialNumber FROM Win32_BIOS", "WQL", 0x10 + 0x20) Spoiler Things I've Made: Always On Top Tool ◊ AU History ◊ Deck of Cards ◊ HideIt ◊ ICU ◊ Icon Freezer ◊ Ipod Ejector ◊ Junos Configuration Explorer ◊ Link Downloader ◊ MD5 Folder Enumerator ◊ PassGen ◊ Ping Tool ◊ Quick NIC ◊ Read OCR ◊ RemoteIT ◊ SchTasksGui ◊ SpyCam ◊ System Scan Report Tool ◊ System UpTime ◊ Transparency Machine ◊ VMWare ESX BuilderMisc Code Snippets: ADODB Example ◊ CheckHover ◊ Detect SafeMode ◊ DynEnumArray ◊ GetNetStatData ◊ HashArray ◊ IsBetweenDates ◊ Local Admins ◊ Make Choice ◊ Recursive File List ◊ Remove Sizebox Style ◊ Retrieve PNPDeviceID ◊ Retreive SysListView32 Contents ◊ Set IE Homepage ◊ Tickle Expired Password ◊ Transpose ArrayProjects: Drive Space Usage GUI ◊ LEDkIT ◊ Plasma_kIt ◊ Scan Engine Builder ◊ SpeeDBurner ◊ SubnetCalcCool Stuff: AutoItObject UDF ◊ Extract Icon From Proc ◊ GuiCtrlFontRotate ◊ Hex Edit Funcs ◊ Run binary ◊ Service_UDF Link to comment Share on other sites More sharing options...
LurchMan Posted May 3, 2010 Author Share Posted May 3, 2010 (edited) $colItems = $objWMIService.ExecQuery("SELECT SerialNumber FROM Win32_BIOS", "WQL", 0x10 + 0x20) With this would i still just use $objitem.serialnumber to get the data? Edit: Nevermind...forgot to think and test before posting...I'll give that a try and see if its any better. Edited May 3, 2010 by LurchMan Dating a girl is just like writing software. Everything's going to work just fine in the testing lab (dating), but as soon as you have contract with a customer (marriage), then your program (life) is going to be facing new situations you never expected. You'll be forced to patch the code (admit you're wrong) and then the code (wife) will just end up all bloated and unmaintainable in the end. Link to comment Share on other sites More sharing options...
99ojo Posted May 4, 2010 Share Posted May 4, 2010 (edited) Hi, it is maybe faster. My idea is, to check the computers by a Dos ping with several pings at the 'same time' and then check the ping visible computers by wmi. 1) Compile your own 'ping'.exe. I compiled it as _myping.exe in @ScriptDir as console application !! See @Edit at the end !! #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Change2CUI=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <Constants.au3> ;1 ping to computer, which is param 1 on commandline $pid = Run(@ComSpec & " /c ping -n 1 " & $CmdLine[1], @SystemDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) Local $line While 1 $line = StdoutRead($pid) If @error Then ExitLoop ;get reply -> write computername into result file If StringInStr ($line, "Reply from") Then FileWriteLine (@ScriptDir & "\_myping.txt", $CmdLine [1]) EndIf Wend 2) Changes to your script: expandcollapse popup#include <Constants.au3> #include <ADfunctions2.au3> #Include <File.au3> Global $aComputers ; amount of hidden cmd boxes running Global $proccount = 30 ;delete existing resultfile from _myping.exe If FileExists (@ScriptDir & "\_myping.txt") Then FileDelete (@ScriptDir & "\_myping.txt") Global $sSN = StringUpper (InputBox ("Serial Number", "Please enter the serial number you are trying to locate:")) $msg = MsgBox(52, "Warning!", "This program can take up to 30 minuets or more to complete. Are you sure you wish to continue?") If $msg = 7 Then Exit MsgBox (64, "Continuing", "This program will be running in the background with no GUI...") $sOU = $strDNSDomain _ADGetObjectsInOU($aComputers,$sOU,"(&(&(&(&(&(objectCategory=Computer)(operatingSystem=Windows XP Professional))))))",2,"name") _ArraySort ($aComputers) ;~ _ArrayDisplay ($aComputers) For $i = 1 To UBound($aComputers) - 1 ;get amount of _myping processes $arproc = ProcessList ("_myping.exe") ;If defined proccount is reached, wait until amount of processes is smaller then proccount If $arproc [0] [0] = $proccount Then Do sleep (1000) $arproc = ProcessList ("_myping.exe") Until $arproc [0] [0] < $proccount EndIf ;Pinging several computers at nearly the 'same time' Run ("_myping.exe " & $aComputers [$i], @ScriptDir, @SW_HIDE) Next ;wait until all _myping processes are finished Do sleep (100) $arproc = ProcessList ("_myping.exe") Until $arproc [0] [0] = 0 ;read result file into array _FileReadToArray (@ScriptDir & "\_myping.txt", $result) ;loop over result array and start wmi For $i = 1 To $result [0] _wmiserial ($result [$i]) Next Func _wmiserial ($computer) $objWMIService = ObjGet("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" _ & $computer & "\root\cimv2") If IsObj ($objWMIService) Then $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Bios", "WQL", 0x10 + 0x20) If IsObj($colItems) Then For $objItem In $colItems If StringUpper($objItem.SerialNumber) = $sSN Then MsgBox (64, "Found It", "Computer Name: " & $computer & " | SN: " & $sSN) Exit EndIf Next EndIf EndIf ;MsgBox (64, "Not Found", "Could not find the serial number " & $sSN & " on the network.") EndFunc I cant test it by myself, because at home i have only single PC without AD. Maybe you can give it a try. ;-)) Stefan @Edit: Faster _myping.exe Version: #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Change2CUI=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** AutoItSetOption ("TCPTimeout", 250) $var = Ping ($CmdLine[1], 250) If $var Then FileWriteLine (@ScriptDir & "\_myping.txt", $CmdLine [1]) Edited May 4, 2010 by 99ojo Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now