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.

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)>
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.

comments powered by Disqus

Redmond Tech Watch

Sign up for our newsletter.

I agree to this site's Privacy Policy.