Link to home
Start Free TrialLog in
Avatar of nemakcanada
nemakcanada

asked on

WMI with printers routers and switches.

I've written a network discovery tool that will discover all of the available machiens on the network. The next step is for me to run through the list of available devices and query for as much information as possible. Now, I can query the windows machines no problem, but I'd also like to be able to get some information on our routers/printers. My understanding is that I should be able to do this with WMI, but I'm wondering if the connection/query methods are different? Our routers just received software updates and 80% of the printers we have are about 1 year old, so I'm guessing I should be able to pull SOMETHING back.  Here's the line of code that I am using to determine the machine I should connect to:

ms = new ManagementScope("\\\\" + next_machine + "\\root\\cimv2", Connection);

My question is, has anyone successfully queried a router or printer (any network device that is not a windows machine) using WMI, and if so, do I setup the ManagementScope object differently? Is there anything else I should know? Thanks!

Brian
Avatar of gav_jackson
gav_jackson

my own understanding of wmi is that printers and routers cannot be connected to as they do not have windows installed on them.

a possible work around is querying SNMP -i have not done this myself but would be interested if you manage it.
Avatar of nemakcanada

ASKER

WMI is a layer above SNMP and can act as a mediary between multiple protocols for remote management. This is a decent article on how they interact.

http://www.microsoft.com/technet/prodtechnol/windows2000serv/maintain/featusability/wmisnmp.mspx


I'm getting closer to figuring this out. Basically, I know I need a MIB file for my router/switch for example, I convert that MIB file to a MOF file for use in WMI, then in theory, I think I'm all set. I can get MIB files here:

http://www.cisco.com/public/sw-center/netmgmt/cmtk/mibs.shtml

but how to convert the thing I don't know =) . I've read that there is a WMI studio or something like that freely available from M$, but I haven't found it yet, nor do I know how to use it. I'm thinking that once I have all this stuff figured out, I'm going to create my own white paper with step-by-step instructions cause documentation on WMI is scattered and sketchy at best.
If anyone has info on how to convert MIB files and use them with WMI, it would be appreciated.

Brian
Ok, I figured it out, took me 5 days of straight reading, but I figured it out. Here's my code, hope it helps someone. I'm going to try and find time to write a WMI/.NET How-to for the rest of the developers in my company, and if I do, I'll try to post it online and get a link up with this post. Anyway, here's the basics:

1) Install the SNMP service on your PC from the win2k (xp) cd.
2) Install the WMI SDK if you don't have it already.
3) Open a command prompt and CD the "c:\winnt\system32\wbem" direcory and find the snmpsmir.mof and the snmpreg.mof files .
4) run mofcomp snmpsmir.mof   and mofcomp snmpreg.mof  . This get WMI ready to connect and read SNMP information for standard devices. I haven't done much work on using specific MIB/MOF files from Cisco or other Vendors yet, sorry.
5) Determine what your community string is for the device you want to connect to
6) Here's my code, works great:


ConnectionOptions conOpt = new ConnectionOptions();
conOpt.Impersonation = ImpersonationLevel.Impersonate;

ManagementPath path = new ManagementPath("SNMP_RFC1213_MIB_system");

ManagementNamedValueCollection context = new ManagementNamedValueCollection();
// Pass in values as strings!
context.Add("AgentAddress", "10.10.10.1);   //CHANGE IP TO SUIT YOUR NEEDS
context.Add("AgentReadCommunityName", "public"); //THIS YOUR COMMUNITY STRING FROM STEP 5 ABOVE

ObjectGetOptions options = new ObjectGetOptions(context, new TimeSpan(0,0,0,5), true);

ManagementScope scope = new ManagementScope(@"root\snmp\localhost", conOpt);
System.Management.ObjectQuery oq = new System.Management.ObjectQuery("select * from SNMP_RFC1213_MIB_system where __CLASS = \"SNMP_RFC1213_MIB_system\"");

ManagementObjectSearcher query1 = new ManagementObjectSearcher(scope,oq);
query1.Options.Context = context;  // MOST IMPORTANT LINE. SEE MY NOTE BELOW
ManagementObjectCollection moc = query1.Get();

try
{
      foreach (ManagementObject mo in moc)
      {
            foreach(PropertyData prop in mo.Properties)
            {
                  if(!(prop.IsArray))
                  {
                        System.Windows.Forms.MessageBox.Show(prop.Value.ToString());
                  }
                  else
                  {
                        System.Array propArray = (System.Array)prop.Value;
                        System.Text.StringBuilder strProp = new System.Text.StringBuilder();
                        foreach (Object o in propArray)
                        {
                              strProp.Append(o.ToString()+"|");
                              System.Windows.Forms.MessageBox.Show(o.ToString());
                        }
                  }
            }
      }
}
catch(Exception ex)
{
      System.Windows.Forms.MessageBox.Show(ex.ToString());
}



In my code above, this line is VERY important:
query1.Options.Context = context;

The context variable is used to set the community string and the AgentAddress (ip address) of the device you WANT to connect to. Now, .NET works in a funny way when it comes to actually using the context settings. The ConnectionOptions class has a Context property, and you can set it there, but it doesn't work =) .NET will then only pull up information from your local machine for some reason. The only place I found to set the Context settings and have them used properly is in the query options as I have done above. A good chunk of this code was found here:

http://groups.google.ca/groups?q=ManagementClass+snmp&hl=en&lr=&ie=UTF-8&c2coff=1&selm=ujoDdQ3SDHA.2020%40TK2MSFTNGP11.phx.gbl&rnum=2

I just fixed this guy's original problem and modified the code a little bit, but that was my original base.
The only major error I encountered was a "Generic Failure" when querying. I fixed that by stopping the "Windows Management Instrumentation Service", deleting all the files in the "C:\WINNT\system32\wbem\Repository" directory, then restarting the service. Basically, my WMI repository was corrupt and needed to be re-built. Ok, enough rambling, hope this helps someone!

Brian
I just noticed something in my code.... this line:

ManagementPath path = new ManagementPath("SNMP_RFC1213_MIB_system");


Isn't used and can be safely removed.

Brian
nice post...should come in handy when i need to query SNMP.


Ok, I've done a little more today when working with a Cisco switch, so I'll add more info here:

It's pretty easy to use the manufacturer's MIBs to run and SNMP query on a device. For my Cisco switch, I downloaded the appropriate MIB files from:

http://www.cisco.com/public/sw-center/netmgmt/cmtk/mibs.shtml

..and saved them to C:\winnt\system32\wbem\snmp .

Open a command prompt, and CD to the above directory... you're going to use the smi2smir.exe command. What you need to do is load the MIB into the repository, the easiest way is to use the following (assuming my file is called xxx.mib):

smi2smir /a xxx.mib

Some of the MIBs you may be using require information contained in other MIB files, you would have to download those as well. Supposing the above xxx.mib file required file yyy.mib, I would have gotten an error(s) like the following:

<1070> Fatal: "xxx.mib" (line n, col m): MIB module "yyy"   ...etc

This tells you that you need MIB file yyy.mib.... go download it.  Once downloaded you'd then execute the command like:

smi2smir /a xxx.mib yyy.mib

And you should be all set. The tough part is finding out what 'tables' you can query using WMI on the device using the new information you just loaded. The easiest way for me was to create a MOF file from the downloaded MIB. No worries, that's easy too, you use the same command as above with a minor change. To create the MOF file, you'd execute the following command:

smi2smir /gc xxx.mib yyy.mib > xxx.mof

All you need to do now, is open up the MOF file in notepad for example, and look for lines like:

class SNMP_OLD_CISCO_SYSTEM_MIB_lsystem : SnmpObjectType

This defines a 'table' type object called SNMP_OLD_CISCO_SYSTEM_MIB_lsystem that you can query, enclosed in braces ( '}' ) is the definition of the class (table) and what columns it contains. That's it... pretty simple.

Brian
Mmm... how about drop your stuff onto http://www.codeproject.com/ ?
Good idea, but I can't. It's work related so the company owns my code etc...
Mmm.... modify it so not to include company related info. Or at least post up the steps, URLs, and resources that work out the stuff?

So, next time when you intend to move on to other "prospective" career, you got a "live" reference.

PS: Company info cannot reveal to outside, ok. But outside info can be absorb into company work?
ASKER CERTIFIED SOLUTION
Avatar of CetusMOD
CetusMOD
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial