This article shows how to retrieve Physical and Virtual memory usage on a specific
process using WMI (Windows Management Instrumentation). WMI is Microsoft's implementation
of WBEM (Web-Based Enterprise Management).
Click here for more information on WBEM.
Most administrators are familiar with viewing information in task manager. One of
the most common things I look for are memory settings.
Note: the example below shows the physical memory usage for the 'sqlserver.exe'
process at 43,716 K and Virtual memory size of 55,376 K. This is a 'moment in time'
setting and can change often.
Using this code sample can help query a remote machine on a periodic basis to identify
offending processes. I use this technique to monitor 'W3WP.exe' processes on shared
web servers to identify high memory application pools.
The other feature in the component is the ability to pass custom user id and password
to the remote machine. This can be handy to not assume the user id credentials the
process is running under.
Imports System.Management
Imports System.Data.SqlClient
Module Module1
Private _ComputerName
As String = "."
Private _UserName
As String = "Changeme
to Run on a remote machine"
Private _Password
As String = "Changeme
to Run on a remote machine"
Private _SelectQuery
As String = "SELECT
* FROM Win32_Process WHERE name='w3wp.exe'"
Private _DateEntered
As DateTime = System.DateTime.Now()
Sub Main()
Try
GetProcessInfo()
Catch f
As Exception
ErrorHandler(f)
End
Try
End Sub
Sub GetProcessInfo()
Try
'**********************************************
'Uncomment this
out if you want to run on a remote machine and
'comment out the
other 'scope' variable
'You will get an
error about trying pass credentials to the local machine
'
'Dim options As
New ConnectionOptions()
'options.Username
= _UserName
'options.Password
= _Password
'Dim scope As New
ManagementScope("\\" & _ComputerName & "\root\cimv2", options)
'**********************************************
'Comment this out
if you are going to test on a remote machine
'This will default
to authenticating to the local machine
Dim scope
As New ManagementScope("\\" & _ComputerName &
"\root\cimv2")
Dim selectQuery
As New SelectQuery(_SelectQuery)
Dim searcher
As New ManagementObjectSearcher(scope,
selectQuery)
Try
scope.Connect()
Catch
f As Exception
ErrorHandler(f)
Exit
Sub
End Try
For Each queryObj As
ManagementObject In searcher.Get()
Console.WriteLine(queryObj("WorkingSetSize") / 1024)
Console.WriteLine(queryObj("PeakWorkingSetSize") / 1024)
Console.WriteLine(queryObj("PageFileUsage") / 1024)
Console.WriteLine(queryObj("PeakPageFileSystem") / 1024)
Console.WriteLine(GetOwnerObject(queryObj("Handle")))
Next
Catch f
As Exception
ErrorHandler(f)
End
Try
End Sub
Function GetOwnerObject(ByVal
strHandle As String)
As Object
Dim options
As New ConnectionOptions()
options.Username = _UserName
options.Password = _Password
'**********************************************
'Uncomment this out if you want
to run on a remote machine and
'comment out the other 'scope'
variable
'You will get an error about
trying pass credentials to the local machine
'
'Dim options As New ConnectionOptions()
'options.Username = _UserName
'options.Password = _Password
'Dim s As New ManagementScope("\\"
& _ComputerName & "\root\cimv2", options)
'**********************************************
'Comment this out if you are
going to test on a remote machine
'This will default to authenticating
to the local machine
Dim s
As New ManagementScope("\\"
& _ComputerName & "\root\cimv2", options)
Dim p
As New ManagementPath( _
"Win32_Process.Handle='"
& strHandle & "'")
Dim opt
As ObjectGetOptions
opt = New ObjectGetOptions()
Dim o
As ManagementObject
o = New ManagementObject(s,
p, opt)
' Execute the method and obtain
the return values.
Dim outParams As ManagementBaseObject = _
o.InvokeMethod("GetOwner",
Nothing, Nothing)
Return outParams("User").ToString()
End Function
Sub ErrorHandler(ByVal
exp As Exception)
Dim LogName
As String
Dim Message
As String
Dim Log
As New System.Diagnostics.EventLog
Try
LogName = "Application"
Message = "Message:
" & exp.ToString()
If (Not System.Diagnostics.EventLog.SourceExists(LogName))
Then
System.Diagnostics.EventLog.CreateEventSource(LogName,
LogName)
End If
Log.Source = LogName
Log.WriteEntry(Message)
Log.Close()
Log.Dispose()
Catch ex
As Exception
End
Try
End Sub
End Module