VBS: Running my ADSI modify script from a non-domain controller?
-
Thursday, February 28, 2013 6:50 AM
Hello Scripting Guys Forum :)
Firstly, let me say how great this resource is, how much I enjoyed getting started many months ago with the 'Sesame Script' series of articles and how much it has furthered my career (I am now the resident AD SME and a good deal of this is due to my ability to write code for use on my client's directories). I haven't invested much time in PowerShell yet, I decided to still focus on vbs as its got 100% compatibility in all current Windows environments, while in some older environments Powershell requires plugins to be installed. Even in just scripting for AD against 2008 DCs, my vbs can just do what it needs to while the equivalent in PowerShell code requires the PowerShell commandlets to be installed on the DCs (from what I understand).
However with Server 2012, I’m sure I’ll be working with PS a lot more. Good to know many of the core principals I’ve learned about the directory and its functions will be unchanged, it’s just getting my head around syntax.
Anyways, the reason I am here is because I want to know about the details of remote execution of vbs code, specifically vbs code that modifies the directory. I know with PS there are ‘remote execution’ permissions that need to be enabled on the DC, but I don’t know how that applies to vbs.
The problem is:
- I’ve written a script that modifies some user attributes in the directory.
- When I run this script from a Domain Controller, it works fine. Every time I run one of my own scripts I do it from a DC, because that’s the access I have. I’ve never had any problems (beyond my own misunderstandings ;)).
- This particular script is to go to the Service Desk, and they will be using it on their Jumphosts, which are just MS Terminal Servers that enable many Service Desk operators to do work on the domain, they’ve got the RSAT tools installed and they do simple things like reset passwords and create user accounts.
- The script does not work on the Jumphost. The Jumphost obviously has ‘rights’ to modify the directory (ADUC can be run from there and modify operations performed) but I didn’t think that was computer specific anyway. It’s the user’s rights on the domain that allow the modify operation, assuming the tools are installed on the local machine. So I’m logging into the Jumphost as a Domain Administrator and the script still does not function under my login.
Additional Notes:
I’ve seen use of the impersonate method to try and get around this, where I impersonate a domain controller and perhaps the script works because the directory believes it’s being executed from there? Is that possible? If it is possible, is there a less ‘hacky’ way to do it?
Here is the code I’m using to modify the attribs, its really boiler-plate stuff and shouldn’t be the cause of the problem:
objCommand.CommandText = "<LDAP://THEDC/THEDOMAIN>;(&(objectCategory=user)(samaccountname=" & username & "));distinguishedname;subTree"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
strUserDN = objRecordSet.Fields("distinguishedname").Value
Set objUser = GetObject("LDAP://" & strUserDN)
objUser.put "msExchOmaAdminWirelessEnable", 7
objUser.Setinfo
Any help would be appreciated! :)
- Edited by Marco (Australia) Friday, March 01, 2013 2:21 AM
All Replies
-
Thursday, February 28, 2013 7:07 AM
You do not need to use credentials in a domain. Just run from an account that can run the AD tools. VBScript uses the same authentication method.
You cannot remote into an AD domain to AD unless AD has been modified to allow non-Kerberos authentication.
There is no impersonate in LDAP/ADSI. You are thinking of WMI
he server the script is running on must be connected to the domain. If it is then you can run the VBScript query with no problems.
If you have RSAT tools installed why use VBScript?
You say the scrip doesn't work. What doesn't work? What error messages?
You need to be clear and post a complete script and not just a few bits.
¯\_(ツ)_/¯
- Marked As Answer by Marco (Australia) Thursday, March 07, 2013 5:46 AM
-
Thursday, February 28, 2013 7:17 AM
-
Thursday, February 28, 2013 11:23 AMModerator
Your script can be run on any computer joined to the domain. In fact, it is recommended that scripts not be run on a domain controller.
I found two example scripts where the number in the Put statement is quoted:
objUser.Put "msExchOmaAdminWirelessEnable", "7"
As in this article:
http://support.microsoft.com/kb/830188
Otherwise, please indicate any error message, including the statement that raises the error. There is a slight chance that an error can be raised on your "Set objUser" statement, but it should be very rare (when the common name of the user includes the "/" character).
Richard Mueller - MVP Directory Services
- Marked As Answer by Marco (Australia) Thursday, March 07, 2013 5:47 AM
-
Thursday, March 07, 2013 6:10 AM
Thanks for the responses, guys :)
Took me a little while to get back, but I took what you said and went back and tested again.. and it worked. Let me respond to some of the logic involved here, I'll explain what I believe has happened and I'd be interested to hear if you agree. I'll also post my whole script incase someone else wants to use it.
You do not need to use credentials in a domain. Just run from an account that can run the AD tools. VBScript uses the same authentication method.
Yep, this is what was confusing me as I knew this.
You cannot remote into an AD domain to AD unless AD has been modified to allow non-Kerberos authentication.
I was thinking the 'remote code execution' permission as used by PowerShell. vbs does not need this from what I know.
If you have RSAT tools installed why use VBScript?
The intention was to automate part of the dsa.msc GUI to allow service desk to bulk process these kind of requests. Actually looking up the user in dsa.msc and navitgating the tabs takes longer than a simple script that asks for the username and sets the attribute. Keep this in context of a very large Service Desk servicing multiple large corporate networks.
Your script can be run on any computer joined to the domain. In fact, it is recommended that scripts not be run on a domain controller.
I found two example scripts where the number in the Put statement is quoted
Oh, I know the mechanics of how the attribute works is sound, because I could manually manipulate it (through ADSIedit or there is a tab in dsa.msc if you don't use the 'Find' feature) and get the behaviour I wanted. It was then automating it that wasn't working.
I will now post the script, please understand I only modified this and did not write it from scratch. This is not the way I would have done it, but my task was just to add some functionality and I've done that. For instance I'd use RootDSE rather than define a domain controller..
'Title: ActiveSync and OCS User configuration 'Contributor: Marco 'Author: Unknown 'Date: 26/2/2013 'Version: 1.1 ' 'Set locale to Australia for date formatting and other values SetLocale(3081) 'Active Directory Connection Parameters Const Ads_Scope_SubTree = 2 Set objConnection = CreateObject("ADODB.Connection") Set objCommand = CreateObject("ADODB.Command") objConnection.Provider = "ADsDSOObject" objConnection.Open "Active Directory Provider" Set objCommand.ActiveConnection = objConnection objCommand.Properties("Page Size") = 1000 objCommand.Properties("Searchscope") = Ads_Scope_SubTree If Msgbox ("Do you want to remove ActiveSync rights for bulk users?" & chr(13) & chr(13) & "Pressing NO will allow you to add or remove OCS and ActiveSync for a single user.",vbYesNo,"OCS and ActiveSync Configuration") = vbyes then If Msgbox ("You need to place the usernames in a text file called OCSUsers.txt, one at the start of each new line and nothing else on each line. Then place this text file in c:\GSD\ directory on the Domain Controller this script is run from. Putting this script in there as well is probably smart to keep it neat. A log file will also be generated in that directory showing you the progress of the process." & chr(13) & chr(13) & "Have you done this and are ready for me to process?",vbYesNo,"OCS and ActiveSync Configuration") = vbyes then 'Read computer list from txt file and write progress to a log Const ForReading = 1 dt = Replace(Date,"/","-") strFileName = "C:\GSD\" & dt & "-OCSandActiveSyncLog.txt" Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.CreateTextFile(strFileName) 'Users.txt requires the usernames of the computers to be listed one on each new line Set objFile2 = objFSO.OpenTextFile("C:\GSD\OCSUsers.txt", ForReading) 'Set up log objFile.WriteLine ("Active Sync Removal Log") objFile.WriteLine ("-----------------------") objFile.WriteLine () 'Loop through the user list and and configure parameters for each Do Until objFile2.AtEndOfStream user = objFile2.ReadLine objCommand.CommandText = "<LDAP://DC/DOMAINFQDN>;(&(objectCategory=user)(samaccountname=" & user & "));distinguishedname;subTree" Set objRecordSet = objCommand.Execute objRecordSet.MoveFirst strUserDN = objRecordSet.Fields("distinguishedname").Value Set objUser = GetObject("LDAP://" & strUserDN) objUser.put "msExchOmaAdminWirelessEnable", 7 objUser.Setinfo objFile.WriteLine (Time & ": " & "ActiveSync rights removed for " & user & "!") Loop objFile.WriteLine (Time & ": " & "Bulk processing complete!") Msgbox "Processing is complete",vbinformation,"OCS and ActiveSync Configuration" wscript.quit Else Msgbox "Get the resources set up and then run this script again!", vbcritical, "OCS and ActiveSync Configuration" End If wscript.quit Else user = InputBox("Please Enter User Name", "OCS and ActiveSync Configuration") if user = "" then Msgbox "No username entered", vbcritical wscript.quit end if objCommand.CommandText = "<LDAP://DC/DOMAINFQDN>;(&(objectCategory=user)(samaccountname=" & user & "));distinguishedname;subTree" Set objRecordSet = objCommand.Execute objRecordSet.MoveFirst strUserDN = objRecordSet.Fields("distinguishedname").Value Set objUser = GetObject("LDAP://" & strUserDN) on error resume next objUser.GetInfo mail = objuser.Get("mail") gn = objUser.Get("givenName") sn = objUser.Get("sn") moc = objUser.Get("msRTCSIP-UserEnabled") mocsip = objUser.Get("msRTCSIP-PrimaryUserAddress") on error goto 0 Select Case mail Case "" Msgbox gn & " doesn't have an email address setup yet. Configure Exchange mailbox for this user before running this script again", vbcritical wscript.quit End Select Select Case moc Case "True" If Msgbox (gn & " already has Office Communicator enabled with SIP address " & right (mocsip, len(mocsip) - 4) & vbcrlf & "Remove the access and ActiveSync?", vbYesNo + vbquestion, "OCS and ActiveSync Configuration") = vbyes then objUser.put "msRTCSIP-UserEnabled", false objUser.put "msExchOmaAdminWirelessEnable", 7 objUser.Setinfo msgbox "OCS and ActiveSync rights removed", vbinformation, "OCS and ActiveSync Configuration" wscript.quit else Msgbox "Process Aborted", vbcritical, "OCS and ActiveSync Configuration" end if wscript.quit Case "False" If Msgbox ("Add Office Communicator for " & gn & " " & sn & vbcrlf & "with SIP address " & mail & " and remove ActiveSync?", vbYesNo + vbquestion, "OCS and ActiveSync Configuration") = vbyes then objUser.put "msRTCSIP-OptionFlags", 256 ' set this value to a bitmask representing which OCS features you want to enable/disable objuser.Put "msRTCSIP-PrimaryHomeServer", "FQDNOFSERVER" Objuser.Put "msRTCSIP-PrimaryUserAddress", "sip:" & mail objUser.put "msRTCSIP-UserEnabled", true objUser.put "msExchOmaAdminWirelessEnable", 7 objUser.Setinfo Msgbox "OCS and ActiveSync rights added",vbinformation,"OCS and ActiveSync Configuration" Else Msgbox "User OCS setup aborted", vbcritical, "OCS and ActiveSync Configuration" End If End Select End If wscript.quitWhat I believe was happening, and causing me to think it wasn't working, is that the query in here to fetch the FQDN of the user is pointed to a DC. However, the put and SetInfo statements do not necessarily set the attribute on that same DC, it's just the first DC that responds to the request. So I was checking on the defined DC, not seeing the attribute set and not understanding why it wasn't working. Only it was working, just a faster, better specced DC on a better connection was answering first and I didn't wait for the replication interval to see the change on the specified DC.
Do you agree this sounds likely?
- Edited by Marco (Australia) Thursday, March 07, 2013 6:19 AM missed a letter!
-
Thursday, March 07, 2013 6:12 AM
You cannot authenticate on AD from outside of a trust with VBScript or any other tools. AD must be set to allow this or it will not work.
¯\_(ツ)_/¯
-
Thursday, March 07, 2013 6:25 AM
You cannot authenticate on AD from outside of a trust with VBScript or any other tools. AD must be set to allow this or it will not work.
¯\_(ツ)_/¯
I'm not. I'm within the domain. With PowerShell you need to enable Remote Code Execution to run AD Cmdlets against DCs from another source. That's how I understand it anyway.

