Getting Hardware Information from multiple machines

dlvonde

Active member
Joined
Oct 26, 2007
Messages
26
Programming Experience
1-3
Hello All,

I've been researching this for the past couple weeks and it seems everyone has a different way of doing things so I needed an opinion.

I'm making a little application for a school project that grabs the following data:
- CPU Utilization
- Amount of System Memory & Amount Free
- Size of Hard Drive & Amount Free
- Network Utilization
- Services Running
- Processes running

I am making a customer user control that will house all of this information so I'd like to be able to call up all this information in that user control class. The idea is to create a seperate instance of the class for each computer and feed it the IP Address or Computer name as a string argument. The way that seems easiest to me so far is something like this:

Dim processorUtilization as New System.Diagnostics.PerformanceCounter
With processorUtilization
.CategoryName = "Processor"
.CounterName = "% Processor Time"
.InstanceName = "_Total"
.MachineName = machineName <-- this is the string variable I would pass in.

Is there an easier/more effective/more efficient way of doing things? I tried this on my computer and kept getting 0 for the cpu utilization so there is obviously SOMETHING else I need to do.

Anyone with this type of experience please let me know what direction I should go.

thanks
 
so I'm having limited success with the PerformanceCounters...

I can get memory information (% Free and MB Free)
I can get HDD Information (% Free and MB Free)

But when I try to get the CPU information I always get 0 as the result

VB.NET:
Sub GetCPUInfo(byVal machineName as String)
   Dim cpuUtilization As New System.Diagnostics.PerformanceCounter

   With cpuUtilization
      .MachineName = machineName
      .CategoryName = "Processor"
      .CounterName = "% Idle Time"
      .InstanceName = "_Total"
   End With

   msgbox(cpuUtilization.NextValue())

End Sub

the messagebox always pops up 0. any ideas?
 
In looking around I see everyone saying to import System.Management

I do not have the System.Management option...would this make things easier on me? And if so how to I get it?

thanks
 
But when I try to get the CPU information I always get 0 as the result
You are creating a new performance counter for each call. Instead create one and use that for many calls to NextValue. (the first call always return 0)
In looking around I see everyone saying to import System.Management
I haven't seen anyone saying that in relation to performance counters. But you can use WMI from System.Management to get info also. To use it you have to add reference to the System.Management.dll first.
 
thanks again John...as you can tell my status is an accurate reflection of my vb.net knowledge :).

yes I'm sorry I meant people were talking about System.Management in regards to WMI. So do you think that would be a better route to take than trying to use the performance counters? If so I'll look up how to import this .dll.
 
WMI can also get performance counters data, but is usually used to get much other info. To have an easy go, try the WMI Code Creator and see what you can get.
 
I've decided to actually use a combination of the WMI and performance counter tools. I actually tried the wmi code generator a week or so ago but didn't know how to import the system.management .dll. After i did that everything worked well..I was able to edit the queries to make it a little more efficient.

I think I have something now that I can use with multiple machine, I am getting an RPC error sometimes but I think it's because I'm not validating myself with an admin name/password.
 
ok so i've put together this little string of code to grab some information..I still need to get some networking, services, and processes info but that's not the issue (I know how to get that info)

The issue now is I'm only able to look up information by using "." for local pc address or the PC Name. If I try using the IP address of the local machine and of course the IP address of any remote machine I get an RPC Server error.

VB.NET:
Imports System.Management

Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub

    Public Sub GetHWInfo(ByVal machineName As String)

         ' GET COMPUTER NAME
        Dim computerName As String = ""
        Try
            Dim searcher As New ManagementObjectSearcher( _
                "root\CIMV2", _
                "SELECT Name FROM Win32_ComputerSystem")

            For Each queryObj As ManagementObject In searcher.Get()
                computerName = queryObj("Name")
            Next
        Catch err As ManagementException
            MessageBox.Show("An error occurred while querying for WMI data: " & err.Message)
        End Try

        computerNameLabel.Text = computerName

        ' GET CPU Speed, Utilization, and Name
        Dim clockSpeed As Integer = 0
        Dim loadPercentage As Integer = 0
        Dim name As String = ""
        Try
            Dim searcher As New ManagementObjectSearcher( _
                "\\" & machineName & "\root\CIMV2", _
                "SELECT CurrentClockSpeed, LoadPercentage, Name FROM Win32_Processor")

            For Each queryObj As ManagementObject In searcher.Get()
                clockSpeed = queryObj("CurrentClockSpeed")
                loadPercentage = queryObj("LoadPercentage")
                name = queryObj("Name")
            Next
        Catch err As ManagementException
            MessageBox.Show("An error occurred while querying for WMI data: " & err.Message)
        End Try

        hardwareResults.Text = "CPU Type: " & name.Trim & System.Environment.NewLine & _
           "Clock Speed (Current): " & clockSpeed.ToString & System.Environment.NewLine _
           & "CPU Utilization: " & loadPercentage.ToString & "%" & _
           System.Environment.NewLine & System.Environment.NewLine



        ' GET HARD DRIVE SIZE & Free Space
        Dim hardDriveSize As Double = 0
        Dim freeSpace As Double = 0
        Dim percentFree As Double = 0
        Try
            Dim searcher As New ManagementObjectSearcher( _
                "\\" & machineName & "\root\CIMV2", _
                "select FreeSpace,Size from Win32_LogicalDisk where DriveType=3")

            For Each queryObj As ManagementObject In searcher.Get()
                hardDriveSize = hardDriveSize + queryObj("Size")
                freeSpace = freeSpace + queryObj("FreeSpace")
            Next
        Catch err As ManagementException
            MessageBox.Show("An error occurred while querying for WMI data: " & err.Message)
        End Try
        hardDriveSize = ((hardDriveSize / 1048576) / 1024)
        freeSpace = ((freeSpace / 1048576) / 1024)
        percentFree = freeSpace / hardDriveSize

        hardwareResults.Text = hardwareResults.Text & "Hard Disk Size: " & _
          hardDriveSize.ToString("N2") & "GB" & System.Environment.NewLine & _
          "Free Space: " & percentFree.ToString("P2") & System.Environment.NewLine

        ' GET MEMORY INFO
        Dim totalPhysicalMemory As Double = 0
        Try
            Dim searcher As New ManagementObjectSearcher( _
                "root\CIMV2", _
                "SELECT TotalPhysicalMemory FROM Win32_LogicalMemoryConfiguration")

            For Each queryObj As ManagementObject In searcher.Get()
                totalPhysicalMemory = queryObj("TotalPhysicalMemory")
            Next
        Catch err As ManagementException
            MessageBox.Show("An error occurred while querying for WMI data: " & err.Message)
        End Try

        totalPhysicalMemory = totalPhysicalMemory / 1024
        Dim freeMemory As New System.Diagnostics.PerformanceCounter
        With freeMemory
            .MachineName = machineName
            .CategoryName = "Memory"
            .CounterName = "Available MBytes"
        End With

        hardwareResults.Text = hardwareResults.Text & System.Environment.NewLine & _
           "Total Memory: " & totalPhysicalMemory.ToString("N2") & "MB" & _
            System.Environment.NewLine & "Free Memory: " & freeMemory.NextValue() _
            & "MB" & System.Environment.NewLine

    End Sub

    Private Sub goButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles goButton.Click
        GetHWInfo(ipAddressTextBox.Text)
    End Sub
End Class

Currently I've just got a form with a textbox prompting for the ip address/computer name and a go button. then I have a big multi-line textbox that spits out all the info...I figure if I can get this working in this class then I can dump the code straight into my user control (tab control) and just re-assign the results to the appropriate labels, progress bars..etc.

I need to be able to get to any machine on the network and grab this type of info...what else do I need to do?

I've been doing some different research and I think I need to authenticate myself to the machine with an admin name/password but is there anything else i need to do? and what would be the best way to go about doing it? When I look it up I see everyone doing something different

thanks
 
Run the WMI Code Creator again, see that you can select Target Computer on menu. When you select Remote computer it sets up a ManagementScope with ConnectionOptions to authenticate.

Your code worked when I ran it, also in a local network (without credentials even). RPC error could be a firewall issue. Also verify that RPC and WMI services are running on remote computer.
 
thanks again johnH!!!

it looks like I had a leftover "End Sub" from something else I was trying in my code..sorry about that.

So if I create this connection and open the connection at the very beginning of my function I should be able to just keep creating new searcher objects and querying right? I have to do the connection thing each time as long as I'm querying the same computer correct? Once I better understand what is happening I'm sure I can make my code more compact.

thanks again.
 
So if I create this connection and open the connection at the very beginning of my function I should be able to just keep creating new searcher objects and querying right?
That is correct.
 
ok so I'm still plugging away at it...I tried the WMI Code creator for a remote machine but still get the RPC Server is unavailable. I enabled some RPC and WMI services on my local machine and this time I got some results (although the memory free space using performance counter still wouldn't work).

*EDIT: I looked back over the WMI stuff and found out where I can find free memory and total memory capacity so I'm going to try to go all WMI. Now I can get the information on my local computer using both IP address and computer name.

I checked my firewall settings on my router and as of right now it's wide open but I'm still not able to get these through...

any other suggestions?

thanks again,
dlv
 
Last edited:
OK I'm so close!

I've now got a re-usable control and it's pulling up the CPU, Hard Drive, Services, and Processes....The only thing left is network utilization.

I've looked all through the WMI functions in the WMI creator tool and cannot find something that pulls up Network utilization. We were able to do it with the performancecounters but I was having issues with that and wanted to do all WMI.

I googled for a good while on how to do it and never found any accurate hits. if anyone knows how to pull up Network utilization using WMI please let me know!

thanks.
 
Back
Top