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?
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....
ASKER
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
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.CheckIfMach ineActive"
Version="1.00"
ClassID="{00000000-aaa2-00 00-0000-00 0000000003 }"
>
</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=MachineNam e
End Function
Function put_MachineName(WhatMachin e)
MachineName=WhatMachine
End Function
Function Check()
Dim WSH
Set WSH=CreateObject("Wscript. Shell")
Dim CommandLine
Dim proc
Set proc=WSH.Environment("Proc ess")
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.Che ckIfMachin eActive")
t.machinename="<MACHINENAM E HERE>"
IF t.check then ' machine is active
'do something
else 'machine not active
'do something else
end if
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.CheckIfMach
Version="1.00"
ClassID="{00000000-aaa2-00
>
</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=MachineNam
End Function
Function put_MachineName(WhatMachin
MachineName=WhatMachine
End Function
Function Check()
Dim WSH
Set WSH=CreateObject("Wscript.
Dim CommandLine
Dim proc
Set proc=WSH.Environment("Proc
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
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.Che
t.machinename="<MACHINENAM
IF t.check then ' machine is active
'do something
else 'machine not active
'do something else
end if
ASKER
Are network settings available with WMI and where is the best place to look for the WMI documentation?
ASKER
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.
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.
ASKER
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
ASKER
Does this mean if a workstation locks up or gets turned off then the active directory information doesn't get updated?
that is correct
ASKER
thx
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(NetRe source: 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_GLOB ALNET, RESOURCETYPE_ANY, 0, NetResource,EnumHandle) = NO_ERROR then
begin
try
Count := $FFFFFFFF;
BufSize := SizeOf(NetArray);
if WNetEnumResource(EnumHandl e, 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 +'(WorkGro up)';
RESOURCEDISPLAYTYPE_GENERI C : nametmp:=' |'+NetArray[i].lpRemoteNam e+'(Generi c)';
RESOURCEDISPLAYTYPE_SERVER : nametmp:=' |'+NetArray[i].lpRemoteNam e+'(Comput er)';
RESOURCEDISPLAYTYPE_SHARE : nametmp:=' |->'+NetArray[i].lpRemoteN ame+'(Shar e)';
else
nametmp:=NetArray[i].lpRem oteName;
end;
if pos('\\',nametmp) > 0 then
delete(nametmp,pos('\\',na metmp),2);
name :=pchar(nametmp);
// If true and (pos('(Share)',nametmp)= 0) then // list all but shares
If true then // list all
SendMessage(list,lb_addstr ing,0,dwor d(name));
mcount:=sendmessage(mlist, LB_GETCOUN T,0,0);
Fmtstr(tmpstr,'Hazirlaniyo r / %d adet bulundu',[mcount]);
name:=pansichar(tmpstr);
SendMessage(mfrm,WM_SETTEX T,0,dword( name));
EnumNetworkComputers(@NetA rray[i], ComputerType, list);
end;
end;
finally
WNetCloseEnum(EnumHandle);
end;
end;
end;
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(NetRe
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_GLOB
begin
try
Count := $FFFFFFFF;
BufSize := SizeOf(NetArray);
if WNetEnumResource(EnumHandl
begin
for i := 0 to Count -1 do
begin
DoAdd := False;
case NetArray[i].dwDisplayType of
RESOURCEDISPLAYTYPE_DOMAIN
RESOURCEDISPLAYTYPE_GENERI
RESOURCEDISPLAYTYPE_SERVER
RESOURCEDISPLAYTYPE_SHARE : nametmp:=' |->'+NetArray[i].lpRemoteN
else
nametmp:=NetArray[i].lpRem
end;
if pos('\\',nametmp) > 0 then
delete(nametmp,pos('\\',na
name :=pchar(nametmp);
// If true and (pos('(Share)',nametmp)= 0) then // list all but shares
If true then // list all
SendMessage(list,lb_addstr
mcount:=sendmessage(mlist,
Fmtstr(tmpstr,'Hazirlaniyo
name:=pansichar(tmpstr);
SendMessage(mfrm,WM_SETTEX
EnumNetworkComputers(@NetA
end;
end;
finally
WNetCloseEnum(EnumHandle);
end;
end;
end;
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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.
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
Please Let me know if you need any help with the implementation
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