WMI ManagementObjectSearcher Options

Posted on 2004-08-26
Last Modified: 2008-01-09
I'm running WMI queries on several machines on our network. What I am finding is that although a group of machines (same make, model, hardware, software platform) are physically located the same distance from me, and are plugged into the same switch, I'm getting large differences in the return time of the following query:

SELECT * FROM Win32_OperatingSystem

I generally get results in roughly 6 seconds, but sometimes the result return takes 1min+ . I'm trying to figure out if I can just force a timeout on a query using the Options property of the ManagementObjectSearcher class, but I'm not sure what options can be set here. Does anyone have any other thoughts why the delays may occur? It's not always the same delay length or from the same computers. It seems like it just randomly pauses. Our network usage hovers at a low 2%, and collisions are little to none, so I'm sure it's not a network issue. The TimeOut property of the Connection class doesn't work, cause I connect just fine, its the call to ManagementObjectSearcher.Get() that causes the delay. Thanks!

Question by:nemakcanada
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2

Expert Comment

ID: 11902354
funnily enough i am writing a similar WMI scanner.

I also noticed a big and differential delay between scans...i am not sure of the actual reason for this but i do have a solution.

use multi-threading, as in for each machine queue a call to the scan class in a new thread in the threadpool, this will automatically queue all your scans and will send out up to 25scans at the same time, ie you should recieve your results 25 times faster than before.

check out

for more info on threads

Author Comment

ID: 11902730
Good advice, I'm going to have to play around with the Thread priorities and sleep times cause this approach bumped up my CPU usage by 10 times. Ok, so here's what I have:

Main Application Thread
       ->creates multiple scanning threads

Suppose I want the application to terminate when scan is complete, how can I determine when all the the Threads I have created, are complete. I realize that there is an IsAlive property for each thread, but I'm basically creating my Threads like this:

while(this.current_machine_index < 200)
      RootScanner root = new RootScanner(ip);
      Thread scan_thread = new Thread(new ThreadStart(root.RunWMIScan));
      scan_thread.Priority = ThreadPriority.BelowNormal;

When I exit this loop, scan_thread no longer references the 195th thread I created for example, it now references thread 199, therefore scan_thread.IsAlive no refers to thread 199. Suppoer 199 returns faster that 195, I'd incorrectly terminiate the app. Any thoughts?


Expert Comment

ID: 11910057
why not create a simple array of Threads ?

somewhere past the class declaration
private Thread[] scan_thread;

somewhere in Form_Load or constructor:
scan_thread = new scan_thread[200];

somewhere in your code:
while (...)
scan_thread[index] = new Thread(ThreadStart(.......))

or am I completely missing the point ?

Accepted Solution

gav_jackson earned 250 total points
ID: 11910495
i used a threadpool, let me explain the code below.

1. get list of computers to scan into an array (i personally used a DirectorySearcher to retrieve my list but there are a number of different ways to acheive this)

2. Iterate through this list of computers

3. Using "ThreadPool.QueueUserWorkItem(new WaitCallback "
    Queue a call to "ThreadFunctions" passing the parameter "arrComputers[i]"

    This will automatically queue any calls until an available thread can take each call and process it individually, giving you a maximum of 25 'concurrent(ish)' calls to "ThreadFunctions"

*you can only pass one parameter when using "WaitCallback"

4. The private function threadfunctions calls the public method threadfunctions  
*dunno why it does this, all the examples i saw worked like this *shrugs* hey it works!

5. Do your wmi scan to "strComputerName" here

6. This is my attempt to figure out when the scans are finished by checking to see the number of available threads in the pool.
*i think this bit is flawed, im reading through it and it doesnt make any sense....but its a start

good luck

    private static void scanDomain(string strScanType)
      Scanner.myScanner gv = new Scanner.myScanner();
      string [] arrComputers = gv.getListComputers(strDomain);

      nNumberOfPCsToAudit = arrComputers.GetLength(0);
      for(int i = 0; i <= nNumberOfPCsToAudit; i++)
            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadFunctions),arrComputers[i]);

    private static void ThreadFunctions(object strComputerName)
      ThreadFunctions((string) strComputerName);

    public static void ThreadFunctions(string strComputerName)
      //this is where you scan strComputerName

      int nWorkerThreads;
      int nPortThreads;
      int nMaxThreads;

      ThreadPool.GetMaxThreads(out nWorkerThreads, out nPortThreads);
      nMaxThreads = nWorkerThreads;

      ThreadPool.GetAvailableThreads(out nWorkerThreads, out nPortThreads);
      if(nWorkerThreads >= nMaxThreads)
        //Finished All Scans
        //Scanned " + strComputerName


Author Comment

ID: 11911588

I could create an array, but due to memory consumption issues, I'd rather not. The array could be anywhere from 300-1000 items in size for our internal network alone, let alone if we start using a scanner like this throughout the company 3000+.


Good call on checking the number of threads in the pool, it'll work good enough for me. I've created a configuration app for my scanner that will allow an end user to throttle the speed/cpu usage up and down based on a few things. By default, it uses the ThreadPool class, but it allows the user (an admin) to configure how many threads (1-24) and how long of a delay between thread execution so that no matter what machine we run this on, we can keep CPU usage down. Thanks for your help on this, I'll award you the points.

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary: Persistence is the capability of an application to store the state of objects and recover it when necessary. This article compares the two common types of serialization in aspects of data access, readability, and runtime cost. A ready-to…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below.…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question