Time Hierarchy in Active Directory

Time is more critical in Active Directory than many admins realise. Time inaccuracy can cause logs to mismatch or things like license failures for anything with DRM. Larger time differences can begin to cause authentication failures since Keberos relies on accurate time or affect replication health.

By default, all AD member machines synchronise with any available domain controller, and in turn domain controllers will synchronise with the PDC Emulator of that domain. This article by Microsoft explains most of the above along with a similar overview of setting up Time Sync correctly. Whenever doing a large audit for an on-premise AD customer or have the chance to build out a new AD Forest, we always recommend ensuring that the PDC gets it’s time from an accurate external time source, and I’ll usually go as far as setting up a set and forget GPO to manage this to ensure newer PDCs get this treatment.

To ensure we target only our PDC emulator we can create a WMI filter that we can use against the Group Policy object that we’ll be creating shortly. The following WMI query will filter a PDC Emulator in an AD environment

select * from Win32_ComputerSystem where DomainRole = 5

Next step is to create the Group Policy Object, in this case I’ve create a PDC External Time Sync GPO, open it up and go to Computer Configuration > Policies > Administrative Templates > System > Windows Time Service > Time Providers. We now want to configure the following settings as follows

Set Configure Windows NTP Client to Enabled
For NtpServer enter your NTP servers details: ntp.nml.csiro.au,0x9 ntp.monash.edu,0xa
For Type set to NTP
Set Enable Windows NTP Client to Enabled
Set Enable Windows NTP Server to Enabled

It’s also important to ensure you’re specifying the correct flags to ensure reliable time, with my example I’ve specified a primary and secondary time source to minimise any potential drift when Windows decides to synchronise. By making the primary NTP server flag 0x9, we made it “Client 0x08 + SpecialInterval 0x01” and as for the second NTP time server.
By making the secondary NTP peer flag 0xa, we made it “0x08 Client + 0x02 UseAsFallbackOnly”.The following options are available to use with w32tm.

0x01 SpecialInterval
0x02 UseAsFallbackOnly 
0x04 SymmatricActive 
0x08 Client

The final GPO should look something like this with the WMI filter attached an linked to an OU with your DCs.

Since I’m based in Australia I’ll tend to use au.pool.ntp.org or use the Australian Governments NMI NTP service, which requires you to get your public IP whitelisted but is unlikely to be poisoned or attacked unlike the NTP Pool project.

Hope that helps.

Hide the Bing button in Edge

I’m not a fan of the Bing button that now appears in Edge. Microsoft seem to have rushed it out as there isn’t an easy way to remove it. We’ll do this via a registry key (that can also be deployed via Group Policy)

Close out of Microsoft Edge completely and open the Registry Editor and navigate to HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft. Right-click on the Microsoft folder and select New > Key from the context menu to create a new Key and name it Edge. Enter the Edge folder and then right-click an empty area on the right and choose New> Dword (32-bit) value, name this value HubsSidebarEnabled . Its default value is 0, which is correct. Now close Regedit and open Microsoft Edge again and navigate to edge://policy and click on the Reload Policies button that appears – the button should disappear.

As of Edge version 114 (Edge Dev Channel) users can do this via Edge settings and navigate to Sidebar > App and notification settings > Discover and then Disable the Show Discover toggle at the top.

Enabling BitLocker with Group Policy and backing up Existing BitLocker recovery keys to Active Directory

So getting BitLocker enabled in an Active Directory environment is fairly painless and helps to get your end user devices more Secure.  I’ll outline the steps you need to take to enable it as well as get the recovery keys stored in Active Directory.  I’ll also dive into replicating this setup on Azure AD/Intune in a future post.

First thing is to create a new GPO (i.e. Configure – BitLocker) – Edit it and navigate to Policies > Administrative Templates > Windows Components > BitLocker Drive Encryption. Enable the following Options:

  • Choose drive encryption method and cipher strength (Windows 10 Version 1511 and later)
  • Choose drive encryption method and cipher strength (Server 2012, Win 8.1 etc…)
  • Choose how users can recover BitLocker protected drives
  • Store BitLocker recovery information in Active Directory Domain Services

Then go down one folder into Operating System Drives and enable the following:

  • Choose how BitLocker protected operationg system drives can be recovered

Once you’ve set this all up, it should look something similar to the image below.

Now target the GPO to some machines and if you’re running 1809 (from what I’ve discovered so far) or later you’ll notice them start the BitLocker process to encrypt automatically.  If not then you may need to check and ensure the TPM is enabled for the device (as we haven’t specified to encrypt devices without a TPM in this case).

What happens if you have already enabled BitLocker but now want to store the recovery keys in Active Directory? With this GPO set it will allow windows to write the recovery key to AD however we need to use the manage-bde utility, that is a command based utility that can be used to configure BitLocker

manage-bde -protectors -get c:
for /f "skip=4 tokens=2 delims=:" %%g in ('"manage-bde -protectors -get c:"') do set MyKey=%%g
echo %MyKey%
manage-bde -protectors -adbackup c: -id%MyKey%

I saved that as a batch file and ran that on the machines that had already been encrypted prior to rolling out the GPO.  Once run, it escrows the key into Active Directory.

The last bit you will need to do so you can actually see the keys in the Properties tab or via the Search function in Active Directory Users and Computers, ensure that the BitLocker RSAT is enabled in Server Features and Roles.

Deploy Firefox in the Enterprise with uBlock Origin, HTTPS Everywhere and Privacy Badger using Group Policy

So we’ve been deploying Firefox for quite a while pretty much everywhere we can however, only recently have we started standardising the deployments across the organisation’s that we manage. We’ve deployed Internal Root CAs using the CCK2 method to improve our user experience with Deep Packet SSL inspection however setting up configurations and extensions and having that consistent was a challenge. Recently I learnt that Mozilla begun developing Group Policy Objects not long ago and that now allows for enterprise management straight into Firefox without the fuss. In this article I’ll go through setting up uBlock Origin, HTTPS Everywhere and Privacy Badger which are our go to Extensions for end-user protection.

To deploy Firefox (or any windows application), you generally want to use an MSI based installer (for better control and management). Mozilla have now been building them for a shot while via their Enterprise Deployment Support page for beta and standard releases. If you are after the Extended Support Release (ESR), visit the FrontMotion download page (they also offer a number of other services such as a custom packager). In a managed environment you’d either use Group Policy to deploy software or System Center Configuration Manager or some other form of MDM (ala InTune). The MSI should be in a network share accessible by all machines, you would then be imported either into Policies > Software Settings > Software installation for Group Policy (then Right-Click, New > Package) or an Application under the Software Library for Config Manager and pushed out. There are much better guides than what I can fit in here so please Google if you’re unsure. In our case, I used Config Manager and since we’re upgrading and I’ve setup a Supersedence rule like below.

Once Firefox is being deployed we need to get these extensions onto the machines, so the first part is getting the URLs of the extensions you wish to deploy. Visit the add-on store and start searching for what you’re after. For our example, as mentioned we will be installing uBlock Origin, Privacy Badger and HTTPS everywhere. When you are at the add-on page, right-click on the Add to Firefox button and select Copy Link Location and save that for later. Once you have your list of Extensions it should look like something similar to the below (I’ve removed the tracking string at the end).

https://addons.mozilla.org/firefox/downloads/file/1672871/ublock_origin-1.18.4-an+fx.xpi
https://addons.mozilla.org/firefox/downloads/file/1688114/privacy_badger-2019.2.19-an+fx.xpi
https://addons.mozilla.org/firefox/downloads/file/1669416/https_everywhere-2019.1.31-an+fx.xpi

Next is to get the Group Policy Definitions from Mozilla and load them onto your Active Directory Group Policy. I’d highly recommend you have a Group Policy Central Store setup as it makes managing this stuff a whole lot easier. Download the latest version or ones that match your deployment of Firefox from the Mozilla GitHub Releases page, unzip and then copy across those files to the Group Policy Central Store or required location. Now the fun part.

Create a new Group Policy Object, in my case Configure – Firefox and then open it up, and navigate to the following policy branch; Computer Configuration > Policies > Administrative Templates> Mozilla > Firefox > Extensions. Here we will be enabling Extensions to Install. Using the list we compiled earlier, enter the URLs one by one into the list so it will look like something similar to the below.

The next step I’d recommend, is we want to stop or prevent our end users from being able to remove these extensions/protections. To do this we need to get the Extension IDs, so fire up Firefox and install the list of Extensions we compiled earlier (if you didn’t already for testing). Now the easiest way I’ve found of getting the Extension IDs is to use the in-built memory profiler of Firefox. In the address bar enter about:memory and once it loads under Show memory reports group, click Measure. Do a search for Extensions and you’ll get to a list of all currently running extensions. Now extract everything for the id key (in this case a GUID but can be text as well);

Extension(id={d634138d-c276-4fc8-924b-40a0ea21d284}, name="1Password X – Password Manager", baseURL=moz-extension://31872614-f67c-4cda-84e4-18c0515c8b48/

The above is an example of what you’ll find in the list (using 1Password). Below is what we’ll be entering into the Prevent Extensions from being disabled or removed based on our setup so far – with the last line belonging to Privacy Badger.

[email protected]
[email protected]
jid1-MnnxcxisBPnSXQ@jetpack

Now that we have the list of Extension IDs we want to enter these into the Prevent extensions from being disabled or removed Group Policy setting located in the same branch as Extensions to Install. Again, enter them into the list one by one until you have something similar

Once that is configured, apply the Group Policy Object to your Test Machines preferably with Mozilla Firefox installed on it, log in and do a gpupdate /force with the end result being those Extensions magically appearing as per the below image.

Hope that helps.

Reset the Default Domain and Domain Controller Group Policy Objects to their out of box state

So, I recently inherited a small client with SBS 2011 and their previous IT admin only ever used the Default Domain Policy to apply computer and users settings (such as mapped drives and printers). Microsoft has quite a strong recommendation of best practice for the two policies which goes along the lines of;

  • Default Domain Policy GPO should only be used to manage the default Account Policies settings, Password Policy, Account Lockout Policy, and Kerberos Policy.
  • Default Domain Controllers Policy GPO should only be used to set user rights and audit policies.

So I first needed to create separate GPOs to store these custom settings and then a way to clear out all of those changes and revert them back to their default state.  So how do you go about reversing the damage if you don’t have backups far enough? In comes a small utility called dcgpofix which resets these two Group Policy Objects to their default settings. Launch an admin command prompt window and run the following command;

dcgpofix /target:both

Once executed it will confirm you want to restore them to their out of box defaults, which we can confirm with a couple of Y responses and then bang they should be restored, see the screen shot for an example of it running in my test lab.

How to easily Check your SPN and Delegation settings for SQL Server in an Active Directory environment

I was recently setting up some Linked SQL Servers for a customer to perform queries against a database on one server through another. One of the things you need to get right when setting up linked servers when using Service accounts in Active Directory is SPNs (or Service Principal Names) and Authority to Delegate (for Kerberos authentication) which can sometimes be quite cumbersome through ADUC or ADSI edit.

I then stumbled upon a little tool from Microsoft called the Microsoft Kerberos Configuration Manager for SQL Server. Running this little tool on the two SQL servers I could quickly and more easily see the SPNs (see picture to the right) and Delegation permissions.  As one server was quite old (and before my time) I could easily see that the SPNs configured for that particular service account were incorrect and the tool even allows you to fix this by generating the correct SPN. Hope that helps save some time in the future.

Get a list of users in Active Directory who have not logged in for specified number of days using PowerShell

A client is currently in the planning stages of doing a migration to Azure AD and Office 365 and one of the things we needed was a list of users who have not logged on in the last few months but are still active in our AD.

Well it’s PowerShell to the rescue again (with Visual Studio Code my IDE of choice) with the following snippet of code which will query an AD environment looking for accounts which haven’t been touched in this case for 90 days and give me a nice CSV of their name and last logon timestamp.

import-module ActiveDirectory 
$domain = "adatum.com.au" 
$DaysInactive = 90
$time = (Get-Date).Adddays(-($DaysInactive))
 
# Get AD Users with lastLogonTimestamp less than time specified and is enabled
Get-ADUser -Filter {LastLogonTimeStamp -lt $time -and enabled -eq $true} -Properties LastLogonTimeStamp |
 
# Output Name and lastLogonTimestamp attributes into CSV
select-object Name,@{Name="Stamp"; Expression={[DateTime]::FromFileTime($_.lastLogonTimestamp).ToString('yyyy-MM-dd')}} | export-csv Inactive_Users.csv -notypeinformation

Save the above into a PS1 and then run this on a server which has the AD PowerShell modules (usually one of your DCs) and will then create a CSV located where the script is with a list of all the users who are still enabled but haven’t logged on in your environment.

Remote Desktop is Blocked in Windows Firewall even though Group Policy Setting is set to allow

So I’m going through and trying to automate a lot of things in our environment (one thing you should always try and do as a SysAdmin is to automate repetitive tasks) and to help me achieve this I’m using Group Policy, step one is enable Remote Desktop to all of our Servers automatically. Created the Group Policy Object, allowed Remote Desktop Connections and also setup a list of IP Addresses to allow connections from.

After a while I added another IP Address to the exemptions and the next morning I found that I was no longer able to RDP directly to some of my servers, wondering what had happened I logged into our Hyper-V host (where RDP was still working) and I logged onto one of the affected servers. I firstly went and checked to ensure that RDP was still enabled, yup sure is, I then went and checked the Firewall and I spotted a Block and Deny All rule that I was sure I didn’t create. So I went back over the GPO that I had applied, went into the IP exceptions and turns out there was a SPACE separating one of the IP Addresses after the comma. Removed that space, performed a GPUpdate on the affected machines and Remote Desktop started working again.

 

How to allow an Active Directory Certificate Authority to generate Certificates with a Subject Alternative Name attribute

Starting with Google Chrome 58 no longer trusts certificates without the Subject Alternative Name attribute, so this makes it a little troublesome for those with internal CAs where you rely on them for Software Development. We noticed last week that some end users couldn’t hit an internal application over HTTPS, but was fine in Firefox and IE. After a quick search, I’d found the culprit was a change in the behavior of Google Chrome to adhere more stringently to RFC 2818. So I went to work on our CA in enabling certificates to be requested with the Subject Alternative Name Attribute.

Start an administrative command prompt on one of your intermediate CA server and issue the following command;

certutil -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTALTNAME2

You’ll then need to restart Certificate Services. Once done, best thing to do is to create a new Template (ours is called Dev Web Servers) along with giving the right permissions to allow users or machines to enroll and begin issuing the new certificates. We do this manually at the moment via the Web interface so when requesting a certificate you need to fill in the attribute text field with the following (like the image to the left)

san:dns=hostname1&dns=hostname2&dns=devweb2

Fill in the dns= part until you cover off all of the sites you need. Complete the request to install the certificate onto your server and adjust the SSL bindings to use the new certificate.

Fixing The trust relationship between this computer and the primary domain failed Error when restoring a Snapshot or Old Virtual Machine

I had a VM snapshot/checkpoint running for several months in my test lab and after reverting the snapshot back I went to login to the machine and got the dreaded Trust relationship between this computer and the primary domain failed error message.  So I logged in as a local admin onto that machine, opened up an Administrative PowerShell window and entered the below commands.

$cred = Get-Credential – (enter domain admin account when prompted)
Reset-ComputerMachinePassword -Credential $cred -Server ada-dc-02.adatum.com.au

Replace the server at the end with a FQDN of one of your Domain Controllers.  As I wasn’t authenticated to the domain, I needed to enter my domain admin credentials by using the Get-Credential cmdlet and then using those stored credentials to issue the Reset-ComputerMachinePassword cmdlet.

So there you have it, no more re-joining a computer to the domain.