// 获取域信息
procedure TMainFrmGetDomainInformation(Domain: IADsContainer);
var
Enum: IEnumVariant;
ADsTempObj: OLEVariant;
ADsObj: IADs;
Value: LongWord;
begin
//清空用户组和计算机列表
UserListViewItemsClear;
GroupListViewItemsClear;
ComputerListViewItemsClear;
//获取枚举对象并赋值给 Enum 变量
Enum := (Domain_NewEnum) as IEnumVariant;
//利用枚举对象查找把每个子对象赋值给临时的 OLEVariant 对象
while (EnumNext( ADsTempObj Value) = S_OK) do
begin
ADsObj := IUnknown(ADsTempObj) as IADs; //获得临时对象OLEVariant 变量赋值给 ADSI 对象
if AdsObjClass_ = User then //如果是用户对象
AddUserToList(ADsObj);
if AdsObjClass_ = Group then //如果是组对象
AddGroupToList(ADsObj);
if AdsObjClass_ = Computer then //如果是计算机对象
AddComputerToList(ADsObj);
ADsTempObj:=Null; //释放OLEVariant
end;
end;
procedure TMainFrmAddUserToList(ADsObj:IADs);
var aListItem:TListItem;
begin
aListItem:=UserListViewItemsAdd;
aListItemCaption:=ADsObjName;
aListItemSubItemsAdd(ADsObjClass_);
aListItemSubItemsAdd(ADsObjADsPath);
aListItemSubItemsAdd(ADsObjParent);
// aListItemSubItemsAdd(ADsObjGet(sAMAccountName));
end;
procedure TMainFrmAddGroupToList(ADsObj:IADs);
var aListItem:TListItem;
begin
aListItem:=GroupListViewItemsAdd;
aListItemCaption:=ADsObjName;
aListItemSubItemsAdd(ADsObjClass_);
aListItemSubItemsAdd(ADsObjADsPath);
end;
procedure TMainFrmAddComputerToList(ADsObj:IADs);
var aListItem:TListItem;
begin
aListItem:=ComputerListViewItemsAdd;
aListItemCaption:=ADsObjName;
aListItemSubItemsAdd(ADsObjClass_);
aListItemSubItemsAdd(ADsObjADsPath);
end;
procedure TMainFrmbtnClick(Sender: TObject);
var
UnknownObject: IUnknown;
DomainPathADUserADPass: WideString;
Domain: IADsContainer;
begin
// 指定域路径
DomainPath := WinNT:// + ADSIDomainNameText;
ADUser:= ADSIUsernameText;
ADPass:= ADSIPasswordText;
DomainPath := WinNT://;
ADUser: ADUser:= Hebmc\OAWebUser; //注意用户名称的写法domain\User 或
ADUser:= ; //注意用户名称的写法domain\User 或
ADPass:= chenzuooaup;
// 如果使用用户登录了信息
if cbUseLoginChecked then // 使用用户登录的信息创建域对象
OleCheck(AdsOpenObject(PWideChar(DomainPath)
PWideChar(ADUser)
PWideChar(ADPass)
IID_IADsContainer
UnknownObject))
else
OleCheck(ADsGetObject(PWideChar(DomainPath)
IID_IADsContainer
UnknownObject));
// 设定域对象
Domain := UnknownObject as IADsContainer;
// 从域中获得信息列表
GetDomainInformation(Domain);
end;
end
备注
*注意用户名的写法domain\User 或
*Delphi使用WinNT Provider方式访问AD在使用ADsObjGet(属性)时会有一个报错高速缓存中找不到目录属性 (The directory property cannot be found in the cache)
目前该问题还不知如何解决
*资料参考《Delphi深度探索活动目录开发》
作者陈省(Hubdog)
Delphi使用LDAP访问Window Server AD
unit Main;
interface
uses
Windows Messages SysUtils Variants Classes Graphics Controls Forms
Dialogs StdCtrls ActiveDs_TLB ActiveX ComObj;
type
TMainFrm = class(TForm)
Button: TButton;
ObjMemo: TMemo;
OUMemo: TMemo;
UserMemo: TMemo;
cbUseLogin: TCheckBox;
Obj_Label: TLabel;
OU_Label: TLabel;
Users_Label: TLabel;
procedure ButtonClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure GetADInfo(aUseraPassaDomainPath: WideString);
end;
//连接 Win NT 目录服务就是找到域控制器然后绑定到相应的对象上
//绑定可以通过 ADsGetObject 或 ADsOpenObject 函数来实现
//第一个函数使用登录用户缺省的信任级别
//第二个函数允许开发者指定特殊的安全信任机制来绑定 ADSI 对象
//缺省条件下ADsGetObject函数根据当前用户进行安全认证
function ADsGetObject(lpszPathName: PWideChar; //第一个参数是对象的路径名
const riid: TIID; //第二个参数是对象的接口标识符
out obj): HResult; stdcall; external activedsdll;// 第三个参数用于返回得到的被请求的接口指针
//ADsOpenObject 函数在不同的安全认证机制下绑定 ADSI 对象
//它主要是通过调用参数返回的用户名和口令来认证的
function ADsOpenObject(lpszPathName: PWideChar; //第一个参数是对象的路径名
lpszUserName: PWideChar; //第二个参数是调用者提供的用户名
lpszPassword: PWideChar; //第三个参数是调用者提供的口令
dwReserved: LongInt; //第四个参数是一个保留的 provider 标识用来确定绑定的认证方法
const riid: TIID; //第五个参数是请求接口的接口标识符
out obj): HResult; stdcall; external activedsdll; //最后一个参数用来返回请求的接口指针
var
MainFrm: TMainFrm;
implementation
{$R *dfm}
procedure TMainFrmButtonClick(Sender: TObject);
var DomainPathADUserADPass: WideString;
begin
DomainPath := LDAP:///OU=省公司OU=组织架构DC=HebmcDC=com;//LDAP访问AD的路径
ADUser:=Hebmc\OAWebUser; //注意用户名称的写法域名称 + 用户名称 或
ADUser:=; //注意用户名称的写法域名称 + 用户名称 或
ADPass:=chenzuooaup; //用户密码
GetADInfo(ADUserADPassDomainPath);
end;
procedure TMainFrmGetADInfo(aUseraPassaDomainPath: WideString);
var
UnknownObject: IUnknown;
Enum: IEnumVariant;
ADsTempObj: OLEVariant;
Domain: IADsContainer;
ADsObj: IADs;
Value: LongWord;
begin
// 如果使用AD用户信息登录
if cbUseLoginChecked then // 使用用户登录的信息创建域对象
OleCheck(AdsOpenObject(PWideChar(aDomainPath)
PWideChar(aUser)
PWideChar(aPass)
IID_IADsContainer
UnknownObject))
else
OleCheck(ADsGetObject(PWideChar(aDomainPath)
IID_IADsContainer
UnknownObject));
// 设定域对象
Domain := UnknownObject as IADsContainer;
//获取枚举对象并赋值给 Enum 变量
Enum := (Domain_NewEnum) as IEnumVariant;
//利用枚举对象查找把每个子对象赋值给临时的 OLEVariant 对象
while (EnumNext( ADsTempObj Value) = S_OK) do
begin
ADsObj := IUnknown(ADsTempObj) as IADs; //获得临时对象OLEVariant 变量赋值给 ADSI 对象
ObjMemoLinesAdd(AdsObjClass_); //对象类型
if AdsObjClass_ = organizationalUnit then //如果是组织单元对象
OUMemoLinesAdd(ADsObjName) ;
if AdsObjClass_ = user then //如果是用户对象
UserMemoLinesAdd(ADsObjName+(用户代码=+ADsObjGet(sAMAccountName)+));
//递归得到组内相关用户
GetADInfo(aUseraPassADsObjADsPath);
ADsTempObj:=Null; //释放OLEVariant
end;
end;
end
备注
* 注意用户名的写法domain\User 或
* Delphi使用LDAP方式访问AD可以使用ADsObjGet(属性)时得到相关属性值
属性的取值域可以通过JAVA程序得到