我正在尝试创建允许通过 WOL 在 Windows 域中唤醒 PC 的脚本/服务。现在我想让用户选择一个 AD 容器作为唤醒其中包含的 PC 的起点。我最初的想法是使用 DHCP 作为存储库来查询给定主机名的 MAC 地址(在给定容器的情况下,我可以很容易地从 AD 中提取)。
有没有办法以编程方式查询 DHCP 服务/服务器、传递主机名并恢复关联的 MAC 地址?
或者,有没有更好/更简单的方法来解决我的问题?
我正在尝试创建允许通过 WOL 在 Windows 域中唤醒 PC 的脚本/服务。现在我想让用户选择一个 AD 容器作为唤醒其中包含的 PC 的起点。我最初的想法是使用 DHCP 作为存储库来查询给定主机名的 MAC 地址(在给定容器的情况下,我可以很容易地从 AD 中提取)。
有没有办法以编程方式查询 DHCP 服务/服务器、传递主机名并恢复关联的 MAC 地址?
或者,有没有更好/更简单的方法来解决我的问题?
这有点古怪,似乎无法以编程方式查询 DHCP 服务器。感谢cottsak提出这个问题。我知道 DHCP 协议没有这样的查询,但我认为微软的可执行文件可能有某种方式可以从命令行解决它。我在任何地方都没有听到任何人说没有这种情况,但一定是这样。
哇,等一下……我想我找到了我们要找的东西:NETSH。参看:
http://social.technet.microsoft.com/Forums/en/ITCG/thread/afb4be16-09bd-4260-b515-8323d85d4ccb
如果您在 DHCP 服务器上打开命令提示符,则可以运行以下命令:
netsh dhcp 服务器范围 192.168.1.0 显示客户端
并得到这样的报告:
10.10.98.53 - 255.255.255.0 -00-0c-29-02-a4-09 - 永不过期 -D 10.10.98.54 - 255.255.255.0 - 00-22-19-10-29-75 -1/21/2012 8 :39:25 AM-D
耶!感谢您的线程!如果不是这个,我会缩小搜索范围到 technet 并找到那个。
或者,如果您更喜欢使用纯C。DhcpEnumSubnetClientsV4
没问题; 因为所有机器都在您的域中,您可以将一个 VBScript 放在一起,该 VBScript 将从本地机器获取 MACAddress(es) 并将其作为计算机对象的属性存储在 Active Directory 中。
这是一个关于如何做到这一点的快速技巧(将其保存为 .vbs 文件):
Option Explicit
Const ADS_PROPERTY_UPDATE = 2
Const COMPUTERLOCATION = "ou=Member Servers,dc=yourdomain,dc=com"
Const ATTRIBUTETOUSE = "otherTelephone"
Dim wshNetwork, strComputerName
Set wshNetwork = WScript.CreateObject("WScript.Network")
strComputerName = wshNetwork.ComputerName
Dim objWMIService, colNetCards, objComputer, objNetCard
Set objWMIService = GetObject("winmgmts:\\" & strComputerName & "\root\cimv2")
Set colNetCards = objWMIService.ExecQuery("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
Set objComputer = GetObject("LDAP://cn=" & strComputerName & "," & COMPUTERLOCATION)
For Each objNetCard in colNetCards
objComputer.PutEx ADS_PROPERTY_APPEND, ATTRIBUTETOUSE, Array(objNetCard.MACAddress)
objComputer.SetInfo
Next
因为您的客户端并不都在上面的“成员服务器”OU 中,所以您需要修改上面的脚本以包含目录搜索以strComputerName
获取COMPUTERLOCATION
.
当您有一个工作脚本时,请您的域管理员将该脚本作为启动脚本,针对您需要监控的计算机;这样它就会在计算机启动时执行。您还可以将脚本作为计划任务运行,以从尚未重新启动的任何客户端获取数据,或使用psexec或您能想到的其他方式立即获取数据。或者您可以完全重写脚本以远程连接到您的所有机器并以这种方式获取数据(由于本地防火墙,这可能是不可能的)。或者您可以编写一个小型 .NET 控制台应用程序来执行相同的操作,这取决于您...
此外,虽然networkAddress
为计算机对象定义了 - 属性;默认情况下,计算机对象本身无权写入此属性。因为启动脚本在SYSTEM
特定机器上的帐户上下文中运行,所以最简单的方法是使用计算机对象 ( SELF
) 具有写入权限的属性。-属性otherTelephone
是多值的,并且是个人信息属性集的一部分,默认情况下所有计算机对象都具有写入权限。如果要使用 - 属性,则networkAddress
需要为所有计算机设置对该属性的显式写入访问权限。
您还需要记住,将 MAC 地址存储在 Active Directory 中意味着您域中的所有用户都将拥有对其的读取访问权限,这反过来可能(取决于您的环境)会带来很小的安全风险。
像网络那样做。
抓取SharpPcap(C# 的 Pcap 包装器)和 WinPcap (Windows) 或 libpcap (*nix)。编写一个创建 SNMP 数据包以查询路由器上的 ARP 表的应用程序。
注意:ARP(地址解析协议)表是包含IP地址到MAC地址映射的表。
我最近一直在考虑实现一个这样做的例子,但我还没有一个可以展示。完成后,我将确保将其添加到项目源代码树中的 SharpPcap 示例中。
你不能用 DHCP 做到这一点。DHCP 将 IP 属性来自 MAC,而不是相反。ARP是将IP转换为MAC的东西,但它是机器本身回答ARP请求,所以如果它关闭它显然不会回答......
我建议您直接将 MAC 存储在您的 AD 中(我猜 AD 支持自定义属性?)
您需要使用 arp 来获取 mac 地址,并且在 C 中这样做是一个漫长的过程。
Mac 地址是硬编码的,所以如果你有 X 台计算机,去获取 X mac 地址并将它们绑定到 AD。
请注意,计算机必须打开才能请求其 MAC 地址。
是的,不用担心,如果 PC 有租约,您可以直接从 DHCP 中提取此信息。
知道如何右键单击并在 DHCP 中添加预留吗?
在 DHCP 中查找“唯一 ID”。这是MAC地址,没有冒号。