Adding third-party components to your scripting efforts will get the job done faster and easier.
Supercharge Your Scripts
Adding third-party components to your scripting efforts will get the job done faster and easier.
- By Chris Brooke
- 10/01/1999
Once, a long, long time ago, a prehistoric man named
Grog invented a device that he called “Unnngg!” which
means “wheel.” This was quite an exciting piece of workmanship,
allowing many things to be accomplished faster and easier
than ever before. Shortly after Grog invented the wheel,
his friend Trog hit him over the head with a club and
stole it from him. Even way back then our prehistoric
entrepreneur could see that reinventing the wheel was
a costly and time-consuming process he would just as soon
avoid.
Today, while our methods may be somewhat more civilized,
efforts to avoid “reinventing the wheel” in our development
and administrative capacities are ongoing. Time, after
all, is money, and if we can take advantage of something
someone else has created to get the job done faster and
easier… well, that’s pretty much a no-brainer. One way
to accomplish this is through the use of components in
our scripts.
Compelling Reasons for Components
A component is essentially a self-contained piece of
code designed to accomplish a specific task. Application
developers have been using them for years for everything
from drawing a graph on the screen to performing complex
financial calculations. New features in the Windows Script
Host (WSH) have now opened up many avenues for leveraging
them in the administration of your Windows NT enterprise,
as well. Some of these components come as part of Windows.
(See Jeff Honeyman’s article, “WSHful
Thinking” in the August issue, in which he talks about
the Wscript object and the file system object.). Other
components are created by third-party vendors.
Since we’re talking about NT administration here, the
components we’ll look at are based on the Microsoft Component
Object Model (COM). Without wandering too far into developer-speak,
let me just say that COM is the mechanism that allows
your script and the components to talk to each other.
Theoretically, as long as the component is COM-based,
WSH can use it. (However, since everything works “in theory,”
I’ve included a sidebar for a dash of reality!)
We’ve already established that using components can help
you build scripts faster. Not only is the amount of scripting
reduced, but you can use a component to accomplish a task
that you’d have no idea how to complete otherwise. But
did you know that in many cases components can provide
functionality that’s simply not provided within the WSH?
VBScript and JScript are great, but let’s face it: They’re
subsets of larger programming languages. In some cases,
there are things they just can’t do. A component, however,
may be written in C++, Visual Basic, or whatever, and
brings with it the additional power of the language in
which it was written. In addition to that power, most
third-party components are written with a specific solution
in mind. This usually allows you to accomplish a given
task with fewer lines of code than would be necessary
if you used equivalent Windows components. Usually.
The Nitty Gritty
Let’s look at some ways we can use components inside
our scripts to beef them up. For my examples I’ve decided
on EDS’ Simple Encryption and SoftArtisans’ SA-Admin suite.
Both of these products can provide functionality that
NT administrators should find quite valuable. Don’t forget,
though… the third-party market for components is huge!
The small sampling we’re looking at today is just a taste.
While most software components are tailored for code monkeys,
many can be very useful to the average server jockey.
EDS Simple Encryption/Decryption
This component provides simple encryption services. It
can encrypt a string of text or a file based upon a key
that you provide. The key is used by the 32-bit algorithm
to encrypt the data and can be no more than 16 bytes long.
Let me clarify that. You can pass it a key that is longer,
but it ignores everything past the 16th character. To
decrypt the data, you (of course) must provide the same
key.
EDS Simple Encryption has four methods (A.K.A. “things
that it does”):
EncryptData
DecryptData
EncryptFile
DecryptFile
The first thing you have to do is instantiate the component
(create it):
MyEncrypt=CreateObject(“EDS.Encryption”)
Then you set the encryption key:
MyEncrypt.EncryptionKey=”EncryptMe!”
Last but not least, you invoke the method that you want—in
this case, EncryptFile. To encrypt a file, you have to
give it the name of the source file, the destination file,
and the block size. Block size tells the encryption component
how much of the file to encrypt at a time. This is important
to remember because it has to be set to the same value
when you decrypt the file. [Note: Some of the following
lines of code are broken in order to fit them in the column
width.—Ed.]
Success=MyEncrypt.EncryptFile("c:\mcpmag\
SalarySurvey.xls”,“c:\mcpmag\SalarySurvey.enc”, 5)
If everything goes as planned, the EncryptFile method
will return a Boolean True. This is something you’ll want
to verify, especially if you plan to delete the source
file after it’s encrypted. Probably the easiest way to
check this is to use a message box:
Msgbox Success
Of course, you wouldn’t want to hard-code the encryption
key into your script. Yeah, you can encrypt them using
the Windows Script Encoder (Screnc.exe), but it’s still
not good security. And you know how I am about security!
Furthermore, there’s not much joy in hard-coding the filenames,
either. You’ll end up spending hours editing your script.
Since the idea is to save time, let’s not do that. I’ve
got a better idea!
The WSH allows you to pass arguments to your scripts.
Since this is going to be your script, we’ll assume you
know which arguments are needed (and in what order), but
we’ll throw in some minor error handling, anyway. First,
we need to get the arguments:
Set Args=Wscript.Arguments
Just in case you didn’t provide any, let’s remind you
about what they need to be:
‘If user type a “?” or leaves the arguments
blank,
‘show the correct order
If (Args.Count=0) Then
Call HowTo()
Elseif (InStr(Args(0), “ ?”)) Then
Call HowTo()
End If
‘Place this at the end of the script
Sub HowTo()
Wscript.echo “Arguments needed: Sourcefile
DestinationFile BlockSize EncryptionKey”
Wscript.Quit
End Sub
Next, you can get the arguments and assign them to variable
names inside the script:
SourceFile=Args.Item(0)
DestFile=Args.Item(1)
BlockSize=Args.Item(2)
Key=Args.Item(3)
Now you only have to change two lines in your script
to use variables instead of static values:
MyEncrypt.EncryptionKey=Key
Success=MyEncrypt.EncryptFile(SourceFile,
DestFile, BlockSize)
When it comes time to decrypt your files, the script
remains the same save one change:
Success=MyEncrypt.DecryptFile(SourceFile,
DestFile, BlockSize)
A word of warning about “Success.” When Success=True,
it means that the encryption/decryption process completed
successfully. It doesn’t necessarily mean that your file
is readable. If you use a different EncryptionKey or BlockSize
during decryption, you’ll still get a message box of “True”,
but your file will be gibberish. “True” just means that
the algorithm was successfully applied to the data. Listing
1 shows the completed script.
Listing
1. Our encryption script component in
its entirety. |
' *********
EncryptEm.vbs **********
'Set up the variables
I need
Option Explicit 'Require all variables
to be declared
dim MyEncrypt, SourceFile, DestFile,
Success,
BlockSize, Key, args
'Set Encryption
properties from the
'command line arguments
Set args=WScript.Arguments
'If user type
a "?" or leaves the arguments
blank,
'show the correct order
If (Args.Count=0) Then
Call HowTo()
Elseif (InStr(Args(0), “?”)) Then
Call HowTo()
End If
SourceFile=args.Item(0)
DestFile=args.Item(1)
BlockSize=args.item(2)
Key=args.Item(3)
'Create the Encryption
object
Set MyEncrypt=CreateObject("EDS.Encryption")
MyEncrypt.EncryptionKey=key
Success=MyEncrypt.EncryptFile(SourceFile,Dest
File,BlockSize)
'EDS.Encryption
returns a true if
'encryption succeeded
msgbox success
'Clean up after
yourself
set MyEncrypt=nothing
WScript.Quit
'Show correct
usage
Sub HowTo()
Wscript.echo "Arguments needed:
Sourcefile DestinationFile BlockSize
EncryptionKey"
Wscript.Quit
End Sub
|
|
|
Naturally, there are still some things we could do to
spiff up this baby. For instance, you could use the Windows
Scripting Component (also called the Microsoft Scripting
Runtime and named SCRRUN.DLL in the SYSTEM32 directory)
to access folder and file information so that you can
pass a folder name as an argument, and the script can
then be coded to encrypt every file in the folder and
delete the originals. You might also set parameters so
that only files of a specific type are encrypted. Experiment.
Have fun! (Just don’t practice in the System32 directory!)
SA-Admin
SoftArtisan’s SA-Admin is a suite of NT components for
performing user, group, RAS, performance, and share management
from within your scripts. These components were initially
written to provide functionality to an Active Server Page.
As such, some of the functionality—while possible in the
WSH—is a bit redundant, since you can just use the appropriate
NT tool. An example of this would be Performance. You
could use this component on an ASP page to check server
performance from the beach in the Cayman Islands, but
since viewing the information from the WSH means you have
to be at your workstation anyway, you might as well just
use PerfMon.
On the other hand, providing the ability to query, add,
and change User, Group, and RAS settings with the WSH
is invaluable to the NT administrator. For our examples,
we’re going to look at adding a user and a group and adding
a user to a group.
One last thing before we get to the scripts I’ve created:
Make sure you don’t try to install SA-Admin or run the
scripts from Win9x. They’re only compatible with NT 4.0.
NewUser
All that’s needed to create a new user is a username,
password, and comments (optional). You can configure which
server the user is being added to, or have it set to the
PDC (for adding users to a domain). Once the user is added,
you can set all those little account properties like Account
Disabled, Home Directory, and whether or not they can
change their password (you know the drill). We’re going
to start by selecting the PDC and getting our new user
information from the command-line arguments. (Note that
the actual component we’ve called on is prefaced in the
code with “SoftArtisans” as in SoftArtisans.User.)
'******* NewUser.vbs *******
Dim ntu, uName, uPass, uComment,
Args
Set Args=WScript.Arguments
If (Args.Count=0) Then
Call HowTo()
Elseif (InStr(Args(0),"?")) Then
Call HowTo()
End If
uName=Args.Item(0)
uPass=Args.Item(1)
uComment=Args.Item(2)
Set ntu=CreateObject("SoftArtisans.User")
ntu.GetDomainController “MyDomain”, true
'specify the server first
ntu.AddUser uName, uPass, uComment
ntu.User=uName
ntu.CantChangePassword=true
ntu.Disabled=true ‘and so on…
Set ntu=nothing
WScript.Quit
Sub HowTo()
Wscript.echo "Arguments needed:
Username Password Comment"
Wscript.quit
End Sub
WScript parses the command line arguments by looking
for spaces, so don’t use commas. If you want to pass a
string that includes spaces (which will be necessary unless
you like single-word comments), you must enclose it in
quotes:
Cscript newuser.vbs johndoe secret
"MCSE+Internet, MCSD, MCT, CCIE"
Now you need to make this guy a member of a group. Oops!
I just remembered that he’s the first person hired for
a new department. You need to create a new group for that
department first. For this you use the component SoftArtisans.Groups:
'******* NewGroup.vbs ***********
Dim ntg, gName, gComment, Args
Set Args=WScript.Arguments
If (Args.Count=0) Then
Call HowTo()
Elseif (InStr(Args(0),"?")) Then
Call HowTo()
End If
gName=Args.Item(0)
gComment=Args.Item(1)
Set ntg=CreateObject("SoftArtisans.Groups")
ntg.GetDomainController "MyDomain", true
ntg.Global=true
ntg.NewGroup gName, gComment
Set ntg=nothing
WScript.quit
Sub HowTo()
Wscript.Echo "Arguments: Groupname Comments"
Wscript.quit
End Sub
And finally, you can add the new user to the new group.
'********** GroupEm.vbs *************
Dim ntg, uName, gName, Args
'Copy everything from previous script
Set args...
.
.
Set ntg...
Ntg.AddUserToGroup uName, gName
For the sake of showing you each task separately, I wrote
three scripts. You could really save some redundant typing
if you did this from one script. Also, you may have noticed
that, as written, the script doesn’t really save a lot
of time. If you have to enter each name individually at
the command line, you might as well just use User Manager.
Well, just like with EDS Simple Encryption, a little bit
of work could really supercharge this script, too. Imagine
that your company has just hired a bunch of new people
and you need to set up their NT accounts and put them
in the correct groups. Chances are that your personnel
department already has (for its own use) a spreadsheet
with name, manager, etc. already typed up. You could export
this into a text file and have your script import everything
from it. Sure beats all that typing at the command line.
We’ve just scratched the surface of the SA-Admin Suite.
Just in the User and Group objects alone there are over
50 methods and properties, to say nothing of the Share,
RAS, and Performance components.
Encryption
Examples |
EDS Encryption
You may have noticed that the encryption
script in the article doesn't seem to
save a lot of time. Indeed, passing
the script an individual file name to
encrypt each time would get old quickly!
Since the idea of using components in
our scripts— or even scripting in general—
is to make our lives easier, we need
to come up with a better way.
You'll recall that I mentioned the
Windows Scripting component as one of
Microsoft's built-in components. We
can use it in conjunction with our third-party
components to create a fully functional,
time-saving script. The following script
uses the Scripting component— in particular
the FileSystemObject, Folder, and File
components— to give us access to file
and folder information. I've written
the script to encrypt all the files
in a given folder. The script creates
a new child folder in the source folder
to contain the encrypted files. I've
left it for you to decide if you want
to move the encrypted files back to
the original folder. (Hint: You'll probably
want to do this, because you'll be in
trouble if you don't. Read on.)
'Folders.vbs
'***** Encrypt all files in the specified
folder
'Let's start by getting the command-line
arguments
'We'll pass two arguments: The full
path to the folder
'and the encryption key.
Option Explicit
'Require variables to be declared
Dim objFSO, objFolder,
objFiles, objEncrypt,
objArgs, objEncFolder
Dim strKey, strPath, strFile, strDestPath
DIm bSuccess
Set objArgs=WScript.Arguments
'Check for "?"
or no arguments
If (objArgs.Count<2)>2)>
Call HowTo()
Elseif (InStr(objArgs(0), "?")) Then
Call HowTo()
End If
strPath=objArgs.Item(0)
strKey=objArgs.Item(1)
strDestPath=strPath & "\TempEnc"
'Create all the
necessary objects:
'Create the FileSystemObject,
giving me access
'to file and folder info
Set objFSO=CreateObject("Scripting.FileSystemObject")
'If the temporary
encryption directory is already there,
delete it
If objFSO.FolderExists(strDestPath)
Then objFSO.DeleteFolder strDestPath,
True
'Create the Folder
object for the specified path
Set objFolder=objFSO.GetFolder(strPath)
'Get only the
files from that folder
Set objFiles=objFolder.Files
Set objEncrypt=CreateObject("EDS.Encryption")
objEncrypt.EncryptionKey=strKey
'Go through each
file in the folder, encrypt it with
'a new name and into a new folder, and
delete the
'original
Set objEncFolder=objFSO.CreateFolder(strDestPath)
'Create a new
folder as a sub folder of this one
'and move all encrypted files into it
For each strFile in objFiles
bSuccess=objEncrypt.EncryptFile(strFile,
strDestPath & "\" & strFile.Name
&
".enc", 10)
strFile.Delete(True)
Next
'Tell the user
which arguments are needed
Sub HowTo()
WScript.Echo "Arguments needed: Path
Key"
WScript.Echo "Path must be full path."
WScript.Quit
End Sub
Disclaimer:
The purpose of this example is to show
you how we can use the Scripting component
to give us file and folder access. Even
with the enhanced functionality I've
included there is still more "spiffing-up"
that we could do. In fact, some of you
veteran scripting junkies might notice
that early on in the script I delete
the folder created to hold the encrypted
files. If I run this script more than
once (without relocating the previously
encrypted files), all of my encrypted
files from the last run will be deleted!
Ouch! You may also notice that I don't
take you through the decryption process,
either. Well…you didn't become an NT
god by having your hand held all the
time, did you? Use my examples (on test
folders) and get familiar with the Microsoft
Scripting component. It holds the key
to completing all the tasks I've left
for you. Happy scripting!
SAAdmin
For this example, we have made certain
assumptions:
- You have edited the copy of the
spreadsheet from personnel and exported
only the columns that we need, namely:
Username, First and Last name, group,
and comments, comma delimited, in
that order.
- We have established a default password
consisting of the first three letters
of the first name and the first three
letters of the last name.
- The user will be required to change
their password at first login.
This script also assumes that the target
groups already exist. Also, there is
no error trapping. If one of the users
that you are adding happens to already
exist in the system, the script will
stop and the rest of the users will
not be added.
'users.vbs
'Script to read user and group info
from a .txt file
'and add it to NT using SAAdmin
Option Explicit
Dim objText, objUser,
objGroup, objArgs, objFSO,
objFile
Dim strFile, strLine, strUName, strGroup,
strComment, strFullName, strPass, strArray(5)
Dim iHash, iCount
Set objArgs=WScript.Arguments
If (objArgs.Count=0) Then
Call HowTo()
Elseif (InStr(objArgs.Item(0), "?"))
Then
Call HowTo()
End If
strFile=objArgs.Item(0)
Set objFSO=CreateObject("Scripting.FileSystemObject")
Set objFile=objFSO.GetFile(strFile)
Set objText=objFile.OpenAsTextStream
Set objUser=CreateObject("SoftArtisans.User")
Set objGroup=CreateObject("SoftArtisans.Groups")
Do While objText.AtEndOfStream=False
strLine=objText.ReadLine
'Parse the string
For iCount=1 to 4
iHash=InStr(strLine, ",")
strArray(iCount)=Left(strLine, iHash-1)
strLine=Right(strLine, Len(strLine)-iHash)
Next
strUName=strArray(1)
strFullName=strArray(2) & " " &
strArray(3)
strGroup=strArray(4)
strComment=strLine
strPass=LCase(Left(strArray(2), 3) &
Left(strArray(3), 3))
objUser.GetDomainController
"MyDomain", True
objGroup.Server=objUser.Server
objUser.AddUser strUName, strPass, strComment
objUser.User=strUName
objUser.MustChangePW=True
objUser.FullName=strFullName
objGroup.AddUserToGroup strUName, strGroup
Loop
'Tell the user
which arguments are needed
Sub HowTo()
WScript.Echo "Arguments needed: Path"
WScript.Echo "Path must be full path."
WScript.Quit
End Sub
Since we're doing this to become familiar
with using these components, you might
want to practice on an NT Workstation
rather than your PDC. Simply change
the "objUser.GetDomainController"
line to "objUser.Server=\\MyServer
and it will work fine.
|
|
|
Face it: Components aren’t just for developers anymore.
If you find that your scripts need “more power,” you might
want to consider using components too. That’s new millenium-time
management in action.