Link to home
Start Free TrialLog in
Avatar of courchjo
courchjo

asked on

See local workstations in a network?

I have an application that will run in a Service Center.  I want to have an administrative workstation and satelite workstations in a local area network.  The Application needs to be able to see which machines are turned on at a specific time from the administrative workstation.  I have thought about pinging the machines but would like to see if I could find a better way.  I want to assign tasks to individual workstations and have users go to those workstations. These machines are Windows 2000 and I am using VB.Net.  Any Ideas?
Avatar of plq
plq
Flag of United Kingdom of Great Britain and Northern Ireland image

You can ping from VB, using ICMP

Public Function Ping(sAddress As String, _
                     sDataToSend As String, _
                     ECHO As ICMP_ECHO_REPLY) As Long

   Dim hPort As Long
   Dim dwAddress As Long
   
  'convert the address into a long representation
   dwAddress = inet_addr(sAddress)
   
  'if dwAddress is valid
   If dwAddress <> INADDR_NONE Then
   
     'open a port
      hPort = IcmpCreateFile()
     
     'and if successful,
      If hPort Then
     
        'ping it.
         Call IcmpSendEcho(hPort, _
                           dwAddress, _
                           sDataToSend, _
                           Len(sDataToSend), _
                           0, _
                           ECHO, _
                           Len(ECHO), _
                           glngPingTime)

        'return the status as ping success
         Ping = ECHO.status

        'close the port handle
         Call IcmpCloseHandle(hPort)
     
      End If  'If hPort
     
   Else:
   
        'the address format was probably invalid
         Ping = INADDR_NONE
         
   End If
 
End Function

Also if you download xassets xam discovery, theres a tool in there called netdiscover which isn't license checked which returns a text file, either via netbios or icmp

I can give you the netbios code too if you can guarantee that all PCs are running netbios
Avatar of courchjo
courchjo

ASKER

I'm looking at  System.Management namespace right now.  I'd really like to stay away from looping through a list of ipaddresses to ping.
client server? have a small app on each PC that connects to winsock on server and sends a simple packet? or even just connects to the port, you would then have the IP and time? after that the only really reliable way would be to ping until it stopped, then the machine went off....
Winsock might be good, System.Management didn't look to fit the bill.  It is client server.  Is there something I could periodically query in the Active Directory or can I view network neiborhood within application?
I think you should look at WMI either for SNMP or the stuff thats exposed on normal WMI

All callable from VB and easy to use, except WMI for SNMP which is completed undocumented and rarely used
to see if a workstation is active, (FULLY UP AND RESPONSIVE) use a "net view" command against it,
this will test if rpc is up, if rpc is up, the workstation is fine.

The problem with pings is that it will return okay if the machine is starting up, shutting down or hung (sometimes)

create a text file called CheckIsMachineActive.WSC in your system32 directory

Paste this text to it (without the ***** lines) and save it
*********Begin Script***********
<scriptlet>

<Registration
    Description="Machine Checker By Kavar"
    ProgID="Script.CheckIfMachineActive"
    Version="1.00"
    ClassID="{00000000-aaa2-0000-0000-000000000003}"
>
</Registration>

<implements id=Automation type=Automation>
    <property name=MachineName>
        <get/>
        <put/>
    </property>
     <property name=MaxTimeOut>
        <get/>
        <put/>
    </property>
    <method name=Check>
     </method>
</implements>

<script language=vbscript>
Dim MachineName
Dim MaxTimeOut
MaxTimeOut=10

Function Get_MaxTimeOut()
Get_MaxTimeOut=MaxTimeOut
End Function
Function put_MaxTimeOut(WhatTime)
MaxTimeOut=Int(WhatTime)
End Function
Function Get_MachineName()
Get_MachineName=MachineName
End Function
Function put_MachineName(WhatMachine)
MachineName=WhatMachine
End Function
Function Check()
Dim WSH
Set WSH=CreateObject("Wscript.Shell")
Dim CommandLine
Dim proc
Set proc=WSH.Environment("Process")
Dim windir
windir=proc("Windir")
commandline=windir & "\system32\net.exe view " & MachineName
Dim oExec
Dim start
start=Timer
Set oExec=WSH.Exec(CommandLine)
Do While oExec.Status =1 And Timer-start<MaxTimeOut
WScript.Sleep 10
Loop

If Timer-start=>MaxTimeOut Then
      'went on too long
      oExec.terminate
      Check=False
 Else
       If oExec.StdErr.AtEndOfStream=True Then
             Check=True
        Else
              Check=false
       End if
End if
End Function
</script>
</scriptlet>
************End Script***********

now right click  CheckIsMachineActive.WSC and select register
if all goes well it should say something about suceeded

now within vb.net you can use the following code to check if a machine is active...

Dim t
set t=createobject("Script.CheckIfMachineActive")
t.machinename="<MACHINENAME HERE>"
IF t.check then ' machine is active
'do something
else 'machine not active
'do something else
end if

Are network settings available with WMI and where is the best place to look for the WMI documentation?
Thanks kavar the script looks like what I need.  I will also look at the WMI.  Thanks all
kewl... :}

Just looking from a different angle

Do you have active directory ? If so, I think it may be possible to poll it from VB for what machines are connected, and I reckon it will store when they logged on/off too.

I can give you the base code for LDAP / OLEDB connectivity so you can call it from VBScript / VB etc, but don't know the specifics for the fields you need.

yea we have active directory I wasn't sure if it showed active users or not.  Could you give me the base code to look at?  TIA
although AD does maintain logon/logoff times, machines in particular cannot be counted on for this information
Does this mean if a workstation locks up or gets turned off then the active directory information doesn't get updated?
that is correct
thx
Avatar of Melih SARICA
From an other way
here is a Delphi code for listing all shares and Computers that is running on ur network ...

it works fine..  What this code does.. gets all computers workgroups and shares from the network and adds them to a listbox

i ll try to rewrite it in VB.NET.. but a newbee on .NET .. but i ll try... over all it gives u an idea .
   
type
  TComputerType = (ctDomain, ctGeneric, ctServer, ctShare);

  procedure EnumNetworkComputers(NetResource: PNEtResource;ComputerType: TComputerType; List: Hwnd);
var
        EnumHandle, Count, BufSize, I   : Cardinal;
        NetArray                        : array[0..250] of TNetResource;
        Name                            : Pchar;
        nametmp                         : string;
        DoAdd                           : Boolean;
        mcount                          : cardinal;
        tmpstr                          : string;
begin
EnableWindow(mbtnsf,false);
EnableWindow(mbtn,false);
if WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, NetResource,EnumHandle) = NO_ERROR then
   begin
     try
        Count := $FFFFFFFF;
        BufSize := SizeOf(NetArray);
        if WNetEnumResource(EnumHandle, Count, @NetArray, BufSize) = NO_ERROR then
          begin
            for i := 0 to Count -1 do
                begin
                  DoAdd := False;
                  case NetArray[i].dwDisplayType of
                    RESOURCEDISPLAYTYPE_DOMAIN  : nametmp:=' '+NetArray[i].lpRemoteName+'(WorkGroup)';
                    RESOURCEDISPLAYTYPE_GENERIC : nametmp:=' |'+NetArray[i].lpRemoteName+'(Generic)';
                    RESOURCEDISPLAYTYPE_SERVER  : nametmp:='   |'+NetArray[i].lpRemoteName+'(Computer)';
                    RESOURCEDISPLAYTYPE_SHARE   : nametmp:='     |->'+NetArray[i].lpRemoteName+'(Share)';
                  else
                    nametmp:=NetArray[i].lpRemoteName;
                  end;
                  if pos('\\',nametmp) > 0 then
                     delete(nametmp,pos('\\',nametmp),2);
                  name :=pchar(nametmp);
//                If  true and (pos('(Share)',nametmp)= 0) then    // list all but shares
                If  true  then    // list all
                   SendMessage(list,lb_addstring,0,dword(name));
                   mcount:=sendmessage(mlist,LB_GETCOUNT,0,0);
                   Fmtstr(tmpstr,'Hazirlaniyor / %d adet bulundu',[mcount]);
                   name:=pansichar(tmpstr);
                   SendMessage(mfrm,WM_SETTEXT,0,dword(name));
                EnumNetworkComputers(@NetArray[i], ComputerType, list);
            end;
        end;
   finally
        WNetCloseEnum(EnumHandle);
   end;
  end;
end;

   
ASKER CERTIFIED SOLUTION
Avatar of Kavar
Kavar

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ok,  Currently I'm planning on using the script you sent me y-day.  Thanks :}
unfortunately the script I sent yesterday only works for ftp....

we need to create a new one for your download page but I need more info to write it.
sorry!!! wrong question....

Please Let me know if you need any help with the implementation