ADSI 入门

友在初学ADSI的时候,往往向往那些神奇的 脚本,赶紧把脚本拿来运行,却往往在开头的第一句就遇到问题,去翻那些生涩的msdn仍然是一头雾水。今天用一个例子,做一个抛砖引玉,希望能够让急于学习它的朋友抓住一些灵感。
提问:
Set objOU = GetObject(" LDAP://OU=management,dc=fabrikam,dc=com") 
①问:LDAP这里代表什么意思?
Set objUser = objOU.Create ("User", "cn=MyerKen")       
②问:user代表什么?是创建名字叫user的用户吗?还是代表要创建一个用户,而MyerKen才是用户名称?
objUser.Put "sAMAccountName", "myerken"          
③ 问:sAMAccountName这个在这里代表什么?
objUser.Setinfo
①问:LDAP这里代表什么意思?
答:这个涉及到命名空间的问题。每一个驻留的对象都会使用一个唯一的名字标识。比如:存储在硬盘上的文件驻留在文件 系统命名空间。文件的唯一标识是基于它在文件系统命名空间中的存储位置,类似这样:

 

C:publicdocumentsadsiadsi_spec.doc

目录服务命名空间也是使用基于目录定位的唯一名称来标识对象,这个位置必须是可以查询的。比如在遵循 X.500 目录中, 一个既定的对象使用的名称应该类似于这样:

 

CN=John,OU=Marketing,O=Fabrikam
不同的目录服务为它们所包含的对象使用不同的格式,那么如何处理这种情况就变得很富有挑战性,尤其对于开发者来说, 要考虑让代码适用于所有环境。

Active Directory Service Interfaces (ADSI) 应运而生,它的一个目标就是提供一个命名的架构,以便不同的目录服务提供者都能够访问它。

ADSI 定义一个命名规范,能够在多种目录结构的复杂环境中唯一的标识命名。这些名称称为 ADsPath 字串 ADsPath 字串遵循如下格式:

 

"ADs://" "LDAP://" "WinNT://"

附加的 ADsPath 格式被不同的 ADSI 提供者定义 (比如 Internet Information Services  ADSI 提供者,支持 "IIS://" ADsPaths).那么Microsoft LDAP Provider ADsPath 定义如下:

LDAP://HostName[:PortNumber][/DistinguishedName]

注意:被[ ] 包括的是可选的参数

HostName 可以是一个计算机名称,一个 IP 地址或者一个域名,当然也可以指定一个服务器的名字。大多数 LDAP provider 都遵循这一模式。

PortNumber 指定用于连接的端口。如果没有指定,LDAP 将使用默认端口号 389 (使用 SSL )或者 636 (不使用用 SSL )

(详见 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adsi/adsi/ldap_adspath.asp

DistinguishedName 指定作用对象的 distinguished name ,这个名称必须是唯一的。

Distinguished Name 定义如下:

 LDAP API 通过 distinguished name (DN) 访问一个 LDAP 对象。DN 是一个相对 distinguished names (RDN) 的序列,构成序列的各个字串之间通过逗号间隔。RDN 是一个以这样格式关联的属性值 attribute=value; 一般使用 UTF-8 编码,下面的列表中定义了各 RDN 属性类型。

String      Attribute type
DCdomainComponent
CNcommonName
OUorganizationalUnitName
OorganizationName
STREETstreetAddress
LlocalityName
STstateOrProvinceName
CcountryName
UIDuserid

下面是一个 distinguished names 的例子:


如果是在windows active directory中,那么通常按照从上至下的层级结构,这个名称按照从后往前的顺序书
写,比如在一个域中 shenzhen.china.com 存在一个ou:department ,其下有个ou: purchase ,再下面
有一个用户或者组 gnaw0725 & SMgroup ,写法应该如下:
唯一标识用户 gnaw0725 cn=gnaw0725,ou=purchase,ou=department,dc=shenzhen,dc=china,dc=com
唯一标识组 SMgroup cn=SMgroup,ou=purchase,ou=department,dc=shenzhen,dc=china,dc=com
可以看到一般最后用cn来标识对象。

(gnaw0725注:如果您在运行脚本的时候提示类似于这样的错误,

 

 "D:ADBackupcreateuser.vbs(1, 1) (null): �o法指出的�e�`" 

那么请注意LDAP Provider是否小写了,这里一定要大写。)

②问:user代表什么?是创建名字叫user的用户吗?还是代表要创建一个用户,而MyerKen才是用户名称?

答:的确,这里的user表示需要创建的对象类型是user,而user的名称是MyerKen。

按照create method 定义如下:

 IADsContainer::Create method 接受创建一个目录对象的请求,这个对象必须指定架构类型和既定名称。然后通过调用 IADs::SetInfo 将这个对象固定下来(关于为什么要执行 IADs::SetInfo 在后面描述),您就可以这个对象的属性了。

HRESULT Create(   BSTR bstrClass,  BSTR bstrRelativeName,  IDispatch** ppNewObject);
参数
bstrClass
[in] Name of the schema class object to be created. The name is that returned from the IADs::get_Schema property method.
bstrRelativeName
[in] Relative name of the object as it is known in the underlying directory and identical to the one retrieved through the IADs::get_Name property method.
ppNewObject
[out] Indirect pointer to the IDispatch interface on the newly created object.
返回值

This method supports the standard return values, including S_OK for a successful operation. For more information about error codes, see ADSI Error Codes.

类似,Getobject method 定义如下:

The IADsContainer::GetObject method 为连接容器中的目录对象获取接口

HRESULT GetObject(   BSTR bstrClass,  BSTR bstrRelativeName,  IDispatch** ppNamedObject);
参数
bstrClass
[in] A BSTR that specifies the name of the object class as of the object to retrieve. If this parameter is NULL, the provider returns the first item found in the container.
bstrRelativeName
[in] A BSTR that specifies the relative distinguished name of the object to retrieve.
ppNamedObject
[out] Pointer to a pointer to the IDispatch interface on the specified object.
返回值

This method supports standard return values, including S_OK for a successful operation. For more information about error codes, see ADSI Error Codes.

类似,setinfo method定义如下:

The IADs::SetInfo method 将缓存中 ADSI 对象的属性值写入目录数据库

 

HRESULT SetInfo();
参数

This method has no parameters.

返回值

This method supports the standard return values, including S_OK for a successful operation. For more information, see ADSI Error Codes.

备注:

强调 IADs::Put 和 IADs::SetInfo methods 之间的不同是非常重要的。 前者设定缓存中的属性值,而或者将这个变化写入目录数据库。 因此,在没有调用 IADs::SetInfo 写入前,如果执行了 IADs::GetInfo (或者 IADs::GetInfoEx) ,任何被 IADs::Put 改变的属性值都会丢失。

由于最终的结果将要通过网络传输数据,出于安全、效率、带宽的考虑,不可能让使用者一直连接到数据库,那么出于设计的考虑,系统将每次修改的数据先存放在本地缓存,最后由 IADs::SetInfo  将所有变更数据提交给服务器上的数据库,这样做极大的降低了客户端连接服务器数据库的次数,提高了效率。在平时程序设计中您也应该遵循这个规则,尽可能在最后提交所有或者大多数的变更,把缓存的数据一次性写入。

这个原则仅适用于和 IADs::Put method 相关联的 IADs::SetInfo ,这和 IADs::PutEx method 是不同的。

详见 http://www.microsoft.com/resources/documentation/windows/2000/server/scriptguide/en-us/sas_ads_yrig.mspx

③问:sAMAccountName这个在这里代表什么?

答:这里定义用 IADs::Put method写入的属性值。
IADs::Put method定义如下:

The IADs::Put method 设置位于ADSI属性缓存中的一个属性值。(为什么说是在缓存中,前面IADS::SetInfo已经提到)

HRESULT Put(   BSTR bstrName,  VARIANT vProp);
参数bstrName 
[in] Contains a BSTR that specifies the property name.
vProp
[in] Contains a VARIANT that specifies the new values of the property.

返回值

This method supports the standard return values, as well as the following.

For more information, and other return values, see ADSI Error Codes.

Creating a user 步骤如下
1、调用 IADsContainer.Create 按照指定的位置(cn)在本地缓存中创建用户 
2、使用 IADs.Put method 将 sAMAccountName 属性值设定为将要创建用户的用户名 
3、调用 IADs.SetInfo 将新的用户提交到服务器数据库 
4、接着修改用户的其他属性,比如 userAccountControl。这个约束将也会应用到其他 ADSI 属性,比如 IADsUser.AccountDisabled, 或者ADSI methods ,比如 IADsUser.SetPassword
5、调用 IADs.SetInfo 再次将修改提交到服务器数据库 
gnaw0725注:
由于win2000 scripting guide还不完善,在msdn中很多对于脚本的描述,所给出的例子很多都不是vbscript,但其中给出的vb的代码,和vbscript不仅结构还是语法都非常的类似,我们可以结合自己的经验做一些改动,即可转换为vbscript。例如下面这段代码就是描述如何新建一个domain user,并随后设定user的属性。
[Visual Basic]
Const ADS_UF_SCRIPT = &H1Const ADS_UF_ACCOUNTDISABLE = &H2Const ADS_UF_HOMEDIR_REQUIRED = &H8Const ADS_UF_LOCKOUT = &H10Const ADS_UF_PASSWD_NOTREQD = &H20Const ADS_UF_PASSWD_CANT_CHANGE = &H40Const ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = &H80Const ADS_UF_TEMP_DUPLICATE_ACCOUNT = &H100Const ADS_UF_NORMAL_ACCOUNT = &H200Const ADS_UF_INTERDOMAIN_TRUST_ACCOUNT = &H800Const ADS_UF_WORKSTATION_TRUST_ACCOUNT = &H1000Const ADS_UF_SERVER_TRUST_ACCOUNT = &H2000Const ADS_UF_DONT_EXPIRE_PASSWD = &H10000Const ADS_UF_MNS_LOGON_ACCOUNT = &H20000Const ADS_UF_SMARTCARD_REQUIRED = &H40000Const ADS_UF_TRUSTED_FOR_DELEGATION = &H80000Const ADS_UF_NOT_DELEGATED = &H100000Const ADS_UF_USE_DES_KEY_ONLY = &H200000Const ADS_UF_DONT_REQUIRE_PREAUTH = &H400000Const ADS_UF_PASSWORD_EXPIRED = &H800000Const ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = &H1000000Public Sub CreateUser(strName As String, strSAMAccountName As String, strInitialPassword As String)
    为后面即将使用的变量定义类型,这是个编程的好习惯    Dim objRootDSE As IADs                     Dim objUsers As IADsContainer    Dim objNewUser As IADsUser
    忽略可能出现的错误,错误返回码自行处理    On Error Resume Next        绑定到 rootDSE 对象.    Set objRootDSE = GetObject(LDAP://rootDSE)
    为了便于debug和监控代码,每一句后都为可能出现的错误给出处理方法,即直接退出子程序。    If (Err.Number <> 0) Then        Exit Sub    End If        绑定到即将放置新建用户所处目录层次    Set objUsers = GetObject("LDAP://CN=Users," & objRootDSE.Get("defaultNamingContext"))    If (Err.Number <> 0) Then        Exit Sub    End If        创建用户对象    Set objNewUser = objUsers.Create("user", "CN=" + strName)    If (Err.Number <> 0) Then        Exit Sub    End If        设置用户 sAMAccountName 属性    objNewUser.Put "sAMAccountName", strSAMAccountName    If (Err.Number <> 0) Then        Exit Sub    End If        提交新的用户    objNewUser.SetInfo    If (Err.Number <> 0) Then        Exit Sub    End If    设置初始化密码。这个动作必须在 Setinfo 之后,因为用户账户必须已经存在于ad中。    objNewUser.SetPassword strInitialPassword    If (Err.Number <> 0) Then        Exit Sub    End If        设置 pwdLastSet 属性为0,这样做的目的是强制用户下次登陆时更改密码。    objNewUser.Put "pwdLastSet", 0    If (Err.Number <> 0) Then        Exit Sub    End If        为了启用用户账户,从 userAccountControl 属性中移除 ADS_UF_ACCOUNTDISABLE 标志量。
同样也移除 ADS_UF_PASSWD_NOTREQD 和 ADS_UF_DONT_EXPIRE_PASSWD 标志量    
userActCtrl = objNewUser.Get("userAccountControl")    userActCtrl = userActCtrl And Not (ADS_UF_ACCOUNTDISABLE + 
      ADS_UF_PASSWD_NOTREQD + ADS_UF_DONT_EXPIRE_PASSWD)
    使用 Put Methon 写入 userAccountControl 属性     objNewUser.Put "userAccountControl", userActCtrl    If (Err.Number <> 0) Then        Exit Sub    End If        提交属性变更    objNewUser.SetInfoEnd Sub
参考文档:
Active Diretory 技术背景
ADSI 脚本入门
使用Active Diretory
Microsoft TechNet Microsoft Windows 2000 脚本指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值