I am currently using the following code to see if the current machine has joined a domain. I was wondering if there is a more efficient way of doing this. I am currently using the JNA to receive the Secur32
instance variable.
public static String CurrentDomainName() {
char[] userNameBuf = new char[10000];
IntByReference size = new IntByReference(userNameBuf.length);
boolean result = NativeMethods.Secur32.INSTANCE.GetUserNameEx
(Secur32.EXTENDED_NAME_FORMAT.NameSamCompatible, userNameBuf, size);
if (!result)
throw new IllegalStateException("Cannot retrieve name of the currently logged-in user");
String[] username = new String(userNameBuf, 0, size.getValue()).split("\\\\");
return username[0];
}
public static String CurrentMachineName() {
try {
java.net.InetAddress localMachine = java.net.InetAddress.getLocalHost();
return localMachine.getHostName();
} catch(UnknownHostException e) {
e.printStackTrace();
}
return "Error";
}
This is the final function that returns the result:
public static Boolean IsDomainJoined() {
return !Windows.UserInfo.CurrentMachineName().equals(CurrentDomainName());
}
1 Answer 1
Different approaches to determine the domain membership of a computer
Usage of command line tools
If you use command line tools you have the burden to parse the output of the process.
A naive implementation to execute command line tools in windows:
public class CmdExecutor {
private String cmdString;
public CmdExecutor(String cmdString) {
this.cmdString = cmdString;
}
public void execute() throws IOException, InterruptedException {
final Process process = Runtime.getRuntime().exec("cmd /C " + cmdString);
final BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = br.readLine();
while (line != null) {
System.out.println(line);
line = br.readLine();
}
process.waitFor();
}
}
wmic
public static void main(String[] args) throws IOException, InterruptedException {
new CmdExecutor("wmic computersystem get domain").execute();
}
systeminfo
public static void main(String[] args) throws IOException, InterruptedException {
new CmdExecutor("systeminfo | findstr /B /C:\"Domain\"").execute();
}
LDAP access
If you have access to the LDAP interface of your Active Directory you can query LDAP for a specific computer account:
(&(objectClass=computer)(name=MyPC))
Comparing the approches
Using JNA and the command line approaches on the local machine can only return the local state. The only reliable information you can get from LDAP. This especially relates to disabled or deleted computer accounts.
Querying LDAP and evaluating the result (including server not reachable) may be difficult. But as the ldap schema does not change frequently you can rely on the query parameters and the result fields to remain stable.
Command line tools and Windows system libraries tend to change in usage from time to time. That is a lot more probable than in LDAP. So you have to expect to adapt the result parsing or the parameter structure.
This you can say for the command line tools as well, but there is a higher abstraction. You can deal with standard command line tools very well and easily provide alternate implementations. This is even possible with JNA but you a dealing with system libraries and not with command line tools. (My personal view on this is that command line tools are easier to handle).
-
\$\begingroup\$ The "systeminfo" command is very useful for other stuff too! I didn't know that even existed thanks! \$\endgroup\$JWCompDev– JWCompDev2017年02月05日 03:07:54 +00:00Commented Feb 5, 2017 at 3:07