活动目录是 Windows NT 4.0 和 Windows 2000 使用的目录服务
|
图 1.111 |
活动目录运行在 Windows NT 4.0 和 Windows 2000 上
ADSI 可以使 Windows NT 管理员的工作变得轻松
ADsOpenObject 函数在不同的安全认证机制下绑定 ADSI 对象,它主要是通过调用参数返回的用户名和口令来认证的
Domain: IADsContainer;
IADsContainer 变量将被用来从指定的 ADSI 对象中获得全部用户、组和计算机
网络
DomainPath: WideString;
第三是一个 IADsContainer 接口类型变量 , 用来保存返回的接口变量
UnknownObject: IUnknown;
第二个参数是 WideString 类型的变量 , 用来在绑定函数中产生一个对象路径
www.orchn.com
下面指定想要获得的对象路径 , 如果域名是 "PRISMA" , 要想获得 ADSI 对象 , 就需要指定路径为 "WinNT://PRISMA" :
// 设定域名路径
DomainPath := 'WinNT://' + ADSIDomainName.Text;
下面代码使用不同的安全认证方式:
// 如果使用登录信息
if cbUseLogin.Checked then
// 使用登录并创建域对象
OleCheck(AdsOpenObject(PWideChar(DomainPath),
PWideChar(ADSIUsername.Text),
PWideChar(ADSIPassword.Text), 0, IID_IADsContainer,
UnknownObject));
else
// 创建域对象
OleCheck(ADsGetObject(PWideChar(DomainPath),
IID_IADsContainer, UnknownObject));
然后我们获取 IADsContainer 指针,以便查询域中的子对象:
// 获取域对象
Domain := UnknownObject as IADsContainer;
最后 , 把 IADsContainer 接口指针作为参数调用来获得域中的子对象 :
GetDomainInformation(Domain);
在域中查找
要想在域中查找子对象 , 可以使用 GetDomainInformation 过程 , 代码如下 :
// 获取域信息
procedure TMainFrm.GetDomainInformation(
Domain: IADsContainer);
var
Enum: IEnumVariant;
ADsTempObj: OLEVariant;
ADsObj: IADs;
Value: LongWord;
begin
// 清空用户、组和计算机列表
UserListView.Items.Clear;
GroupListView.Items.Clear;
ComputerListView.Items.Clear;
// 获取枚举对象
Enum := (Domain._NewEnum) as IEnumVariant;
// 利用枚举对象查找
while (Enum.Next(1, ADsTempObj, Value) = S_OK) do begin
// 获得临时对象
ADsObj := IUnknown(ADsTempObj) as IADs;
// 如果是用户对象
if AdsObj.Class_ = 'User' then
AddUserToList(ADsObj);
// 如果是组对象
if AdsObj.Class_ = 'Group' then
AddGroupToList(ADsObj);
// 如果是计算机对象
if AdsObj.Class_ = 'Computer' then
AddComputerToList(ADsObj);
end;
end;
下面是对程序流程的详细说明,首先获得枚举对象,并赋值给 Enum 变量:
Enum := (Domain._NewEnum) as IEnumVariant;
然后利用枚举变量进行查找并把每个子对象赋值给临时的 OLEVariant 对象:
while (Enum.Next(1, ADsTempObj, Value) = S_OK) do begin
OLEVariant 变量赋值给 ADSI 对象
ADsObj := IUnknown(ADsTempObj) as IADs;
获得 ADSI 对象后,开始检查对象类,根据对象类别把 ADSI 分别处理,并把不同 ADSI 对象的属性添加到各自的列表视图中去:
// 如果是用户对象
if AdsObj.Class_ = 'User' then
AddUserToList(ADsObj);
// 如果是组对象
if AdsObj.Class_ = 'Group' then
AddGroupToList(ADsObj);
// 如果是计算机对象
|
图 1.112 |
if AdsObj.Class_ = 'Computer' then AddComputerToList(ADsObj);
运行结果如 图 1.112 所示
www.orchn.com
使用 ADSI 控制 Windows NT/2000
ADSI 可以使我们控制用户、组、计算机、文件共享、打印任务、打印队列和服务等系统资源
www.orchn.com
创建或删除计算机用户
通过 WinNT provider ,可以创建或删除域中任意一台计算机的用户,要想创建一个域中指定的计算机的用户,需要绑定到指定的计算机上
控制 NT 服务
WinNT provider 还可以用来控制 NT 服务、服务器和工作站 , 下面的代码遍历 NT 服务 , 并根据相应的计算机添加服务到相应列表中 :
var
UnknownObject: IUnknown;
Computer: IADsContainer;
ComputerPath: WideString;
Enum: IEnumVariant;
AdsTempObj: OLEVariant;
AdsObj: IADs;
Value: LongWord;
begin
if Item.Caption = '' then
Exit;
// 指定域名路径
ComputerPath := 'WinNT://' + ADSIDomainName.Text +'/' + Item.Caption;
// 创建计算机对象
OleCheck(ADsGetObject(PWideChar(ComputerPath),
IID_IADsComputer, UnknownObject));
// 获得计算机容器接口
Computer := UnknownObject as IADsContainer;
// 清空服务视图列表
ServiceListView.Items.Clear;
// 获取枚举对象用于遍历
Enum := (Computer._NewEnum) as IEnumVariant;
// 用枚举对象进行查找
while (Enum.Next(1, ADsTempObj, Value) = S_OK) do begin
// 保存临时对象
ADsObj := IUnknown(ADsTempObj) as IADs;
// 如果对象为服务的话 ,添加到视图中
if AdsObj.Class_ = 'Service' then
AddServiceToList(ADsObj);
end;
end.
要想获得 NT 服务的信息,需要绑定服务对应的 ADSI 对象, ADSI 提供了 IADsService 对象来维护 NT 服务的信息,下面代码演示了如何绑定 NT 服务,并显示服务名:
var
ServiceObj: IADsService;
AdsPath: WideString;
begin
// 指定域名路径
AdsPath := 'WinNT://' + ComputerName + '/' + ServiceName;
// 获得服务对象
OLECheck(ADsGetObject(PWideChar(AdsPath),
IID_IADsService, ServiceObj));
// 获得服务名
lblServiceName.Caption := ' 服务名 : ' + ServiceName;
lblDisplayName.Caption := ' 服务显示名称 : ' +
ServiceObj.Get_DisplayName;
要想启动或停止 NT 服务 , 可以使用 IADsServiceOperations ADSI 对象
网络
程序演示
图 1.111 所示的程序演示了如何调用 WinNT provider 提供的功能
程序运行结果如图 1.113 所示
www.orchn.com
第一个函数使用登录用户缺省的信任级别,而第二个函数允许开发者指定特殊的安全信任机制来绑定 ADSI 对象
服务器
绑定 Win NT 目录服务
连接 Win NT 目录服务就是找到域控制器然后绑定到相应的对象上
结论
毫无疑问,通过 ADSI 目录服务,调用 WinNT provider 可以更容易实现 NT 的管理功能,但它也是一个庞大的系统,光 Windows 的活动目录编程参考就有上千页,说明我们必须花费大量时间才能真正掌握它的精髓
ADSI 2.5 SDK 可以从 Microsoft ADSI 网址 http://www.microsoft.com/adsi 下载
ADSI 支持管理员执行一些一般的管理任务,比如添加新用户、管理打印机、安全设定和控制 NT 域
ADSI 是一组以 COM 接口的形式提供目录服务的,程序员可以通过 ADSI 存取四种网络目录结构: WinNT (Microsoft SAM 数据库 ) 、 LDAP ( 轻量目录存取协议 ) 、 NDS (NetWare 目录服务 ) 和 NWCOMPAT (Novell NetWare 3.x)
www.orchn.com ADsGetObject 函数声明如下:
function ADsGetObject(lpszPathName: PWideChar; const riid: TIID; out obj): HResult; stdcall; external 'activeds.dll';
第一个参数是对象的路径名,第二个参数是对象的接口标识符,第三个参数用于返回得到的被请求的接口指针
SDK 包括文档、在线帮助和很多例子,不过不幸的是这些例子都是针对 VB 和 VC 的,这里我们将演示如何使用 Delphi 调用 ADSI
procedure TMainFrm.actOpenWinNTExecute(Sender: TObject);
var
UnknownObject: IUnknown;
DomainPath: WideString;
Domain: IADsContainer;
begin
// 指定域路径
DomainPath := 'WinNT://' + ADSIDomainName.Text;
// 如果使用用户登录了信息
if cbUseLogin.Checked then
// 使用用户登录的信息创建域对象
OleCheck(AdsOpenObject(PWideChar(DomainPath),
PWideChar(ADSIUsername.Text),
PWideChar(ADSIPassword.Text), 0, IID_IADsContainer,
UnknownObject));
else
OleCheck(ADsGetObject(PWideChar(DomainPath),
IID_IADsContainer, UnknownObject));
// 设定域对象
Domain := UnknownObject as IADsContainer;
// 从域中获得信息列表
GetDomainInformation(Domain);
end;
下面我们需要声明三个变量 :
第一个是接口变量 , 用来绑定由指定的对象路径返回的函数
www.orchn.com 下面就来演示如何枚举组中的用户并察看用户相关信息
通信 为了使用 ADSI ,必须安装 ADSI COM 接口
函数声明如下:
function ADsOpenObject(lpszPathName: PWideChar; lpszUserName: PWideChar; lpszPassword: PWideChar; dwReserved: LongInt; const riid: TIID; out obj): HResult; stdcall; external 'activeds.dll';
第一个参数意义同上,第二、三个参数是调用者提供的用户名和口令,第四个参数是一个保留的 provider 标识,用来确定绑定的认证方法,第五个参数是请求接口的接口标识符,最后一个参数用来返回请求的接口指针
同上面一样需要先绑定到 NT 服务上去,而同前面不一样的是,这回不是获得 IADsService ADSI 对象,而是获得 IADsServiceOperations ADSI 对象:
// 创建计算机对象
OleCheck(AdsGetObject(PWideChar(AdsPath),
IID_IADsServiceOperations, Result));
然后使用 GetServiceObj 函数来绑定到 IADsServiceOperations ADSI 对象上 , 并返回 IADsServiceOperations 接口 :
// 获得服务对象
ServiceObj := GetServiceObj;
启动服务需要调用 IADsServiceOperations 接口的 Start 方法:
|
图 1.114 |
// 启动服务 , Get_Status = 1 表明服务正处于停止状态
if ServiceObj.Get_Status = 1 then
ServiceObj.Start;
要停止服务需要调用 IADsServiceOperations ADSI 对象的 Stop 方法 , 运行结果如图 1.114 所示
同时这个程序还演示了如何察看域中计算机上的服务和察看、添加、删除 NT 组中的用户
因为 ADSI 使用 COM 接口,任何支持 COM 的编程语言像 Delphi 、 BCB 、 VB 、 VC 等都可以调用 ADSI
客户端程序可以运行在 Windows 95 、 Windows 98 、 Windows NT 4.0 和 Windows 2000 上
容器对象的 Create 方法需要两个参数,一个是要创建的 ADSI 对象的类别,一个是要用来描述 ADSI 对象的名字
当然也可以使用 IADsDomain 类型的变量,但它不适合枚举域中的子对象
最后使用 IADsUser 接口变量 UserObj 来获得 NT 组中的用户信息
www.orchn.com 演示程序用来连接到一个域,一旦连接到域,程序将会列出在 PDC 上找到的 NT 的用户和组以及域中的计算机
绑定可以通过 ADsGetObject 或 ADsOpenObject 函数来实现
缺省条件下,函数根据当前用户进行安全认证
服务器 要想使用活动目录服务,需要调用 ADSI( 活动目录服务接口 )
要想在 Delphi 中调用 ADSI ,需要引入活动目录类型库,调用菜单 Project | Import Type Library 命令,选择 ActiveDs (Version 1.0) 点确认, Delphi 会生成相应的封装文件
调用 Create 方法后会返回新的 ADSI 对象的引用参考,下面代码演示了如何创建一个用户:
var
ComputerObj: IADsContainer;
TempUserObj: IUnknown;
UserObj: IADsUser;
PDCName: WideString;
NewUserName: WideString;
AdsPath: WideString;
begin
// 获取用户信息
PDCName := InputBox(' 创建新用户 ', ' 请输入域名 : ', '');
NewUserName := InputBox(' 创建新用户 ', ' 请输入用户名 : ', '');
// 指定域名路径
AdsPath := 'WinNT://' + PDCName + ',computer';
// 创建计算机对象
OleCheck(AdsGetObject(PWideChar(AdsPath),
IID_IADsContainer, ComputerObj));
// 创建新用户
TempUserObj := ComputerObj.Create('user', NewUserName);
UserObj := TempUserObj as IADsUser;
// 设定目录信息
UserObj.SetInfo;
// 刷新列表
actOpenWinNT.Execute;
删除用户也非常类似 , 只不过不需要创建任何的用户对象 , 可直接调用容器对象 IADsContainer 接口的 Delete 方法 , Delete 方法需要两个参数 , 第一个是要删除的对象类别 , 第二个是对象名称 , 代码示意如下 :
var
ComputerObj: IADsContainer;
PDCName: WideString;
UserName: WideString;
AdsPath: WideString;
begin
// 获取用户信息
PDCName := InputBox(' 删除用户 ', ' 请输入域名 ', '');
UserName := InputBox(' 删除用户 ', ' 请输入要删除的用户名 : ', '');
if MessageDlg(' 你是否确信要删除用户 : ' +UserName + ' ?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
begin
// 指定域名路径
AdsPath := 'WinNT://' + PDCName + ',computer';
// 创建计算机对象
OleCheck(AdsGetObject(PWideChar(AdsPath),
IID_IADsContainer, ComputerObj));
// 删除用户
ComputerObj.Delete('user', UserName);
// 刷新列表
actOpenWinNT.Execute;
end;
end
查看组中的用户
通过 WinNT provider ,我们还可以执行各种用户组的维护任务,比如从组中添加或删除用户
首先让下面代码获得一个 IADsGroup 对象,然后使用 IADsMember 对象来枚举 IADsGroup 对象中所有用户对象,列出不同组中的所有用户:
var
GroupObj: IADsGroup;
Members: IADsMembers;
AdsPath: WideString;
Enum: IEnumVariant;
TempUserObj: OLEVariant;
UserObj: IADsUser;
TempListObj: TListItem;
Value: LongWord;
begin
// 清空列表
GroupListView.Items.Clear;
// 指定域名路径
AdsPath := 'WinNT://' + MainFrm.ADSIDomainName.Text +'/' + GroupName;
// 创建组对象
OLECheck(AdsGetObject(PWideChar(AdsPath), IID_IADsGroup,
GroupObj));
// 获得 members 对象
Members := GroupObj.Members;
// 获取枚举对象
Enum := (Members._NewEnum) as IEnumVariant;
// 使用枚举对象进行查找
while (Enum.Next(1, TempUserObj, Value) = S_OK) do
try
// 保存临时对象
UserObj := IUnknown(TempUserObj) as IADsUser;
// 创建新的列表项
TempListObj := GroupListView.Items.Add;
// 指定属性
TempListObj.Caption := UserObj.Name;
except
on E:Exception do
|
图 1.113 |
end;
IADsGroup 接口是用来管理 NT 组信息的接口,而它的 Members 属性是一个管理组中用户或 ADSI 对象列表的接口
0
顶一下0
踩一下