VBS if you are using the VBScript scripting language). VBScript: When combined
with technologies such as Windows Management Instrumentation (WMI) and ...
Monica Dohnji
VBSCRIPT SCRIPTING What is Scripting? A script is nothing more than a plain-text file created using Notepad or some other text editor, and saved with a particular file extension (for example: .VBS if you are using the VBScript scripting language). VBScript: When combined with technologies such as Windows Management Instrumentation (WMI) and Active Directory Service Interfaces (ADSI), Microsoft® Visual Basic®, Scripting Edition (VBScript) is a powerful scripting language. Using VBScript in combination with these other technologies, you could conceivably write a script of 10,000 or so lines, a script complete with error handling, subroutines, and other advanced programming constructs. In turn, that one script could give you complete control over all aspects of your computing environment. But what makes VBScript such a useful tool for system administrators is the fact that you do not have to create such elaborate and complicated solutions. Admittedly, scripting can be used to create an allencompassing enterprise management solution. Perhaps more important, however, scripting can also be used in this way: a system administrator can spend a few minutes typing a few lines of code into Notepad, and instantly create a custom solution to a specific problem. For example, the three-line script shown in below can be run any time you need to know how much free disk space is available on drive C of your computer. Example 1: Retrieving Free Disk Space Using VBScript 1 Set objWmiService = GetObject("winmgmts:") 2 Set objLogicalDisk = objWmiService.Get("Win32_LogicalDisk.DeviceID='C:'") 3 WScript.Echo objLogicalDisk.FreeSpace If you have been having problems with users filling up drive C on their computers, you now have a custom solution for identifying the computers running low on disk space. Furthermore, you can develop this custom solution using nothing more powerful than Notepad, and with little effort beyond typing in those three lines of code. Of course, it might very well be that this script does not fully address your needs. For example, the script tells you only the free space available on your local computer; it cannot tell you how much free space is available on a remote computer. Likewise, the script reports only the free space available on drive C; it tells you nothing about free space available on, say, drives D or E. But if the script does not fully meet your needs, it can be easily modified, with no need to start a new script from scratch. This is another advantage of VBScript: you can start with a very simple script, and add to it as your needs change and as you become more proficient with the language. VBScript Fundamentals: This chapter has been designed to illustrate the process of starting with a very basic script, and then gradually adding more sophisticated features to it. The chapter begins with the script shown in Example 1, a script that reports the amount of free disk space on drive C. Subsequent sections in the chapter will take this simple three-line script and gradually add additional capabilities to make it more useful in more situations. By the time this series of script enhancements is complete, you will have a script that can: • Retrieve free disk space information for any computer in your organization, including remote computers. • Retrieve free disk space information from multiple computers. • Retrieve free disk space information for all drives installed in a computer. • Issue a notification only if a drive is low on disk space.
1
Monica Dohnji VBScript allows system administrators to create complex scripts using such advanced programming capabilities as decision trees, looping, error-handling, and the ability to call functions and subroutines. What VBScript does not include are intrinsic functions for performing system administration tasks. VBScript has built-in functions for determining the square root of a number or the ASCII value of a character, but there are no built-in functions for stopping services, retrieving events from event logs, or carrying out other tasks of interest to system administrators. Using COM Objects Fortunately, there are ways to programmatically perform these tasks, primarily through the use of Automation objects. Automation objects are a subset of COM (Component Object Model), a standard way for applications (.exe files) or programming libraries (.dll files) to present their capabilities as a series of objects. In turn, programmers (or script writers) can utilize these objects -- and thus the features of the application or programming library -- in their own projects. For example, a word processing application could expose its spell checker as an Automation object, thus providing a way for script writers to add spell checking to their projects. The ability to work with Automation objects, and to utilize the properties and methods of these objects, make VBScript a powerful tool for system administration. VBScript alone cannot read events from an event log; however, VBScript can use the capabilities included within WMI to retrieve these events. VBScript has no intrinsic functions for creating user accounts in Active Directory; however, the language can use the capabilities in ADSI to create these accounts. In fact, VBScript is often referred to as a "glue language" because one of its primary uses is to "glue" objects together. Rather than provide an infinite number of intrinsic functions devoted to system administration, VBScript instead provides two functions, GetObject and CreateObject, and the language elements necessary for using the methods and properties of Automation objects. The script shown in Example 2 illustrates the importance of Automation objects within VBScript. This script reports the amount of free disk on drive C of the local computer. Furthermore, it does this using very little VBScript code. Instead, the script: 1. Uses the VBScript GetObject function to connect to WMI by way of the WMI Scripting Library (an Automation object). 2. Uses the Get method, provided by the WMI Automation object, to retrieve the properties for drive C. 3. Uses the Windows Script Host (WSH) Echo method to report the amount of free disk space on drive C. WSH, by the way, is just another Automation object. 4. Example 2: Using Objects in VBScript 1 Set objWmiService = GetObject("winmgmts:") 2 Set objLogicalDisk = objWmiService.Get("Win32_LogicalDisk.DeviceID='C:'") 3 WScript.Echo objLogicalDisk.FreeSpace In the preceding example, the primary purpose of VBScript is to glue together the capabilities of WMI and WSH. In turn, this allows you to retrieve the amount of free disk space (something WSH alone cannot do), and echo the value back to the screen (something WMI alone cannot do). Creating Objects Before you can do anything with the methods or properties of an Automation object, you must obtain a reference to that object, a process known as creating or instantiating the object. Creating objects can seem confusing at first, because VBScript and WSH both provide a GetObject and a CreateObject method for accessing objects. Furthermore, although the implementations are similar, there are a few subtle differences that grow in importance as you become more proficient in scripting. Use the following rules-of-thumb without worrying about whether you are using the VBScript functions or the WSH methods (although in most cases you will use the VBScript functions): •
Use GetObject to create either WMI or ADSI objects. When using GetObject, you use a moniker to identify the object to create. A moniker is simply a string, with a mandatory prefix, that
2
Monica Dohnji makes it easy to describe the target object, much like a fully qualified path and filename describe a specific file in the file system. •
Use CreateObject to create objects other than WMI or ADSI. CreateObject uses a programmatic identifier, ProgID, to identify the object to create. A ProgID is the fixed string an object adds to the registry when the object is installed and registered on the computer. Moniker prefixes are also stored in the registry. These are not hard-and-fast rules; sometimes you will need to use CreateObject to create WMI objects other than SWbemServices (for example, SWbemDateTime). Similarly, some ADSI objects require the use of CreateObject. In general, though, CreateObject will be required only when creating new instances of such things as the WSH Controller, Network, and Shell objects, the FileSystemObject, the Dictionary object, and Internet Explorer, among numerous other objects. Intrinsic Objects Some objects are intrinsic objects. Intrinsic objects are objects that are created without ever making a call to GetObject or CreateObject. In the script shown in Example 2, the script connects to WMI using this code: Set objWmiService = GetObject("winmgmts:") This creates a reference, named objWmiService, to the WMI Scripting Library's SWbemServices object. You might notice that no similar string is used to create a reference to the WSH WScript object in Example 2. Instead, the Echo method is called without first creating any kind of WSH object. This is because WScript is an intrinsic object. You do not need to create a WScript object because WScript is automatically created for you when you run a VBScript script. The VBScript error object, Err, is another intrinsic object. The Err object is automatically created when an error occurs in your script. Using an Object Reference With Automation, you do not work directly with the object itself. Instead, you create a reference to that object by using GetObject or CreateObject and assigning the object to a variable. After this reference has been created, you can then access the methods and properties of the object using the variable rather than the object itself. In Example 2, GetObject is used to assign the WMI SWbemServices object to the variable objWmiService. After the assignment has been made, all the methods and properties of the SWbemServices object can be accessed through objWmiService. For example, in line 2 of the script, the Get method is used to retrieve the properties for drive C. Any time you create an object reference, you must use the Set keyword when assigning that reference to a variable. For example, this line of code will result in a runtime error: objWmiService = GetObject("winmgmts:") To create the object reference, you must use the Set keyword like this: Set objWmiService = GetObject("winmgmts:") Set is only used when creating an object reference. If you use Set for other purposes, such as assigning a value to a variable, a runtime error will occur. For example, this line of code will fail, because no object named y can be found on the computer: Set x = y Why learn Scripting? Do you ever find yourself typing the same set of commands over and over again in order to get a certain task done? Do you ever find yourself clicking the same set of buttons in the same sequence in the same wizard just to complete some chore … and then have to repeat the same process for, say, multiple computers or multiple user accounts? Scripts help eliminate some of this repetitive work. A script is a file you create that describes the steps required to complete a task. After you create the script, you can "run" that script, and it will perform all of
3
Monica Dohnji the steps for you, saving you a great deal of time and energy. You need only create the script once, and then you can reuse it any time you need to perform that task. Scripts can also be scheduled to perform tasks at certain times on certain days, even at night, when no one is around. Furthermore, scripts can be designed to perform the same task on many different computers. Do you need to retrieve events from the event logs on each of your domain controllers? No problem; schedule a single script to run in the middle of the night, and when you come in the next morning, you'll have your data. Software needed to run/write Scripts: As long as you have Notepad then you have everything you need to start writing scripts. The following table lists the recommended software for the various flavors of Windows. Bear in mind, however, that this does not mean that all you have to do is install this software and every script will run on your computer. Because of changes made to the scripting technologies (particularly WMI), many scripts that run on Windows XP or Windows .NET Server may not run on Windows 2000 without minor modifications; others will not run at all on Windows 2000. Likewise, many scripts that run on Windows 2000 will not run on Windows NT 4.0 or Windows 98. Platform WSH VBScript WMI ADSI Windows 95 5.6 5.6 1085.0005 (1.5) 5,0,00,0 (DSClient) Windows 98 5.6 5.6 1085.0005 (1.5) 5,0,00,0 (DSClient) Windows NT 4.0 5.6 5.6 1085.0005 (1.5) 5,0,00,0 (DSClient) Windows 2000 5.6 5.6 1085.0005 (1.5) 5,0,00,0 Windows XP 5.6 5.6 2600.0000 5,0,00,0 Windows .NET Server TDB TBD TBD TBD Check if the right software is installed: Copy the following script, paste it into Notepad, and save it with a .VBS file extension (for example, Versions.vbs). Run the script, and it will report back the versions of WSH, VBScript, WMI, and ADSI installed on your computer. If any of the version numbers come back blank, that means that technology is not installed. On Error Resume Next WScript.Echo "WSH Version: " & WScript.Version Wscript.Echo "VBScript Version: " & ScriptEngineMajorVersion _ & "." & ScriptEngineMinorVersion strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer _ & "\root\cimv2") Set colWMISettings = objWMIService.ExecQuery _ ("Select * from Win32_WMISetting") For Each objWMISetting in colWMISettings Wscript.Echo "WMI Version: " & objWMISetting.BuildVersion Next Set objShell = CreateObject("WScript.Shell") strAdsiVersion = _ objShell.RegRead("HKLM\SOFTWARE\Microsoft\Active Setup\Installed Components\{E92B03ABB707-11d2-9CBD-0000F87A369E}\Version") If strAdsiVersion = vbEmpty Then strAdsiVersion = objShell.RegRead("HKLM\SOFTWARE\Microsoft\ADs\Providers\LDAP\") If strAdsiVersion = vbEmpty Then strAdsiVersion = "ADSI is not installed." Else
4
Monica Dohnji strAdsiVersion = "2.0" End If End If WScript.Echo "ADSI Version: " & strAdsiVersion How to Run a Script: Here's the simplest way to run one of the scripts: Copy the script code from the Script Center Web page. Paste the copied code into Notepad. In Notepad, save the file with a .VBS file extension (for example, MyScript.vbs). It is strongly recommended that you do not include spaces within the file name. It is also a good idea to save these scripts to a common folder (for example, C:\Scripts). Open a command window. If necessary use the cd command to switch to the folder where the scripts are stored. In the command window, type the word cscript followed by the name of the script. For example: Myscript Sample scripts for Computer management: Shut down a local Computer: Set colOperatingSystems = GetObject("winmgmts:{(Shutdown)}").ExecQuery("Select * from Win32_OperatingSystem") For Each objOperatingSystem in colOperatingSystems ObjOperatingSystem.Win32Shutdown(1) Next Remove Software: strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set colSoftware = objWMIService.ExecQuery _ ("Select * from Win32_Product Where Name = 'Personnel database'") For Each objSoftware in colSoftware objSoftware.Uninstall() Next Create a computer Account: strComputer = "atl-pro-001" Const ADS_UF_PASSWD_NOTREQD = &h0020 Const ADS_UF_WORKSTATION_TRUST_ACCOUNT = &h1000 Set objRootDSE = GetObject("LDAP://rootDSE") Set objContainer = GetObject("LDAP://cn=Computers," & _ objRootDSE.Get("defaultNamingContext")) Set objComputer = objContainer.Create("Computer", "cn=" & strComputer) objComputer.Put "sAMAccountName", strComputer & "$" objComputer.Put "userAccountControl", _ ADS_UF_PASSWD_NOTREQD Or ADS_UF_WORKSTATION_TRUST_ACCOUNT objComputer.SetInfo Further Reading on scripts: For Further Information and reading on Scripts, visit http://www.microsoft.com/technet/treeview/default.asp
5