Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.
Keywords: Exchange 2000 AD ADSI msExchMailboxSecurityDescriptor
Anything you can tell me about this property would be helpful.
I have attempted to add the security descriptor: msExchMailboxSecurityDescriptor
After the program creates the user account, this property is found to be blank and I believe this is why I can't use the MMC to look at the mailbox rights. The program is my attempt to create a descriptor. Everything appears to work, but the dsSetProperty gives a 1062 error. I can find no error list for this extender. The message says: There was a constraint violation
// // MessageId: ERROR_SERVICE_NOT_ACTIVE // // MessageText: // // The service has not been started. // #define ERROR_SERVICE_NOT_ACTIVE 1062Lfor a list of error codes see...
http://msdn.microsoft.com/library/psdk/psdkref/errlist_9usz.htmWhen you stated that the copy failed do you mean that do you mean that the function return an error and if so, what error? Or do you mean that the copied SD could not be set on the object property? For the rest of the post I will assume the latter.
Copying security objects is the same no matter the security object type. As indicated in the help file, you pass any "security object" in and the function returns a copy. As with all other ADSI functions the underlying object must support the operations for the function to succeed. Also, copying a security object does not guarantee that it will work. A security object may only make sense on the directory object that has it as a property value.
That said, the Winbatch.ini file error indicates that you have the error "The security descriptor is invalid." This is a win32 error. When ever the ADSI extender encounters an error that is not documented, it checks to see if the OS understands what is going on. When ever the extender does this and the OS returns an error message, the extender prepends the text "ADSI error:" to the OS generated error message. If you set error mode to @CANCEL in your script, you will most likely see the error message "ADSI error: The security descriptor is invalid."
The question then becomes: what is invalid about your SD? I do not know the answer. SD's are very temperamental things and not always well documented by the vender. I suggest using the ADSI extender to get a valid SD for an Exchange 2000 mailbox and then dump all of its properties, including the ACLs and all the ACEs in the ACLs. This may give some hint to the problem. I have included a script at the bottom of this post that I use to dump the SD's of Exchange 5.5 mailboxes. It needs some modification to work with Exchange 2000 but it should give you a start.
Also, I will do a documents search and try to identify the unique needs of Ex2k security descriptors.
"SD Dump" script example:
; Mailbox path pre-defined variables required. sMailBoxPath = "LDAP://%server%/cn=%suserName%,cn=Recipients,OU=%Site%,O=""%Org%""" ; Get the security descriptor property. sd = dsgetProperty(sMailBoxPath, "NT-Security-Descriptor") ; Display all SD properties. ncontrol = dsGetSecProp(sd, "Control") message("Control", ncontrol) nRevision = dsGetSecProp(sd, "Revision") message("Revision",nRevision) Owner = dsGetSecProp(sd, "owner") message("Owner", owner) Ownerdefaulted = dsGetSecProp(sd, "OwnerDefaulted") message("Ownerdefaulted ", Ownerdefaulted ) Group = dsGetSecProp(sd, "Group") message("Group ", Group ) Groupdefaulted = dsGetSecProp(sd, "GroupDefaulted") message("Groupdefaulted ", Groupdefaulted ) Dacldefaulted = dsGetSecProp(sd, "DaclDefaulted") message("Dacldefaulted ", Dacldefaulted ) SaclDefaulted = dsGetSecProp(sd, "SaclDefaulted") message("SaclDefaulted ", SaclDefaulted ) dacl = dsGetSecProp(sd, "DiscretionaryAcl") ACLRevision = dsGetSecProp(dacl, "ACLRevision") ; ACL propreties message("ACLRevision",ACLRevision) AceCount = dsGetSecProp(dacl, "AceCount") message("AceCount",AceCount) ;Step through each ACE ; This is really tedious if you have a lot of them. ACES = dsACLGetAces(dacl, 3) nCount = ItemCount( ACES, @TAB) for i=1 to nCount ace = ItemExtract(i, ACES, @Tab) ; Display the ACE's properties. AccessMask = dsGetSecProp(ace, "AccessMask") message("AccessMask",AccessMask) AceType = dsGetSecProp(ace, "AceType") message("AceType",AceType) AceFlags = dsGetSecProp(ace, "AceFlags") message("AceFlags",AceFlags) Flags = dsGetSecProp(ace, "Flags") message("Flags",Flags) ObjectType = dsGetSecProp(ace, "ObjectType") message("ObjectType",ObjectType) InheritedObjectType = dsGetSecProp(ace, "InheritedObjectType") message("InheritedObjectType",InheritedObjectType) Trustee = dsGetSecProp(ace, "Trustee") message("Trustee",Trustee) next
You said the winbatch.ini shows an invalid Security Descriptor. I saw only a message about a constraint. Are these one in the same?
The scripts in the help file work for Exchange 5.5 and Win2k but are not written to work with Exchange 2000. In theory to create a mailbox for Ex2k you will need to create a Win2k user with ADSI and then associate the user with a mailbox using CDO as I mentioned in the previous post. I have not tried this so I am not familiar with all the gory details.
I have some good news and some bad news.
First the bad news:
According to MS you can not create a mailbox with ADSI on Exchange 2000. This means you can not use
the ADSI extender to create the mailbox either. You can create a user but you can not create the Exchange
mailbox for the user. You need to use the CDO function "CreateMailBox" to create the mailbox.
The good news: Winbatch's ole functions support CDO objects and the "CreateMailBox" method. You may want to search the tech support database http://techsupt.winbatch.com for CDO examples.
I have not tried it so it would be interesting to hear how it works.
So you have to use OLE/CDO. It cannot be done with ADSI alone.
Function ADSICreateMailBoxRecipient(ServerName As String, _ DomainName As String, _ emailname As String, _ FirstName As String, _ LastName As String) As Integer 'ServerName is something like "MyServer6" 'DomainName is something like "DC=MYDOMAIN3,DC=microsoft,DC=com" 'emailname is something like "jamessmith" 'this assumes the MDB to be "Private MDB" Dim objUser As IADsUser Dim objContainer As IADsContainer Dim objMailbox As CDOEXM.IMailboxStore Dim recipname As String, recip As String recip = "CN=" & emailname ' get the container Set objContainer = GetObject("LDAP://" + ServerName + "/" + _ "CN=users," + DomainName) ' create a recipient Set objUser = objContainer.Create("User", recip) objUser.Put "samAccountName", emailname objUser.Put "sn", LastName objUser.Put "givenName", FirstName objUser.Put "userPrincipalName", emailname objUser.SetInfo objUser.SetPassword "password" 'let user change it later objUser.AccountDisabled = False Set objMailbox = objUser 'Create a mailbox for the recipient 'You cannot create a mailbox using ADSI, so use CDOEXM objMailbox.CreateMailbox "LDAP://" + ServerName + _ "/CN=Private MDB" + _ ",CN=First Storage Group,CN=InformationStore,CN=" + _ ServerName + _ ",CN=Servers,CN=First Administrative Group," + _ "CN=Administrative Groups,CN=First Organization," + _ "CN=Microsoft Exchange,CN=Services," + _ "CN=Configuration," + DomainName objUser.SetInfo End FunctionHere's the URL:
"http://msdn.microsoft.com/library/psdk/exchsv2k/_cdo_imailboxstore_createmailbox.htmI know the ojbMailBox.createmailbox refers to an object/method contained within CDOEXM.DLL. CDOEXM is Collaborative Data Objects for Exchange Management and is installed on all Exchange 2000 servers under the Exchsrv\bin dir. I have no idea how to get Winbatch to make this call, but I will start trying to understand objects and go from there.
I am trying to use the IMailStore method in the CDOEXM.DLL to create a mailbox for an AD user that already exists. I know little about objects, so this may be a dumb question - How does winbatch access a method in a DLL? The VB sample code shows a "DIM var as CDOEXM.IMailboxstore". This seems to be where the link to the CDOEXM object is made.
The CDOEXM DLL is registered on the server on which my code is executing. An Object viewer tool I found lists this method and interface as being present on the system. It seems I am only lacking how to open this object by name. I tried:
objmailbox=Objectopen("CDOEXM.IMailboxstore") ObjMailbox.createmailbox(xxx)and the objectopen() failed to initiate.
So, is there a way to access this method without using IADS objects first?
THIS REPORTED SOMETIME LATER...
I was able to open the CDO.Person object, open a particlar user account and read properties:
UserPath = "LDAP://cn=%displayname%,cn=users,%domain%" objperson=objectopen("CDO.Person") OPdatasource=objperson.datasource opdatasource.open(userpath) thisfn=objperson.firstname thisln=objperson.lastnameWhere userpath is the same LDAP url value used for with the ASDI extender calls.
I'm still very unclear about the object-interface-method naming convention. I can't find any documentation of the COM objects to tell me where objperson.datasource.open() comes from. The "Open" method under CDO.Person object is found under the IDatasource interface. This implies you drop the "I" and use the interface name when accessing an object. That means to access the createmailbox method under the IMailboxStore interface you'd do the following:
opMB=objperson.mailboxstore opMB.createmailbox=(xxx)but the first line fails with a OLE bad name error. That means to me the naming convention we spoke about doesn't apply. I tried various object names and got the same error - bad name. My COM Object Viewer showed createmailbox as a method under IMailboxStore interface under the CDO.Person object, but that is the only indicator that the MS object is CDO.Person.mailboxstore.createmailbox or CDO.person.IMailboxstore.createmailbox.
I have found no sample code other than what we have here.
Here's one more url that says the IMailboxStore interface is under the cdo.person object, but there's no examples of syntax:
http://msdn.microsoft.com/library/psdk/exchsv2k/_cdoex_cdo_for_exchange_2000_server.htmI'll ask my buddy about the syntax for these objects and about that set command where the mailbox object is set to the person object.
FirstName="First Name" LastName="Last Name" LoginName="login" objPerson = ObjectOpen("CDO.Person") objPerson.FirstName=FirstName objPerson.LastName=LastName objPersonFields = objPerson.Fields objPersonFields("mailNickname")= LoginName objPersonFields("userPrincipalName")= LoginName objPersonFields("userAccountControl")= 512 objPersonFields("userPassword")= LoginName objPersonFields("samAccountName")= LoginName objPersonFields.Update objPersonDS = objPerson.DataSource objPersonDS.SaveTo(strcat("LDAP://exchange2000/cn",FirstName," ",LastName,",oubizOA Evaluation Accounts,dcbizoa,dccom") objMailbox=objPerson.GetInterface("IMailboxStore") str1 = "LDAP://EXCHANGE2000/CNMailbox Store(EXCHANGE2000),CNLocal HDD(36GB),CNInformationStore,CNEXCHANGE2000" str2 = ",CNServers,CNbizOA Administrative Group,CNministrative Groups,CNMediaSolv,CNMicrosoftExchange,CNServices," str3 = "CNConfiguration,DCbizoa,DCcom" LDAPstuff = strCat(str1,str2,str3) objMailbox.CreateMailbox(LDAPstuff) str1 = "LDAP://EXCHANGE2000/CNMailbox Store(EXCHANGE2000),CNFirst StorageGroup," str2 = "CNInformationStore,CNEXCHANGE2000,CNServers,CNFirst AdministrativeGroup,CNministrative Groups" str3 = ",CNMediaSolv,CNMicrosoft Exchange,CNServices,CNConfiguration,DCbizoa,DCcom" LDAPstuff = strCat(str1,str2,str3) objMailbox.CreateMailbox(LDAPstuff) objPersonDS.SaveThe line - "objMailbox=objPerson.GetInterface("IMailboxStore")" does work. I have tried it on our local E2k machine. The return value is the mailbox interface with the desired "CreateMailbox" method. MS is a bit unclear on when you can use the "dot" notation instead of the "GetInterface" method to obtain a different interface on an object. All in all, however, the CDO COM server has a much, much cleaner design than the ADSI COM design. They at least try to preserve the interfaces idea in the scripting context with CDO.
Anyway, I have not been able to create a mailbox locally yet. I use the ADSI extender to create a user then use WinBatch's Createobject to create a person. I attach my ADSI extender to the persion object and get the IMailbox interface but the Createmailbox method fails. It appears I do not have the correct common names in the passed in URL.
Grrrrr.
Thank you all! Here the code that I works:
After using the ADSI extender to create the user and set all properties, the following is executed, the "open" accesses the user account (userpath is the same values used in the ADSI extender to create the user account.
objperson=objectopen("CDO.Person") OPdatasource=objperson.datasource opdatasource.open(userpath) thisfn=objperson.firstname thisln=objperson.lastname objMailbox=objPerson.GetInterface("IMailboxStore") homeMDB="CN=Mailbox Store (%homeserver%),CN=First Storage Group,CN=InformationStore,CN=%homeserver%,CN=Servers,CN=First Administrative Group,CN=Administrative Groups,CN=%subdom%,CN=Microsoft Exchange,CN=Services,CN=Configuration,%domain%" objmailbox.CreateMailbox(homemdb)HomeMDB was taken from an account & mailbox made with the MMC on my domain. I suggest you'll need to do the same to get it to work on your side. I have no clue where the "getinterface" came from, but I'll take it. Be aware that it is my experience that the mailbox does not show up in the mmc until an e-mail is sent to it - so you may have already created mailboxes successfully.
I know this isworking because I can now access the security discriptor under the "Mailbox Rights" button. Note also that this descriptor does not have the same ACL as when it is made by the MMC wizard, but I'll start work on that next. Once this is done as we can make an account that looks just like one made by the MMC wizard, you might want to more completely document it so that others will be able to use it without much effort.
When the MMC new user wizard is run to create an account and mailbox - SELF is the only ACE and it has the Full Mailbox right and read permissions right. When the user logs on for the first time, this ACL gains all the inherited permission seen when the mailbox is created programmatically.
The Good News:
A user can log on and use e-mail with the account in this condition. I only wonder why it is this way and
what harm it is to create thousands of accounts like this.
It seems that with the ADSI extender one should be able to set this security descriptor however one wants - and clean this mess up left by defaults. The problem is I haven't been able to do this. I had assumed the User Account property msExchMailboxSecurityDescriptor housed this ACL (sounds like it should), but it doesn't seem to work that way.
More Info:
Prior to using the MMC to access mailbox rights, the user property msExchMailboxSecurityDescriptor has
no value. After doing so, it has a value. It seems this value is applied by the Recpients Update Service. A
technet article states that the Mailbox Security Descriptor is not created until the user logs into the mailbox
or the mailbox receives mail. See:
http://support.microsoft.com/support/kb/articles/q272/1/53.aspUsing the ADSI extender, I found that the msExchmailboxSecurityDescriptor had no value until after the user logged into mail (sending e-mail showed up in the mailbox, but there was still no value in msExhcMailboxSecurityDescriptor) or I pulled up the Mailbox Rights ACL (this worked only after a time had passed after creating the account & mailbox).
It seems the msExchMailboxSecurityDescriptor property is not actually the security Descriptor the MMC sets under Mailbox Rights. I believe this because When I use the MMC to change an ACE (e.g. the Self ACE), the msExchMaiboxSecurityDescriptor show the change made (checking one box results in a one bit change in the AccesssControl security property for that ACE). Unfortunately, when one makes the same or any change to this property programmatically, it does not show up under the MMC mailbox rights button, but it does show up when the property is re-queried programmatically. So, I conclude the MMC or some other agent is updating the msExchMailboxSecurityDescriptor property, but there must be some other security descriptor that is the source for this.
It could be that the mailbox is actually a separate object from the user and the Security Descriptor seen under the MMC are ACLs for the mailbox itself - perhaps the NTsecuritydescriptor property. I have looked all over for the mailbox object path but have had no luck.
Does anyone know if a mailbox is a separate object and if so, where it is in the directory?
More to the point, does anyone have a clue where the Mailbox Rights ACL seen in the MMC is actually stored. If we can't set this ACL programmatically, it will be difficult to create Win2K/Exchange2K accounts in Winbatch.
Thanks again for all the help.
I don't know what subcontainers can exist under a User Account Object or Mailbox (if it's a separate object), but my test have shown everything works fine from the desktop.
I'll test everything more thoroughly and let you know if we go ahead with this as-is. It still makes no sense that I can't edit that ACL. There are 30 examples showing how to do that in Exchange 5.5, so we'll have to be able to modify eventually.
PS - It's a real bear when you can't believe what you see in an ACL w/o going to the Advanced button. I believe I've seen the same nasty behavior in NTFS file security. Ain't Win2K wonderful?
A few caviats:
;generic debug setting progname=itemextract(1,winexename(""),".") gosub dbgchk gosub constants addextender("WWADS34I.DLL") addextender("wwwnt34i.dll") AddExtender("wwwsk34i.dll ") IntControl( 52, 0, 0, 0, 0 ) types="User Templates (*.usr)|*.usr|Text Files (*.txt)|*.txt|All Files (*.*)|*.*|" ACCESS_ALLOWED = 0 ; AceType GENERIC_ALL = 268435456 ; AccessMask currentdir = dirget() ;load default user template filename=strcat(currentdir,"default.usr") gosub loadtemplate while @true gosub getinfo ; Define some constants. MANDATORY = 1 OPTIONAL = 2 MANANDOPT = 3 sAdsiPath = "LDAP://rootDSE" sValue = dsGetProperty(sAdsiPath , "defaultNamingContext") sDomainDNS = "LDAP://%sValue%" domain = dsGetProperty("LDAP://rootDSE" , "defaultNamingContext") UsersPath = "LDAP://cn=users,%domain%" xxx=itemextract(1,domain,",") xxx=itemextract(2,xxx,"=") yyy=itemextract(2,domain,",") yyy=itemextract(2,yyy,"=") subdom=xxx dnsdomain1=strcat(xxx,".",yyy) dnsdomain2=strcat(xxx,".com") if MI <> "" if strsub(MI,strlen(MI),1) == "." displayname=strcat(FirstName," ",MI," ",LastName) else displayname=strcat(FirstName," ",MI,". ",LastName) endif else displayname=strcat(FirstName," ", LastName) endif displayname=strtrim(displayname) username=strlower(strtrim(strfixchars(strcat(strsub(firstname,1,1),lastname)," ",15))) ; Memberof="CN=Home_%homeserver%_G,CN=Users,DC=tc1,DC=priv" ; List all objects in the user container of the default domain. ;lValues = dsGetChldPath(UsersPath, "") ;message("Object in Users", lValues) ; Create a user in the default user container on a ; Windows 2000 server with Active directory. ; Create a new user object sObjectClass = "user" while @true UserPath = "LDAP://cn=%displayname%,cn=users,%domain%" err=dsIsObject(UserPath) if err==1 newname = askline("User Name Already Exists","User %displayname% already exists. Please enter a new Full Name for this user account.", displayname) if newname <> "" displayname= newname endif else break endif endwhile while @true err=dsFindPath(UsersPath,"SamAccountName=%username%") if err<>"" newname = askline("User Name Already Exists","User %Username% already exists. Please enter a new User Name for this user account.", username) if newname <> "" username= newname endif else break endif endwhile profilepath=strcat("\\",homeserver,"\profiles$\",username) sObjectPath = dsCreateObj(UsersPath, sObjectClass, strcat("cn=",displayname)) mail=strcat(username,"@",dnsdomain2) mailnickname=username ; ; Set the mandatory property. dsSetProperty(sObjectPath, "samAccountName", username) ;set optional properties dsSetProperty(sObjectPath, "c", "US") dsSetProperty(sObjectPath, "co", "United States") if companyname <> "" then dsSetProperty(sObjectPath, "company", CompanyName) dsSetProperty(sObjectPath, "CountryCode", "840" ) if department <> "" then dsSetProperty(sObjectPath, "Department", department) if description <> "" then dsSetProperty(sObjectPath, "description", description) if displayname <> "" then dsSetProperty(sObjectPath, "displayname", displayname) if faxnumber <> "" then dsSetProperty(sObjectPath, "FacsimileTelephoneNumber", faxnumber ) if firstname <> "" then dsSetProperty(sObjectPath, "givenname", FirstName ) if homephone <> "" then dsSetProperty(sObjectPath, "HomePhone", homephone) if MI <> "" then dsSetProperty(sObjectPath, "initials", MI) if city <> "" then dsSetProperty(sObjectPath, "L", city) ;dsSetProperty(sObjectPath, "MemberOf", memberof) if mobilephone <> "" then dsSetProperty(sObjectPath, "Mobile", mobilephone) if PagerNumber <> "" then dsSetProperty(sObjectPath, "Pager", pagernumber) if zipcode <> "" then dsSetProperty(sObjectPath, "PostalCode", ZipCode) if profilepath <> "" then dsSetProperty(sObjectPath, "profilepath", profilepath) if logonscript <> "" then dsSetProperty(sObjectPath, "scriptpath", logonscript) if lastname <> "" then dsSetProperty(sObjectPath, "SN", lastname) if state <> "" then dsSetProperty(sObjectPath, "ST", State) if address <> "" then dsSetProperty(sObjectPath, "StreetAddress", Address) if workphone <> "" then dsSetProperty(sObjectPath, "TelephoneNumber", WorkPhone) if mail <> "" then dsSetProperty(sObjectPath, "userprincipalname", mail) ;e-mail properties: homeMDB="CN=Mailbox Store (%homeserver%),CN=First Storage Group,CN=InformationStore,CN=%homeserver%,CN=Servers,CN=First Administrative Group,CN=Administrative Groups,CN=%subdom%,CN=Microsoft Exchange,CN=Services,CN=Configuration,%domain%" homeMTA="CN=Microsoft MTA,CN=%homeserver%,CN=Servers,CN=First Administrative Group,CN=Administrative Groups,CN=%subdom%,CN=Microsoft Exchange,CN=Services,CN=Configuration,%domain%" LegacyExchangeDN="/o=%subdom%/ou=First Administrative Group/cn=Recipients/cn=%username%" msExchHomeServerName="/o=%subdom%/ou=First Administrative Group/cn=Configuration/cn=Servers/cn=%homeserver%" mdbUseDefaults="1" if mail <> "" then dsSetProperty(sObjectPath, "mail",mail) if mailnickname <> "" then dsSetProperty(sObjectPath, "MailNickName", MailNickName) if homeMDB <> "" then dsSetProperty(sObjectPath, "homemdb", homemdb) if homeMTA <> "" then dsSetProperty(sObjectPath, "homemta", homemta) if legacyExchangeDN <> "" then dsSetProperty(sObjectPath, "legacyexchangedn", legacyexchangedn) if msExchHomeServerName <> "" then dsSetProperty(sObjectPath, "msExchHomeServerName", msExchHomeServerName) if mdbUseDefaults <> "" then dsSetProperty(sObjectPath, "mdbUseDefaults",mdbUseDefaults) ; Now, commit the object to the DS dsSetObj(sObjectPath) ;password may not be accepted by domain errormode(@off) While @true lasterror() dsSetPassword(sObjectPath, "", password) if lasterror() == 1026 gosub fixpwd else break endif endwhile errormode(@notify) ;can't enable the account until the password is set dsSetProperty(sObjectPath, "UserAccountControl", "512") dsSetProperty(sObjectPath, "msExchUserAccountControl","0") debugtrace(1,"%progname%.log") ; now switch to CDO COM object to create the mailbox ; Open the CDO.Person object and go to the account just created objperson=objectopen("CDO.Person") OPdatasource=objperson.datasource opdatasource.open(userpath) thisfn=objperson.firstname ; unnecessary, but it shows you are on the correct user account thisln=objperson.lastname ;don't know where the getinterface method came from or why we need to call it, but it works objMailbox=objPerson.GetInterface("IMailboxStore") ;Use the same homeMDB used when creating the account objmailbox.CreateMailbox(homemdb) ;no need to call the save method, we changed nothing, so just close the object objectclose(objperson) ; give the e-mail server a chance to create the mailbox - come back to this later ;Now add group membership: groupname = "Home_%homeserver%_G" grouppath = "LDAP://cn=%groupname%,cn=users,%domain%" dsAddtoGrp(GroupPath, UserPath) ;Make home dir err=dirmake("\\%homeserver%\home$\%username%") ;make required dirs err=dirmake("\\%homeserver%\home$\%username%\My Documents") err=dirmake("\\%homeserver%\home$\%username%\Application Data") ;Make profile dir err=dirmake("\\%homeserver%\profiles$\%username%") ;Boxopen("Checking For Server Synchronization","") errormode(@off) ;wait for the user to show up at the server ;this may be unnecessary if the server is a Win2K DC ;but can be needed if homeserver is not the DC changes are ;being made on - AD can take a few secs to replicate t=0 tm = 15 ;secs x = 0 while t==0 groups=wntMemberGrps("\\%homeserver%",username,@GLOBALGROUP,0) err=lasterror() if err == 562 x=x+(tm/60.0) ;min ;boxtext("Waiting for %param2% account%@CRLF%to appear on %param1%%@crlf%Time waited So Far: %x% min") timedelay(tm) else t=1 endif endwhile ;boxshut() errormode(@notify) ; Homeserver knows about the new user account, so we can now set ACLS err=wntAccessAdd(homeserver, "\\%homeserver%\home$\%username%", username, 303, "Win2000:Modify") err=wntAccessAdd(homeserver, "\\%homeserver%\profiles$\%username%", username, 303, "Win2000:Modify") ; send a message to this mailbox to make sure it gets created now, and to create the ACL ; Messages sent to this account immediately after account creation seem to fail. ; shell hidden program to send mail in 3 minutes ; I choose SMTP so I need no e-mail client. This program will be run from the e-mail server. ; Server must be able to accept SMPT messages from internal addresses. ; Server must be able to resolve the from address (in most cases) ; could use MAPI, POSTIE or SMTP. ; param1 = full server name ; param2 = users Internet e-mail address ; param3 = delay time tm = timeymdhms() x=strcat(homeserver,".",dnsdomain1) y=mail err=runshell("emailwelcome.exe","%x% %mail% 180","",@hidden,@nowait) department="" description="" FirstName="" LAstName="" MI="" workphone="" pagernumber="" faxnumber="" homephone="" mobilephone="" pw_password="" password="" pw_confirm="" confirm="" Title="" endwhile ; exit ;=================================================================== :getinfo MyDialogFormat=`WWWDLGED,5.0` MyDialogCaption=`UnaVia New User` MyDialogX=187 MyDialogY=109 MyDialogWidth=359 MyDialogHeight=230 MyDialogNumControls=47 MyDialog01=`130,0,92,DEFAULT,STATICTEXT,DEFAULT,"Create a New User Account"` MyDialog02=`14,20,40,DEFAULT,STATICTEXT,DEFAULT,"First Name:"` MyDialog03=`8,32,46,DEFAULT,STATICTEXT,DEFAULT,"Middle Initial:"` MyDialog04=`14,44,40,DEFAULT,STATICTEXT,DEFAULT,"Last Name:"` MyDialog05=`6,56,48,DEFAULT,STATICTEXT,DEFAULT,"Home Server:"` MyDialog06=`8,68,46,DEFAULT,STATICTEXT,DEFAULT,"Logon Script:"` MyDialog07=`10,80,44,DEFAULT,STATICTEXT,DEFAULT,"Work Phone:"` MyDialog08=`8,128,46,DEFAULT,STATICTEXT,DEFAULT,"Home Phone:"` MyDialog09=`4,92,50,DEFAULT,STATICTEXT,DEFAULT,"Pager Number:"` MyDialog10=`12,140,42,DEFAULT,STATICTEXT,DEFAULT,"Department:"` MyDialog11=`10,116,44,DEFAULT,STATICTEXT,DEFAULT,"FAX Number:"` MyDialog12=`6,104,48,DEFAULT,STATICTEXT,DEFAULT,"Mobile Phone:"` MyDialog13=`12,152,42,DEFAULT,STATICTEXT,DEFAULT,"Description:"` MyDialog14=`22,164,36,DEFAULT,STATICTEXT,DEFAULT,"Address:"` MyDialog15=`36,176,36,DEFAULT,STATICTEXT,DEFAULT,"City:"` MyDialog16=`34,188,36,DEFAULT,STATICTEXT,DEFAULT,"State:"` MyDialog17=`22,200,36,DEFAULT,STATICTEXT,DEFAULT,"Zip Code:"` MyDialog18=`56,18,134,DEFAULT,EDITBOX,FirstName,"FirstName"` MyDialog19=`56,30,36,DEFAULT,EDITBOX,MI,"MI"` MyDialog20=`56,42,134,DEFAULT,EDITBOX,LastName,"LastName"` MyDialog21=`200,30,134,DEFAULT,EDITBOX,PW_password,""` MyDialog22=`200,54,134,DEFAULT,EDITBOX,PW_Confirm,""` MyDialog23=`56,54,134,DEFAULT,EDITBOX,HomeServer,"HomeServer"` MyDialog24=`56,66,134,DEFAULT,EDITBOX,logonscript,"LogonScript"` MyDialog25=`56,78,134,DEFAULT,EDITBOX,WorkPhone,"WorkPhone"` MyDialog27=`56,90,134,DEFAULT,EDITBOX,Pagernumber,"PagerNumber"` MyDialog28=`56,102,134,DEFAULT,EDITBOX,MobilePhone,"MobilePhone"` MyDialog29=`56,114,134,DEFAULT,EDITBOX,FAXNumber,"FAXNumber"` MyDialog30=`56,126,134,DEFAULT,EDITBOX,HomePhone,"HomePhone"` MyDialog31=`56,138,134,DEFAULT,EDITBOX,Department,"Department"` MyDialog32=`56,150,134,DEFAULT,EDITBOX,Description,"Description"` MyDialog33=`56,162,134,DEFAULT,EDITBOX,Address,"Address"` MyDialog35=`56,174,134,DEFAULT,EDITBOX,City,"City"` MyDialog36=`56,186,36,DEFAULT,EDITBOX,State,"State"` MyDialog37=`56,198,134,DEFAULT,EDITBOX,ZipCode,"ZipCode"` MyDialog38=`56,210,134,DEFAULT,EDITBOX,CompanyName,"Company Name"` MyDialog39=`196,192,74,DEFAULT,PUSHBUTTON,DEFAULT,"&Create Account",1` MyDialog40=`278,192,74,DEFAULT,PUSHBUTTON,DEFAULT,"&Load Template",2` MyDialog41=`278,210,74,DEFAULT,PUSHBUTTON,DEFAULT,"&Save Template",3` MyDialog42=`196,210,74,DEFAULT,PUSHBUTTON,DEFAULT,"Ca&ncel",4` MyDialog43=`20,212,36,DEFAULT,STATICTEXT,DEFAULT,"Company:"` MyDialog44=`202,18,36,DEFAULT,STATICTEXT,DEFAULT,"Password:"` MyDialog45=`202,42,36,DEFAULT,STATICTEXT,DEFAULT,"Confirm:"` MyDialog46=`202,66,36,DEFAULT,STATICTEXT,DEFAULT,"Title:"` MyDialog26=`200,78,134,DEFAULT,EDITBOX,Title,"Title"` MyDialog47=`202,150,36,DEFAULT,STATICTEXT,DEFAULT,"P.O. Box:"` MyDialog34=`200,162,136,DEFAULT,EDITBOX,POBOX,"POBox"` ButtonPushed=Dialog("MyDialog") select buttonpushed case 1 password = pw_password confirm = pw_confirm if password <> confirm message("Password error","Password Not Confirmed. Please re-enter password and confirm.") break endif return case 2 filename=AskFileName("Load User Template", currentdir, types, "Default.usr", 1) if filename == "" then break password = "" confirm = "" gosub loadtemplate break case 3 gosub savetemplate break case 4 exit endselect goto getinfo ;=================================================================== :dbgchk if fileexist("%progname%.dbg") debugtrace(1,"%progname%.log") else debugtrace(0,"%progname%.log") endif return ;==================================================================== :loadtemplate if fileexist(filename) hndl=fileopen(filename,"read") while @true xxx=fileread(hndl) if xxx == "*EOF*" then break ;line in file is of form propname = "value" %xxx% endwhile err=fileclose(hndl) endif return ;==================================================================== :savetemplate filename=AskFileName("Save User Template", currentdir, types, "Default.usr", 0) if filename == "" then return hndl=fileopen(filename,"Write") err=filewrite(hndl,'firstname = "%firstname%"') err=filewrite(hndl,'MI = "%mi%"') err=filewrite(hndl,'lastname = "%lastname%"') err=filewrite(hndl,'homeserver = "%homeserver%"') err=filewrite(hndl,'logonscript = "%logonscript%"') err=filewrite(hndl,'workphone = "%workphone%"') err=filewrite(hndl,'pagernumber = "%pagernumber%"') err=filewrite(hndl,'mobilephone = "%mobilephone%"') err=filewrite(hndl,'faxnumber = "%faxnumber%"') err=filewrite(hndl,'HomePhone = "%HomePhone%"') err=filewrite(hndl,'Department = "%Department%"') err=filewrite(hndl,'Description = "%description%"') err=filewrite(hndl,'Address = "%address%"') err=filewrite(hndl,'city = "%city%"') err=filewrite(hndl,'State = "%state%"') err=filewrite(hndl,'zipcode = "%zipcode%"') err=filewrite(hndl,'Companyname = "%companyname%"') err=filewrite(hndl,'title = "%title%"') err=filewrite(hndl,'POBox = "%pobox%"') ;err=filewrite(hndl,' = "%%"') err=fileclose(hndl) return ;==================================================================== :fixpwd while @true MyDialogFormat=`WWWDLGED,5.0` MyDialogCaption=`Password Does Not Pass Minimum Requirements` MyDialogX=89 MyDialogY=115 MyDialogWidth=293 MyDialogHeight=110 MyDialogNumControls=9 MyDialog01=`12,8,174,DEFAULT,STATICTEXT,DEFAULT,"The password you entered did not pass the minimum"` MyDialog02=`186,8,100,DEFAULT,STATICTEXT,DEFAULT,"requirements for this domain."` MyDialog03=`12,20,184,DEFAULT,STATICTEXT,DEFAULT,"The password may be too short or not complex enough."` MyDialog04=`12,32,142,DEFAULT,STATICTEXT,DEFAULT,"Please Enter a new password and confirm:"` MyDialog05=`12,48,38,DEFAULT,STATICTEXT,DEFAULT,"Password:"` MyDialog06=`12,60,132,DEFAULT,EDITBOX,pw_password,""` MyDialog07=`12,76,36,DEFAULT,STATICTEXT,DEFAULT,"Confirm:"` MyDialog08=`12,88,132,DEFAULT,EDITBOX,pw_confirm,""` MyDialog09=`210,88,64,DEFAULT,PUSHBUTTON,DEFAULT,"&OK",1` ButtonPushed=Dialog("MyDialog") password = pw_password confirm = pw_confirm if password <> confirm message("Password error","Password Not Confirmed. Please re-enter password and confirm.") continue endif break endwhile return ;===================================================================================== :Constants ; This file contains a list of constants commonly used with the ADSI extender. ; Meaning of bits in userFlags properties of a WinNT: and the userAccountControl property of a LDAP: namespaces' user object. ; Operating System = Windows NT 4.0 / Windows 2000 ; Namespace = WinNT, LDAP ; object class = user ; properties = userFlags (WinNT), userAccountControl (LDAP on Windows 2000) ; The following used with both userFlags and userAccountControl UF_SCRIPT = 1 ; The logon script will be executed. UF_ACCOUNTDISABLE = 2 ; The user's account is disabled. UF_HOMEDIR_REQUIRED = 8 ; The home directory is required. UF_LOCKOUT = 16 ; The account is currently locked out. UF_PASSWD_NOTREQD = 32 ; No password is required. UF_PASSWD_CANT_CHANGE = 64 ; The user cannot change the password. You can read this flag ; but you cannot set it directly. UF_DONT_EXPIRE_PASSWD = 65536 ; The password, which should never expire on the account. UF_TEMP_DUPLICATE_ACCOUNT = 256 ; This is an account for users whose primary account is in another domain. ; This account provides user access to this domain, but not to any domain ; that trusts this domain. Sometimes it is referred to as a local user account. UF_NORMAL_ACCOUNT = 512 ; This is a default account type that represents a typical user. UF_INTERDOMAIN_TRUST_ACCOUNT = 2048 ; This is a permit to trust account for a system domain that trusts other domains. UF_WORKSTATION_TRUST_ACCOUNT = 4096 ; This is a computer account that is a member of this domain. UF_SERVER_TRUST_ACCOUNT = 8192 ; This is a computer account for a system backup domain controller that is a member of this domain. ; The following used with userFlags only. UF_ENCRYPTED_PASSWORD_ALLOWED = 128 ; The user can send an encrypted password. (Windows 2000 only) UF_MNS_LOGON_ACCOUNT = 131072 ; This is an MNS logon account. UF_SMARTCARD_REQUIRED = 262144 ; When set, this flag will force the user to log on using smart card. (Windows 2000 only) UF_TRUSTED_FOR_DELEGATION = 524288 ; When set, the service account (user or computer account), under which a service runs, ; is trusted for Kerberos delegation. Any such service can impersonate a client requesting ; the service. To enable a service for Kerberos delegation, you must set this flag on the ; userAccountControl property of the service account. (Windows 2000 only) UF_NOT_DELEGATED = 1048576 ; When set, the security context of the user will not be delegated to a service even ; if the service account is set as trusted for Kerberos delegation ; Guid used to prevent a user from changing their password. ; Operating System = Windows 2000 ; Namespace = LDAP: ; Object class = user ; Property = ntSecurityDescriptor ; Security object = ACE ; Security Property = ObjectType CHANGE_PASSWORD_GUID = "{ab721a53-1e2f-11d0-9819-00aa0040529b}" ; Constant used it indicate that a user has unlimited disk storage rights. ; Operating System = Windows NT 4.0 / Windows 2000 ; Namespace = LDAP: ; object class = user ; properties = maxStorage USER_MAXSTORAGE_UNLIMITED = -1 ; Use all available disk space. ; Meaning of bits in groupType property of a LDAP namespace's group object. ; Operating System = Windows 2000 ; Namespace = LDAP ; object class = group ; properties = groupType GLOBAL_GROUP = 2 ; Group that contains only accounts and other account groups from its own domain. ; This group may be exported to a different domain. DOMAIN_LOCAL_GROUP = 4 ; Group that can contain accounts and universal groups from any domains. It may ; not be included in either access-control lists of resources in other domains or ; groups other than global groups in the same domain. LOCAL_GROUP = 4 ; This bit is for the WinNT provider as the DOMAIN_LOCAL_GROUP bit ; is for the LDAP provider. UNIVERSAL_GROUP = 8 ; Group that can contain accounts and account groups from any domains, but not domain local groups. SECURITY_ENABLED = 2147483648 ; If this bit is set, the group is a security group. If this bit is not set, ; the group is a distribution group. ; The following values are for security objects all accessed through the ntSecurityDescriptor property. ; Some can also be used with the NT-Security-Descriptor property of a mailbox object ; Current revision of security descriptor . ; Operating System = Windows 2000 ; Namespace = LDAP ; Security object = Security Descriptor ; Property = Revision ACL_REVISION = 2 ACL_REVISION_DS = 4 ; If the DACL contains an object-specific ACE you must use this. ; Current revision of Access Control List. ; Operating System = Windows 2000 ; Namespace = LDAP ; Security object = Access Control List ; Property = AclRevision ACL_REVISION = 2 ACL_REVISION_DS = 4 ; If the ACL contains an object-specific ACE you must use this. ; Bit values associated with the Security Descriptor Control property. ; Operating System = Windows 2000 ; Namespace = LDAP ; Security object = Security Descriptor ; Property = Control OWNER_DEFAULTED = 1 ; A default mechanism, rather than the the original provider of the ; security descriptor, provided the security descriptor's owner security identifier (SID). GROUP_DEFAULTED = 2 ; A default mechanism, rather than the the original provider of the security descriptor, ; provided the security descriptor's group SID. DACL_PRESENT = 4 ; Indicates a security descriptor that has a DACL. If this flag is not set, or if this ; flag is set and the DACL is NULL, the security descriptor allows full access to everyone. DACL_DEFAULTED = 8 ; Indicates a security descriptor with a default DACL. For example, if an ; object's creator does not specify a DACL, the object receives the default DACL ; from the creator's access token. SACL_PRESENT = 16 ; Indicates a security descriptor that has a DACL. This flag is used to hold the ; security information specified by a caller until the security descriptor is associated ; with a securable object. SACL_DEFAULTED = 32 ; A default mechanism, rather than the the original provider of the security descriptor, provided the SACL. DACL_AUTO_INHERIT_REQ = 256 ; The DACL of the security descriptor must be inherited. SACL_AUTO_INHERIT_REQ = 512 ; The SACL of the security descriptor must be inherited. DACL_AUTO_INHERITED = 1024 ; Indicates a security descriptor in which the DACL is set up ; to support automatic propagation of inheritable ACEs to existing child objects. SACL_AUTO_INHERITED = 2048 ; The SACL of the security descriptor supports automatic propagation of inheritable ; ACEs to existing child objects. DACL_PROTECTED = 4096 ; The security descriptor will not allow inheritable ACEs to modify the DACL. SACL_PROTECTED = 8192 ; The security descriptor will not allow inheritable ACEs to modify the SACL. SELF_RELATIVE = 32768 ; The security descriptor is of self-relative format with all the security information in ; a continuous block of memory. ; Bit values associated with an Access Control Entry's AccessMask property. ; Operating System = Windows 2000 ; Namespace = LDAP ; Security object = ACE ; Property = AccessMask DELETE = 65536 ; The right to delete the object. READ_CONTROL = 131072 ; The right to read information from the security descriptor of the object, ; not including the information in the SACL. WRITE_DAC = 262144 ; The right to modify the discretionary access-control list (DACL) in the ; object's security descriptor. WRITE_OWNER = 524288 ; The right to assume ownership of the object. The user must be a trustee ; of the object. The user cannot transfer the ownership to other users. SYNCHRONIZE = 1048576 ; The right to use the object for synchronization. This enables a thread ; to wait until the object is in the signaled state. ACCESS_SYSTEM_SECURITY = 16777216 ; The right to get or set the SACL in the object's security descriptor. GENERIC_READ = 2147483648 ; The right to read from the security descriptor, examine the object as ; well as its children, and read all properties. GENERIC_WRITE = 1073741824 ; The right to write all the properties and write to the DACL. The user ; can add and remove the object to and from the directory. GENERIC_EXECUTE = 536870912 ; The right to list children of this object. GENERIC_ALL = 268435456 ; The right to create or delete children, delete a subtree, read and write ; properties, examine children and the object itself, add and remove the ; object from the directory, and read or write with an extended right. DS_CREATE_CHILD = 1 ; The right to create children of the object. The ObjectType member of an ; ACE can contain a GUID that identifies the type of child object whose ; creation is being controlled. If ObjectType does not contain a GUID, the ; ACE controls the creation of all child object types. DS_DELETE_CHILD = 2 ; The right to delete children of the object. The ObjectType member of an ; ACE can contain a GUID that identifies a type of child object whose ; deletion is being controlled. If ObjectType does not contain a GUID, the ; ACE controls the deletion of all child object types. ACTRL_DS_LIST = 4 ; The right to list children of this object. DS_SELF = 8 ; The right to modify the group membership of a group object. DS_READ_PROP = 16 ; The right to read properties of the object. The ObjectType member of an ; ACE can contain a GUID that identifies a property set or property. If ; ObjectType does not contain a GUID, the ACE controls the right to read ; all of the object's properties. DS_WRITE_PROP = 32 ; The right to write properties of the object. The ObjectType member of ; an ACE can contain a GUID that identifies a property set or property. ; If ObjectType does not contain a GUID, the ACE controls the right to ; write all of the object's properties. DS_DELETE_TREE = 64 ; The right to delete all children of this object, regardless of the ; permission on the children. DS_LIST_OBJECT = 128 ; The right to list a particular object. If the user is not granted such ; a right, the object is hidden from the user. DS_CONTROL_ACCESS = 256 ; The right to perform an operation controlled by an extended access right. ; The ObjectType member of an ACE can contain a GUID that identifies the ; extended right. If ObjectType does not contain a GUID, the ACE controls ; the right to perform all extended right operations associated with the object. ;************************************Exchange 5.5 only********************************************** ; The Exchange 5.5's mailbox security descriptor has different meanings for several AccessMask bits. ; Operating System = Windows 2000, NT 4.0 ; Namespace = LDAP ; Security object = ACE ; Property = AccessMask EXCH_MODIFY_USER_ATT = 2 ; Modify User Attributes EXCH_MAIL_SEND_AS = 8 ; Send As EXCH_MAIL_RECEIVE_AS = 16 ; Mailbox Owner ; The Exchange 5.5 secuirty descriptors for container objects have these bit values associated with ; their Access Control Entry's AccessMask property. ; Operating System = Windows 2000, NT 4.0 ; Namespace = LDAP ; Security object = ACE ; Property = AccessMask RIGHT_DS_ADD_CHILD = 1 RIGHT_DS_MODIFY_USER_ATT = 2 RIGHT_DS_MODIFY_ADMIN_ATT = 4 RIGHT_DS_DELETE = 65536 RIGHT_MAIL_SEND_AS = 8 RIGHT_MAIL_RECEIVE_AS = 16 RIGHT_MAIL_ADMIN_AS = 32 RIGHT_DS_REPLICATION = 64 RIGHT_DS_MODIFY_SEC_ATT = 128 RIGHT_DS_SEARCH = 256 ;***********************************End Exchange 5.5 only******************************************* ; Values associated with an Access Control Entry's AceType property. ; Operating System = Windows 2000 ; Namespace = LDAP ; Security object = ACE ; Property = AceType ACCESS_ALLOWED = 0 ; The ACE is of the standard ACCESS ALLOWED type, where the ObjectType and ; InheritedOjectType fields are NULL. ACCESS_DENIED = 1 ; The ACE is of the standard ACCESS_DENIED type, where the ObjectType and ; InheritedObjectType fields are NULL. SYSTEM_AUDIT = 2 ; The ACE is of the standard system type, where the ObjectType and ; InheritedObjectType fields are NULL. ACCESS_ALLOWED_OBJECT = 5 ; The ACE is of the ADSI extension of the ACCESS ALLOWED type, where either ; ObjectType or InheritedObjectType or both contain a GUID. ACCESS_DENIED_OBJECT = 6 ; The ACE is of the ADSI extension of the ACCCESS_DENIED type, where either ; ObjectType or InheritedObjectType or both contain a GUID. SYSTEM_AUDIT_OBJECT = 7 ; The ACE is of the ADSI extension of the system type, where either ObjectType ; or InheritedObjectType or both contain a GUID. ; Bit values associated with an Access Control Entry's AceFlag property. ; Operating System = Windows 2000 ; Namespace = LDAP ; Security object = ACE ; Property = AceFlags INHERIT_ACE = 2 ; Child objects will inherit this access-control entry (ACE). The inherited ; ACE is inheritable unless the NO_PROPAGATE_INHERIT_ACE flag is set. NO_PROPAGATE_INHERIT_ACE = 4 ; ADSI will clear the INHERIT_ACE flag for the inherited ACEs of ; child objects. This prevents the ACE from being inherited by subsequent ; generations of objects. INHERIT_ONLY_ACE = 8 ; Indicates an inherit-only ACE that does not exercise access control on the ; object to which it is attached. If this flag is not set, the ACE is an ; effective ACE that exerts access control on the object to which it is attached. INHERITED_ACE = 16 ; Indicates whether or not the ACE was inherited. The system sets this bit. VALID_INHERIT_FLAGS = 31 ; Indicates whether the inherit flags are valid. The system sets this bit. SUCCESSFUL_ACCESS = 64 ; Generates audit messages for successful access attempts, used with ACEs that ; audit the system in a system access-control list (SACL). FAILED_ACCESS = 128 ; Generates audit messages for failed access attempts, used with ACEs that audit ; the system in a SACL. ; Bit values associated with an Access Control Entry's Flags property. ; Operating System = Windows 2000 ; Namespace = LDAP ; Security object = ACE ; Property = Flags OBJECT_TYPE_PRESENT = 1 ; The ObjectType field is present in the ACE, but InheritedObjectType is not. INHERITED_OBJECT_TYPE_PRESENT = 2 ; The InheritedObjectType field is present in the ACE, but ObjectType is not. ; Possible values for the Authentication method (3rd) parameter of the dsSetCredentx function. ; Use these values to control the CLEAR_TEXT = 0 ; Use basic authentication to bind to directory service objects. SECURE_AUTHENTICATION = 1 ; Requests secure authentication. When this flag is set, the WinNT provider uses NTLM ; to authenticate the client. Active Directory will use Kerberos, and possibly NTLM, ; to authenticate the client. When the user name and password are NULL, the extender ; binds to the object using the security context of the user account under which ; WinBatch is running. USE_ENCRYPTION = 2 ; Use encryption for data exchange over the network. USE_SSL = 2 ; Data will be encrypted using SSL. READONLY_SERVER = 4 ; For a WinNT provider, the extender tries to connect to a primary domain ; controller (PDC) or a backup domain controller (BDC). For Active Directory, this ; flag indicates that a writeable server is not required for a serverless binding. PROMPT_CREDENTIALS = 8 ; Not supported. NO_AUTHENTICATION = 16 ; The providers may attempt to bind the client to an object, as an anonymous user. ; The WinNT provider does not support this flag. FAST_BIND = 32 ; This flag is not supported by the extender. USE_SIGNING = 64 ; Verifies data integrity to ensure the data received is the same as the data sent. ; The SECURE_AUTHENTICATION flag must be set also. USE_SEALING = 128 ; Encrypts data using Kerberos. The SECURE_AUTHENTICATION flag must be set also. USE_DELEGATION = 256 ; Enables the extender to delegate the user's security context, which is necessary ; for moving objects across domains. SERVER_BIND = 512 ; Windows 2000 SP1 and later: Specify this flag when using the LDAP provider if your ; ADsPath includes a server name. Do not use this flag for paths that include a domain ; name or for serverless paths. If you specify a server name without also specifying ; this flag, unnecessary network traffic is the result. ; The SECURE_AUTHENTICATION flag can be used in combination with other flags such as READONLY_SERVER, ; PROMPT_CREDENTIALS, FAST_BIND, USE_SIGNING, USE_SEALING AND SERVER_BIND. return
;EmailWelcome ; Post the first message to UnaVia mailbox ; have to wait to give the E-mail server time to create the mailbox. ; Param1 = server ; param2 = user's email address (user1@tc1.com) ; param3 = time delay in seconds ;generic debug setting progname=itemextract(1,winexename(""),".") if fileexist("%progname%.dbg") debugtrace(1,"%progname%.log") else debugtrace(0,"%progname%.log") endif AddExtender("wwwsk34i.dll ") tm = timeymdhms() x=param1 y=param2 z=param3 timedelay(param3) err=smtpSendText(param1, "UnaViaUserSupport@netwaysolutions.com", param2, "Welcome to UnaVia", "Your E-mail Account was created on %tm%") err=wxGetLastErr() exit
Where does winbatch look for the ole object specified in objectopen("object")?
dim objectmailbox as cdoexm.imailboxstoreappears to be:
objectmailbox=objectopen("CDOEXM.MailboxstoreDB")so to create a mailbox in Exchange 2000 for a user *correctly* you will need to use the following code to set the homemdb property
homemdb="correctly formatted homemdb string for your organization" sObjectPath="full ldap path to user" objUser=ObjectOpen(sObjectPath) objMailbox=ObjectOpen("CDOEXM.MailboxStoreDB") objMailbox=objUser ObjMailbox.CreateMailbox(homemdb) objUser.SetInfo objectClose(objMailbox) objectClose(objUser)
Article ID: W14917
File Created: 2013:06:19:15:16:32
Last Updated: 2013:06:19:15:16:32