As I was going through my own personal script repository, I noticed that I had compiled quite a number of simple scripts and code snippets that I had either found or created to perform simple but often necessary scripting tasks. A good many of them are workarounds developed to add functionality that is otherwise unavailable in WSH or VBScript alone. I decided to package them up and offer them to my readers.
Contributed by Nilpo Rating: / 2 December 15, 2008
Some of these are simple and may not appear to have any immediate use. Others, however, you will find to be quite priceless. They are presented here in no particular order. If you don’t have a use for the code in particular, try to at least learn from them by seeing how their techniques were used to accomplish each task.
Forcing a specific scripting engine
As you well know, the Windows Script Host provides two different scripting engines: cscript.exe and wscript.exe. While most scripts can be run equally well in one or the other, there are often times when one or the other is preferred or even necessary. Since the default engine can be changed from system to system, it is nice to include some code in your script to force the use of a necessary engine for compatibility purposes.
If LCase(Right(WScript.FullName, 11)) <> "cscript.exe" Then
This simple If statement can be placed at the top of your script to force it to run using Cscript.exe. It uses the WScript object to determine the current scripting engine by examining the FullName property.
If the script is running in the correct engine, the If statements exits and script execution continues. Otherwise, it launches the script again in the correct engine from the command line and then exits the first instance.
I have seen this one asked hundreds of times across various forums and newsgroups. “Is there a way to determine if a user is an Administrator?” Quite often this question goes unanswered, but it doesn’t have to.
Function IsAdminUser(strUserName)
strUserName = Chr(34) & strUserName & Chr(34)
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & strComputer & "rootcimv2")
Set colInstances = objWMIService.ExecQuery("Select * From Win32_GroupUser")
You begin by building a function that queries the Win32_GroupUser class. This class returns several instances that represent the installed users and their group assignments. Each instance will have a GroupComponent that represents the user group and a PartComponent that represents the user name. There will be one instance for every group that a user is in, so there can be several times as many instances as there are users.
If strGroup = """Administrators""" And strAccount = strUserName Then blnIsAdmin = True
Next
Since this query will return several instances, we’ll use a Boolean value to track the data we’re looking for. It should begin with a default value of false. Next, we loop through each instance, determining the user name and group assignment. If a particular instance finds the user we’re looking for listed with an administrator user group, then the Boolean value is set to true.
IsAdminUser = blnIsAdmin
End Function
The function then returns that Boolean value. So the function can be used like this:
Set WshNetwork = CreateObject("WScript.Network")
strUserName = WshNetwork.UserName
If IsAdminUser(strUserName) Then
WScript.Echo strUserName, "is an administrator."
Else
WScript.Echo strUserName, "is not an administrator."
There are three basic ways to wait for a program to terminate in WSH. If you are launching the program from your script, the first is by far the easiest.
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run "cleanmgr.exe",, True
The first example launches the Disk Cleanup Wizard using the WshShell object’s Run method. The Run method provides an optional third parameter that accepts a Boolean value indicating whether the script should wait until the program terminates before continuing. Setting this value to true will cause the script to wait until the Disk Cleanup Wizard finishes before moving on.
Do While WshShell.AppActivate("Disk Cleanup")
WScript.Sleep 1000 ' Wait while window is open
Loop
The second method is a little less reliable, but can be effective when monitoring programs that run in a window. The WScript Shell object provides an AppActivate method that is used to bring a specific window into focus. The method returns true if the window can be activated and false if not. Since this can only return false if the window doesn’t exist, it provides a handy workaround for monitoring programs that run in windows.
Do While IsRunning
WScript.Sleep 1000
Loop
Function IsRunning
Set objWMI = GetObject("winmgmts:.rootcimv2")
Set colProcesses = objWMI.ExecQuery("Select * From Win32_Process " & _
"Where Name = 'cleanmgr.exe'")
If colProcesses.Count > 0 Then
IsRunning = True
Else
IsRunning = False
End If
End Function
The third and final method relies on WMI’s ability to monitor the actual executable process. It queries WMI for the existence of a specific process and pauses execution based upon that finding. This method is extremely reliable and works effectively, although it’s not as efficient as the first method I showed you.
I recently saw a very long discussion in which a half a dozen or more people were suggesting different ways of reading only the last line of a text file. Some suggested splitting the file into an array at lone breaks, others suggested parsing by other means. My point is that this was a classic example of over thinking a problem.
Const ForReading = 1
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objFile = objFso.OpenTextFile("C:file.txt", ForReading)
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
Loop
First off, parsing a text file in VBScript requires reading the entire file into memory. That is far too inefficient right from the get-go. All you need to do is open the text file with the FileSystemObject and create a loop that reads the file line by line. Because the value of strLine is reassigned each time the loop iterates, it only ever contains one line. When the loop exits, strLine contains the last line that was read, which incidentally happens to be the last line of the file.
Playing system sounds
I was recently asked on my web site if there was any way to play system sounds in a script. As it turns out, there sure is.
Windows system sounds are .wav files that can be found in the Media folder in the Windows directory. They can be played through sndrec32.exe from the command line without any extra windows.
Well, that wraps up volume one of Nilpo’s Scripting Secrets. Stick around for the next installment, when I will reveal even more useful scripting techniques. Until next time, keep coding!