#72910 - 2003-02-06 01:47 AM
FindMe KiXform
|
JimRobinson
Fresh Scripter
Registered: 2003-01-10
Posts: 42
Loc: Tempe, AZ
|
My assignment: Steal as much code and as many ideas as I possibly can and put a GUI on a KiX script that will query WINS and return an IP and computername given a username. See is there a "RemoteComputerFromUser" UDF...
So, thanks to jpols and sealeapord for the base of InStrArray(), Chris S. for WshPipe(), and Shawn, et al for Kixforms, I got this.
It is a little crowded (but I wanted to keep it small), and I don't think the Copy buttons are all that worthwile, since you need to select the text first anyway, but I don't think it's too bad.
I may change one of the Copy buttons to one that would start an Explorer session on the root share of the computername, since that's what I need the info for usually.
What do you think?
;Change this IP address to that of your local WINS server $WINSserver = "YOUR_WINS_SERVER_ADDRESS" $file = "@ScriptDir\winscl.txt"
;KiXforms Designer Code Output
;***** Main Form Properties *****
$form = createobject("kixtart.form") $form.width = 355 $form.height = 87 $form.center $form.caption = "Locate"
;***** Control Properties *****
$lblUser = $form.Label $lblUser.width = 60 $lblUser.height = 20 $lblUser.left = 25 $lblUser.top = 48 $lblUser.caption = "User Name" $lblUser.FontName = MS Shell Dlg $lblUser.FontSize = 8
$lblIP = $form.Label $lblIP.width = 60 $lblIP.height = 20 $lblIP.left = 130 $lblIP.top = 48 $lblIP.caption = "IP Address" $lblIP.FontName = MS Shell Dlg $lblIP.FontSize = 8
$lblHost = $form.Label $lblHost.width = 60 $lblHost.height = 20 $lblHost.left = 250 $lblHost.top = 48 $lblHost.caption = "Hostname" $lblHost.FontName = MS Shell Dlg $lblHost.FontSize = 8
$txtUser = $form.textbox $txtUser.width = 100 $txtUser.height = 20 $txtUser.left = 5 $txtUser.top = 25 $txtUser.FontName = MS Shell Dlg $txtUser.FontSize = 8 $txtUser.text = "USERNAME"
$txtIP = $form.textbox $txtIP.width = 102 $txtIP.height = 20 $txtIP.left = 109 $txtIP.top = 25 $txtIP.text = "000.000.000.000" $txtIP.FontName = MS Shell Dlg $txtIP.FontSize = 9
$txtHost = $form.textbox $txtHost.width = 130 $txtHost.height = 20 $txtHost.left = 215 $txtHost.top = 25 $txtHost.text = "HOSTNAME" $txtHost.FontName = MS Shell Dlg $txtHost.FontSize = 8
$btnFindMe = $form.CommandButton $btnFindMe.width = 60 $btnFindMe.height = 20 $btnFindMe.left = 25 $btnFindMe.top = 1 $btnFindMe.caption = "Find Me" $btnFindMe.FontName = MS Shell Dlg $btnFindMe.FontSize = 8 $btnFindMe.OnClick = "btn_FindMe()"
$btnCopyIP = $form.CommandButton $btnCopyIP.width = 60 $btnCopyIP.height = 20 $btnCopyIP.left = 130 $btnCopyIP.top = 1 $btnCopyIP.caption = "Copy" $btnCopyIP.FontName = MS Shell Dlg $btnCopyIP.FontSize = 8 $btnCopyIP.OnClick = "btn_CopyIP()"
$btnCopyHost = $form.CommandButton $btnCopyHost.width = 60 $btnCopyHost.height = 20 $btnCopyHost.left = 250 $btnCopyHost.top = 1 $btnCopyHost.caption = "Copy" $btnCopyHost.FontName = MS Shell Dlg $btnCopyHost.FontSize = 8 $btnCopyHost.OnClick = "btn_CopyHost()"
;***** Show the form ***** $form.show ;***** While Loop to display the form ***** while $form.visible $=execute($form.doevents) loop ;***** End of Form *****
;***** User Defined Functions ***** ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; function btn_CopyHost() $txtHost.SetFocus $txtHost.Copy EndFunction
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; function btn_CopyIP() $txtIP.SetFocus $txtIP.Copy EndFunction
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; function btn_FindMe() $ShortOffset = Len($WINSserver) $LongOffset = ($ShortOffset+25) del $file
;Write the command file used by winscl.exe and output the username $X = open (1, "$file", 5) $X = writeline(1, "$WINSserver" + @CRLF) $X = writeline(1, "QN" + @CRLF) $X = writeline(1, $txtUser.text + @CRLF) $X = writeline(1, "1" + @CRLF) $X = writeline(1, "03" + @CRLF) $X = writeline(1, "0" + @CRLF) $X = writeline(1, "EX" + @CRLF) $X = Close(1)
$WINSarray=WshPipe("%comspec% /c winscl.exe T NOME< winscl.txt",1) del $file $X = InStrArray("Address is (", $WINSarray) $Y = InStrArray("Member is (", $WINSarray) Select Case $X <> -1 $SrchLen = (LEN($WINSarray[$x])-($ShortOffset+1)) $IP = SubStr($WINSarray[$x],$ShortOffset, $SrchLen ) $txtIP.text = $IP Case $Y <> -1 $SrchLen = (LEN($WINSarray[$y])-($LongOffset+1)) $IP = SubStr($WINSarray[$y],$LongOffset, $SrchLen ) $txtIP.text = $IP Case 1 $txtIP.text = "IP Not Found" EndSelect
$HostArray = WshPipe("%comspec% /c ping -a -n 1 $IP",1) $X = InStrArray("Pinging", $HostArray) if $X <> -1 $YArray = Split($HostArray[1],"") if $YArray[1] = $IP $txtHost.text = "Not Resolved" else $txtHost.text = $YArray[1] ? endif else $txtHost.text = "Not Found in WINS" ? endif EndFunction
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; function InStrArray($string, $array) if vartype($array) >= 8192 for $i = 0 to ubound($array) if instr($array[$i],$string) $InStrArray = $i return endif next endif $InStrArray = -1 return endfunction
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function WshPipe($ShellCMD, OPTIONAL $NoEcho) Dim $WshShell, $oExec, $AllOutput, $Exit, $WshExitCode $WshErrorMsg="" $WshShell=CreateObject("WScript.Shell") $oExec=$WshShell.Exec($ShellCMD) While $Exit<>1 Dim $Output Select Case Not $oExec.StdOut.AtEndOfStream $Output=$oExec.StdOut.ReadAll Case Not $oExec.StdErr.AtEndOfStream $Output=$oExec.StdErr.ReadAll $WshErrorMsg = $Output Case 1 $Output=-1 EndSelect If $Output=-1 If $oExec.Status=1 $Exit=1 Endif Else If $NoEcho<>1 ? $Output Endif $AllOutput = $AllOutput + $Output Endif Loop $WshExitCode=$oExec.ExitCode $WshPipe=split($AllOutput,chr(10)) Exit($WshExitCode) EndFunction
Jim
_________________________
Jim --------------------
|
Top
|
|
|
|
#72912 - 2003-02-06 04:36 AM
Re: FindMe KiXform
|
Radimus
Moderator
Registered: 2000-01-06
Posts: 5187
Loc: Tampa, FL
|
I have ideas you could steal... see inquisitor on my web page
|
Top
|
|
|
|
#72916 - 2003-02-06 07:32 AM
Re: FindMe KiXform
|
JimRobinson
Fresh Scripter
Registered: 2003-01-10
Posts: 42
Loc: Tempe, AZ
|
I pulled out all the comments (that wasn't too smart) to make the post smaller. Oops. I am using version 5.0.2134.1 of both winscl.exe (Win2k RK) and winsrpc.dll (Win2k Server). I love dlls!
Funny about the "(" in IP. I tested using redirected output from winscl, changing WINS server address to different lengths, not to mention the 'found' IP addresses, just to make sure I got the substr offsets right.
The name resolution problem is likely due to the "(", since the script sets $IP to the result of the substr(), then pings $IP. So if it attempts to ping (xxx.xxx... it will certainly fail.
Looks like I need to lay my hands on a couple NT and XP boxes. My employer doesn't officially endorse XP, I don't normally have an NT box at hand, and I don't support 9x anymore (Yippee!), so writing for all OS levels is sometimes a challenge. In fact, one time...
About the screenshot. I don't have an externally visible web server to provide a URL to an image. Is there another method to use? For example is there a space on this board for that purpose?
Thanks for the input.
_________________________
Jim --------------------
|
Top
|
|
|
|
#72918 - 2003-02-06 10:37 PM
Re: FindMe KiXform
|
Radimus
Moderator
Registered: 2000-01-06
Posts: 5187
Loc: Tampa, FL
|
I have UDF'ed the Winscl routine i'll go over it a bit more for testing before it goes into the forum.:
Function WinsResolve($username,optional $winsserver) dim $winsserver, $ipconfig, $line, $wins1, $wins2, $file, $WINSarray, $ip if not $winsserver $ipconfig=WshPipe("%comspec% /c ipconfig /all",1) for each $line in $ipconfig if instr($line,'Primary WINS Server') $wins1=trim(split($line,':')[1]) endif if instr($line,'Secondary WINS Server') $wins2=trim(split($line,':')[1]) endif next if $wins1 $winsserver= $wins1 else $winsserver= $wins2 endif if not $winsserver exit 1 return endif
$file='c:\winscl.txt' del $file $X = open (1, "$file", 5) $X = writeline(1, "$WINSserver" + @CRLF) $X = writeline(1, "QN" + @CRLF) $X = writeline(1, $username + @CRLF) $X = writeline(1, "1" + @CRLF) $X = writeline(1, "03" + @CRLF) $X = writeline(1, "0" + @CRLF) $X = writeline(1, "EX" + @CRLF) $X = Close(1)
$WINSarray=WshPipe("%comspec% /c winscl.exe T NOME< $file",1) del $file for each $line in $WinsArray if instr($line,'Address is (') $IP = split(split($line,'(')[1],')')[0] endif next if $ip $WinsResolve='$ip' else exit 1 return endif endfunction
[ 06. February 2003, 22:54: Message edited by: Radimus ]
|
Top
|
|
|
|
#72919 - 2003-02-06 10:42 PM
Re: FindMe KiXform
|
Radimus
Moderator
Registered: 2000-01-06
Posts: 5187
Loc: Tampa, FL
|
BTW... Here is the screenshot of Jim's cool little app.
[ 06. February 2003, 22:43: Message edited by: Radimus ]
|
Top
|
|
|
|
#72920 - 2003-02-06 11:40 PM
Re: FindMe KiXform
|
JimRobinson
Fresh Scripter
Registered: 2003-01-10
Posts: 42
Loc: Tempe, AZ
|
Here is the latest (not yet including Radimus') modifications.
I discovered that the name resolution is an issue with XP's ping. Winscl would find the IP address, and the host would respond to a ping, but I could not resolve any name. It must be written to use Microsoft's Active DNS or something. 2k's ping however, works on XP and does resolve names correctly.
Radimus, was your screenshot taken from XP? It looks like I just need to make the form and textboxes bigger to accomodate that. NT and 2k display OK. And I had increased the form.height to 100 to resolve the label falling off the bottom in XP.
I'm still not sure about the "(" in the IP that LLigetfa noticed. I queried a server with a shorter address than my primary, which should have shortened the substr offset to the left, but I still got correct results. I can't find one with a longer address, so I will have to play around with it some more using redirected files.
And I added a button to open an Explorer window on the resolved hosts' C$ share, I'm kinda liking this. But how can I make the 'Find Me' button keep focus, so that I can type a username and hit enter, instead of needing to hit the 'Find Me' button? (That's me being lazy. I'll find out sooner or later, just figured I'd get someone that knew right off the top of their head).
break on ;Change this IP address to that of your local WINS server $WINSserver = "YOUR_WINS_SERVER_ADDRESS_HERE" $file = "@ScriptDir\winscl.txt"
;KiXforms Designer Code Output ;***** Main Form Properties *****
$form = createobject("kixtart.form") $form.width = 355 $form.height = 100 $form.center $form.caption = "Locate"
;***** Control Properties *****
$lblUser = $form.Label $lblUser.width = 60 $lblUser.height = 20 $lblUser.left = 25 $lblUser.top = 48 $lblUser.caption = "User Name" $lblUser.FontName = MS Shell Dlg $lblUser.FontSize = 8
$lblIP = $form.Label $lblIP.width = 60 $lblIP.height = 20 $lblIP.left = 130 $lblIP.top = 48 $lblIP.caption = "IP Address" $lblIP.FontName = MS Shell Dlg $lblIP.FontSize = 8
$lblHost = $form.Label $lblHost.width = 60 $lblHost.height = 20 $lblHost.left = 250 $lblHost.top = 48 $lblHost.caption = "Hostname" $lblHost.FontName = MS Shell Dlg $lblHost.FontSize = 8
$txtUser = $form.textbox $txtUser.width = 100 $txtUser.height = 20 $txtUser.left = 5 $txtUser.top = 25 $txtUser.FontName = MS Shell Dlg $txtUser.FontSize = 8 $txtUser.text = "USERNAME"
$txtIP = $form.textbox $txtIP.width = 102 $txtIP.height = 20 $txtIP.left = 109 $txtIP.top = 25 $txtIP.text = "000.000.000.000" $txtIP.FontName = MS Shell Dlg $txtIP.FontSize = 9
$txtHost = $form.textbox $txtHost.width = 130 $txtHost.height = 20 $txtHost.left = 215 $txtHost.top = 25 $txtHost.text = "HOSTNAME" $txtHost.FontName = MS Shell Dlg $txtHost.FontSize = 8
$btnFindMe = $form.CommandButton $btnFindMe.width = 60 $btnFindMe.height = 20 $btnFindMe.left = 25 $btnFindMe.top = 1 $btnFindMe.caption = "Find Me" $btnFindMe.FontName = MS Shell Dlg $btnFindMe.FontSize = 8 $btnFindMe.OnClick = "btn_FindMe()"
$btnCDollar = $form.CommandButton $btnCDollar.width = 60 $btnCDollar.height = 20 $btnCDollar.left = 250 $btnCDollar.top = 1 $btnCDollar.caption = "C$" $btnCDollar.FontName = MS Shell Dlg $btnCDollar.FontSize = 8 $btnCDollar.OnClick = "btn_CDollar()"
;***** Show the form ***** $form.show ;***** While Loop to display the form ***** while $form.visible $=execute($form.doevents) loop ;***** End of Form *****
;***** User Defined Functions ***** ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; function btn_FindMe() ;*********Clear the form, write winscl.txt********** $IP = "" $txtIP.text = "" $txtHost.text = "" $ShortOffset = Len($WINSserver) $LongOffset = ($ShortOffset+25) del $file $X = open (1, "$file", 5) $X = writeline(1, "$WINSserver" + @CRLF) $X = writeline(1, "QN" + @CRLF) $X = writeline(1, $txtUser.text + @CRLF) $X = writeline(1, "1" + @CRLF) $X = writeline(1, "03" + @CRLF) $X = writeline(1, "0" + @CRLF) $X = writeline(1, "EX" + @CRLF) $X = Close(1) ;*********Find the IP********** $WINSarray=WshPipe("%comspec% /c winscl.exe T NOME< winscl.txt",1) $X = InStrArray("Address is (", $WINSarray) $Y = InStrArray("Member is (", $WINSarray) Select Case $X <> -1 $SrchLen = (LEN($WINSarray[$x])-($ShortOffset+1)) $txtIP.text = SubStr($WINSarray[$x],$ShortOffset, $SrchLen ) Case $Y <> -1 $SrchLen = (LEN($WINSarray[$y])-($LongOffset+1)) $txtIP.text = SubStr($WINSarray[$y],$LongOffset, $SrchLen ) Case 1 $txtIP.text = "IP Not Found" EndSelect if $txtIP.text = "IP Not Found" return endif $IP = $txtIP.text ;*********Resolve the hostname********** $HostArray = WshPipe("%comspec% /c ping -a -n 1 $IP",1) $X = InStrArray("Pinging", $HostArray) if $X <> -1 $YArray = Split($HostArray[1],"") if $YArray[1] = $IP $txtHost.text = "Not Resolved" else $txtHost.text = $YArray[1] ? endif else $txtHost.text = "Not Found in WINS" ? endif $Host = $txtHost.text EndFunction ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function btn_CDollar() Run "%COMSPEC% /c start \\$Host\c$" EndFunction ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; function InStrArray($string, $array) if vartype($array) >= 8192 for $i = 0 to ubound($array) if instr($array[$i],$string) $InStrArray = $i return endif next endif $InStrArray = -1 return endfunction
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function WshPipe($ShellCMD, OPTIONAL $NoEcho) Dim $WshShell, $oExec, $AllOutput, $Exit, $WshExitCode $WshErrorMsg="" $WshShell=CreateObject("WScript.Shell") $oExec=$WshShell.Exec($ShellCMD) While $Exit<>1 Dim $Output Select Case Not $oExec.StdOut.AtEndOfStream $Output=$oExec.StdOut.ReadAll Case Not $oExec.StdErr.AtEndOfStream $Output=$oExec.StdErr.ReadAll $WshErrorMsg = $Output Case 1 $Output=-1 EndSelect If $Output=-1 If $oExec.Status=1 $Exit=1 Endif Else If $NoEcho<>1 ? $Output Endif $AllOutput = $AllOutput + $Output Endif Loop $WshExitCode=$oExec.ExitCode $WshPipe=split($AllOutput,chr(10)) Exit($WshExitCode) EndFunction
Jim
_________________________
Jim --------------------
|
Top
|
|
|
|
#72921 - 2003-02-07 03:36 AM
Re: FindMe KiXform
|
Les
KiX Master
Registered: 2001-06-11
Posts: 12734
Loc: fortfrances.on.ca
|
Jim, I couldn't wrap my mind around some of your code.
Particularly this: $ShortOffset = Len($WINSserver)
just didn't do it for me.
Decided to rework that portion to:
code:
Select Case $X <> -1 $SrchLen = (LEN($WINSarray[$x])-($ShortOffset+1)) ;$txtIP.text = SubStr($WINSarray[$x],$ShortOffset, $SrchLen ) $txtIP.text = Split(Split($WINSarray[$x],'Address is (')[1],')')[0] Case $Y <> -1 $SrchLen = (LEN($WINSarray[$y])-($LongOffset+1)) ;$txtIP.text = SubStr($WINSarray[$y],$LongOffset, $SrchLen ) $txtIP.text = Split(Split($WINSarray[$y],'Member is (')[1],')')[0] Case 1 $txtIP.text = "IP Not Found" EndSelect
Hope you don't mind.
I can't really take credit for it though because I er.. borrowed the Split(Split()) thingy from Lonkero.
Incidentally, my WINS IP is in the format of: $WINSserver = "11.222.33.44"
_________________________
Give a man a fish and he will be back for more. Slap him with a fish and he will go away forever.
|
Top
|
|
|
|
#72922 - 2003-02-07 04:46 AM
Re: FindMe KiXform
|
Radimus
Moderator
Registered: 2000-01-06
Posts: 5187
Loc: Tampa, FL
|
I couldn't do much with that either... so I replaced that whole section with this.
for each $line in $WinsArray if instr($line,'Address is (') $IP = split(split($line,'(')[1],')')[0] endif next
|
Top
|
|
|
|
#72924 - 2003-02-07 10:16 AM
Re: FindMe KiXform
|
Richard H.
Administrator
Registered: 2000-01-24
Posts: 4946
Loc: Leatherhead, Surrey, UK
|
On the subject of name resolution, perhaps the DNS services have not got reverse domains correctly configured?
You can use "nslookup" to check it out.
For a host name such as "myhost.acme.com" the command
code:
nslookup myhost.acme.com.
Will return the "A" record (address) record.
If the IP address is "1.2.3.4", then the command
code:
nslookup 4.3.2.1.in-addr.arpa.
will return the "PTR" (pointer) record. This is the reverse record, and is what is used to convert IP addresses to host names.
If the reverse lookup fails, ask your administrator to configure the reverse lookup domains.
Note, if you are using NT4.0 DNS services you are stuffed, as it doesn't support DDNS and the pass-through WINS lookup is a bit crap.
|
Top
|
|
|
|
#72926 - 2003-02-08 12:54 AM
Re: FindMe KiXform
|
Radimus
Moderator
Registered: 2000-01-06
Posts: 5187
Loc: Tampa, FL
|
Going on vacation... ahh the silence...
MSN will stop bleeping at me every 3 minutes
the split(split()) works great... when your output is something like:
Pinging server.domain.net [192.168.110.4] with 32 bytes of data:
$temp=split($line,'[')[1] -> 192.168.110.4] with 32 bytes of data: $result=split($temp,']')[0] -> 192.168.110.4
split on the left bracket, and take the second element and split that on the right bracket, taking the first element... to make it look complex, combine the lines into one.
IP Address. . . . . . . . . . . . : 192.168.214.1
trim(split($line,':')[1]) is the way to go
|
Top
|
|
|
|
#72928 - 2003-02-07 03:01 PM
Re: FindMe KiXform
|
Radimus
Moderator
Registered: 2000-01-06
Posts: 5187
Loc: Tampa, FL
|
perhaps, this could be UDF'd for those confused with the array elements
Function MidStr($string,$leftchar,$rightchar,optional $trim)
Want to do it Les?
|
Top
|
|
|
|
Moderator: Glenn Barnas, NTDOC, Arend_, Jochen, Radimus, Allen, ShaneEP, Ruud van Velsen, Mart
|
0 registered
and 980 anonymous users online.
|
|
|