Professional Documents
Culture Documents
AD e WMI Reporting
AD e WMI Reporting
AD e WMI Reporting
95
A Penton Publication
May 2003
tation (WMI) data, several tools are at your disposal. The Csvde command-line utility
(csvde.exe) and the Scriptomatic tool (scriptomatic.exe) are both extremely useful in this
respect. To get the most out of this data, you can use Microsoft Excel to format the out-
put into clean and easy-to-read reports. Here are some scripts to show you how.
Remote PCs
How can you modify the provided script as an array and cycle through Csvde and a modification to the Scrip-
script to return information about one each one in turn. However, if you want tomatic-generated WMI Win32_Oper-
or more remote PCs? The answer lies to check more PCssay, all the PCs in atingSystem script. The script that
in the scripts strComputer line, which a specific OUyou need a way to Listing 3, page 5, shows uses Csvde to
specifies the target computer. By retrieve all those long DNS names extract the list of client PCs to a .csv
default, Scriptomatic sets this line of from AD. That requirement takes us file, opens that file in Excel (placing
code (at callout A in Listing 2) to ".", back to Csvde, which you can use to the information about each PC in a
indicating the current PC. To check a export the names of all the PCs in a new row), and reads the file line by
remote PC instead, change "." to the certain group, a certain OU, or the line. The script then uses WMI to try to
full DNS name of the remote PC entire network. connect to each PC and read the OS
"anotherpc.emea.mycorp.com", for Suppose that you want to find all data. The script writes the results to a
example. What about checking multi- the PCs listed in AD, then pull out the second Excel spreadsheet, indicating
ple PCs? If you want to check only a OS Caption and Version information for each PC whether the script could
dozen PCs, you can add them to the from each one. You can do so by using connect to the PC and providing the
www.winscriptingsolutions.com
AD and WMI Reporting
OS data for those PCs to which it to search for computers and the prop- extra header row identifying each
could connect. erty to be returned (-l) to the PCs long returned item. We dont need this infor-
The script begins by declaring the DNS names. mation in our report, so the script
necessary constants and variables. After the script populates the .csv deletes the first column and first row.
Youll need to change the specified file, it creates an Excel Application Now the .xls file contains the data
PATH, CSV, XLS, and AD_ROOT vari- object, opens the .csv file, and saves the we need in one worksheet named
able values to ones that are appropri- file as an .xls file, closing the original Machines (or whatever you called your
ate for your environment. .csv file in the process. The script then .csv fileExcel opens the .csv file into
The script then uses the WSH Shell:: uses the standard FileSystemObject:: one worksheet and gives that work-
Run method to run Csvde, ensuring DeleteFile call to delete the .csv file sheet whatever name you gave the .csv
that the Run window remains hidden and the csv.log file. file). Because only one worksheet
and that the scripts execution pauses The .xls file has one sheet containing exists, the script can rename the sheet
until Csvde has finished running. The the PC data. This data includes an extra (with a more descriptive name such as
script uses the Csvde string that I first column containing each returned OS Details for All PCs, for example)
described earlier but sets the filter (-r) items distinguished name (DN) and an simply by selecting all worksheets and
www.winscriptingsolutions.com
AD and WMI Reporting
Q: I recently downloaded Microsofts Management Instrumentation (WMI) script to another scripting language is
Scriptomatic utility from http://www scripts, so its ideal for WMI scripting simple. After you know how to port
.microsoft.com/technet/treeview/default newbies like me. However, the utility gen- one Scriptomatic script, you can eas-
.asp?url=/technet/scriptcenter/wmimatic erates scripts in VBScript only. How can ily port any Scriptomatic script be-
.asp. Scriptomatic generates Windows I port a Scriptomatic-generated script to cause the scripts all follow the same
Perl? basic template.
AT A GLANCE For example, Listing 1 shows the
A: Scriptomatic has no built-in capa- VBScript code that Scriptomatic gen-
Porting Scriptomatic scripts to Perl . . . . . . . . . . . . . . 6 bility for porting its VBScript code to erates when you select the Win32_
Accessing a Win98SE computer remotely . . . . . . . . . 7 Perl. However, with a bit of Perl and Environment class, which lets you
Searching for users in an NT 4.0 domain . . . . . . . . . . 8 VBScript knowledge, you can port the manage environment variables on any
code yourself. Porting a Scriptomatic WMI-enabled computer. I selected
www.winscriptingsolutions.com
Rem
time to run because our domain contains
LISTING 3: Code That Inefficiently Searches an thousands of user accounts. Can you
NT 4.0 Domain offer any suggestions to improve the
scripts performance?
Option Explicit
WScript.Echo Time
Dim blnFound, objDomain, objUser, strDomainName, strUserName A: To improve the scripts perfor-
blnFound = False mance, you can bind directly to the user
strDomainName = acme object in question instead of enumerat-
strUserName = johndoe
ing all users. When the user exists, the
Set objDomain = GetObject(WinNT:// & strDomainName) GetObject function succeeds. When the
objDomain.Filter = Array(User) user doesnt exist, GetObject fails. This
For Each objUser In objDomain approach will not only significantly
If LCase(objUser.Name) = LCase(strUserName) Then
improve your scripts performance but
blnFound = True
Exit For also reduce the scripts impact on your
End If network and domain controller (DC).
Next The script in Listing 4 demonstrates
how to use the bind operation to
WScript.Echo strUserName & : & blnFound
WScript.Echo Time determine whether a user exists. The
code at callout A in Listing 4 is key. This
code begins by enabling the On Error
7. Restart the Win98SE computer. (ADSI) WinNT provider doesnt have a statement, VBScripts error-handling
38406 search mechanism like the ADSI Light- mechanism. Next, the script tries to
8 weight Directory Access Protocol (LDAP) bind directly to the user object in the
Q: I need to search for users in our provider does, Im using a script similar NT 4.0 domain. This code works
Windows NT 4.0 domain. Because the to the one in Listing 3 to perform the equally well with Active Directory (AD)
Active Directory Service Interfaces search operation. This script takes a long in Windows 2000 and local SAM data-
bases in NT 4.0 member servers and
workstations. Following the GetObject
LISTING 4: Code to Efficiently Search an call, the script checks the VBScript Err
NT 4.0 Domain object to determine whether GetOb-
ject succeeded.
Option Explicit
When the Err objects Number
WScript.Echo Time
Dim blnFound, objUser, strDomainName, strUserName property is 0 (i.e., no error), GetObject
succeeded, so the script sets blnFound
Const USERNAME_NOT_FOUND = &h800708AD to True. When the Err objects Number
blnFound = False
property is equal to the Win32 error
To run this script, change the strDomainName variables code assigned to the USERNAME_
value to your domains name and change the strUserName NOT_FOUND constant, GetObject
variables value to the name of the user account to search for. failed, so the script sets blnFound to
strDomainName = acme
strUserName = johndoe False. When the Err objects Number
property is something other than 0
A On Error Resume Next or the USERNAME_NOT_FOUND
Set objUser = GetObject(WinNT:// & strDomainName _
constants value, some other error
& / & strUserName & ,User)
If Err.Number = 0 Then occurred. The script echoes that value
blnFound = True to the console and immediately exits.
ElseIf Err.Number = USERNAME_NOT_FOUND Then 38407
blnFound = False
Else Bob Wells (bobwells@winnetmag.com) is a
WScript.Echo CStr(Hex(Err.Number)) & : & Err.Description
contributing editor for Windows & .NET
WScript.Quit
Magazine. He is a programming writer at
End If
Microsoft, where he is contributing to a
WScript.Echo strUserName & : & blnFound new System Administration Scripting
WScript.Echo Time Guide that Microsoft will include in its
next Windows Server resource kit.
Most programs require that a user log every minute to determine whether the the state of a service. Such requests can
on to the system to run them. How- server is online. This script is a perfect come from not only local or remote
ever, long ago before Windows ever candidate for a Win32 service because it users but also local or remote applica-
appeared, UNIX developers realized needs to run as soon as the OS is loaded tions and system components. Thus, the
the importance of having some pro- and must continue running regardless Perl script continuously monitors the
grams run from the time that a com- of which users log on and log off. SCM for state changes and reacts
puter booted until the computer was Win32 services are truly great tools. accordingly. For example, when the
shut down because the programs pro- However, when you use C or Visual state changes to SERVICE_PAUSE_
vided important services that had to Basic (VB) to develop them, the task is PENDING, the script reacts by perform-
run, even when nobody was logged fairly daunting because you have to ing whatever actions are required to
on. Hence, the daemon was born. A manage multiple threads interacting at make the script pause. The script must
daemon is software thats designed to different times. This task leaves you then inform the SCM that it has entered
run at boot time and keep running, with little time to benefit from the ser- the SERVICE_PAUSED state. The script
without user intervention. The OS vices. However, you can use a Perl reacts similarly to the SERVICE_START_
launches the program because a user script to create Win32 services, which PENDING, SERVICE_CONTINUE_
might not be available to do so. is far easier than using C or VB to cre- PENDING (essentially unpausing), and
Most of the common services asso- ate them. And modifying a service is as SERVICE_STOP_PENDING states and 9
ciated with the Internet are daemons, easy as modifying a Perl script. performs the necessary actions to enter
such as Web, FTP, email, firewall, the pending state.
streaming-media, and print services. How Win32 Perl Services One of the most important states is
These services start running when the Work SERVICE_RUNNING. When the SCM
computer starts and stop running Windows uses a specialized software reports this state, the script performs
when the computer shuts down. manager called the Service Control the actions for which it was designed.
Windows OSs based on the Win- Manager (SCM) to handle services. The For example, if the script was designed
dows NT kernel (e.g., Windows Server SCM manages the state of a service. to ping a server every minute, during
2003, Windows XP, Windows 2000, NT) When Windows boots up, the SCM the SERVICE_RUNNING state, the
refer to daemons as services. You can starts any service configured to start at script issues a ping every minute.
find your machines Win32 services and boot time. When a user wants to start,
their states (e.g., running, stopped) in pause, or stop a service, the SCM per- The Win32::Daemon Perl
the Control Panel Services applet, forms the action on the users behalf. Extension
which is in the Control Panels Admin- The SCM then interacts with the service A few tools are available to create a
istrative Tools folder. When you double- to inform it that its state must change. Win32 Perl service, such as the srvany
click the Services applet, the Microsoft When the SCM starts a service, the .exe freeware utility and ActiveStates
Management Console (MMC) Services SCM executes the services .exe file. For PerlSvc utility. However, srvany.exe has
snap-in appears. The Services snap-in Perl scripts, the SCM launches perl.exe limitations, and PerlSvc requires the
lists each services name and provides and passes to perl.exe the name of the purchase of ActiveStates Perl Dev Kit.
information about that service, such as Perl script and any parameters that the An alternative is the Win32::Daemon
its description and status. script needs. The Perl script then tells extension (http://www.roth.net/perl/
Win32 services are useful for many the SCM to treat it as a service. There- daemon) and the Win32::Daemon::
reasons. For example, Win32 services after, the script is officially considered Simple extension (http://jenda.krynicky
provide the means to run a program to be running as a service. In addition .cz), which depends on Win32::Dae-
when the OS starts. In addition, you to whatever tasks the script is pro- mon. These extensions provide full
can control a service from a remote grammed to do, the script has only one Win32 service functionality from a
machine. service-related task that it must per- simple Perl script.
You can make almost any applica- form: monitor the SCM for state You can install Win32::Daemon by
tion or tool a Win32 service. For exam- changes. running the Perl Package Manager
ple, consider a script that pings a server The SCM receives requests to change (PPM) from a command line:
www.winscriptingsolutions.com
Win32 Perl Services
from running the registry editors block of code. The code first sets the
LISTING 1: Code That Lists (regedit.exe and regedt32.exe) and the default configuration settings, then calls
the Applications FTP client. You can also use the script to the Configure( ) subroutine to check for
terminate a process after the process user-specified parameters, some of
to Kill has run for a specific amount of time. which might override the default set-
%PROC_LIST = ( For example, I configured the script to tings. Depending on the configuration
telnet.exe => 120, terminate any Telnet session that runs options you specify when you launch
ftp.exe => 0,
longer than 2 minutes. This termination ProcMon.pl, the code either installs the
regedit.exe => 0,
regedt32.exe => 0 prevents users from staying logged on to script as a service, stops the script from
); a Telnet client for long periods of time. running as a service, or displays the
The scripts %PROC_LIST hash lists scripts syntax and exits. Figure 1 shows
the applications to kill and when to kill the configuration options that you can
PPM install http://www.roth.net/ them, as the code in Listing 1 shows. use when launching ProcMon.pl.
perl/packages/win32-daemon.ppd Each hash key lists the applications After setting the service configura-
filename (e.g., telnet.exe), which must tions, the script creates the log file. The
be in all lowercase letters. The value default logs filename is the name of the
Creating a Process- associated with each hash key speci- script with the .log extension. So, if you
Monitoring Service fies how many seconds the application leave the scripts name as ProcMon.pl,
In the Code Library on the Windows is allowed to run before being termi- the resulting default log file will be
Scripting Solutions Web site (http:// nated. Notice that all but one of the ProcMon.log. The log file will reside in
www.winscriptingsolutions.com), youll applications have a value of 0 seconds. the same directory as the script. The
find ProcMon.pl, a script that creates a This value causes the script to termi- code at callout A in Listing 2 configures
10 process-monitoring service. You can nate those applications just after the this default location. However, you can
use this script to prevent specific pro- script notices theyre running. override the default by using the -l
cesses from running. For example, I Next, the script sets the service parameter when you launch the script.
configured the script to prevent users configurations. Listing 2 shows this
Starting the Service and
Processing Service States
LISTING 2: Code That Configures the Service Now that the script has made the nec-
%Config = ( essary preparations to run as a service,
machine => Win32::NodeName(), the script starts the service by calling the
A logfile => ( Win32::GetFullPathName( $0 ) =~
Win32::Daemon::StartService() function,
/^(.*)\.[^.]*$/ )[0] . .log,
service_alias => ProcMon, as Listing 3 shows. If the call is success-
service_name => Perl Process Monitor, ful, the SCM starts interacting with the
# Specify how long (in milliseconds) to sleep Perl script as if the script were a built-in
# after polling the service state.
Win32 service. If the call fails, the script
service_sleep_time => 100,
# Specify how often (in seconds) to query the list of logs an error message and exits.
# processes to determine whether theres a process to kill. After the service starts, the script
update_proc_list_time => 5 continuously checks the SCM for mes-
);
sages. The script uses a long loop that
Configure( \%Config, @ARGV );
if( $Config{install} ) continuously calls the Win32::Dae-
{ mon::State() method to check for any
InstallService(); state change. In this loop, which List-
exit;
}
ing 4, page 12, shows, the script has a
elsif( $Config{remove} ) block of code for each possible state
{ that can occur. The code executes an
RemoveService(); appropriate action for that state. For
exit;
} example, the block of code for the
elsif( $Config{help} ) SERVICE_PAUSE_PENDING state
{ doesnt do anything other than log an
Syntax();
indicator that specifies that the script is
exit;
} entering the paused state. Each block
of code calls the Win32::Daemon::
www.winscriptingsolutions.com
Win32 Perl Services
need to run constantly anyway. By
LISTING 4: Code That Checks the SCM default, the script falls asleep for
100ms before starting over.
while( SERVICE_STOPPED !=
( my $State = Win32::Daemon::State() ) )
{ Customizing ProcMon.pl
if( SERVICE_START_PENDING == $State ) Now that you understand how a Win32
{
Perl Service works, you can customize
Log( Linking to WMI... );
if( $WMIServices = Win32::OLE-> ProcMon.pl to monitor the processes
A
GetObject( winmgmts://$Config{machine}/root/cimv2 ) ) that you want to limit. Simply modify
{ the %PROC_LIST hash in Listing 1 to
Log( ...successful. );
include those processes. Then, to install
Win32::Daemon::State( $PrevState = SERVICE_RUNNING );
Log( $Config{service_name} service has started. ); the script as a service, use the following
} command to launch ProcMon.pl:
else
{
Perl ProcMon.pl -install
Log( ...failure. );
Win32::Daemon::State($PrevState = SERVICE_STOPPED );
Log( $Config{service_name} service could not get a process To start the service, run the command
list object: Aborting. );
Log( Error: . Win32::OLE->LastError() );
} net start ProcMon
}
elsif( SERVICE_PAUSE_PENDING == $State ) To test the service, run a program thats
{
in your %PROC_LIST hash. You can
# Pausing
12 then check the log file for details about
Win32::Daemon::State($PrevState = SERVICE_PAUSED );
Log( $Config{service_name} service has paused. ); what the service has done.
next;
}
elsif( SERVICE_CONTINUE_PENDING == $State )
Debugging the Service
{ If all goes well, your Win32 Perl service
# Resuming will run smoothly. However, problems
Win32::Daemon::State($PrevState = SERVICE_RUNNING ); can arise, and you might need to de-
Log( $Config{service_name} service has resumed. );
bug the service.
next;
} Win32 services have limitations that
elsif( SERVICE_STOP_PENDING == $State ) can be difficult to work around. The
{ biggest limitation is that a service runs
# Stopping
Win32::Daemon::State($PrevState = SERVICE_STOPPED );
headless, which means it doesnt have
Log( $Config{service_name} service is stopping. ); a UI. Thus, Win32 services are difficult
next; to debug because they dont have any
} windows that display information, so
elsif( SERVICE_RUNNING == $State )
{ you cant directly interact with the ser-
B my $Now = time(); vices. This limitation can be especially
if( $Now - $LastRunTime >= $Config{update_proc_list_time} ) frustrating for Perl scriptwriters because
{
they typically use an interactive debug-
$LastRunTime = $Now;
my $ProcList = ger to debug their scripts.
$WMIServices->InstancesOf( Win32_Process ); The most practical way to debug a
foreach my $Process ( in( $ProcList ) ) Win32 Perl service is to have it write
{
debug messages to a log file. You can
my $ProcName = $Process->{Name};
if( defined $PROC_LIST{lc $ProcName} ) then examine the log file to see the data
{ that your script printed out. However,
my( @List ) = ( $Process->{CreationDate} =~ this type of debugging is slow and
/(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/ );
# Index 0 = full year, 1 = month, 2 = day,
cumbersome because you have to walk
# 3 = hour, 4 = minute, 5 = second. Month through a potentially long log file just
# must be changed to be 0 indexed. to see the results of debug messages. A
$List[1] ; better alternative is to run SysLogD.pl,
Continued on page 13
which you can find in the Code
www.winscriptingsolutions.com
Group Membership Tracking
shipTracker.bat running in your envi-
LISTING 1: Main Code to Configure ronment, perform the following set of
steps:
:: Replace London with your domains name.
Set Domain=London 1. Copy the script into a dedicated
folder on the server or workstation on
:: Replace FredSmith@yourcompany.com with the email addresses which you plan to schedule the script
:: of the recipients you want to receive the email message.
to run.
Set Recipients=FredSmith@yourcompany.com
2. Determine the local and global
:: Replace CindyWong@yourcompany.com with the email address groups that you need to monitor. Cre-
:: of the person sending the email message. ate localgroups.txt and globalgroups
Set From=CindyWong@yourcompany.com
.txt input lists, and place these files in
:: Replace mailserver.yourcompany.com with your SMTP servers name. the folder that holds GroupMember-
Set Mailserver=mailserver.yourcompany.com shipTracker.bat. If you have all local and
no global groups, or vice versa, you
on your servers. That script gives you This script assumes youre moni- dont need to create an empty input file.
a good snapshot of group member- toring key administration groups as If the script cant find an input file, it
ships for your quarterly audits, but its opposed to large groups with hundreds simply moves on to the other input file.
not much help when you want to track of members. The script can perform the 3. Configure GroupMembership-
day-to-day additions to and deletions latter task but can take a while to com- Tracker.bat for your environment. List-
from group memberships. Discovering plete. Most domains or OUs contain 6 ing 1 shows the code that you must
a user account with authority thats too to 10 key groups, such as Domain change. First, configure the domain in
generous is important at audit time, Admins, OU Admins, GPO Admins, which your local and global groups
14 but discovering potential problems Local PC Admins, and other adminis- exist. If you want to track groups in
sooner is better. trative groups that have sweeping more than one domain, you need to
domain powers and whose member- either run additional instances of the
Comparing Lists ship deserves constant attention. script or modify the code to handle
The GroupMembershipTracker.bat additional domains. Next, at the top of
script, which you can find in the Code Using Blat the script, configure the To and From
Library on the Windows Scripting Solu- Blat is a freeware utility that lets you email addresses that Blat will use for the
tionsWeb site (http://www.winscripting send email messages from a com- email notifications. For the email noti-
solutions.com), uses the Local and mand-shell script. In the case of fications To address, you can specify
Global utilities from the Microsoft GroupMembershipTracker.bat, Blat multiple recipients by separating the
Windows 2000 Server Resource Kit or lets you send notification messages addresses from one another with a
the Microsoft Windows NT Server 4.0 when any new group is added to the comma but no space. Finally, configure
Resource Kit to periodically list a local or global group tracking lists. You the SMTP server name that Blat will use
groups members. The script then can download Blat from http://www to send the email notification.
compares that list with the previous .interlog.com/~tcharron/blat.html. 4. Verify that the scripts utilities (i.e.,
list. For more information about Blat, see now.exe, local.exe, global.exe, and
The code that performs the line-by- Real-World Scripting: Using Blat to blat.exe) reside in the folder from
line comparison uses the Findstr com- Send Email Notification Messages, which the script will run. As Listing 2
mand to determine whether the new November 2000, http://www.win shows, the script sets the folder loca-
file contains every line entry from the scriptingsolutions.com, InstantDoc ID tion to the %~dp1 variable. The per-
old file and whether the old file con- 15848. The GroupMembershipTracker cent sign (%) specifies a replaceable
tains every line entry from the new file. .bat code shows Blat syntax for SMTP parameter. The ~dp1 portion tells the
If something doesnt match, someone servers that dont require authentica- scripting engine to capture the drive
has added or deleted a member and a tion. Review the Blat documentation letter (d) and the path (p). If your script
notification event occurs. In addition for information about the -u and -pw path is C:\AdminScripts\GroupMem-
to sending notification messages, authentication switches. bershipTracker.bat, the %~dp1 vari-
GroupMembershipTracker .bat creates able contains the C:\AdminScripts
a running timestamped log, in case Putting It Together folder location information. Thus, if
you need to review the entire history of GroupMembershipTracker.bat is com- your utilities arent in the same loca-
changes. If no changes exist, no notifi- patible with Windows XP, Win2K, and tion as the script or you want to locate
cation event is necessary. NT 4.0 systems. To get GroupMember- input and output files elsewhere, you
Reader to Reader
Win2K and NT Which Command
[Editors Note: Share your scripting dis- Ive found the Which command so script uses only batch tools and relies
coveries, comments, problems, solu- useful in UNIX that I decided to dupli- on the native Win2K and NT tool find-
tions, and experiences with products. cate its behavior in Win2K and NT. I str.exe. The VBScript file requires Win-
Email your contributions (500 words or wrote a command-shell script, which dows Script Host (WSH). You can use
less) to r2rwinscriptsol@winnetmag Web Listing 1 (http://www.winscripting Win2Ks default version of WSH; for
.com. We edit submissions for style, solutions.com, InstantDoc ID 38399) NT, you must manually install a version
grammar, and length. If we print your shows, and a VBScript file, which Web of WSH. Both of my scripts validate
submission, youll get $100.] Listing 2 shows. The command-shell command-line syntax and search for
The UNIX Which command lets you Windows Scripting Solutions (ISSN 1537-4483; USPS 017-852) is published monthly by Penton Technology Media, Inc.,
find in the current users path a speci- 221 E. 29th St., Loveland, CO 80538
fied executable. By default, Which lists Vol. 5, No. 5 2003 by Penton Media, Inc. ALL RIGHTS RESERVED.
Subscriptions in US $129.00 for one year; add $7.00 for all countries outside the US.
only the first instance of the specified
Windows Scripting Solutions is an independent publication not affiliated with Microsoft Corporation. Microsoft Cor-
file in the path. If you use the -a option, poration is not responsible in any way for the editorial policy or other contents of the publication.
Which lists all locations of the file in Windows Scripting Solutions, 221 E. 29th St., Loveland, CO 80538, 800-621-1544 or 970-663-4700.
any directory in the path. In UNIX, the Sales and Marketing Offices: 221 E. 29th St., Loveland, CO 80538
Periodicals Postage Paid at Loveland, CO and additional mailing offices.
current directory isnt in the path by
POSTMASTER: Send address changes to Windows Scripting Solutions, P.O. Box 447, Loveland, CO 80539-0447
default. In Windows 2000 and Windows
SUBSCRIBERS: Send all inquiries, payments, and address changes to Windows Scripting Solutions, Circulation Depart-
NT, the current directory is in the path ment, P.O. Box 447, Loveland, CO 80539-0447, 970-203-2782 or 800-793-5697, scripting@winnetmag.com.
but only implicitly.
www.winscriptingsolutions.com
Publisher
EDITORIAL
Kim Paulsen
Reader to Reader
kpaulsen@winnetmag.com
Editor-in-Chief Janet Robbins
janet@winnetmag.com
Technical Editors Alistair G. Lowe-Norris any file that the OS deems executable. Both overran the command-line character limit.
alistair@winnetmag.com
Dino Esposito scripts also explicitly include the current The VBScript file is simpler than the com-
dino@winnetmag.com
Bob Wells
directory. mand-shell script. I use the VBScript file
bobwells@winnetmag.com The command-shell script contains some solely from the command line, so Ive written
Dick Lewis
dlewis@winnetmag.com unusual logic to delimit certain strings cor- a small batch wrapper for the file, which Web
Editor Michelle Crockett rectly. This script also breaks some For loops, Listing 3 shows. You must write the full path
crockett@winnetmag.com jumping in and out of them based on certain to which.vbs into the wrapper batch file.
Group Managing Editor Dianne Russell conditions. I repeated one line, which tests for 38399
drussell@winnetmag.com
Editorial Content Manager Amy Eisenberg
the existence of the command issued as the Glen Campbell
amy@winnetmag.com argument, because the elements I needed to gcampbel@dante.com
Editors Karen Bemowski
execute based on the commands success
Jason Bovberg
Rob Carson
Juliann Feuerbacher
Barb Gibbens
Renee Munshi
Lisa Pere
Warren Pickett
Gayle Rodcay
www.winscriptingsolutions.com