我已经让Perl创建了一个用户名数组(@ua);现在我需要检查一下Active Directory中是否存在每个。我想到的最好的方法是在每个用户上运行dsquery,并确定命令是以零还是非零退出。我写了以下内容:
foreach(@ua)
{
$out = `C:\\Windows\\System32\\dsquery.exe user -samid $_`;
}
当我运行它时,我在命令行控制台中得到了一个重复的列表:
'C:\ Windows \ System32 \ dsquery.exe'无法识别为内部或 外部命令,可操作程序或批处理文件。
但是,dsquery.exe 在位于该位置,因为我可以通过简单地运行它来证明:
C:\verify_users>C:\Windows\System32\dsquery.exe user -samid ...
"CN=...,OU=...,OU=...,OU=...,DC=...,DC=...,DC=..."
有什么想法吗?
谢谢!
答案 0 :(得分:3)
如果需要运行外部命令,可以使用系统命令:
system("C:\\Windows\\System32\\dsquery.exe user -samid $_");
如果您需要更深入地控制命令,请尝试以下模块:Expect
但是如果您真的想要查询Active Directory,最好使用特定的CPAN模块,例如Net::LDAP。
答案 1 :(得分:3)
正如Miguel所说,请改用Net :: LDAP。
#!/usr/bin/perl
use warnings;
use strict;
use Net::LDAP;
my $tgt_user = shift or die "Usage: fetch_user_details <username>";
my $Server = 'server.foo.local';
my $User = 'user@foo.local';
my $Password = 'userpass';
my $LdapBase = 'OU=SBSUsers,OU=Users,OU=MyBusiness,DC=foo,DC=local';
# To AND conditions: "(&(cond1) (cond2))"
my $Filter = "SAMAccountName=$tgt_user";
# Bind a connection
my $ad = Net::LDAP->new("ldap://$Server")
or die("Could not connect to LDAP server: $Server");
my $res = $ad->bind( $User, password=>$Password );
if ($res->code) { die("Unable to bind as user $User: ".$res->error); }
# Run the search
# Could have attrs=>'a,b,c' for a search too
$res = $ad->search(base=>$LdapBase, filter=>$Filter);
if ($res->code) { die("Failed to search: ".$res->error); }
# Display results
my $count = $res->count;
print "Found $count matches\n";
for my $entry ($res->entries) {
$entry->dump;
# print $entry->get_value('givenname'),"\n";
}
$ad->unbind;
exit;
上面应该假设你的域命名就像是带有SBS的machine.foo.local - 如果没有,你需要谷歌一点点看看如何设置LdapBase。
答案 2 :(得分:0)
如果您想使用输出,请使用open
功能:
open(N, "C:\\Windows\\System32\\dsquery.exe user -samid $_ |");
或者如果您只想运行命令,请使用system
功能:
system("C:\\Windows\\System32\\dsquery.exe user -samid $_");