Inventorying RAMs Remotely on Windows

Say you need to find a remote solution for grabbing the values of RAM modules of a huge number of computers. This is not unusual for large companies that need to do inventories of some kind to keep track of all of their computers for maintenance purposes. We want to gather the manufacturer, serial number, model number, and other values for each module.

Contributed by
Rating: 5 stars5 stars5 stars5 stars5 stars / 4
August 11, 2009
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

As we pointed out in our earlier article, there is a relatively seamless solution with a few lines of script code—based on WMI—we can try to query the SPD data of each RAM module. Unfortunately, when this approach was placed into action, the results weren’t promising at all. Lots of data were missing, most of which were truly required for our inventory needs, such as the manufacturer, part number, and serial number.

Windows Management Instrumentation, abbreviated WMI, is the interface that Microsoft designed with programmers in mind. It allows users to access certain parts and hardware components by providing a hardware abstraction layer. Querying via WMIs is really a task and can be done with scripting languages as well. Since this simple approach wasn’t enough for us, it was time to look further.

Once again, we got lucky, finding the following CodeProject article by wjfrancis. Apparently, the author realized the reason why querying the WMI does not return the required “depth” of information that it promises. In short, there is a limitation in the mechanism of WMI that does not parse and “make available” all of the gathered information. The author found a way around this. The results were satisfying.

In that article there is an entire story explaining the way you can peek into the SMBIOS to gather the necessary information in an approach similar to the way WMI does it when it loads up its collections and all that. In the end, though, it does not expose all of it. The source code that’s featured within that article is written in C++ and the application is console-based. Basically, it dumps and prints out the entire SMBIOS data. It’s in-depth!

Our task now is to show you how we can modify this application that already “does wonders” a tiny bit, and explain how we can execute it remotely on hundreds, if not thousands, of computers within a domain(s). Modifying is not compulsory, but you may find it essential to style the SMBIOS dump into the required form and shape. I’m sure you'll find out that it reports way too much information in the case of memories.

Shaping the Output

First of all, download the entire source code of the application from the CodeProject article. Executing the application lists pages of SMBIOS dump; the amount of information it is able to dump is overwhelming. But that’s way better than having too little and struggling to find what we really need.

In order to keep the application simple and not ruin its overall structure, we will rather extend the tool and not modify. This way we will add the ability to specify modes with arguments, something along the lines of adding “-m” in the end followed by a number. Let’s say “1” for Mode 1, the one that dumps out the information we need; and “2” for Mode 2, the original way the application works. We leave this untouched.

As mentioned earlier, this part is not compulsory so we won't get too involved with it. Anyone with intermediate experience in programming in C++ could simplify this application to suit his or her needs. If you don’t want to modify, then you can write simple scripts to parse the output dump to “extract” just the information you need. Either way, it works. The bottom line is that the application touches the SMBIOS and truly retrieves the data we need, along with much more.

On the other hand, if you want to follow our style and edit the source code by including these “two” available modes to run the tool, then here it goes. There are several approaches; the easiest is adding a global variable that stores which mode is currently chosen. It parses the arguments (_TCHAR* args[]), the value follows the “m.” Check this sample out. You can do something similar.

if (_wcsicmp(args[i],_T("-m"))==0) // -m option

{

if (++i > arg_count-1)

{

p(_T("You failed to specify a valid mode for the '-m' option.nn"));

return false;

}

else

{

global_mode = 2; // default, lists the entire dump

if (_wcsicmp(args[i],_T("1"))==0) // if 1, our style

global_mode = 1;

}

The above is to be found in the smbios_p.cpp file, within the parse_command_line function. This is the place where the author also originally checks the –f option when the output is about to be saved in a file. Once the above is expanded and the global mode is implemented, you can continue editing the _tmain() function.

Please find the following snippet and edit accordingly. As you can see, there’s an error-handling piece that checks whether the command line arguments are good; if so, then the program moves further, and tries to initialize the data. If this also succeeds, then it checks which mode the user has picked. If the second one, then it lists everything—the original way the tool works; otherwise, it prints out only the memory-related data.

if (good_command_line)

{

if (!init_raw_smbios_data())

{

p(_T("Failed to initialize raw smb bios data.nn"));

}

else

{

if (global_mode == 2)

{ // the original mode, lists everything

show_bios_information();

show_system_information();

show_system_enclosure();

show_processor_information();

show_cache_information();

show_system_slots();

show_physical_memory_array();

show_memory_device();

show_memory_array_mapped_address();

show_system_boot_information();

}

if (global_mode == 1)

{ // lists only the data we need, memory-related

show_memory_device();

}

}

}

On the next page we will see how this tool performs when put into action.

Using the Tool

In our next article we'll be remotely querying the HDD-specific information of hard disk drives; you'll see that we've implemented a feature that retrieves the name of the computer where the tool is being executed, and prints it out along with the other data. This is important for inventorying with ease later on.

We should not neglect this right now either. We can do this easily with C++.

LPWSTR ComputerName;

DWORD cbComputerName = sizeof (ComputerName);

TCHAR infoBuf[32767];

DWORD bufCharCount = 32767;

bufCharCount = 32767;

if( !GetComputerName( infoBuf, &bufCharCount ) )

_tprintf( TEXT("ERROR: Could not detect computer name"));

_tprintf( TEXT("Executing script on computer name: %sn"), infoBuf );

It also helps to increase practicality and improve visibility by adding some sort of “ending” when the output has been listed. This is required if you want to automate the data extraction and import it into your inventory system. Imagine a text file with hundreds of memory modules logged without any delineating tags or anything. Who the hell knows which memory module and its data belongs to which computer?

_tprintf( TEXT("Finished. Successful execution on computer name: %sn"), infoBuf );

_tprintf( TEXT("--------------------n"));

As you can see, now you can easily delineate the components of each computer. You first search for the string “computer name:” and there you will have its name, followed by the details of memory modules, which can be imported into your Asset Management and IT Inventory software suite into the appropriate fields (such as manufacturer, part number, serial number, etc.). Then when the end-delimiter is found, a new one begins…

Moving on, let’s present the output of the tool being run on mode 1 (only memory).

Executing script on computer name: SUSANPC

 

total width: 64; data width: 64

size: 2048 megabytes

form factor: DIMM; memory type: DDR2

device locator: J1MY

bank locator: CHAN A DIMM 0

additional memory details: synchronous

speed: 800 mhz

manufacturer: 0x7F7F7F7FCB000000

serial number: 0x8D2A19DB

 

Finished. Successful execution on computer name: SUSANPC

The output looks really clean and neat. Its visibility is great, and you can later write numerous automation scripts to speed up the inventory process by importing the specific fields to their appropriate place. However, as you can see, there are a few limitations. First of all, the manufacturer is being reported in HEX values. You need to have sources to know which one represents which. You need to test this on source PCs.

For example, we have found out that 0x7F7F7F7FCB stands for A-DATA. The above sample is an excerpt of an A-DATA module that’s DDR2-800 with 2GB. It is located on the Channel A, Dimm 0 (first bank). It runs synchronous mode and its serial number is 8D2A19DB. Ignore the 0x HEX prefix.

But you do need to test the utility on so-called sample machines to find out which HEX manufacturer values represent which ones. In our environment, our dominant RAM modules were manufactured by A-DATA and Kingston. We’ve found that 0x7F9800000 is akin to Kingston. Nevertheless, please do the sampling process on your machines.

In the case of DDR sticks (not DDR2) some issues occurred when specific fields weren’t reported thoroughly. By looking into the situation, we’ve found that certain manufacturer do a really poor job of completing their own information within the SPD tables. Others are poorly recognized by the SMBIOS. Some fields end up as <null>, others as 0x0000000. There are no guarantees.

Final Thoughts

Arriving here means that you’ve learned how to query model-specific data of RAM modules. As a system administrator, this task is sometimes tiresome when you want to do everything on your own without additional third party tools that require deployment of fuzzy agents and who knows what else. And in the end, after all, they don’t come cheap at all.

Our solutions rely heavily on open-source utilities, source code that other people have developed and put a lot of work into R&D. Credit goes where it's due, that’s for sure. Moreover, PsTool (PsExec is part of it) is also freely available and is a really useful tool for Windows system administrators.

Assuming we’ve called our executable PeekSMB.exe let’s see how to remotely run it on a set of computers or perhaps on all of the machines within a domain. In the first case we can use a text file that contains the names of the computers, in the latter you can opt for wild cards and set * to the destination. These options are documented in PsExec, just read its help (execute without any arguments).

psexec @mycomps.txt -u ourfirmadmin -c -n 10 PeekSMB.exe -m 1 > peeklog.txt

In the example above: mycomps.txt contains a list of computers on which the script is ought to be executed, the –u is followed by the domain admin account inside the so-called “ourfirm” domain, –c means it copies the file prior to execution to the target PC, the –n argument specifies a ten second timeout (this is plentiful), and the > argument logs the output into a text file.

Keep in mind: nothing will appear on the screen once you press enter on the above command to launch PsExec. But you still need to enter your domain administrator password, even though you won’t be able to see it being asked—this is because the output is logged into the specified text file, and not on the screen. So don’t worry, that’s the way it works.

You can download our compiled executable along with the source code of the main file that was slightly edited. Please download the rest of the project from the original CodeProject article. Don’t hesitate to shape the output accordingly to meet your needs.

PeekSMB_source.zip

Lastly, I’d like to thank wjfrancis for his amazing publication over at CodeProject.

In closing, I’d like to invite you to join our experienced community of technology professionals on all areas of IT&C starting from software and hardware up to consumer electronics at Dev Hardware Forums. As well, be sure to check out the community of our sister site at Dev Shed Forums. We are friendly and we’ll do our best to help you.

blog comments powered by Disqus
WINDOWS SECURITY ARTICLES

- Botnet Malware Sleeps Eight Months Activatio...
- Windows Media Player Vulnerability, PCAnywhe...
- Solera Networks Threat Predictions for 2012,...
- ESET Windows Predictions, January Patch Tues...
- Windows Store: A Closer Look
- McAfee Identifies Threats for Windows 8 in 2...
- Automatic Updates Coming to Internet Explore...
- Microsoft`s December Patch Tuesday Fixes 17 ...
- Symantec: Spam Hits Three Year Low
- Latest Microsoft Security Essentials Public ...
- 25 Passwords to Avoid to Thwart Hackers
- Microsoft Seeks Beta Testers
- Windows 8 Promises Less Painful Security Upd...
- How to Detect and Fix an Infected PC
- Windows 8 Security Flaws

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 4 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials