In-Depth
Automate Your Security
Many security-related tasks can be tedious—and, therefore, overlooked. Using these 10 scripts can make your life easier, while simultaneously locking down your network.
Security, of course, has become a lot more important than it used to
be in the “old days,” when we were merely concerned about keeping all
the servers up and running. Unfortunately, much of security involves routine,
repetitive tasks, like backing up event logs, keeping track of service
account passwords and so on. There’s a growing market of third-party utilities
out there to help manage those tasks, but the concern about security has
coincided with reductions in IT budgets, making it difficult to buy every
new tool that promises to do the job for you.
Fortunately for the harried administrator, Windows comes with two perfect
built-in tools that can handle much of your security automation: Windows
Script Host (WSH), and VBScript. While I won’t promise that WSH can stop
hackers and take your next certification exam for you, it certainly can
remove the monotony out of many security-related tasks. In fact, simply
having some automation around makes it more likely that you’ll do these
boring tasks to begin with, thereby making your environment that much
more secure.
Picking just 10 scripts is a tough job, so I’ve tried to pick ones that
are short, easy to understand and adaptable to almost any environment
(many even run on Windows NT). More importantly, I’ve tried to pick scripts
that can act as examples or building blocks for your own scripts, giving
you sort of a mini-library of scripts to start building a collection.
Changing Service Account Passwords
I hate keeping up with service account passwords, so much so that I usually
just set them to never expire and forget about them. That’s a bad
idea, of course, but while changing the passwords in AD Users & Computers
is easy, changing all the passwords in the Services snap-in can be pretty
time-consuming. Here’s a quick script that uses every administrator’s
friend, Windows Management Instrumentation (WMI), to connect to a remote
server and change the password that a particular service will use to log
in. You’ll change the actual account password in some other way;
this is just changing the service itself to use the new password. You’ll
need to have administrative privileges on the remote server, and you’ll
want to change the server name, the service name and the new password
to suit your environment.
The first two lines of code simply define the remote server’s name
and then connect to its WMI provider, which runs as a background service.
Next, the script asks the WMI provider to return every instance of the
Win32_Service class that has the name “myservice,” or whatever
you change the service name to. Of course, only one service will meet
that criterion, so the next line of code can simply change the password.
You must have all seven commas before the password. These are placeholders
for other service attributes that aren’t being changed.
'connect to the computer's WMI provider
sComputer = "server1"
Set oWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" &
_
sComputer & "\root\cimv2")
'retrieve the MyApp service
Set oService = oWMIService.ExecQuery _
("Select * from Win32_Service WHERE Name" & _
" = 'myservice'")
'change the password
errReturn = oService.Change( , , , , , , _
, "NeWP@ss#0rD")
Changing Services’ Logon Account
Changing the user account utilized by a service can be painful, too. Sometimes
you may want to standardize a particular service to use the same account
throughout your domain; other times, you may simply want to find every
service using a particular account and change it to something else. That’s
what this next script does for you.
This script starts
by connecting to a remote server, where you’ll need to have administrative
privileges. Next, the script retrieves all of the services installed on
that machine by querying the server’s WMI provider. Those services
are retrieved into a special structure called a collection, which stores
multiple complex objects. The script then uses a “For Each…Next”
loop to examine each object—or service—in the collection.
An “If…Then” statement examines the service’s
StartName property to see if the service is using the local user account
“Bob.” You could change this to a domain account by using
the domain\username format, or even the user@domain format on Windows
XP or Windows Server 2003. For every service using the specified account,
the script sets the new startup account to “.\LocalSystem,”
which represents the built-in LocalSystem account. Again, you can specify
whatever you like for the new account. If you’re not using LocalSystem
(which doesn’t require a password), you can combine this script
with the previous one to also set the password that the service will use
to log on when it starts. You can combine them by adding the new password
to the call to oService.Change. There’s no need to run both separate
scripts.
'Connect to the remote computer
sComputer = "Server2"
Set oWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& sComputer & "\root\cimv2")
'Retrieve all services
Set cServices = oWMIService.ExecQuery _
("Select * from Win32_Service")
'Examine each service one at a time
For Each oService in cServices
'If the service uses the account "Bob,"
'then change it to LocalSystem.
If oService.StartName = ".\Bob" Then
errServiceChange = oService.Change _
( , , , , , , ".\LocalSystem"
, "")
End If
Next
Do
as I Say |
To conserve space and keep
these scripts easy to read, I’ve done a couple of things
my high school programming teacher wouldn’t approve
of. To begin with, I haven’t specifically declared any
of the script variables I use. VBScript isn’t picky
and lets me get away with it, but it can make script
troubleshooting and maintenance a lot harder. I’ve also
shorted the generally-accepted variable naming conventions
to use just a single letter to designate objects, strings,
collections, and so forth. While it makes the script
a bit harder for a programmer to read, it also keeps
the scripts short. None of my shortcuts should affect
how these scripts run, so hopefully you’ll forgive me
and not live by my example in your own scripts.
Also note that, due to space limitations,
not all of the scripts have been included in their entirety.
Sometimes I’ll just pull out the sections that do the
legwork and explain what’s going on. However, you can
download all of the scripts in the online edition of
this article.
—Don Jones |
|
|
Disabling a Service
Some services don’t deserve a new password or a new account. They deserve
to be shut down entirely. The Messenger service (the built-in one, not
the Windows Messenger or MSN Messenger applications) is a good example,
due mainly to the amount of annoying pop-up spam I get from it. You might
also want to shut down services that use a particular service account,
for security reasons.
This time, I’ve created a script that takes its input from a text file.
This file should simply list one computer name per line, allowing the
script to contact each of those computers and disable the offending services.
The script starts by creating a special object known as the FileSystemObject,
which is built into WSH and provides access to files and folders. Next,
the script uses the FileSystemObject to open a text file named c:\computers.
txt (you can substitute something appropriate when you run it). Inside
the script, this text file is now represented by something called a text
stream, or TextStream object, which makes sense because a text file is
basically a stream of characters. The script’s “Do…Loop” construct will
repeat once for each line of text in the file.
For each computer
mentioned in the text file, the script will reach out and connect to its
WMI provider. You’ll need to have administrative privileges on each machine,
which generally means you’ll have to run the script against domain members
while using a Domain Admin account. For each computer, the script retrieves
a list of all services set to use a specified domain account, “Domain\ServiceAcct.”
Having retrieved all of the services I want to disable, I have the script
use a “For…Next” loop to set each service’s startup attribute to “Disabled.”
Once the TextStream reaches its end, the script will end. VBScript is
smart enough to close the text file when the script ends, although it’s
not a bad idea to explicitly do so yourself by adding the following to
the end of the script:
oTS.Close
You could also retrieve—and disable—the Messenger service
or any other service, by name, by changing the query to read:
Set cServiceList = oWMIService.ExecQuery _
("Select * from Win32_Service where " & _
" Name = 'Messenger'")
For information on other attributes provided by the Win32_Service
class (and every other WMI class), hop over to msdn.microsoft.com/library;
in the left-hand pane look for “Setup and System Administration”
| Windows Management Instrumentation” | WMI Reference | WMI Classes
and drill down into Win32 Classes.
'Create a FileSystemObject
Set oFS = CreateObject("Scripting.FileSystemObject")
'Open a text file of computer names
'with one computer name per line
Set oTS = oFS.OpenTextFile("c:\computers.txt")
'go through each computer name
Do Until oTS.AtEndOfStream
'read the next computer name
sComputer = oTS.ReadLine
'connect to its WMI provider
Set oWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" &
_
sComputer & "\root\cimv2")
'get a list of all services set to use the
'domain account "ServiceAcct"
Set cServiceList = oWMIService.ExecQuery _
("Select * from Win32_Service where " & _
" StartName = 'Domain\ServiceAcct'")
'disable each matching service
For Each oService in cServiceList
errReturnCode = oService.Change( , , , , "Disabled")
Next
Loop
Changing the Local Administrator Password
Enough with services and service accounts. Another tedious task is periodically
changing the local Administrator password on every computer in your company.
You know you should do it, but who has that kind of time? Scripts do!
Once again, start with an input text file that lists one computer per
line. In case you’re wondering, it’s also possible to retrieve a list
of computers from AD, an NT domain or even a database, with a little bit
of extra programming.
This script starts out similarly to the last, by opening
a text file and using a “Do…Loop” construct to iterate through each line
of the file. However, this script doesn’t connect to a WMI provider on
each computer. It relies on the Active Directory Scripting Interface,
or ADSI, to connect. Wait a sec—ADSI? Does this only work on 200x domain
controllers? Nope, this script will run against everything from NT 4.0
on up, including NT Workstation, 2000 Pro, and XP Pro, because all NT-based
operating systems have an NT domain-like Security Accounts Manager (SAM).
Notice how the ADSI connection uses the “WinNT://” moniker, which tells
ADSI to stay NT-compatible.
The ADSI connection specifically queries a user account named
“Administrator,” and then changes its password and saves the change back
to the SAM. You can run this script on a monthly basis, if you like, with
a word of warning: As written, the script doesn’t include any error handling,
so it will crash if one of the specified computers isn’t available at
the time. A quick and dirty way to bypass the crash is to add:
On Error Resume Next
As the first line of script code. This will cause the script
to ignore any errors and try the next computer in sequence. If you want
to be a bit more thorough, you could save the failed computer names to
a new text file, which could be used to run the script again the next
day.
'Create a FileSystemObject
Set oFS = CreateObject("Scripting.FileSystemObject")
'Open a text file of computer names
'with one computer name per line
Set oTS = oFS.OpenTextFile("c:\computers.txt")
'go through the text file
Do Until oTS.AtEndOfStream
'get the next computer name
sComputer = oTS.ReadLine
'retrieve that computer's local Admin
Set oUser = GetObject("WinNT://" & _
sComputer & "/Administrator, user")
'reset the password
oUser.SetPassword "New!Ad3in"
'save the change
oUser.SetInfo
Loop
'close the text file
oTS.Close
Creating User Accounts
A major security problem in many environments is that user accounts aren’t
created consistently. To help one of my customers, I created a script
that reads new user information from an Excel spreadsheet and creates
the appropriate user accounts in the domain. Note that you have to have
the spreadsheet (a sample is included with the downloadable, complete
script), and an ODBC DSN named “Excel” that points to the
spreadsheet file. You can create a DSN by using the ODBC utility in the
Administrative Tools folder.
In section 1 (which starts with “Dim oCN”), the
script uses ActiveX Data Objects (ADO) to open the Excel spreadsheet and
retrieve the rows. Much of the script should look familiar. It uses ADSI
to connect to an NT PDC or the AD PDC Emulator, and opens an output text
file to save users’ new passwords. In section 2 (sUserID = oRS(“UserID”)),
the script retrieves information from the current row of the spreadsheet,
giving it the user name and other useful data. In section 3 (sPassword
= Left), a new password is created using pieces of the current date and
time—not the strongest password, of course, and you can add something
more complex if you like. Section 4 (Set oUserAcct = oDomain.Create) actually
creates the user account and sets most of its initial properties. The
script saves the new password to the output file, and in section 5 (sGroupList
= Split) adds the users to the specified groups. The group list must be
comma-delimited, and the script breaks this list into an array of group
names, and then adds the user to each group one at a time. The script
wraps up in section 6 (oRS.Close) by closing the Excel spreadsheet connection,
the output file with passwords, and a final closing message letting you
know that it’s done.
' PART 1: Open up the Excel spreadsheet
' using ActiveX Data Objects
Dim oCN
Set oCN = CreateObject("ADODB.Connection”)
oCN.Open "Excel"
Dim oRS
Set oRS = oCN.Execute("SELECT * FROM [Sheet1$]")
' PART 2: Get a reference to the
' Windows NT domain using ADSI
Dim oDomain
Set oDomain = GetObject("WinNT://MyPDC")
' PART 3: Open an output text file
' to store users' initial passwords
Dim oFSO, oTS
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oTS = oFSO.CreateTextFile("c:\passwords.txt",True)
' PART 4: For each record in the recordset, add the user,
‘ set the correct user properties, and add the user to the
' appropriate groups
' create the necessary variables
Dim sUserID, sFullName, sDescription
Dim sGroups
Dim sPassword, oUserAcct, oFolder
Dim sGroupList, iTemp, oGroup
' now go through the recordset one row at a time
Do Until oRS.EOF
' get the user information from this row
sUserID = oRS("UserID")
sFullName = oRS("FullName")
sDescription = oRS("Description")
sGroups = oRS("Groups")
' make up a new password
sPassword = Left(sUserID,2) & DatePart("n",Time)
& _
DatePart("y",Date) & DatePart("s",Time)
' create the user account
Set oUserAcct = oDomain.Create("user",sUserID)
' set account properties
oUserAcct.SetPassword sPassword
oUserAcct.FullName = sFullName
oUserAcct.Description = sDescription
' save the account
oUserAcct.SetInfo
' get a reference to the new account
' this gets us a valid SID & other info
Set oUserAcct = GetObject("WinNT://NT4PDC/" &
_
sUserID & ",user")
' write password to file
oTS.Write sUserID & "," & sPassword &
vbCrLf
' PART 4A: Add user account to groups
' use the Split function to turn the
' comma-separated list into an array
sGroupList = Split(sGroups, ",")
' go through the array and add the user to each group
For iTemp = 0 To uBound(sGroupList) - 1
' get the group
Set oGroup = GetObject("WinNT://NT4PDC/"
& _
sGroupList(iTemp) & ",group")
' add the user account
oGroup.Add oUserAcct.ADsPath
' release the group
Set oGroup = Nothing
Next
' move to the next row in the recordset
oRS.MoveNext
Loop
' PART 6: Final clean up, close down
oRS.Close
oTS.Close
WScript.Echo "Passwords have been written to" & _
" c:\passwords.txt."
Disabling Inactive User Accounts
How helpful would it be to have a script that could disable any user accounts
that hadn’t been used for six weeks or some other specified period of
time?
This script has a lot in common with some of the previous scripts, so I’ll concentrate on a few specific areas of interest. First, in section A (‘Point to group), I used ADSI to connect to a user group in the domain. Note that I used the “WinNT://” moniker, which means this script will run on NT and later domains, including AD. In section B (dDate = oUser.get), I retrieve the current user’s last login date. The domain supplies that plus the time all in one string, so I also save just the leftmost eight characters, which compose the date part. Finally, in section C (If iDiff >= 6 Then), I actually look at the user’s disabled status. If the difference between today’s date and the user’s last login date is six weeks or more, then the script sets the user’s flags to have a “Disabled” flag, unless the user is already disabled. The script uses SetInfo to save the information back to the directory.
One caveat: Prior to Windows 2003, domain controllers don’t reliably remember the last time a user logged in; in fact, that was a specific new feature for Windows 2003. Be sure to try this script in your test environment before you unleash it in production, so that you’ll know whether or not it’s going to be useful for you.
Dim dDate, oUser, oObject, oGroup
Dim iFlags, iDiff, iResult
Const UF_ACCOUNTDISABLE = &H0002
'Point to group containing users to check
Set oGroup = GetoObject("WinNT://MyDomain/Domain Users")
'Enable error trapping
On error resume Next
'for each user object in the group...
For each oObject in oGroup.Members
'ensure the user isn't a computer
account!
If (oObject.Class="User")
And _
(InStr(oObject.Name, "$")
= 0) Then
'retrieve the
user object
Set oUser =
GetoObject(oObject.ADsPath)
'get the last
login Date from the domain
'and strip off
the time portion
'(just need
the date)
dDate = oUser.get("LastLogin")
dDate = Left(dDate,8)
dDate = CDate(dDate)
'calculate how
long ago that was in weeks
iDiff = DateDiff("ww",
dDate, Now)
'more than six
weeks since last login?
If iDiff >=
6 Then
'yes
- get the user's flags
iFlags
= oUser.Get("UserFlags")
'is the account already disabled?
If
(iFlags AND UF_ACCOUNTDISABLE) = 0 Then
'no
- disable it!
oUser.Put
"UseriFlags", iFlags OR UF_
’
ACCOUNTDISABLE
oUser.SetInfo
End
If
End If
End If
Next
WScript.Echo "All done!"
Dumping the Security Event Log
Here’s a great way to archive off your servers’ security logs. This is a script you can run under Task Scheduler once a day, or manually, if you like. It will dump each server’s security log into a text file and then clear the log for you. Obviously, you’ll need the necessary permissions on the servers. If you set this up to run under Task Scheduler, make sure the task runs under an appropriate user account.
This script starts like many others, by reading in a text file with one server name per line. For each server, it connects to the WMI provider and queries the security log by using a WMI query. The script then asks each log to back itself up to a local file. Notice that the BackupEventLog method returns a value, which is stored in the errBackupError variable. Some of the previous scripts have used this technique, but this is the first time I’ll actually check to see if an error occurred.
Also notice that the filename used to save the log is dynamically generated, and includes both the server’s name and the current date. This technique allows the script to be run every day without overwriting the files. You can create your own naming scheme, of course.
An “If…Then” construct checks to see if the errBackupError variable contains
something other than zero: If it does, an error occurred and a message
is displayed. If not, then the backup was successful and the log is cleared
out. The bit that displays the error message—WScript.Echo—needs to be
removed if using this script under Task Scheduler. That’s because Task
Scheduler can’t respond to the error message and won’t display it so that
you can respond manually. The script will be locked up in the background
until the computer or the Task Scheduler service is restarted.
‘Create a FileSystemObject
Set oFS = CreateObject(“Scripting.FileSystemObject”)
‘Open a text file of computer names
‘with one computer name per line
Set oTS = oFS.OpenTextFile(“c:\computers.txt”)
‘go through the text file
Do Until oTS.AtEndOfStream
‘get next computer
sComputer = oTS.ReadLine
‘connect to the WMI provider
Set oWMIService = GetObject(“winmgmts:” _
& “{impersonationLevel=impersonate,(Backup)}!\\”
& _
sComputer & “\root\cimv2”)
‘query the Security logs
Set cLogFiles = oWMIService.ExecQuery _
(“Select * from Win32_NTEventLogFile where “ & _
“LogFileName=’Security’”)
‘go through the collection of logs
For Each oLogfile in cLogFiles
‘back up the log to a file
errBackupError = objLogFile.BackupEventLog _
(“c:\logfiles\” & sComputer & Date()
& “.evt”)
‘see if an error occurred
If errBackupError <> 0 Then
‘one did - display an error
Wscript.Echo “Couldn’t get log from “
& sComputer
Else
‘no error - safe to clear the Log
oLogFile.ClearEventLog()
End If
Next
Loop
‘close the input file
oTS.Close
Show the Latest Service Pack
Ever need a quick rundown of which computers were on the latest service
pack? WMI to the rescue, again! This next script uses my now-familiar
technique of reading computer names from a text file, giving you complete
control over which machines are checked. I use this script to quickly
check by key servers after a planned service pack deployment, just to
see if any were missed. The script is kind of a poor person’s Systems
Management Server, providing basic inventory information about the operating
system service pack level. With service packs providing the basis for
so many security features—including bugfixes, new security defaults, and
new security capabilities—ensuring that servers are up-to-date is a critical
task.
This script actually uses two text files: One input file
for server names, and an output file listing each server checked and its
reported service pack version. As with many of the previous scripts, it
connects to each server’s WMI provider, queries the necessary WMI class
(starting to see a pattern to this WMI stuff?), and writes the desired
information to a file.
I did one other new thing in this script: Notice the last
line of code, which displays a simple “All done!” message. This message
is a great thing to add to the end of all of your scripts, especially
those that might not seem to do anything, even when they’re working perfectly.
This message will often be your only indication that the script finished
successfully; WSH’s default behavior upon completing a script is to do
nothing, which often leaves you wondering if the script actually ran or
just vanished into a black hole.
‘Create a FileSystemObject
Set oFS = CreateObject(“Scripting.FileSystemObject”)
‘Open a text file of computer names
‘with one computer name per line
Set oTS = oFS.OpenTextFile(“c:\computers.txt”)
‘Now open an output text file
Set oReport = oFS.CreateTextFile(“C:\results.txt”)
‘go through the text file
Do Until oTS.AtEndOfStream
‘get the next computer
sComputer = oTS.ReadLine
‘connect to WMI
Set oWMIService = GetObject(“winmgmts:” _
& “{impersonationLevel=impersonate}!\\” & _
sComputer & “\root\cimv2”)
‘query the Win32_OperatingSystem class
‘(there’s usually only one instance)
Set cOperatingSystems = oWMIService.ExecQuery _
(“Select * from Win32_OperatingSystem”)
‘check each instance returned
For Each oOperatingSystem in cOperatingSystems
‘write the report
oReport.WriteLine sComputer “ is at SP “ &
_
oOperatingSystem.ServicePackMajorVersion _
& “.” & oOperatingSystem.ServicePackMinorVersion
Next
Loop
‘close the input and output files
oTS.Close
oReport.Close
WScript.Echo “All done!”
Creating Computer Accounts
Deploying new computers can be a pain, especially when they all have to be joined to the domain. Here’s a script that can make the task a bit easier, by pre-creating computer accounts in a specified container (or organizational unit) within AD. This time, I’ll use ADSI again, rather than WMI.
I’ve still used an input file that lists the computer names I want to create. For each computer, I connect to the AD root by using an ADSI “LDAP://” moniker. I could have used the “WinNT://” moniker that I used in the last ADSI script, but doing so wouldn’t have provided access to organizational units; all computer accounts would be created in the default container. By using LDAP, I can access the full capabilities of AD. Once I connect to the root of the directory, the script connects to the destination container. In this case, I specified the default Computers container; you could obviously specify any location you wanted, including an organizational unit.
Next the script creates the new account, at the same time retrieving a reference to it. That’s because new accounts still need a couple of settings changed before they’re really usable. In fact, the script handles that next, setting both the computer’s SAM account name and two flags indicating that no password is required and that the account is for a computer, not a user. Notice the two flag names, ADS_UF_
PASSWD_NOTREQD and ADS_UF_WORKSTATION_
TRUST_ACCOUNT: These flags actually represent numeric (hexadecimal, actually) values, which are defined in the beginning of the script by using the CONST keyword. Once all the desired settings have been changed, SetInfo saves the information back to AD and the account is finished.
You can use a substantially similar script to create Contact objects,
users, and other AD objects. For users, of course, you might set a variety
of other settings, such as their initial password, display name, address
and phone number, and more.
‘Create a FileSystemObject
Set oFS = CreateObject(“Scripting.FileSystemObject”)
‘Open a text file of computer names
‘with one computer name per line
Set oTS = oFS.OpenTextFile(“c:\computers.txt”)
‘go through the text file
Do Until oTS.AtEndOfStream
‘get the next computer to create
sComputer = oTS.ReadLine
‘define constants
Const ADS_UF_PASSWD_NOTREQD = &h0020
Const ADS_UF_WORKSTATION_TRUST_ACCOUNT = &h1000
‘retrieve the root directory level
Set oRootDSE = GetObject(“LDAP://rootDSE”)
‘retrieve the destination container
Set oContainer = GetObject(“LDAP://cn=Computers,” &
_
oRootDSE.Get(“defaultNamingContext”))
‘create a computer and retrieve the
‘newly-created object
Set oComputer = oContainer.Create( _
“Computer”, “cn=” & sComputer)
‘save the computer’s name
oComputer.Put “sAMAccountName”, sComputer & “$”
‘save the password and account attributes
oComputer.Put “userAccountControl”, _
ADS_UF_PASSWD_NOTREQD Or ADS_UF_WORKSTATION_TRUST_ACCOUNT
‘write the information to AD
oComputer.SetInfo
Loop
‘close the input file
oTS.Close
WScript.Write “All done!”
WSH Security
I’ll wrap up with a two-for-one offer designed to illustrate how
the latest version of WSH (version 5.6, available as a free download from
www.microsoft.com/scripting)
includes built-in security to prevent untrusted scripts—including
viruses—from running. The first script is a simple Registry hack
to set the WSH trust policy to execute only trusted scripts. You can use
this as a logon script for Win9x machines, although regular users don’t
have the necessary permissions to the registry in NT, 2000, and XP. However,
since this is just a Registry hack, you can also deploy it via System
Policy or Group Policy to all of your client computers.
‘create a shell object
Set oShell = CreateObject(“WScript.Shell”)
‘write the registry key
oShell.RegWrite(“\HKCU\SOFTWARE\Microsoft\” & _
“Windows Script Host\Settings\TrustPolicy”, 2)
Once set, WSH will only execute scripts that have been signed
by using a digital certificate, and it’ll only accept certificates
that have been issued by a trusted certification authority or CA. Keep
in mind that most commercial CAs—VeriSign, Thawte and so on—are
trusted by default, and that you can use Group Policy to deploy different
trust arrangements to 2000 and XP clients. Of course, you’ll need
to sign your own scripts in order for them to execute, and WSH gives you
a way. Here’s your bonus eleventh script, which will use a locally-installed
code-signing certificate named “IT Department” to sign a script
file named “C:\MyScript.vbs.” The certificate must be installed
to the current user’s default certificate store, as is usually the
case with code-signing certificates.
Set oSigner = WScript.CreateObject(“Scripting.Signer”)
oSigner.SignFile “C:\MyScript.vbs”, “IT Department”
Scripts,
Zipped |
To download all the scripts from this article
in one file, click here: http://mcpmag.com/downloads/2003/0204mcp_scripts.zip
or right click the link and "Save As." Having
problems downloading the script? Send e-mail to Michael
Domingo, editor, MCPmag.com at mdomingo@101com.com with
"Scripting" in the subject line of your message
and he'll send it to you. |
|
|
Looking for More?
The Web holds a zillion more scripts that have a direct security purpose,
and even more that can be adapted to help meet your security needs. For
starters, check out my site, www.adminscripting.com.
Microsoft’s TechNet Scripting Center is also a great resource, and
can be found at www.microsoft.com/technet/treeview/default.asp?
url=/technet/scriptcenter/Default.asp. If you’re looking for
the VBScript or WSH documentation, look no further than www.microsoft.com/scripting.
Above all, experiment a bit. You’ll find that scripting will come
more naturally as you work with it. Set up a small test lab or use software
like VMware or Microsoft Virtual PC to set up a virtual test workstation
where your test scripts won’t be able to do any harm. Scripting
can be a great way to cut down on tedious administrative tasks and to
create a more secure environment.