Thursday, April 02, 2015

Environmental surroundings – creating variables to access AD objects



Hi all out there.

If you are working with logon or startup scripts, you usually access computer or user properties through environment variables like %userdomain% or %computername%.

 

The challenge

Our company often deals with trusts. This means %userdomain% is different from the computer’s domain. Unfortunately there’s no variable %computerdomain% nor %computerdnsdomain%.

In addition, we often access domain, user or computer attributes. Usually, you get the domain from the RootDSE object (https://msdn.microsoft.com/library/aa393248.aspx), but for computers and users, you have to search. And searching results in domain controller load – it would be more convenient if we could bind directly. For that, we need the distinguishedName of our objects.

If we manage to provide distinguished names in environment variables, they can be used easily, and no more searching is required. So we want to provide the following variables:

  • ComputerDomain: The NetBIOS name of the computer’s domain 
  • ComputerDNSDomain: The FQDN of the computer’s domain 
  • ComputerDomainDN: The Distinguished Name of the computer’s domain 
  • ComputerNameDN: The Distinguished Name of the computer account 
  • UserDomainDN: The Distinguished Name of the user’s domain 
  • UserNameDN: The Distinguished Name of the user account 
  • UserSID: The Security Identifier of the user account

The UserSID isn’t really in scope, but hey, we are working on it anyway :-)

 

Where shall I find them?

After defining the variables we want to provide, we have to find out where we can populate these from - there’s no “one stop shop” where we can get them all. Ah, and of course, we want to use native group policy and not a script!

ComputerDomain

The NetBIOS domain name is available in Group Policy Preferences as a predefined variable %DomainName%. You can view this list when pressing F3 in any input field.

ComputerDNSDomain

The FQDN is available in WMI. The class Win32_Computersystem has a property Domain that holds the FQDN.

ComputerDomainDN

The DN of the domain can be found in the RootDSE object in a property called defaultNamingContext.

ComputerNameDN

The DN of the computer isn’t available in any local configuration store – at least I failed to find one. So for this, we have to perform a LDAP search against %ComputerDomainDN% for sAMAccountName=%Computername%$ - the $ sign is required for computer accounts.

UserDomainDN

The DN of the user’s domain isn’t available in RootDSE – this object only holds computer domain related properties. So again we perform a LDAP query against the user's domain to get the domain's DN attribute.

UserNameDN

For the user DN itself, the third LDAP query searches the DN against %UserDomainDN% for sAMAccountName=%username%.

UserSID

The SID is -  like ComputerDomain – available in the predefined GPP variables.

 

How can I implement it?

If you worked with GPP in the past, and if you used Item Level Targeting, you almost have a picture of what we will be doing now :-)
We create a GPO that we link to the domain – we want it to apply to all users and computers, don’t we? Security filter remains Authenticated Users, and no WMI filter is required.


All variables are created through Preferences – Windows-Settings – Environment.

 

 
In the following topics, I’ll show you in detail how we create and populate these values.

ComputerDomainDN

There’s not much about that one. Create a new Variable, name it, select the proper value and you’re done.


The only thing to take care of: Create a System Variable and not a User Variable. If you create a User Variable in the computer part of your policy, it will be created in the SYSTEM profile (HKLM\S-1-5-18)… And for environment variables, I suggest to always use Update as action – so it will work across domains and forests after migrations, too.

ComputerDNSDomain

Here we need to do a little bit more work. First we create the variable and enter its name and value.


The value we entered is a variable again, but this one doesn’t exist at the moment, and it is a temporary variable available only during GPP processing. To create this “inner” variable, we navigate to the Common tab and enable Item-Level Targeting (ILT).


The Targeting… button takes us – guess what - to the Targeting Editor, where we configure the following WMI filter item.


This filter retrieves Win32_Computersystem.Domain and stores the result in our temporary ILT_ComputerDNSDomain variable. And this variable in turn provides the value for %ComputerDNSDomain%.

ComputerDomainDN

Here again, we provide a name and a temporary variable as value.


Again we use ILT to do a LDAP query against RootDSE, as shown in the following screen shot.


We bind to RootDSE and query the attribute defaultNamingContext. The value is stored in ILT-ComputerDomainDN which in turn provides the value for our %ComputerDomainDN%.

ComputerNameDN

The technique for this variable is the same as in the domain DN. But this time, we query AD directly.


We are binding to the domain and are filtering for the computer account. The attribute distinguishedName is stored in a temporary variable that populates %ComputerNameDN%. Remember to add a $ sign to the sAMAccountName filter…

UserDomainDN

For this variable, we cannot use RootDSE because here we only have the computer environment available. So we perform a search in AD. And take care to create a User Variable – if you create a System Variable, things will end up funny on terminal servers or when switching users… Since the steps are the same as before, here’s the ILT filter only.


We bind to %LogonDomain% (an internal GPP Variable again – we could use %UserDomain% or %UserDNSDomain% as well) and store the distinguishedName attribute.

UserNameDN

Again, we need to use a LDAP query to fetch the user’s DN. It is almost the same as for %UserDomainDN% or %ComputerDomainDN%.



Instead of %LogonUser% we could have used %UserName% as well, of course.

UserSID

This one is up to the interested reader – that’s you :-) A tip of mine: Press F3.

 

Last words

That’s it – after the next startup and logon, we have our nice fresh variables at hand, ready to use.

 

(Yes, I’m aware that .local domain suffixes are not recommended…)

Have fun with your own implementation and stay tuned for more posts!