Let's recap what we've learned so far about remote scripting using WMI:
- In Part 6 of this series, Remote scripting first steps,
- we tried modifying our ChangeIPAddress.vbs script so we could use it to remotely change the IP address of a computer. Along the way we learned that we needed to use Group Policy to enable the Remote Administration exception in Windows Firewall on the target computer, otherwise the script wouldn't work. Eventually we got the script to work but it also timed out and returned an error.
- Then in Part 7, Troubleshooting the mystery error, we discovered we could work around the error by adding On Error Resume Next to our script. But the script still timed out or took a long time to finish running. I consulted some scripting gurus and we came up with a tentative explanation for the error, but to see whether the problem was more general we created a new script called ChangeGateway.vbs and when we ran this script remotely, it worked.
- Finally, in Part 8, Troubleshooting remote scripting using Network Monitor 3.0, we had a reader suggest a simple possible cause for our error: Changing the IP address of the remote computer breaks the connection to the computer, causing the script to time out with an error. That sounded plausible, so we tried using Network Monitor 3.0 to see what was happening when we ran the script, and sure enough it looks like our network trace analysis confirmed the reader was right. Score one for our readers!
It's time to step back a bit, however, and learn some of the technical details of remote scripting before we go any further. It's all well and good to jump in and try things, but sometimes we hit a wall when we do this. Learning the fundamentals can often help us avoid (or go around or maybe jump over) the wall. So let's start doing that now.
Two types of remote scripting
There are really two kinds of remote scripting. The first kind is when we run a script on Computer A and the script targets Computer B to perform some action on it. In our earlier attempt at remote scripting using our ChangeIPAddress.vbs script, we changed the line:
strComputer = "."
strComputer = "xp2"
If we use the first line above and run the script on Computer A, the script targets Computer A (the local computer or ".") and changes Computer A's IP address. If however we use the second line above and run the script on Computer A, the script targets Computer B (the computer with NetBIOS name "xp2") and changes B's IP address.
But there's a second type of remote scripting and it works like this: I'm an administrator who is logged on to Computer A and I have a script I want to use to do something on Computer B. But instead of trying to run my script on my computer (A) and have the script target Computer B, I want to run my script directly on Computer B. So somehow I have to get my script from my computer (A) to the target computer (B) and then get it to run there. How can I do that? If I have an Active Directory environment, then I can try and run the script as a logon script on the remote computer. We'll look at how to do that soon in a future article, but for now just make a mental note that there are two types of remote scripting:
- Running the script on the local computer and targeting a remote computer
- Running the script directly on the remote computer
Let's express the difference between these two remote scripting paradigms another way:
- The first type of remote scripting involves connecting to the remote computer and then running the script.
- The second type involves deploying the script to the remote computer and then running the script.
Get the difference?
Understanding remote scripting connectivity
Let's focus now on the first type of remote scripting (which we've tried to do in the last few articles). What does it mean for a script that runs on your local computer to connect to a remote computer and run against it? It means three things:
- Network connectivity
- User identity
- Suitable permissions
1. Network connectivity
For the script to do something on the remote computer, the script first of all needs to establish network connectivity with the remote computer. What kind of problems might prevent network connectivity from happening?
First, it could be a name resolution problem. If our script can't resolve the remote computer's hostname or fully-qualified domain name (FQDN) into its IP address, then remote scripting will fail.
Second, it could be a firewall issue. We saw in a previous article that in order to get our WMI scripts to run against a remote computer, we had to open the Remote Administration exception in Windows Firewall on the remote computer. Now if you open the Windows Firewall applet from Control Panel and select the Exceptions tab, you won't find a checkbox labeled Remote Administration that you can select to open this exception. The reason for this of course is that this Control Panel applet is meant primarily for home users to use for configuring their firewall. In a business environment where Active Directory is being used, the preferred way of managing Windows Firewall is using Group Policy. We saw in an earlier article that the Group Policy setting we needed to configure was the following:
Computer Configuration\Administrative Templates\Network\NetworkConnections\Windows Firewall\Domain Profile\Windows Firewall: Allow inbound remote administration exception
When you target this policy against a remote computer, it opens two TCP ports on that computer: 445 and 135:
- TCP port 445 is the port for incoming Server Message Block (SMB) traffic, and if this port is closed on the remote computer's firewall then not only will you not be able to connect to it using WMI, you'll also not be able to connect to it using standard MMC console tools like Computer Management. And when the port is closed and you try to run scripts against the remote machine, you may get cryptic errors like "System error 53 has occurred. The network path was not found" and so on.
- TCP port 135 is the port for incoming Distributed COM (DCOM) traffic. More specifically, port 135 is the listening port for the DCOM Service Control Manager (SCM) which provides RPC-based services for instantiating COM objects and such.
The long and short of it is that both TCP ports 135 and 445 need to be open on the remote computer's firewall if WMI queries run from the local computer are to successfully use RCP to connect to the WMI service on the remote computer and to successfully instantiate DCOM objects on the remote computer.
2. User identity
When you run a script against a remote Computer and it can establish network connectivity with the remote computer, then the script can perform actions on the remote computer. But the actions that it is able to perform depend on the identity with which the script is running on the remote computer. So say for example that I log on to Computer A using an ordinary domain user account. Then I run the script ChangeIPAddress.vbs and have it target remote Computer B. The script uses RPC to connect to the WMI service on Computer B and it tries to change the IP address of the Computer B. But the script fails. Why? Well, who is trying to perform this action on the remote computer? You are -- and on your local Computer A you are a domain user, and when you run the script by default it impersonates your identity, i.e., the script tries to perform its actions using your identity (your domain user account). So when the script is trying to change the remote computer's IP address, it is effectively you, a domain user, who is trying to do this. And that will fail since changing an IP address requires local administrator credentials.
So you're sitting there at Computer A, logged in as a domain user, and you still want to use your script to change the IP address of Computer B. How can you do it?
Well, you could hard code into our script the password for the local Administrator account on the remote computer. In other words, in our ChangeIPAddress.vbs script we could replace this:
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
strUser = "Administrator" strPassword = "Pa$$w0rd" Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2", strUser, strPassword)
The trouble is, this isn't secure -- the local Administrator account's password for the remote computer is sitting right there in plain text in your script for all to see!
How about getting rid of the first two lines above and passing values for strUser and strPassword to the script as arguments when the script is run? That's better than hardcoding these values into the script, but if anyone has a network sniffer running (like Network Monitor 3.0) then they can sniff out this credential information and again you've compromised your remote computer.
How about if we elevate a command prompt using runas /user:Administrator cmd.exe and then run the script from the elevated command prompt without specifying any other credentials? That's probably the best solution for remote scripting where you need to ensure the script has the appropriate identity (usually local admin on the target computer) though it's a bit of a hassle. Of course, you could also simply log on to your workstation as a domain admin account and simply open a command prompt and run the script.
3. Suitable permissions
So you're running your script on Computer A and the script is supposed to perform some action on remote Computer B. The script has established network connectivity with the WMI service on the Computer B, and the script is trying to perform its actions using the proper identity (usually local admin credentials) on Computer B. What else could cause the script to fail at this point? Insufficient permissions! If the script is trying to perform some action that is controlled by an ACL (such as modifying a file system object or creating an object in Active Directory or activating a DCOM object) and you (your identity impersonated by the script) don't have suitable permissions to perform that action, the script will fail. Unfortunately that's often the hardest part of remote scripting since there are NTFS permissions, DCOM permissions, and lots of other types of permissions on Windows platforms. Plus, you may have the right permissions but not the right privileges, i.e., user rights to perform some actions. For example, say you want to use a script to clear the event log on a remote computer but your identity lacks the SeSecurityPrivilege on that remote computer. Guess what? Your script will fail.
There's lots to learn about remote scripting, isn't there? We'll continue with more in our next article.
About the author:
Mitch Tulloch is a writer, trainer and consultant specializing in Windows server operating systems, IIS administration, network troubleshooting, and security. He is the author of 15 books including the Microsoft Encyclopedia of Networking (Microsoft Press), the Microsoft Encyclopedia of Security (Microsoft Press), Windows Server Hacks (O'Reilly), Windows Server 2003 in a Nutshell (O'Reilly), Windows 2000 Administration in a Nutshell (O'Reilly), and IIS 6 Administration (Osborne/McGraw-Hill). You can find more information about his books at his Web site: www.mtit.com