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!
Hi Martin!
ReplyDeleteCongratulations to your MVP. :)
Why are .local suffixes not recommended anymore? Did I miss something? Obviously, but do you have any links/resources to that topic?
Greetings from Vienna,
Mike
Thanks! And yes, I have a link :)
Deletehttp://www.mdmarra.com/2012/11/why-you-shouldnt-use-local-in-your.html