How Can I Run a Script Under Alternate Credentials?

Hey, Scripting Guy! Question

Hey, Scripting Guy! Is there a way for me to log on to a computer using a regular user account, but then run a script as a domain administrator?

— WW

SpacerHey, Scripting Guy! AnswerScript Center

Hey, WW. In answer to your question, yes, both WMI and ADSI provide a way for you to run a script under alternate security credentials; that is, both allow you to specify a user name and a password under which the script will run. Furthermore, both of these technologies provide a way to ensure that this user name and password are encrypted, and are not passed across the network using clear text. Thanks for the question, and hope that helped.


Hey, just kidding! Most likely what you really want to know is how to run a script under alternate security credentials. Let’s start by taking a look at a WMI script that connects to a remote computer (atl-ws-01) and retrieves the name of the operating system installed on that computer. Furthermore, it does this by running under the Administrator account, which in this example has a password of 4rTGh2#1:

Const WbemAuthenticationLevelPktPrivacy = 6

strComputer = “atl-ws-01”
strNamespace = “root\cimv2”
strUser = “Administrator”
strPassword = “4rTGh2#1”

Set objWbemLocator = CreateObject(“WbemScripting.SWbemLocator”)
Set objWMIService = objwbemLocator.ConnectServer _
(strComputer, strNamespace, strUser, strPassword)
objWMIService.Security_.authenticationLevel = WbemAuthenticationLevelPktPrivacy

Set colItems = objWMIService.ExecQuery _
(“Select * From Win32_OperatingSystem”)
For Each objItem in ColItems
Wscript.Echo strComputer & “: ” & objItem.Caption
Next


As you can see, we start by creating a constant named WbemAuthenticationLevelPktPrivacy and assigning it the value 6; this value will be used to encrypt the communication between our computer and the remote computer. We then define four variables – strComputer, strNamespace, strUser, and strPassword – which hold the name of our remote computer; the WMI namespace we want to connect to; the user account we want to run the script under; and the password for that user account.


At this point we’re ready to connect to the remote computer using these alternate credentials. That’s what these lines of code do:

Set objWbemLocator = CreateObject(“WbemScripting.SWbemLocator”)
Set objWMIService = objwbemLocator.ConnectServer _
(strComputer, strNamespace, strUser, strPassword)
objWMIService.Security_.authenticationLevel = WbemAuthenticationLevelPktPrivacy

We begin by creating an instance of the SWbemLocator object, and then calling the ConnectServer method. ConnectServer gets passed four parameters, which just happen to correspond to the four variables we created a moment ago. We then set the Security_authenticationLevel property to WbemAuthenticationLevelPktPrivacy, giving us a more secure connection between the two computers.


From that point on, the rest of the code is the same old WMI code you know and love.


One important note: this approach, in which you run a script under alternate credentials, works only on remote machines. For some reason, WMI won’t let you run a script under alternate credentials on your own computer. Go figure.


Now let’s take a look at the ADSI version of this script. This sample script binds to the Ken Myer user account in Active Directory and tells us whether or not this account is disabled. The script connects to Active Directory using the fabrikam\Administrator, which has a password of 4rTGh2#1:

Const ADS_SECURE_AUTHENTICATION = 1
Const ADS_USE_ENCRYPTION = 2

strPath = “LDAP://cn=kenmyer,ou=Finance,dc=fabrikam,dc=com”
strUser = “fabrikam\Administrator”
strPassword = “4rTGh2#1”

Set objDSO = GetObject(“LDAP:”)
Set objUser = objDSO.OpenDSObject _
(strPath, strUser, strPassword, _
ADS_USE_ENCRYPTION OR ADS_SECURE_AUTHENTICATION)

Wscript.Echo objUser.AccountDisabled


In this script, we create two constants (ADS_SECURE_AUTHENTICATION and ADS_USE_ENCRYPTION) to ensure that the information passed between our computer and the domain is encrypted. We then create three variables – strPath, strUser, and strPassword – which host the ADsPath to the object we want to bind to in Active Directory (in this case, the Ken Myer user account); the account name we want to use when connecting to Active Directory; and the password for that account.


Next we bind to the LDAP provider; we start here because the LDAP provider accepts anonymous bindings. Having connected to the LDAP object, we can then call the OpenDSObject method to bind to the Ken Myer user account. Note that we must pass OpenDSObject four parameters: the ADsPath to the Active Directory object; the user name we want to use when connecting to Active Directory; the password for that account; and the two constants we defined earlier. As with WMI, as soon as we make the connection, the rest of the script is the same as any other ADSI script.


By the way, OpenDSObject also works with local user accounts; the primary difference is that you bind to WinNT provider instead of the LDAP provider (and, of course, the ADsPath will be different). Here are the relevant lines of code from a script that connects to a local computer:

strComputer = “WinNT://atl-ws-01”
strUser = “Administrator”
strPassword = “4rTGh2#1”

Set objDSO = GetObject(“WinNT:”)
Set objComputer = objDSO.OpenDSObject _
(strComputer, strUser, strPassword, _
ADS_SECURE_AUTHENTICATION OR ADS_USE_ENCRYPTION)


One thing we should add is that we don’t recommend you hardcode passwords (especially Administrator passwords) in your scripts. Instead, you should make allowances to enter the password as a command-line argument or via an Input box or whatever works best for you.