我正在使用WMI并且正在尝试查找一个powershell脚本,该脚本将允许我获取本地计算机的OU,然后获取该OU中的完整计算机列表。
答案 0 :(得分:6)
你走了:
$ComputerName = '<Name of Computer>';
$Computer = Get-WmiObject -Namespace 'root\directory\ldap' -Query "Select DS_distinguishedName from DS_computer where DS_cn = '$ComputerName'";
$OU = $Computer.DS_distinguishedName.Substring($Computer.DS_distinguishedName.IndexOf('OU='));
$ComputersInOU = Get-WmiObject -Namespace 'root\directory\ldap' -Query "Select DS_cn, DS_distinguishedName from DS_computer where DS_distinguishedName like '%$OU'";
我认为这也可以在子OU中找到计算机,但我不知道如何在不进行大量查询的情况下将其限制为单个OU。查询语法相当稀疏。在检索完整列表后删除子OU对象可能是执行任何表现的唯一方法。
公平警告:这很慢。 真的慢。就像“哦,垃圾,我打破了什么?!”慢。我把它指向一台与少于20台其他计算机共享OU的计算机,运行起来需要将近一分钟。即使是第一次只读取一台计算机也需要1秒钟以上。
以下是我的建议:
$ComputerName = '<Name of Computer>';
Import-Module -Name ActiveDirectory -Cmdlet Get-ADComputer, Get-ADOrganizationalUnit;
$Computer = Get-ADComputer $ComputerName;
$OU = $Computer.DistinguishedName.SubString($Computer.DistinguishedName.IndexOf('OU='));
$ComputersInOU = Get-ADComputer -Filter * -SearchScope OneLevel -SearchBase (Get-ADOrganizationalUnit $OU).DistinguishedName;
这需要2秒,包括加载Active Directory模块。已经加载,这需要不到200毫秒。
如果您无权访问ActiveDirectory
PowerShell模块,则可以使用[ADSISearcher]
。由于结果如何呈现,这些也很难使用,但它们甚至比ActiveDirectory
模块更快,这基本上只是一个包装器。
$ComputerName = '<Name of Computer>';
$ADSISearcher = New-Object System.DirectoryServices.DirectorySearcher;
$ADSISearcher.Filter = '(&(name=' + $ComputerName + ')(objectClass=computer))';
$ADSISearcher.SearchScope = 'Subtree';
$Computer = $ADSISearcher.FindAll();
$OU = $($Computer.Properties.Item('distinguishedName')).Substring($($Computer.Properties.Item('distinguishedName')).IndexOf('OU='));
$OUADsPath = 'LDAP://' + $OU;
$ADSISearcher = New-Object System.DirectoryServices.DirectorySearcher;
$ADSISearcher.Filter = '(objectClass=computer)';
$ADSISearcher.SearchScope = 'OneLevel';
$ADSISearcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry($OUADsPath);
$ComputersInOU = $ADSISearcher.FindAll();
这大约在50毫秒内运行。
但是,请注意ADSI system is known to contain memory leaks如果未正确调用或调用FindAll()
并且结果从未使用过。我自己用这种方法创建了对象然后没有丢弃它们并且让我的shell进程在一夜之间打开,当我第二天早上进入时,我的系统几乎没有响应,因为所有的内存都被消耗了。 ActiveDirectory
模块完全避免了这些问题,并且代码更轻,所以除非你真的需要那些额外的几毫秒而不是我喜欢的模块。