Apply GPO based on installed Server Feature (WMI Filtering)

Today I came across a server that had been placed in a sub-OU by a colleague simply for the purposes of applying a GPO to it. The GPO in question was configured to make some changes to the BranchCache feature.

If the policy needs to apply to a subset of all servers in an OU, it would be cleaner to apply a WMI filter to the GPO itself rather than limiting the scope of the GPO by explicit security filtering.

Here’s what I did to clean it up:

  1. Created a WMI filter in GPMC:
    SELECT * FROM Win32_ServerFeature WHERE Name like ‘branchcache%’
  2. Applied the filter to the GPO in question
  3. Applied the GPO to the OU where the server originally lived
  4. Moved the server back to the original OU

This same strategy could be used to apply a policy to all IIS servers, all file servers, etc. The possibilities are practically limitless.

You could even filter on something like Win32_Product to apply a specific GPO to Exchange servers, for example.

SELECT * FROM Win32_Product WHERE name = 'microsoft exchange server'

Don’t use Win32_Product. It’s not a good idea, and even Microsoft warn against using it.

Use PowerShell to Determine the NetBIOS domain name given a specific ADUser

I was writing a script to synchronise AD users to Umbraco using the ActiveDirectory PowerShell snapin today, and I came across a scenario that’s not covered by the properties returned by Get-ADUser.

I had this specific requirement:

Determine the NetBIOS domain name given an AD User object

This is distinct to getting the current domain for the logged-in user, which is a piece of cake:

$env:userdomain

I was iterating through a list of users from Get-ADUser, and needed to know the NetBIOS domain name for each user.

Given the $user variable already exists – for example by doing this:

$user = Get-ADUser -Filter * -ResultSetSize 1

Running the below command will return the NetBIOS name for that user:

(Get-ADDomain (($user.DistinguishedName.Split(",") | ? {$_ -like "DC=*"}) -join ",")).NetBIOSName

I love how you can achieve multi-step procedures in little one-liners like this.

Breaking it down

Split the User DN into an array

# DistinguishedName : CN=Joe Bloggs,OU=Users,OU=Sydney,DC=contoso,DC=com

$user.DistinguishedName.Split(",")

# Becomes:
# CN=Joe Bloggs
# OU=Users
# OU=Sydney
# DC=contoso
# DC=com

Pipe the array to Where-Object (alias: ?) and select only the non-user-parts of the distinguished name

| ? {$_ -like "DC=*"}

# Results in:
# DC=contoso
# DC=com

Join the resulting array back up into a domain distinguished name

-join ","

# Results in:
# DC=contoso,DC=com

Grab the NetBIOSName property returned by Get-ADDomain

(Get-ADDomain <the above code>).NetBIOSName

# Returns:
# CONTOSO

Braindump: ADDS NTP Configuration via GPO

There’s a great article on the Microsoft AD team blog about configuring the authoritative time server automatically via group policy and WMI filters. This may save you from domain time sync issues if your PDC emulator role eventually ends up moving to a different server.

http://blogs.technet.com/b/askds/archive/2008/11/13/configuring-an-authoritative-time-server-with-group-policy-using-wmi-filtering.aspx

Their article covers how to set up the WMI filter, but doesn’t address the settings for NTP. Those are listed in detail under this support note.

These are the settings I’ve implemented in my GPO using Admin Templates->System->Windows Time Service:

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesW32TimeConfig]
"MaxNegPhaseCorrection"=dword:00000708
"MaxPosPhaseCorrection"=dword:00000708
"AnnounceFlags"=dword:00000005
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesW32TimeParameters]
"Type"="NTP"
"ntpserver"="au.pool.ntp.org,0x1"
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesW32TimeTimeProvidersNtpClient]
"Enabled"=dword:00000001
"SpecialPollInterval"=dword:00000384
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesW32TimeTimeProvidersNtpServer]
"Enabled"=dword:00000001

VBScript to disable all users in specified OUs

When staff members leave the organisation, we move their account to a sub-OU named “Leavers” under their office’s OU. This triggers their mailbox to be archived in Enterprise Vault.

I thought it was about time to put together a quick scheduled task to ensure that all these “leavers” were automatically disabled and hidden from the Exchange address lists without IT manually having to do it.

I came across this handy and concise example, and modified it to run through a group of OUs while doing what I needed it to do.

Here’s the code. As always, run at your own risk, and test it before putting it into production:

On Error Resume Next

Dim arrLeaverOrgUnits, objOU
arrLeaverOrgUnits = Array("LDAP://OU=Leavers,OU=Sydney,DC=contoso,DC=com",_
                          "LDAP://OU=Leavers,OU=Melbourne,DC=contoso,DC=com")

For Each strOU in arrLeaverOrgUnits
  Set objOU = GetObject(strOU)
    ' Let's be extra-paranoid here, and make sure we're only working on the leavers OU
    '  in case someone adds the wrong OU into the array above
    If objOU.Name <> "OU=Leavers" Then Exit For
    
    ' Loop through each object in the current OU
    For Each objObject In objOU
      ' If the current object is a user
      If objObject.class="user" then
        'Disable the account
        objObject.AccountDisabled = True
        ' Hide the account from the Exchange address lists
        objObject.Put "msExchHideFromAddressLists", True
        ' Write the information back to the user object in AD
        objObject.SetInfo
        
        'WScript.Echo objObject.Name & " disabled and hidden from Exchange address lists"
      End if
    Next
  Set objOU = Nothing
Next