Posted on 04-09-2013 07:14 AM
So right now, I use dsconfigad to tell if a computer is bound to our AD, and while that works beautifully, it is not complete. For example, I can have ```
dsconfigad -showtell me I am bound, but if the computer account has been deleted in AD, from the AD-side of things, -show will still tell me I am bound, though I will not be able to
id $adUserName
```
Does anybody have a better scripting process or workflow that gives me a truer idea of whether or not I am bound and fully functioning from a directory services standpoint to our AD?
Posted on 04-09-2013 07:43 AM
It sounds like you already have the solution with the items in your post. Do a check first with dsconfigad -show to determine if the domain is correct, then do a id -u $someaduser and if that fails, the Mac is not properly bound. You'd have to be sure you're checking an account that never gets deleted though.
This of course all assumes you are in scope of your DC or the id command will fail anyway, so you might want to first do a quick ping check against your AD before continuing.
Something along these lines should work, although it would need to be tested for failure cases.
#!/bin/sh
ping -c 3 -o adserver.org.your.domain 1> /dev/null 2> /dev/null
# If the ping was successful, we're in range of the DC
if [[ $? == 0 ]]; then
# Check the domain returned with dsconfigad
domain=$( dsconfigad -show | awk '/Active Directory Domain/{print $NF}' )
# If the domain is correct
if [[ "$domain" == "org.your.domain" ]]; then
# Check the id of a user
id -u adusername
# If the check was successful...
if [[ $? == 0 ]]; then
echo "The Mac is bound to AD"
else
# If the check failed
echo "The Mac is not bound to AD"
fi
else
# If the domain returned did not match our expectations
echo "The Mac is not bound to domain"
fi
else
# We can't see the DCs, so no way to properly check
echo "Not in range of DC"
fi
Posted on 04-09-2013 07:46 AM
I was just putting an Extension Attribute together as well. My only concern in my was what "id" I use. Obviously you want to use an "id" that you know isn't going to quite, get laid off, or deleted due to inactivity.
# Check to see if it is bound by running the "id" command.
AD=`id XXX`
# Tell us if it's Bound or not.
if [[ "$AD" = "no such user" ]];
then
echo "Not Bound"
else
echo "Bound"
fi
I'm open to any suggestions as well.
Posted on 04-09-2013 07:47 AM
You could search AD for the computer's own computer record. If it can't be found you know either the computer record doesn't exist or the computer isn't talking to AD.
Something along these lines...
ad_computer_name=`dsconfigad -show | grep "Computer Account" | awk '{print $4}'`
dscl /Search read /Computers/$ad_computer_name
Posted on 04-09-2013 07:58 AM
cbrewer's suggestion is good. Using the same logic as above, check to make sure you can talk to AD first, then if the Mac is claiming its bound to AD with dsconfigad -show and finally, if it can find its own record. That makes more sense that checking a user.
@krichterjr - I would use an account that you use for things like binding purposes, if you have something that is designed for that only and no-one logs into. I assume such an account probably wouldn't get deleted from AD, or you'd have other issues to worry about. :)
Posted on 04-09-2013 08:07 AM
@cbrewer - That does make more sense to have the computer check for it's own record than a user. Thanks
Posted on 04-09-2013 04:10 PM
Yea, the problem is that the Macintosh will think it's bound to Active Directory, even if the Computer account is no longer accessible. There's discussion over in this thread: https://jamfnation.jamfsoftware.com/discussion.html?id=7004.
Over there, I posted my Extension Attribute that has worked well for us (and identified other Computer accounts that have failed, requiring us to rebind to AD):
#!/bin/bash
domain="YOURDOMAIN"
user="someuser"
# Can we query a UPN?
domainAns=`dscl /Active Directory/${domain}/All Domains -read /Users/${user} dsAttrTypeNative:userPrincipalName`
if [[ $domainAns =~ "is not valid" ]]; then
result="Invalid"
else
result="Valid"
fi
echo "<result>$result</result>"
Posted on 04-10-2013 06:02 AM
https://github.com/jatoben/dsstatus
Nice like command app here that checks the directory status, combine this with a launchDaemon or agent or JSS policy to check is a client can access the AD / OD etc, you could then script it to restart the opendirectoryd or rebind via script if needed
Posted on 04-10-2013 08:24 AM
@mm2270 just two quick tips :)
In this bit here:
ping -c 3 -o adserver.org.your.domain 1> /dev/null 2> /dev/null
# If the ping was successful, we're in range of the DC
if [[ $? == 0 ]]; then
You can do the following to make things a bit cleaner.
ping -c 1 www.intel.com &> /dev/null
if ping -c 1 www.intel.com &> /dev/null; then
echo 'yes'
else
echo 'no'
fi
or
if grep -q "${input}" "${file}"; then
etc. etc.
Cheers,
Ryan
Posted on 04-10-2013 08:31 AM
dsstatus is essentially performing the same lookup as the ```
dscl /Active Directory/${domain}/All Domains -read /Users/${user} dsAttrTypeNative:userPrincipalName
``` command from above and dscl is already built into all of your systems, no need to compile a binary and distribute.
Posted on 04-10-2013 08:54 AM
@rmanly,
Yeah, I do know of the &> /dev/null approach, and usually use that. The above was pulled from a different project I was working on that actually required the separate stdout and stderr redirections. Too much to explain right now, but the usual approach wasn't giving me the results I wanted, so I had to do it that way. But you're right, under normal circumstances, that does work fine.
Thanks :)
Posted on 04-11-2013 12:50 AM
re - pickerin,
That line only covers AD Binds only, however DSStatus binary can cover ALL directory bindings,
Plus not everyone wants to write long lines of code and troubleshoot them,
All i do is install dsstatus on my macs (part of the complied image), then create an extension attribute as follows
+**#!/bin/sh
/usr/sbin/dsstatus
if [ $? -eq 0 ]
then
echo "<result>Pass</result>"
else
echo "<result>Fail</result>"
fi**+
Thats its, jobs a gooden, much shorted code, much easier and quicker, and times money. I could then scope it to a smart group for "is" "Fail" and then bind or rebind etc.
If i need to check a mac i can do this in Casper Remote, with a single line
dsstatus -v
and get full read out of ALL directory statuses
So much easier for me and covers my Ad and my OD status
Posted on 04-11-2013 11:06 AM
@Bukira "write long lines of code and troubleshoot them", as opposed to downloading source, firing up XCode, and compiling the binary for 32-bit and 64-bit machines. Makes sense.
Yes, the dscl line is only for AD binds, of course that's what the OP asked for.
Posted on 12-20-2013 12:23 PM
use ldapsearch to do a dynamic lookup of the AD and grep for the computer account. Use a service account that has no password expiration. The beauty of ldapsearch is that you can bind to the domain on the fly to do the lookup, so it will work even from unbound Macs.
#!/bin/sh
ComputerName=`scutil --get ComputerName`
LDAPName="your.AD.service.account"
LDAPPasswd="service.account.password"
LDAPAD="domain.example.com"
SearchBase="DC=domain,DC=example,DC=com"
MacOU="ou=Macintosh,cn=Computers,dc=domain,dc=example,dc=com"
IsInAD=$(ldapsearch -LLL -h "$LDAPAD" -x -D "$LDAPName"@"$LDAPAD" -w "$LDAPPasswd" -b "$SearchBase" "name=$ComputerName" | grep name)
Posted on 12-22-2013 05:41 AM
@acdesigntech,
Is there a way to do the same but avoid caching the password and NOT prompting for one either? I just hate the idea of password in the clear.
Posted on 12-23-2013 08:14 AM
I would think you could store a hash of the password for the AD user in a text file in a secure location, and have the script read the hash and convert it on the fly.
Posted on 07-07-2014 09:03 AM
use ldapsearch to do a dynamic lookup of the AD and grep for the computer account. Use a service account that has no password expiration. The beauty of ldapsearch is that you can bind to the domain on the fly to do the lookup, so it will work even from unbound Macs.
#!/bin/sh
ComputerName=scutil --get ComputerName
LDAPName="your.AD.service.account"
LDAPPasswd="service.account.password"
LDAPAD="domain.example.com"
SearchBase="DC=domain,DC=example,DC=com"
MacOU="ou=Macintosh,cn=Computers,dc=domain,dc=example,dc=com"
IsInAD=$(ldapsearch -LLL -h "$LDAPAD" -x -D "$LDAPName"@"$LDAPAD" -w "$LDAPPasswd" -b "$SearchBase" "name=$ComputerName" | grep name)
Could I throw this into an Extension Attribute pulling the data as a string? This is something I would like to be updated on my machines to ensure ones that are on the domain get specific actions.
Posted on 07-07-2014 10:20 AM
you can, but the output of that command is either nothing or the computer name. If you wanted to put some more appropriate info, you can always do something like ```
if [ $? == 0 ]; then
echo "<result>your.domain.name</result>"
else
echo "<result>Not Bound</result>"
fi
```
or similar when defining the EA
Posted on 07-07-2014 10:24 AM
bound and actually functional are two different things, computers can report bound in @acdesigntech solution, but still not be able to authenticate via AD, if a computer is moved to an OU that is for "inactive" computers. most generally the best solution i have seen is to check for an account that should not be on the computer in a local mobile account, such as using my bind account and an id command.
if the id bindaccount command returns unknown user, then its likely lost its trust relationship in windows terms, or needs rebound regardless of what dsconfigad says the bound state is.
Posted on 07-08-2014 10:44 AM
Thanks acdesigntech for the input your addition to your original code works for my process.