Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Constraint Violation Occurred. 1

Status
Not open for further replies.

Brycspain

IS-IT--Management
Mar 9, 2006
150
US
I was wondering if someone could take a look at this script and tell me what could be causing a "Constraint Violation Occurred" error on the highlighted line towards the end of my script. The script halts on that line and gives off the following: (167, 3) (null): A constraint violation occurred.


Code:
Const ForReading = 1
sIOLocation = "C:\Scripts\"
sLogFile = sIOLocation & "IO.log"

Set oFSO = CreateObject("Scripting.FileSystemObject")
Set file = oFSO.OpenTextFile("c:\scripts\example.txt", ForReading )
set oLogOutput = oFSO.CreateTextFile(sLogFile)
oLogOutput.WriteLine Now & ": Log started"

Do While Not file.AtEndOfStream
    aStr = split(File.ReadLine,",")    
    sLogon = aStr(0)    
    sFirstName = aStr(1)    
    sMiddleInit = aStr(2)
    sLastName = aStr(3)
    strOU = dctOU( aStr(4) )
    sMailcluster = aStr(5)
    sStorageGroup = aStr(6)
    sMailStore = aStr(7)
    sSGCapacity = aStr(8)
    sDescription = aStr(9)
    sEmployeeID = aStr(10)
    sHomeFiler = aStr(11)
    sCopyUser = aStr(12)
    sAdminUser = aStr(13)
    sCompTech = aStr(14)
    sDisplayName = sFirstName & " " & sMiddleInit & ". " & sLastName

UsersAll = "OU=Users-ALL,"
Set oRootLDAP = GetObject("LDAP://rootDSE")
defaultNamingContext = (GetObject("LDAP://rootDSE")).Get("defaultNamingContext")
Set oContainer = GetObject("LDAP://" & strOU & usersAll & defaultNamingContext)

'put in to check if account already exists and if so, go to next record
On Error Resume Next
Set oNewUser = GetObject("LDAP://" & SearchDistinguishedName(sLogon))
If Err.Number = &H80005000 Then

' Build the User account
On Error GoTo 0
Set oNewUser = oContainer.Create("User","cn="& sFirstName & " " & sLastName)

oNewUser.put "sAMAccountName",lcase(sLogon)
oNewUser.put "givenName",lcase(sFirstName)
oNewUser.put "sn",lcase(sLastName)
oNewUser.put "UserPrincipalName",lcase(SLogon) & "@" & lcase(sLDAPdomain)
oNewUser.put "displayName",sDisplayName
oNewUser.put "name",sDisplayName
oNewUser.put "description",sDescription 
oNewUser.put "mail",sFirstName & "_" & sLastName
oNewUser.put "employeeID",sEmployeeID
oNewUser.put "homeDirectory", "\\" & sHomeFiler & "\" & sLogon
oNewUser.put "homeDrive", "Z:"
oNewUser.put "givenName",sFirstName
oNewUser.put "initials",sMiddleInit
oNewUser.put "name",sDisplayName

' Write this information into Active Directory so we can
' modify the password and enable the user account
oNewUser.SetInfo

'If it was successful, continue processing
	If err.number = 0 Then
	  oLogOutput.WriteLine Now & ": " & sLogon & ": Successfully created user account"
	
	  ' Change the users password and turn off requirement to change at next login
	  oNewUser.SetPassword "jkl;1234"
	  oNewUser.Put "pwdLastSet", 0
	 
	  ' Enable the user account
	  oNewUser.Put "userAccountControl", 512
	  oNewUser.SetInfo
	
	Else
	  oLogOutput.WriteLine Now & ": " & sLogon & ": Error creating account: " & err.number & err.description
	End If  
  
  ' If the password set and account enable was successful, indicate. Otherwise, write diagnostics.
	  If err.number = "0" Then
	    oLogOutput.WriteLine Now & ": " & sLogon & ": Successfully created user password and enabled account"
	  Else
	    oLogOutput.WriteLine Now & ": " & sLogon & ": Password or account enable error : " & err.number & err.description
	  End If

			sLDAPExchangeServer = "/o=mydomain"
			sLDAPExchangeServer = sLDAPExchangeServer & "/ou=First Administrative Group"
			sLDAPExchangeServer = sLDAPExchangeServer & "/cn=Configuration/cn=Servers"
			sLDAPExchangeServer = sLDAPExchangeServer & "/cn=" & sMailCuster
			
			
			sLDAPhomeMDB = "CN=" & sMailStore & ","
			sLDAPhomeMDB = sLDAPHomeMDB & "CN=" & sStorageGroup & " " & sMBCapacity & ","
			sLDAPhomeMDB = sLDAPhomeMDB & "CN=InformationStore,"
			sLDAPhomeMDB = sLDAPhomeMDB & "CN=" & sMailcluster & ","
			sLDAPhomeMDB = sLDAPhomeMDB & "CN=Servers,"
			sLDAPhomeMDB = sLDAPhomeMDB & "CN=First Administrative Group,"
			sLDAPhomeMDB = sLDAPhomeMDB & "CN=Administrative Groups,"
			sLDAPhomeMDB = sLDAPhomeMDB & "CN=SWN,"
			sLDAPhomeMDB = sLDAPhomeMDB & "CN=Microsoft Exchange,"
			sLDAPhomeMDB = sLDAPhomeMDB & "CN=Services,"
			sLDAPhomeMDB = sLDAPhomeMDB & "CN=Configuration,"
			sLDAPhomeMDB = sLDAPhomeMDB & "DC=mydomain,DC=com"

  ' Build and write the users Exchange attributes
  oNewUser.put "mDBUseDefaults", sLDAPmDBUseDefaults 
  oNewUser.put "mail", lcase(SLogon) & "@" & lcase(sLDAPdomain)
  oNewUser.put "msExchHomeServerName", sLDAPExchangeServer
  oNewUser.put "mailnickname", left(sFirstName, 1) & sLastName
  oNewUser.put "homeMDB", sLDAPHomeMDB
  oNewUser.put "extensionAttribute15", Left(sMailCluster,3)
  [b]oNewUser.SetInfo[/b]

If err.number = "0" Then
	    oLogOutput.WriteLine Now & ": " & sLogon & ": Successfully created user's Exchange attributes"
	  Else
	    oLogOutput.WriteLine Now & ": " & sLogon & ": Exchange attributes error : " & err.number & err.description
	  End If

Else
oLogOutput.WriteLine "Username " & sLogon & " already exists....proceeding to next record"
End If

Loop
  
Function SearchDistinguishedName( vSAN )            
	On Error Resume Next
	Dim oRootDSE, oConnection, oCommand, oRecordSet            
	defaultNamingContext = GetObject("LDAP://rootDSE").Get("defaultNamingContext")        
	Set oConnection = CreateObject("ADODB.Connection")        
	oConnection.Open "Provider=ADsDSOObject;"        
	'On Error GoTo 0
	Set oCommand = CreateObject("ADODB.Command")        
	oCommand.ActiveConnection = oConnection        
	oCommand.CommandText = "<LDAP://" & defaultNamingContext & ">;" _                            
	& "(&(objectCategory=User)" _                            
	& "(samAccountName=" & vSAN & "));" _                            
	& "distinguishedName;subtree"        
	Set oRecordSet = oCommand.Execute        
	' you must use a for/next here or you will get errors    
	' a recordset is always a collection    
	While Not oRecordSet.EOF        
	SearchDistinguishedName = oRecordSet.Fields("DistinguishedName")         
	oRecordset.MoveNext       
	Wend       
	oConnection.Close    
End Function

Also, I would like to populate the TerminalServicesProfilePath and found this snippet that MarkdMac posted a few months ago. Is this the only way to add this attribute to a user's profile? I'm running the script with admin credentials directly on the Win 2K3 domain controller.

Thanks

Code:
'Set DSO = GetObject("WinNT:")
'Set usr = DSO.OpenDSObject("WinNT://TSPServer/markmac,user", "DomainName\Administrator", "Password", ADS_SECURE_AUTHENTICATION)
'Wscript.echo usr.TerminalServicesProfilePath
'usr.TerminalServicesProfilePath = "\\servername\shareName"
'usr.SetInfo
'WScript.echo usr.TerminalServicesProfilePath
 
I would suggest you determine which line is causing the problem by adding some more setInfo lines after the put commands above where you are failing now. Once you have that isolated, try outputting the values you are trying to set and verify that they are as expected.



I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
Thanks Mark...took me 3 minutes to fix the problem. There was a second part to my question on the bottom of the post concerning a snippet you provide another user a few months back. Could you take a look and let me know what you think?

Thanks
 
Here is another way to do it.

Code:
UserDN= "LDAP://tspserver.thespidersparlor.local/CN=Test Dude,OU=Test OU,DC=thespidersparlor,DC=local"

Set objUser = GetObject(userDN)
objUser.TerminalServicesProfilePath = "\\servername\shareName"
objUser.SetInfo

This is a tricky property because ADSI does not expose this proeprty. Open up ADSIEdit and you will see that you can't configure this property in there.

So because of this you can't use the normal format of
objUser.Put attribute, value

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
Thanks for the quick response =)

I'm a bit confused on some of your syntax because we don't use a TS Profile server per se. We place all of our TS profiles on a DFS share.

The UNC for it would be:

\\mydomain.com\remotedata\mydomain-di\Test Dude

How would I phrase that on this line of the snippet?

Code:
UserDN= "LDAP://[b]tspserver.thespidersparlor.local[/b]/CN=Test Dude,OU=Test OU,DC=mydomain,DC=com"

 
Just set the UserDN to be the distinguishedName of the user. You can precede it with DC information as I have or remove that. Doesn't matter.

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
Mark, thanks again for all your help...one last question if you don't mind. This is from another part of my script that I omitted in my original post. I adapted this script you wrote and discovered that it won't run on my domain controllers. I get a permission denied error on the second line of the Sub (highlighted). Do you know what would cause that?

Code:
sLogon = "TestGroup1"
sCopyUser = "TestGroup2"

Const ADS_PROPERTY_APPEND = 3

Set oShell = CreateObject("Wscript.Shell")

forceUseCScript

Set sCopyUser = GetObject("LDAP://" & SearchDistinguishedName(sCopyUser))
sLogon = SearchDistinguishedName(sLogon)

For Each group In sCopyUser.Groups
    Set oGroup = GetObject("LDAP://" & group.distinguishedName)
    oGroup.PutEx ADS_PROPERTY_APPEND, "member", Array(sLogon)
    oGroup.SetInfo
    
    If Err.Number <> 0 And Err.Number <> -2147019886 Then
        oLogOutput.WriteLine oCopyUser & "'s groups couldn't be copied to " & sLogon & "'s"
        oLogOutput.WriteLine "Error Number: " & Err.Number & "Error Desc: " & Err.Description
    End If
Next


Sub forceUseCScript()
   If Not WScript.FullName = WScript.Path & "\cscript.exe" Then
    [b]  oShell.Run "cmd.exe" & WScript.Path & "\cscript.exe //NOLOGO " & Chr(34) & WScript.scriptFullName & Chr(34),1,False[/b]
      'WScript.Quit 0
   End If
End Sub 

Public Function SearchDistinguishedName(ByVal vSAN)
    ' Function:     SearchDistinguishedName
    ' Description:  Searches the DistinguishedName for a given SamAccountName
    ' Parameters:   ByVal vSAN - The SamAccountName to search
    ' Returns:      The DistinguishedName Name
    Dim oRootDSE, oConnection, oCommand, oRecordSet

    Set oRootDSE = GetObject("LDAP://rootDSE")
    Set oConnection = CreateObject("ADODB.Connection")
    oConnection.Open "Provider=ADsDSOObject;"
    Set oCommand = CreateObject("ADODB.Command")
    oCommand.ActiveConnection = oConnection
    oCommand.CommandText = "<LDAP://" & oRootDSE.get("defaultNamingContext") & _
        ">;(&(objectCategory=User)(samAccountName=" & vSAN & "));distinguishedName;subtree"
    Set oRecordSet = oCommand.Execute
    On Error Resume Next
    SearchDistinguishedName = oRecordSet.Fields("DistinguishedName")
    On Error GoTo 0
    oConnection.Close
    Set oRecordSet = Nothing
    Set oCommand = Nothing
    Set oConnection = Nothing
    Set oRootDSE = Nothing
End Function
 
Here is what I use:
Code:
Sub forceUseCScript()
   If Not WScript.FullName = WScript.Path & "\cscript.exe" Then
      oShell.Popup "Launched using wscript. Relaunching...",3,"WSCRIPT"
      oShell.Run "cmd.exe /k " & WScript.Path & "\cscript.exe //NOLOGO " & Chr(34) & WScript.scriptFullName & Chr(34),1,False
      WScript.Quit 0
   End If
End Sub

Looks like you are missing a space after CMD.EXE.

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
Mark,

You were right about the space and now it runs on DC's. Another problem I'm having is the script runs perfectly through 3 test users when I comment out the forceuseCScript sub. When I uncomment it, it screws up the script. Would there be any reason why this sub couldn't be included in a Do While Not loop to accomodate multiple users? I tried pausing the script after each instance of calling the sub but that didn't work.

For example: When I run the script without the sub I get the following output on my log file.

9/4/2007 3:27:06 PM: Log started
-2147463168 received after looking up Testone
Error -2147463168 received after looking up of Testone
9/4/2007 3:27:06 PM: Testone: Successfully created user account
9/4/2007 3:27:07 PM: Testone: Successfully created user password and enabled account
9/4/2007 3:27:07 PM: Testone: Successfully created user's Exchange attributes
Created home folder for Testone
Created root drive folder for Testone
-2147463168 received after looking up Testtwo
Error -2147463168 received after looking up of Testtwo
9/4/2007 3:27:07 PM: Testtwo: Successfully created user account
9/4/2007 3:27:07 PM: Testtwo: Successfully created user password and enabled account
9/4/2007 3:27:07 PM: Testtwo: Successfully created user's Exchange attributes
Created home folder for Testtwo
Created root drive folder for Testtwo
-2147463168 received after looking up Testthree
Error -2147463168 received after looking up of Testthree
9/4/2007 3:27:07 PM: Testthree: Successfully created user account
9/4/2007 3:27:07 PM: Testthree: Successfully created user password and enabled account
9/4/2007 3:27:07 PM: Testthree: Successfully created user's Exchange attributes
Created home folder for Testthree
Created root drive folder for Testthree
9/4/2007 3:27:07 PM: Input ended


When I include the sub I receive this output: (I changed the user names to testfour, testfive, and testsix to ensure there would be no residual testone, testtwo and testthree in any AD replication)

9/4/2007 3:31:47 PM: Log started
0 received after looking up Testfour
Username Testfour already exists....proceeding to next record
-2147463168 received after looking up Testfive
Error -2147463168 received after looking up of Testfive
9/4/2007 3:31:48 PM: Testfive: Successfully created user account
9/4/2007 3:31:48 PM: Testfive: Successfully created user password and enabled account
9/4/2007 3:31:48 PM: Testfive: Successfully created user's Exchange attributes


Why would the first name return a zero and the script then skips the last user? Also, I've turned off error handling but didn't include that below.


Here is the important part of the script:

Code:
[b]Do While Not file.AtEndOfStream[/b]
    aStr = split(File.ReadLine,",")    
    sLogon = aStr(0)    
    sFirstName = aStr(1)    
    sMiddleInit = aStr(2)
    sLastName = aStr(3)
    strOU = dctOU( aStr(4) )
    sMailcluster = aStr(5)
    sStorageGroup = aStr(6)
    sMailStore = aStr(7)
    sSGCapacity = aStr(8)
    sDescription = aStr(9)
    sEmployeeID = aStr(10)
    sHomeFiler = aStr(11)
    sCopyUser = aStr(12)
    sAdminUser = aStr(13)
    sCompTech = aStr(14)
    sDisplayName = sFirstName & " " & sMiddleInit & ". " & sLastName

		' check if account already exists and if so, go to next record
		On Error Resume Next
		Set oNewUser = GetObject("LDAP://" & SearchDistinguishedName(sLogon))
		oLogOutput.WriteLine Err.Number & " received after looking up " & sLogon
		[b]If Err.Number <> 0 Then[/b]
		oLogOutput.WriteLine "Error -2147463168 received after looking up of " & sLogon
		Err.clear
		' Build the User account
		On Error GoTo 0
		
		' Create a connection to the Active Directory Users container.
		Set oContainer = GetObject("LDAP://" & strOU & usersAll & defaultNamingContext)
		Set oNewUser = oContainer.Create("User","cn="& sFirstName & " " & sLastName)
		
		oNewUser.put "sAMAccountName",lcase(sLogon)
		[b](moreuserput stuff here...cut out to save space)[/b]
		
		' Write this information into Active Directory so we can
		' modify the password and enable the user account
		oNewUser.SetInfo

	    'If it was successful, continue processing
		If err.number = 0 Then
		  oLogOutput.WriteLine Now & ": " & sLogon & ": Successfully created user account"
		
		  ' Change the users password and turn off requirement to change at next login
		  oNewUser.SetPassword "jkl;1234"
		  oNewUser.Put "pwdLastSet", 0
		 
		  ' Enable the user account
		  oNewUser.Put "userAccountControl", 512
		  oNewUser.SetInfo

		Else
		oLogOutput.WriteLine Now & ": " & sLogon & ": Error creating account: " & err.number & err.description
		End If  
  
  ' If the password set and account enable was successful, indicate. Otherwise, write diagnostics.
	  If err.number = "0" Then
	    oLogOutput.WriteLine Now & ": " & sLogon & ": Successfully created user password and enabled account"
	  Else
	    oLogOutput.WriteLine Now & ": " & sLogon & ": Password or account enable error : " & err.number & err.description
	  End If

			sLDAPExchangeServer = "/o=SWN"
			[b](All the exchange attributes go here...cut out to shorten the script)[/b]
		    oNewUser.SetInfo
  
  
	      ' If the Exchange attributes were successful, indicate.  Otherwise, write diagnostics.
		  If err.number = 0 Then
		    oLogOutput.WriteLine Now & ": " & sLogon & ": Successfully created user's Exchange attributes"
		  Else
		    oLogOutput.WriteLine Now & ": " & sLogon & ": Exchange attributes error : " & err.number & err.description
		  End If


		' Copies user group membership from a similar user account and adds the new user to those groups
		userDN = SearchDistinguishedName(sLogon)    
		Set oUser = GetObject("LDAP://" & userDN)
		oUser.TerminalServicesProfilePath = sTermSvcP
		oUser.SetInfo
				
		Set oShell = CreateObject("Wscript.Shell")
		
		forceUseCScript
		'WScript.Sleep 2000
		
		Set nCopyUser = GetObject("LDAP://" & SearchDistinguishedName(sCopyUser))
		nLogon = SearchDistinguishedName(sLogon)
		
			For Each group In nCopyUser.Groups
			   Set oGroup = GetObject("LDAP://" & group.distinguishedName)
			   oGroup.PutEx ADS_PROPERTY_APPEND, "member", Array(nLogon)
			   oGroup.SetInfo
			    
			    If Err.Number <> 0 And Err.Number <> -2147019886 Then
			       oLogOutput.WriteLine sCopyUser & "'s groups couldn't be copied to " & sLogon & "'s"
			       oLogOutput.WriteLine "Error Number: " & Err.Number & "Error Desc: " & Err.Description
			    End If
			Next


GHomefolder = HomeFolder(sHomeFiler, sLogon, sLogOutput)
GRootFolder = RootFolder(sLogon, sHomeFiler, oLogOutput)

'GSendMail = SendMail(sAdminUser, sCompTech, sLogon, sFirstName, sLastname)

[b]Else
oLogOutput.WriteLine "Username " & sLogon & " already exists....proceeding to next record"
End If

' Move ahead to the next record
Loop[/b]

 
Mark,

I know you haven't been around the last week. I was able to bypass this problem by running the entire script in cscript and forgoing the use of the forceusecscript sub.

Thanks
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top