Wilson WindowWare Tech Support

WinBatch WinBatch+Compiler WebBatch
Home | Tech Database | Tech BBS | White Papers | Purchase


Using The WinBatch Scripting Language To Automate Security In An NT4 Environment

Terry Chapman

SANS GSEC Cert v.1.2e

August 16, 2000

 

·        Introduction: Why Scripting Is Important for the Security Administrator 1

·        WinBatch Scripting: An Introduction to WinBatch. 1

·        Getting Started: A Practical overview of scripting with WinBatch. 3

·        Baby Steps: A walkthrough of a couple of simple scripts. 3

·        Long Division: A walkthrough of a more advanced Script 5

·        Wrapping Existing Tools: Integrating and combining existing NT tools. 5

·        Know your registry: Managing En Mass Registry Changes. 5

·        Summary: WinBatch – The Security Administrator’s Sidekick. 5

·        References. 5

 

Introduction: Why Scripting Is Important for the Security Administrator

 

A basic scripting knowledge is the Swiss Army knife of any administrator’s repertoire.  The use of scripting can enable the automation of virtually any repetitive task.

For any security administrator working on a network with more that one server, scripting allows automated patch distribution and time to be spent on the important task of interpreting information, rather than generating it!

 

There are a couple of myths about scripting that need to be dispelled;

 

Myth No. 1: Scripting is difficult!

Myth Buster: Anyone who has written a line in a DOS batch file is on the way to writing useful scripts!  Try it now… Open notepad, type ‘@echo Hello World!’ (without quotations), save the file as script.bat, from a command prompt now run your new batch file.  Welcome to the wonderful world of scripting!!

 

Myth No. 2: Scripting takes a long time to learn…I’m too busy to learn how to program…

Myth Buster: Can you afford the time to not learn how to do some basic coding?  Let’s say that you are the security administrator for the XYZ Widget Co.  Your boss has asked you to baseline the open ports on all of the company’s 150 servers.  It is your responsibility to monitor any new ports that open on any of the servers on a daily basis.

Recommending to your boss that you are going to need two assistant administrators to help log on to each of the 150 servers, perform a netstat, and compare the differences with the baseline survey is NOT a good career advancing move!

 

In this document I will endeavour to guide you through a couple of relatively simple scripts in order to demonstrate that getting started with scripting is not as a daunting task as you may have considered.  For the scripting veterans, or those Sysadmins’ with more ambitions goals, I will also guide you through a couple of more advanced scripts using my favourite scripting language, Wilsonware’s WinBatch.

 

As you progress with your own scripting efforts remember if there is a will, there is a way to script it.

 

WinBatch Scripting: An Introduction to WinBatch

 

WinBatch is a scripting language designed specifically for the Windows platform.  It is the brainchild of Morris Wilson, and is supported by the very useful WinBatch resource website (1).  A ‘tongue in cheek’ biography for Mr Wilson can be found on the Wilson WindowWare website (2).

Why WinBatch??  There are plenty of other scripting languages out there for the choosing.  In a recent ZDNet poll of scripting languages (3) WinBatch was clobbered by its scripting nemesis Perl.  Although there is no question that Perl is a great cross-platform scripting language, WinBatch has concentrated solely on what it knows best; Windows, and has produced an easy to use, solid and powerful scripting language that takes some of the shine off Perl.  At the risk of creating a religious scripting war, the gauntlet has been thrown down to all of you expert Perl programmers for security out there!  By the way, I wasn’t completely honest about WinBatch being a solely Windows scripting language; it also interacts well with Novell and can create cool dynamic HTML scripts with its sister product WebBatch!  But that is a topic for another day…

 

WinBatch comes standard with WinBatch Studio which is a useful colour keyed programming interface; although the purists can feel free to write the code in their favourite text editor.  As a network and security administrator one of the most useful features of WinBatch is the ability to easily compile code into distributable executable files.  This feature unfortunately is not part of the base WinBatch product, and is bundled with the product at an additional expense.  With the view that the executables can be run on any computer within your company without needing additional licensing, the extra expense is well worth the money.

Some of the other features of WinBatch that I have found particularly useful are;

 


Getting Started: A Practical overview of scripting with WinBatch

 

Firstly let me say that I am not a hardcore application programmer turned security administrator; nothing could be further from the truth!!  Before I began getting creative with WinBatch scripts I was a fair hand at the old DOS batch files, and I had dabbled in a couple of other simple scripting languages, but I would have found it rather difficult to do much useful coding beyond the complexity of a logon script.

Let’s get to it!  Over the next few pages I have given a few of examples for you to work through.  If you would like to pull them apart and play with them, I would suggest that you download the trial version of WinBatch.  You can download the application using this link; http://www.windowware.com/download.html. (4)

Once you have installed the application you can copy any of the code from this document, and then modify and run it from within the application itself.  If you decide that my code is worthy of use on you LAN/WAN please remember to send me lots of money, or at least acknowledge my contribution within your script!!

 

A word of warning and a disclaimer!

For the same reason that you should never run an executable that has a questionable source, always make sure that you understand what a script (or executable) does before running it!  The following examples have been tested in my particular environment, but may not work as expected under all encountered environments (read; all care, no responsibility!).  You will notice that most of the scripts in this document have built-in error checking that stops the script if an unrecognised environment arises.  If you intend to write scripts that will be directly or indirectly used by end users (e.g. logon scripts or software/patch distribution), make sure that if the script fails, it will fail to a known state.

 

A couple of pointers.

A seasoned word of advice for the new scripter: Test, test, test, test, and when you have finished test again!!  A great way to attract bad publicity towards your scripting efforts is to have your newly distributed patch fail simultaneously on all 2000 of the company’s client computers!!

Remember that scripting a task is supposed to automate and make life easier for everyone; 2000 distressed user calls to the support team will not make you Mr/Ms Popular with your colleagues!!

Personally, I have found that a good guide (depending on complexity) is to spend around 50% of the time used in producing a script in testing it.  Obviously scripts that are likely to affect more than a few users should receive more attention, than one that you are only ever going to use yourself.

Sometimes testing just cannot predict certain events.  In these cases you need to execute your ‘break glass in case of emergency’ procedures.  This is no problem because you have your back-out/rollback plan at the ready…

At this point if your response is ‘What back-out/rollback plan??’ then it would probably be best if you started updating your CV – and maybe not ask for a reference from this particular company!

 

Anyone who has ever experienced the very powerful and potentially company crippling ‘Windows System Policy’ editor will understand when I say; ‘Mass automation can be achieved with a minimum of effort with a well written script, but be aware that it also has the potential to damage the company’s IT infrastructure on a very large scale’.

 

This information is not intended to put you off scripting, but it IS intended to make you very paranoid!

 

Baby Steps: A walkthrough of a couple of simple scripts

 

A convention – all text following the ‘;’ character is a comment/commentary only, and does not effect the execution of the script.  Try to leave a paper trail in all of your scripts; it saves you from having to rewrite chunks of code when you need to recycle.

 

For the purpose of these next few examples I will assume that you have the ability to write simple DOS batch files.  If this is not the case, I would suggest that you complete the tutorial in the WinBatch help file before continuing on.  Another excellent resource, if you are completely new to the scripting world, is the very comprehensive DOS manual, ‘Using MS_DOS 6.22 Second Edition’ published by QUE (5).  The WinBatch help files also provide detailed explanations of all commands used in the following examples.

 

All of the following scripts are real live code!  They are out their doing their automated work as you read this document.  When I need to roll out a particular script to the general user population, I normally compile the script into an executable and distribute it via a logon script.

For the WinBatch script to run, the client needs to have access to the WinBatch system file; wbdbv32i.dll.  This file can be located in the source script directory or in the system path on the client.  For speed efficiency, I prefer to copy this file down to the system32 directory on the client.

The easiest way to do this is to create a batch file that copies the file to the client and then calls the WinBatch logon script.

Try using a variation of the following batch file to get ‘up and running’ if you would like to create a logon script using WinBatch;

 

@echo off

rem Copy this code into a batch file called logonscript.bat

rem Put the file in the export directory of your replication domain controller.

 

If exist %systemroot%\system32\wbdbv32i.dll goto script

 

Copy %logonserver%\netlogon\wbdbv32i.dll %systemroot%\system32\

 

:script

start /w %0\..\logon.exe

 

:end

 

Notice the ‘/w’ after the start command, which means wait.  If you do not put this parameter in, the batch file will execute and then exit; immediately loading the Windows desktop while your WinBatch logon script is still running!

 

Note; some lines in the examples are wrapped for readability.

 

Script One: Disabling Windows Scripting Host

 

Commands used:

Display – Brings up a Windows dialog box that times-out after a specified time.

If…Endif – If the statement following the ‘If’ command is true, execute all lines down to ‘endif’.

RegExistKey – Checks for the existence of the specified registry key.  There are two parts of the command; RegExistKey (@ followed by registry hive, keyname).

RegSetValue – As the name suggests, set a registry value.  Same syntax as RegExistKey with the additional field at the end that specifies what the new value is.

 

One of the first few tasks that I do at a new client company is to disable VBS scripting if it is not being used.  This one action makes a very large number of viruses impotent even before your favourite anti-virus software gets to the virus.  If I subsequently need to re-enable VBS temporarily, I simply need to use the same script with the original value (VBSFile) rewritten to the key value.

The script can be distributed most easily via a logon script.

 

; Disable Windows Scripting Host

; Author: Terry Chapman

; Version: 1

 

title = “Scripting Host Disable” ; This is a variable that can be reused

display (3, title, "Disabling Windows Scripting Host. Please wait...") ; Display message for 3 seconds to the end user

; Check to see if the registry key .VBS exists under hkey_classes.  If it does, execute the two lines following the statement.

If RegExistKey (@RegClasses, ".VBS")

                RegSetValue(@REGCLASSES, ".VBS", "") ; Set the .VBS value to “”, or blank

                display (3, title, "Windows Scripting Host has been disabled")  ; Display a message to the end user

EndIf ; The other half of the ‘If’ statement

 

Script Two: Install remote control software on client workstations

 

The following script was written to install the remote control software ‘Funk Proxy’.  It forms part of a larger script.  In this particular situation each machine needed to be logged on to perform manual copying, and as there were only a few dozen computers to install it on,  I associated this script with a particular user logon account.  Simply logging on as the install user instigated the installation process.

 

Commands used:

Dirget() – Returns current working directory.  This is a very useful command that avoids putting ‘hard-coded’ directory paths in your code.

Strcat – An easy way to tie two or more variables together.

Fileexist – As the name suggests, checks for the existence of the file in the following brackets.

! – The WinBatch equivalent of ‘not’

Message – Similar to the display command, but presents an OK button that needs to be pushed before the script continues.

RunHideWait – There are three parts to this command; run – run an executable file that is external to this script, hide – do not make the called executable interactive, wait – wait for the executable to finish before continuing the current script.  The syntax is RunHideWait (exe name, optional parameters).

IntControl – The WinBatch IntControl commands are able to access some of the core functions of Windows.

 

; Silently installs Proxy Host for Remote Control

; Date: 19/4/2001

; Author: Terry Chapman

; Version: 1.1

 

title = "Proxy Host Installer"

dir = dirget() ; Get the directory path that the installer is running in – e.g. \\servername\setuppath\

setup = strcat (dir, "setup.exe") ; ties 2 or more variables together; in this case \\servername\setuppath\setup.exe

phdir = "C:\Program Files\Funk Software\Proxy\"

phset = strcat (phdir, "phset32.exe")

 

if fileexist (phset) ; Error check to see if the Proxy file is already there. Display a message and exit if it is.

                display (3, title, "Proxy Application is already installed.")

                exit

endif

 

display (3, title, "Installing Remote Control Software. Please wait...")

 

if ! fileexist (setup) ; Check to see that the setup file is available.

message (title, "Proxy setup could not be found.%@crlf%Make sure that this executable (proxyinstall.exe) is in the Proxy setup directory.") ; Note - This line is wrapped.  The %@crlf% simply means line return.

                exit

endif

 

runhidewait (setup, "") ; The line that actually does all of the work!  Run the silent installation of the application.

 

message (title, "Finished!  Rebooting computer.")

IntControl (67, 0, 1, 0, 0) ; Signal for the computer to reboot

 

Long Division: A walkthrough of a more advanced Script

 

The following script was written to automate the disabling of user accounts that have not been used for the previous 30 days.  One of the complexities to overcome with writing this script was that each domain controller stores the logon information for a user when they last logged onto that particular server.  For this reason each domain controller needs to be queried for the user’s last logon, and the latest date is taken as the final logon.

In a nutshell the script does the following; takes each domain account, checks all domain controllers for the last logon date, if the account has not been used for over 30 days and is not already disabled the account is now disabled, at the end of the process an email is sent to the administrator with the newly disabled accounts listed, two log files are created listing users who have never logged on and the last logon date of all domain users.

Use the ‘at’ command to schedule this script to run on a designated server each day.

This script has been tested on a WAN of around 500 users and 15 domain controllers.  It takes around 15 minutes to complete, and doesn’t work well on links less than 128KB!

 

Commands used:

AddExtender – Extenders add functionality to WinBatch.  Note; any extenders that are added need to be located within the setup directory or in the client system path.

WntGetDc – Network extender function that determines a reachable domain controller.

Fileopen – As the name suggests, open a ASCII file.

Filewrite – Write to an ASCII file.

Fileclose – Close a file when finished reading.  Once the contents of a file have been read it is no longer necessary to leave the file open.

WnServerList – Collect list of servers available.

WntUserList – Generate tab delimited list of users

Itemcount – Return the number of items in the specified variable.

For y = 1 to xyz Recurse through the following statement for the specified amount of times.

Itemextract – Get a variable from within the delimited variable list

Random – Generate a random number up to the number within the following brackets.

Box* - Various commands to bring up informational dialogs.

WntUserGetDat – Returns information based on users domain information.

Strsub – Extract part of a variable.

TimeYmdHms() – Returns the current time in the format of year, minute, day, hour, minute, second.

TimeDiffDays – Returns the difference in days of two given dates.

WntUserSetDat – Changes user domain information.

MSendMail – Send an email using installed email client

 

; Disable unused accounts

; Author - Terry Chapman

; Date - 8/6/2001

 

AddExtender("WWWNT32I.DLL") ; Dll for networking operations

AddExtender("wwmap32i.dll") ; Mail extender

 

IntControl (1002, 0, 0, 0, 0) ; Hide script icon

 

title = "Account CleanUp Utility"

dc=wntGetDc( "", "YourDomainName", 1) ; Get the Primary Domain Controller

mail = "" ; Set the variable to blank

 

handle = fileopen ("c:\neverlogon.txt", "WRITE") ; Create a brand new file if this text file already exists

detail = strcat ("User list of members who have never logged on:", @crlf)

filewrite(handle, detail) ; Add the above line of text, ready to be appended to later

fileclose (handle) ; Close file for the moment

handle1 = fileopen ("c:\lastlogon.txt", "WRITE")

detail1 = strcat ("Last logon time;", @crlf, "Format: User, Full name, Last logon, Last logon server, Do not expire, Currently expired, Currently disabled")

filewrite(handle1, detail1)

fileclose (handle1)

 

servers = wntServerList("","",8|16) ; List all of the domain controllers on the network

servercount = itemcount (servers, @tab) ; Count the number of returned servers

userlist = wntUserList(dc, 2) ; Get a list of the users from the PDC

usercount = itemcount (userlist, @tab) ; Count number of items in user list

for y = 1 to usercount ; Repeat the following code until the above number of users have been processed

useritem = itemextract (y, userlist, @tab) ; Extract username from list

                ran = random (7) ; Generate a random number between 0 to 7 – for dialog colour!!

                year = "0" ; Set all of the following variables to 0 or blank

                month = "0"

                day = "0"

                count = "0"

                count1 = "0"

                count2 = "0"

                lastlogon = "0"

                logonfinal = "0"

                lastserver = ""

                already = "0"

 

                BoxTitle(title) ; Display information dialog

                BoxesUp("250,380,750,567", @normal)

BoxColor(1,"0,128,0",ran) ; The random number above is used to generate a different colour dialog on each pass!  Useful for estimating the general speed of the script.

                BoxDrawRect( 1, "0,0,1000,1000", 2)

                BoxTextColor(1, "255,255,255")

                BoxDrawText(1, "200,600,750,350", "Checking last logon details.", @TRUE, 5)

                BoxDataTag(1,"tag")

 

                for x = 1 to servercount ; Query each server for each user

                                serveritem = itemextract (x, servers, @tab)

                                boxtext ("")

                                BoxDrawText(1, "200,600,750,350", "Checking user '%useritem%' on %serveritem%.", @TRUE, 5)

                                lastlogon = wntUserGetDat(serveritem, useritem, "last_logon") ; Get last logon for each server

                                check0 = strsub (lastlogon, 1, 4) ; Check the first four numbers of lastlogon variable

                                if check0 != "0000" ; Execute the next statement if the user has ever logged onto this server

if lastlogon > logonfinal ; If this variable is greater than the last logon variable; increment lastlogon to equal logonfinal

                                                                logonfinal = lastlogon

                                                                lastserver = serveritem

                                                endif

                                endif

next  ; Go back to the for x= statement until all servers have been queried.  At the end of the for/next statement, logonfinal will contain the date of the most recent logon on all domain controllers.

 

                non = itemextract (1, logonfinal, ":")

                if non == "0000" ; If 0000 the user has not logged into any server

                                last = "Account has never been logged in"

                else

                                Now=TimeYmdHms( ) ; Get current time

                                expire=TimeDiffDays(now, logonfinal) ; Calculate the difference between now and the last logon

                                if expire == "0"

                                                last = "Account logged in today"

                                else

                                                if expire < "30"

                                                                last = "Account logged in %expire% days ago"

                                                endif

                                endif

 

                                if expire > "30" ; If over 30 days old the next couple of lines do the job!

                                                last = "Account login over 30 days old!"

                                                flags=wntUserGetDat(dc, useritem,"flags")

                                                if flags & 2 ; Check to see if account is already disabled

                                                                already = "0"

                                                else

                                                                already = "1" ; Set flag for email log

                                                                flags=flags | 2 ; Add disable parameter to flags variable

                                                                wntUserSetDat(dc, useritem, "flags",flags) ; Disable user account

                                                endif

                                endif

                endif

 

                info = wntUserGetDat(dc, useritem, "password_expired")

                disab = wntUserGetDat(dc, useritem, "flags")

                fullname = wntUserGetDat(dc, useritem, "full_name") ; Get full name

               

; The following 3 variables (count, count1, count2) are used as flags to indicate on/off status in the log file and email for the three settings – password expired, password set not to expire, account disabled

if disab & 2 ; Increment count1 variable by one if account is now disabled

                                count1 = count1 + 1

                endif

                if disab & 65536 ; Increment count2 variable by one if account is set to never expire

                                count2 = count2 + 1

                endif

                if info == 1 ; Increment count variable by one if account is set to expire on next logon

                                count = count + 1

                endif

 

                boxdataclear (1, "tag")

 

                year = StrSub (logonfinal, 1, 4) Get year, month and day to transform to readable format

                month = StrSub (logonfinal, 6, 2)

                day = StrSub (logonfinal, 9, 2)

 

                if fullname == "" then fullname = "No name listed"

 

                if count >= "1" ; Reset count* to 1 if it is 1 or greater.   This makes the variable either 1 or 0.

                                count = "1"

                endif

                if count1 >= "1"

                                count1 = "1"

                endif

                if count2 >= "1"

                                count2 = "1"

                endif

 

                if year == "0000" ; If user has never logged in write to log file

                                handle = fileopen ("c:\neverlogon.txt", "APPEND")

                                filewrite(handle, useritem)

                                fileclose (handle)

                                boxtext ("")

                                BoxDrawText(1, "200,600,750,350", "'%useritem%' has never logged on!!", @TRUE, 5)

                Else ; or write previous logon to log file

                                handle1 = fileopen ("c:\lastlogon.txt", "APPEND")

msg = strcat (useritem, @tab, fullname, @tab, day, "/", month, "/", year, @tab, last, @tab, lastserver, @tab, count2, @tab, count, @tab, count1)

                                filewrite(handle1, msg)

                                fileclose (handle1)

                                msg1 = strcat ("'", useritem, "' last logon was ", day, "/", month, "/", year, ".")

                                boxtext ("")

                                BoxDrawText(1, "200,600,750,350", msg1, @TRUE, 5)

if expire > 30 && already == "1" ; If account logon is over 30 days old AND hasn’t been disable previously

                                                mail = strcat (mail, @crlf, msg) ; Append to mail variable

                                endif

 

                endif

next ; Carry on to next user!

 

if mail <> "" ; If the mail variable is populated send an email of the results of disabled users.  No email will be sent if no user accounts were disabled.

                recip_email="Infrastructure Team[SMTP:InfrastructureTeam@company.com]"

                time=timedate()

                msg = "The following are accounts that have been disabled due to not being active for the last thirty days;"

mail = strcat (msg, @crlf, "Format: User, Full name, Last logon, Last logon server, Do not expire password, Password currently expired, Currently disabled", @crlf, @crlf, mail)

                ret=mSendMail(recip_email,"Disabled Users Report for %time%.", mail, "", "") ; Send email

endif

 

beep ; Self explanatory!

boxdestroy (1)

display (15, title, "Utility complete!")

 

Wrapping Existing Tools: Integrating and combining existing NT tools

 

One of the more powerful ways to use scripting is to ‘wrap’ existing tools.  Combining tools within WinBatch (or any scripting language) provide three main benefits;

 

 

The Windows NT Resource Kit (6) should be your first stop when looking for extremely useful tools to help automate your day.

 

Most of the best scripts are written when laziness is the prime motivation!!  Quite often a little bit of lateral thinking goes a long way to making your working day much more restful.  Let’s revisit the earlier example of creating and monitoring an open port baseline on 150 servers in your enterprise.

This is the process that I would use to go about solving this problem;

  1. Finish my first cup of coffee.
  2. Decide how I wanted to collect a list of open ports on all of the servers.  Two valid ideas would be to collect the information centrally using something like Foundstone’sFscan(7) port scanner running from a single server, or generate the information on each server individually using ‘netstat’.
  3. At this point I would trial the Fscan utility on a couple of servers (with permission from management of course).  Upon investigation I would determine that scanning 65535 ports on each server using a centralised scanner would take approximately 10 minutes per server.  For the 150 servers this would take a bit over 24 hours.  Not a particularly concise snapshot!  In addition, if my network were compromised I would want a snapshot of open ports within a few minutes to determine potentially compromised servers.
  4. Next hurdle, netstat cannot be run remotely!  Time for another coffee.
    There are a couple of options for remotely running applications on servers; copy a batch file or script locally to the server and set it to run via the ‘at’ command, or use some sort of remote control software such as the resource kit utility ‘rclient
    (8).
  5. Running 150 separate schedules is not only an administrative nightmare that is prone to break in no time flat, but also makes our emergency snapshot difficult.
  6. Rclient it is!  Now is the time to work some scripting magic!!
  7. Rather than list the names of all 150 servers, I would use a centralised script to list all available servers on the network.  This saves me from having to constantly update the script as new servers are added to and old servers are removed from the domain.  It also eliminates the human error factor of writing out 150 hard coded server names.
  8. Next I would need to find a way to run netstat on each server.  To start, I would need to install the remote DOS client on each server that the script comes across.  You might say that we have just created a worm…and you would be correct!!  This technology is not limited just to the forces of evil!  There are a couple of things that you need to remember if you are going to go down this route; ask permission from a senior manager who understands the benefits and implications, make sure that you have locked down the security for Rclient, test every possible scenario, have an automated problem alerter built in, make sure the script fails to a known state, have an ‘off’ button in case of emergency, and have a back-out/repair utility at the ready.  If this path makes you a bit squeamish, you could always associate an installer with a logon user to use on each server…better ask for your two assistants now…
  9. As part of my automated installer I would need to check whether the server already had Rclient installed.
  10. If not, my script would automatically run Rsetup on the server for the remote client installation.
  11. Create a share on the new server and set secured permissions on the directory.
  12. Set auditing on the log directory to help keep track of intentional and unintentional changes.
  13. Copy down a wrapper for netstat that would archive the netstat results within the newly shared directory.
  14. Now that Rclient is installed on the server, I would call the Netstat wrapper using Rclient batch mode.  This would run the netstat command on the remote server, and log the results to a dated text file.  This would be the baseline for the new server.
  15. Replenish the coffee in-take.
  16. If the Rclient was already installed when the utility attached to the server I would run the batched Rclient and then the NT utility ‘fc(9) from the central console to compare today’s port scan with the baseline.  The baseline would be the earliest dated file in the directory.  Using this method would enable the baseline to change as new software or services were added to each server.  Simply archiving logs prior to the change date would reset the baseline automatically.
  17. Append the results of the ‘fc’ to a central secure log file.
  18. Append failed attempts by the utility to the log file for further investigation.
  19. When all servers have been queried, trawl the log file with the script to find interesting events.
  20. Collate the interesting events (changed ports, unreachable servers) and email the results to your account for you to check through when you arrive in the morning.
  21. Set the script to run each morning from a designated server using the ‘at’ command.

 

As you can see, with a bit of imagination and research, it is fairly straightforward to create a very powerful tool to make your life easier!

 

The following script is a practical example of wrapping the ‘netsh(9) utility.

I wrote the application as a quick way to query a domain user’s location (via subnet) and IP address…kind of a username ping.  The script assumes that you have the ‘netsh’ command in the system path, that you are using WINS for name resolution, and that the user is not logged onto more than one machine!

Of course if you wanted to improve on the script design, you could always include a wrapped ‘nbtstatA xxx.xxx.xxx.xxx’ command to verify the IP address to username resolution!!

 

Commands used;

AskItemList – Return a list tab delimited list that the user can choose from.

dirmake – Create a new directory.

RegOpenKey – You need to open a registry key before you can read its contents.

Strindexnc – Search a string for a wild card string, ignoring case

Filedelete – Self explanatory!  Command can contain wild cards.

 

; Query WINS database to find the current IP address of a user

; Author - Terry Chapman

; Date - 31/7/2001

 

AddExtender("WWWNT32I.DLL") ; Dll for networking operations

dc=wntGetDc( "", "YourDomainName", 1) ;Get the primary domain controller

temp = "c:\temp"

users = wntUserList(dc,2)

get = AskItemList("Select user to find IP for.", users,@TAB,@SORTED,@SINGLE) ; Generate a selectable list of user names

 

if ! direxist (temp) then dirmake (temp)

newtxt = strcat (temp, "\ip", get, ".txt")

param = strcat ("/c netsh wins server xxx.xxx.xxx.xxx show name name=", get, " endchar=3 >", newtxt)

runhidewait ("cmd.exe", param) ; Run the netsh command and write it to a temporary text file

 

handle = FileOpen(newtxt, "READ") ; Read the text file created by netsh

while @TRUE ; While there are still lines to read!

        x = FileRead(handle)

        If x == "*EOF*" Then Break ; If the at the end of the file, exit

        look = strindexnc(x, "IP Address", 1, @FWDSCAN) ; Scan each line for the ‘IP Address’ field

                                  not = strindexnc (x, "The name does not exist", 1, @Fwdscan) ; Look for no WINS entry

                                  if look == 1 then message (get, x) ; Once the IP address field is found, display a message

                                  if