views:

1530

answers:

4

I am trying to create scripts/services that allow for waking PCs in a windows domain via WOL. Now i want to give the user the option to select an AD container as a starting point for the waking of PCs contained within. My initial thought is using DHCP as a repository to query for MAC addresses given the hostnames (which i can easily enough pull from AD given the container).

Is there a way to programmatically query the DHCP service/server, passing hostnames and recover the associated MAC addresses?

Or, is there a better/easier way to solve my problem?

A: 

You can't do that with DHCP. DHCP attributes IP from MAC, not the other way around. ARP is what converts IP into MAC but it's the machine itself that answers ARP requests so if it's off it's obviously not gonna answer ...

I suggest you store the MAC in your AD directly (I guess AD supports custom attributes ?)

246tNt
Why can i not do this with DHCP - DHCP clearly contains the info i'm after. I just need to know if i can get access to it programmatically.
cottsak
No, the DHCP server has a database that contains the data you want. But the DHCP _protocol_ doesn't offer anyway of getting to it.
246tNt
ok, i have edited the question to be more clear. i thought maybe you could query the DHCP service/server. maybe WMI or similar
cottsak
+1  A: 

Try dhcpexim.exe from microsoft.

or, if you prefer using pure C. DhcpEnumSubnetClientsV4

J-16 SDiZ
just tried dhcpexim.exe - it barfed on me. couldn't even export the local scope to file. (1) do you know for sure that i can get the MAC address from `DhcpEnumSubnetClientsV4`? and (2) is there a .net managed version of this function (or equivalent)?
cottsak
Check http://www.pinvoke.net/default.aspx/dhcpsapi/DhcpEnumSubnetClients.html use the `ClientHardwareAddress` field
J-16 SDiZ
not verified yet but seems most likely solution
cottsak
A: 

you need to use arp to get a mac adress and doing so In C is a long process.

Mac adresses are hard coded, so if you have X computers go and get X mac addresses and tie them to the AD.

Note that the computer will have to be on to request its mac address.

http://stackoverflow.com/questions/1104661/finding-mac-address-from-ip

Recursion
I was hoping not to get 'arp' answers. I know arp makes the request from the target NIC. I thought it was simple enough to exclude the arp option given that the PCs would be in a powered down state.
cottsak
+1  A: 

No problem; because all of the machines are in your domain you can put together a VBScript that will get the MACAddress(es) from the local machine and store it as an attribute of the computer object in Active Directory.

Here's a quick hack on how to do that (save this as a .vbs-file):

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

Because your clients aren't all in the "Member Servers" OU above you'll need to modify the above script to include a directory search for the strComputerName do get the COMPUTERLOCATION.

When you have a working script, ask your domain administrator to put the script as a start-up script targetting the computers you need to monitor; that way it'll execute whenever a computer boots up. You can also run the script as a scheduled task to get your data from any clients that haven't rebooted or use psexec or some other way you can think of to get the data immediately. Or you can rewrite the script entirely to remote connect to all of your machines and get the data that way (which might not be possible due to local firewalls). Or you could write a small .NET console application which does the same thing, it's up to you...

Also, although there is a networkAddress-attribute defined for computer objects; by default the computer object itself does not have access to write to this property. Because start up-scripts run in the context of the SYSTEM account on the particular machine the easiest thing is to use an attribute that the computer object (SELF) has write access to. The otherTelephone-attribute is multivalued and part of the Personal-Information Property Set which all computer objects has write access to by default. If you want to use the networkAddress-attribute you need to set explicit write access to that attribute for all of your computers.

Also you need to bear in mind that storing the the MAC address in Active Directory means that all of the users in your domain will have read access to it which in turn might possibly (depending on your environment) pose a small security risk.

Per Noalt
i did think about this but i would prefer not to have to deploy script onto every PC. it seems a little less ideal that getting the data from a place on the server where it's already stored. that being said, failing getting the info from the DHCP repository, i think your idea is the next best bet
cottsak
psexec seems to only work when there is an interactive session active on the PC. ie, when there is no user logged on it can't do it's thing. i was so hoping this was a miracle-app.
cottsak