Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Using WMI to gather netstat data

Status
Not open for further replies.

BobRodes

Instructor
May 28, 2003
4,215
US
I need to access remote machines to get the data that derives from issuing the netstat -anbo command. In particular, I need Protocol (TCP or UDP), the local address and port, the foreign address and port if applicable, the state (listening, established, time_wait, etc.), and the PID. I also need to know which apps are running on which connections.

I considered working with remote shell commands first, but even if I got that working perfectly, the Win2000 boxes don't support the b or o switches.

I've wandered around in the WMI documentation for some time now, and find that I can establish connections and get various information. What I haven't been able to do is find classes which will show the information I'm looking for.

So. Here's where I've been doing most of my looking: Are there other places to look? Does anyone know what classes I need to query to get the info I'm looking for? Can I even use WMI to get this info?

Thanks in advance for helping.

Bob
 
Rats. I was afraid you'd say that. Thanks for the scriptomatic link, too. I'm looking at it. Do you have any thoughts on how one might get the -bo functionality of netstat on Win2000 machines?
 
Something like this should work with NetStat:

Code:
Option Explicit

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, _
ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

Private Const SW_SHOWNORMAL As Long = 1
Private Const SW_HIDE As Long = 0

Private Declare Function GetSystemDirectory Lib "kernel32" Alias "GetSystemDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long

Dim sSave As String, Ret As Long

Private Sub Form_Load()
    'KPD-Team 1998
    'URL: [URL unfurl="true"]http://www.allapi.net/[/URL]
    'E-Mail: KPDTeam@Allapi.net
    Dim sSave As String, Ret As Long
    'Create a buffer
    sSave = Space(255)
    'Get the system directory
    Ret = GetSystemDirectory(sSave, 255)
    'Remove all unnecessary chr$(0)'s
    sSave = Left$(sSave, Ret)
End Sub

Private Sub Command1_Click()
    ShellExecute Me.hwnd, "Open", sSave & "CMD.exe", " /c [COLOR=red]dir c:[/color] > D:\Myfile.txt", "D:\", SW_SHOWNORMAL
End Sub

replace the red code with your command and parameters

-David
2006 Microsoft Most Valueable Professional (MVP)
2006 Dell Certified System Professional (CSP)
 
Unfortunately I don't think that solves the OP problems of working remotely or getting -b and -o functionality on W2K boxes
 
Thanks for the thought David, but as strongm says I don't see where I can run that remotely. I'll keep looking and if I find something I'll post it.

Regards,

Bob
 
This is one of those irritating ones: you feel as if there must be a simple approach that'll work, but I can't for the life of me see it at the moment
 
Yeah, exactly. I'm still in the tank on this one.
 
Ok. After a little more than a day's research, I have a few facts that may be of general interest:

1. Netstat data can be accessed through the iphlpapi.dll API, but only on the local machine.
2. WMI will allow you to access a remote machine, but won't give netstat data.

The best I've come up with is to use WMI to figure out whether I'm dealing with a Win2000 or WinXP machine, then remotely run netstat, using the -bo switches if I have a WinXP machine and giving up on them with a Win2000 machine.

To remotely access a machine without installing some sort of listening agent on it, I used psexec.exe, which is contained in Winternals' psTools suite. Find it at It's freeware, and there are lots of other cool admin tools as well. I've used this from a command prompt and gotten it to run fine:

psexec \\myserver netstat -an >temp.txt

(which redirects the netstat output from the screen to a file called temp.txt)even puts temp.txt in the current directory on the client machine, so I don't have to go fishing for it on the remote one. Looks like a nice piece of work. I'll post code when I get it working.

Bob
 
<won't give netstat data

As strongm says, I'd be happy to be proved wrong....
 
Here's the solution I came up with, using psexec.

Code:
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Private Const PROCESS_QUERY_INFORMATION = &H400

Private Function IsProcessRunning(pid As Long) As Boolean
Dim hProcess As Long
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid)
CloseHandle hProcess
IsProcessRunning = hProcess
End Function

[COLOR=green]'taken from another function, not quoted in full[/color]
ProcessId = Shell("cmd /C " & App.Path & "\psexec \\" & !svr_name & " -u someuser -p somepword [COLOR=blue]netstat -an >c:\temp\temp.txt[/color]", vbHide)
Do While IsProcessRunning(ProcessId)
    lblMessage.Caption = lblMessage.Caption & ". "
    If Len(lblMessage.Caption) >= 300 Then
        lblMessage.Caption = "Processing "
    End If
    Sleep 250
    TryCt = TryCt + 1
    If TryCt = 480 Then 'In other words, time out at 480*250 milliseconds or 2 minutes.
        Err.Raise vbObjectError + 9998, "GetStatsCode", "Timeout"
    End If
    DoEvents
Loop

[COLOR=green]'Open resulting text file and do as you will with it[/color]

I've put the actual command executed on the remote machine in blue. psexec syntax is [tt]psexec \\servername -u username -p password command[/tt]; this is wrapped in the Shell command syntax.

Thanks to Hypetia for the IsProcessRunning trick. Shell runs in its own process, and therefore asynchronously. I ran into a situation where the app was trying to open the text file before the shell command was done in some cases. This code just keeps trying to open the shell process and doesn't exit the loop until it can't, which has the effect of synchronizing the two processes. (As a side benefit, you can update a progress bar each iteration of the loop.) A good, simple solution to the problem.

Bob
 
An alternative to Hypetia's trick is to use the Exec method of the Windows Script Host Object model
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top