
欢迎来到 TechNet 专栏,在这里,Microsoft 脚本专家将为您解答与系统管理脚本编写有关的各种常见问题。如果遇到系统管理脚本编写方面的问题,请将电子邮件发送到 scripter@microsoft.com。我们不能保证回答收到的所有问题,但是我们将尽最大的努力。
同时,不要忘了查看您好,脚本专家!存档。
今日问题:在使用脚本返回本地管理员帐户的成员时,如何区分本地用户和域用户?
您好,脚本专家!在使用脚本返回本地管理员帐户的成员时,如何区分本地用户和域用户?
-- KS
您好,KS。如您所知,多年前有一个电视娱乐节目叫我是干哪行的?该节目的前提是,由一些特殊职业的人出场,一组名人嘉宾会向该人提出一连串只需回答“是”或“否”的问题,以设法确定该人的特殊职业是什么。(嗨,我们只说了那是一个娱乐节目;我们从未说过那是一个引人入胜又充满趣味的娱乐节目。)如果某位猜答参与者问到了恰当的问题,则他(她)可能会确定出该人的职业。但如果他们问的问题都不贴题,那就…。
我们在这里遇到了同类情况。(嘿,谁说的“首先,这个专栏既不吸引人又没有乐趣”?还有什么可能比区分本地用户帐户和域用户帐户更吸引人、更有乐趣吗?)假设我们有一个脚本会返回名为 atl-fs-01 的计算机上的本地管理员组的成员。该脚本可能会如下所示:
strComputer = "atl-fs-01"
Set colGroups = GetObject("WinNT://" & strComputer & "/Administrators")
For Each objUser In colGroups.Members
Wscript.Echo objUser.Name
Next
运行该脚本后,将返回类似下面内容的信息:
Administrator Domain Admins kenmyer InfoSec Secure Environment pilarackerman jonathanhaas
这太棒了,但是 KS,正像您指出的那样,我们无法知道 kenmyer(挑选一位)是本地用户还是域用户。就像名人组成的猜答参与者(脚本专家与在我是干哪行的?节目中出现的多数“名人”的知名度相差无几),我们的任务是确定可以提出什么问题才能得以知道他们是本地用户还是域用户。这也不是件轻松的任务,因为我们需要使用 WinNT 提供程序来获得有关这些用户的信息;我们都知道,WinNT 提供程序(与其搭档 Active Directory 不同)只能告诉我们有关某本地计算机上指定帐户的少量信息。
但幸亏我们还有一个问题可以期望从 WinNT 提供程序那里得到答案:“用户的 ADsPath 是什么?”(这样看来,它不是一个只需回答“是”或“否”的问题。但是,我们在这里并不是在真正上演我是干哪行的?节目。这只是一个比喻而已。)用户帐户的 ADsPath 大致相当于文件的 UNC 路径。例如,假设某文件的 UNC 路径是 \\atl-fs-01\public\kenmyer\test.doc。通过此 UNC 路径就可以找到文件 Test.doc 的准确位置:该文件位于计算机 atl-fs-01 的共享文件夹 Public 的 KenMyer 文件夹中。
同样,假定有个如下所示的 ADsPath:WinNT://FABRIKAM/atl-fs-01/Administrator。通过它可以知道在计算机 atl-fs-01 上有一个名为 Administrator 的本地帐户,该帐户是 Fabrikam 域的成员。换句话说,本地帐户的特点是始终将计算机的名称作为 ADsPath 的一部分;而域帐户却不是这样。例如,以下是我们回显管理员组成员的 ADsPath 时所返回的内容:
WinNT://FABRIKAM/atl-fs-01/Administrator WinNT://FABRIKAM/Domain Admins WinNT://FABRIKAM/kenmyerp WinNT://FABRIKAM/InfoSec Secure Environment WinNT://FABRIKAM/atl-fs-01/pilarackerman WinNT://FABRIKAM/jonathanhaas
这时您已经得到答案。如果仔细看一看,您会发现其中有两个路径中出现了字符串 /atl-fs-01/:一个属于 Administrator,一个属于 PilarAckerman。因此,这两个肯定是本地帐户,而其他帐户肯定是域帐户。
但毫无疑问,我们不想这样费神地仔细看,是吧?反之,我们只是希望脚本告诉我们哪些帐户是本地用户,哪些帐户是域用户。以下脚本会做到这点:
strComputer = "atl-fs-01"
strTestString = "/" & strComputer & "/"
Set colGroups = GetObject("WinNT://" & strComputer & "/Administrators")
For Each objUser In colGroups.Members
If InStr(objUser.AdsPath, strTestString) Then
Wscript.Echo "Local user: " & objUser.Name
Else
Wscript.Echo "Domain user: " & objUser.Name
End If
Next
如您所见,此脚本首先是将计算机的名称赋值给一个名为 strComputer 的变量。然后我们采用该计算机的名称 (atl-fs-01),并在其开头和结尾分别加上一个 / (/atl-fs-01/)。此值被赋值给一个名为 strTestString 的变量。我们为何需要在该名称的开头和结尾分别加上 /?老实说,这只不过是一种安全措施。虽然您不太可能有一个名为 atl-fs-01999 这样的域,但是在计算机名称的开头和结尾加上一个 / 有助于确保我们不会由于疏忽而将某个域帐户识别为本地帐户。
设置变量后,我们就可以使用这行代码绑定到计算机 atl-fs-01 上的本地管理员帐户:
Set colGroups = GetObject("WinNT://" & strComputer & "/Administrators")
我们现在要做的是遍历 Members 属性的值,这是一个多值属性,可列出管理员组的每位成员。对于该组的每位用户,我们会使用这行代码来确定是否可在用户的 ADsPath 中的某处找到测试字符串 (/atl-fs-01/):
If InStr(objUser.AdsPath, strTestString) Then
如果找到该字符串,我们则认为这是一个本地用户并回显该结果;如果未找到该字符串,我们则认为这是一个域用户,并回显该结果。所有工作完成之后,我们将得到一个如下所示的清晰的小报告:
Local user: Administrator Domain user: Domain Admins Domain user: kenmyerp Domain user: InfoSec Secure Environment Local user: pilarackerman Domain user: jonathanhaas
这并不是世界上最别出心裁的输出方式,但是它可以告诉您所需了解的信息。
这样看来,此时您已得到了答案:我是干哪行的?的脚本编写版下一次,我们将制作一个恐惧要素节目的脚本编写版。想到这些,您可能要重温吃蜘蛛、喝香蕉鼻涕虫泡制的台克利酒的情形了。同时不要忘了抽些时间在装满癞蛤蟆和鳄鱼的浴缸中坐一下(虽然这是每位脚本专家无论如何都应做的事情)。
欢迎访问您好,脚本专家!- 存档