C++ & Script program to find computer information

I am trying to use a combination of windows batch scripts as well a C++ program to put users data into one single .CSV file. Right now, I have a batch file that will output data from the command line into multiple .txt files. These files are mac.txt, serialnumber.txt, computermodel.txt, and computer name.txt. What I want to do, is to have users run the batch file, which will in turn run the .exe C++ file which will concatenate all their data into one file, computerinfo.csv. The file format for this file would be to have the mac address, serialnumber, computer model, and computer name all in their own column.

My main issue is that these individual files don't have the format that I would like, but based on the command prompt functions, there isn't really any good format. For example, the mac.txt file has the following format:


Physical Address Transport Name
=================== ==========================================================
xx-xx-xx-xx-xx-xx \Device\Tcpip_{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
yy-yy-yy-yy-yy-yy Media disconnected
zz-zz-zz-zz-zz-zz Media disconnected

but all I really want is xx-xx-xx-xx-xx-xx

The other files have other issues with format, but if I can figure out this one then the others should be a piece of cake.

Also, I want the output of this to all go in one row, and as other users run this file, they will go into new rows without touching the rows above.

Any help is greatly appreciated, what do I need to know in order to do this? Is this going to be a complicated task? It seems like it should be pretty straight forward, I just don't' know what is needed.
Is this going to be a complicated task?

Compared to what you have now? No. I am curious to know what your batch files look like but I won't ask since they are the wrong approach and it would only serve to take us off topic. Here your entire request in VB Script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const strComputer = "."
const Append = 8

Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set objFSO = CreateObject("Scripting.FileSystemObject")

Set oFile = objFSO.OpenTextFile("computerinfo.csv", Append)

set colOS = objWMI.ExecQuery("Select * From Win32_OperatingSystem")
set colSys = objWMI.ExecQuery("Select * From Win32_ComputerSystem")
set colNIC = objWMI.ExecQuery("Select * From Win32_NetworkAdapter")

for each objOS in colOS

	
	DataLine = objOS.CSName + "," + objOS.SerialNumber + ","
        
         for each objSys in colSys
                DataLine = DataLine + objSys.DnsHostName + "," + objSys.Model + vbCRLF
         next 	

	for each objNIC in colNIC
		if objNIC.NetConnectionStatus = 2 then
			DataLine = DataLine + ",," + objNIC.MACAddress + vbCRLF
		end if
	next	
	
next

oFile.WriteLine DataLine


You will have to already have a file called "computerinfo.csv" in the directory that you run this from or this script will fail on Line 7. Also notice that this does not put the headers that you wanted in the text file, you will need to do that yourself at some point.

If you are taking this apart you'll notice some craziness in Lines 16 - 20. This is because Windows Machines usually have more then one "NIC", so they will have more then one MAC Address. These other network cards are often just virtual drivers for VPN or VM's and the like. I made it a point to include the names of the devices so that you can parse through them at your discretion.

f you have your heart set on writing this in C or C++ then we can help you with that to. It's only a little more complicated and I suspect that you'll learn quite a bit from it. You won't gain much in the scope that was given for this part of your project though so it's up to you.

Here are links to the relevant WMI classes:

- Win32_OperatingSystem: http://msdn.microsoft.com/en-us/library/aa394239%28v=vs.85%29.aspx

- Win32_ComputerSystem: http://msdn.microsoft.com/en-us/library/aa394102%28v=vs.85%29.aspx

- Win32_NetworkAdapter: http://msdn.microsoft.com/en-us/library/aa394216%28v=vs.85%29.aspx

EDIT: Punctuation, grammar, the usual.

EDIT_2: Really sorry about that OP. I always seem to rush through things and miss some crucial detail the first time through. THIS should be the VB script you want.

EDIT_3: AARRGGGHHH!!! I give up. This will give you data. Tell me what I forgot and I'll comeback and fix it.
Last edited on
Thanks for the script! That is much closer to what I want but still not correct, as you have stated already.

No worries with regards to your edits. I didn't look at it until just now. After running the script, I noticed that it outputs like this.

Computer Name - Product ID - Computer Name - Computer Model
blank space - blank space - MAC Address -

MAC Address appears in same column as the second computer name column.

As for writing it entirely in c++? That is actually what I wanted to do, but (after a very short research session) could only figure out how to find the computers hostname in C++. So I turned to writing a batch file that would find the information I am looking for, put it in a .txt file, then have my c++.exe look at these text files to get the information I want. After the .exe file is done, the batch file would then delete the .txt files leaving only the .csv file left over.

I am a beginner at C++, I have been looking at a book for a few weeks now so this may still be above my level of experience. A vbs script, if it does the same thing, would be good as well.

The main purpose of this is to have many users from the company I work for run the file so that it outputs all of their data in a single .csv file. This script will be sitting in a public folder on a server.
Last edited on
Here's the revised script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const strComputer = "."
const Append = 8

Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set objFSO = CreateObject("Scripting.FileSystemObject")

Set oFile = objFSO.OpenTextFile("computerinfo.csv", Append)

set colOS = objWMI.ExecQuery("Select * From Win32_OperatingSystem")
set colSys = objWMI.ExecQuery("Select * From Win32_ComputerSystem")
set colNIC = objWMI.ExecQuery("Select * From Win32_NetworkAdapter")

for each objOS in colOS

	
	DataLine = objOS.CSName + "," + objOS.SerialNumber + ","
        
         for each objSys in colSys
                DataLine = DataLine + objSys.Model + vbCRLF
         next 	

	for each objNIC in colNIC
		if objNIC.NetConnectionStatus = 2 then
			DataLine = DataLine + ",,," + objNIC.Name + "," + objNIC.MACAddress + vbCRLF
		end if
	next	
	
next

oFile.WriteLine DataLine

The white space is actually intentional, I just think it looks better that way. If you run it more then once I think you'll see what I mean

You can do this entirely in C\C++, but the problem is that most of the data that you want is only available through COM\COM+ which is why I proposed VB Script for your solution. COM is "fun" for intermediate users and it is definitely not something I would recommend if you've only been learning C++ for a few weeks*. In COM Microsoft forces C to pretend to be C++ and it can quickly turn into an unholy mess if you're just starting out, in fact the examples for COM on MSDN illustrate this perfectly. Once you get the hang of object life time, inheritance and polymorphism (the last one is just a big fancy word we use to describe how we tell the compiler to treat a class as if it were the class it inherited from, this is done with an ampersand and it is not as scary or as complicated as it sounds) then you can wrap the classes that COM provides into a more manageable and more sane configuration.


*: At the same time it is not as impossible to learn and use as most people would have you believe.
Last edited on
Topic archived. No new replies allowed.