Ryan Adams Blog

SQL, Active Directory, Scripting

Browsing Posts in Windows Server

A co-worker messaged me today to ask for my help in giving one of our development domain controllers some additional disk space.  Due to space constraints and lack of funding I had to get creative last year in redesigning our development environment to handle four more servers for a new application with no new hardware.  I had 3 physical servers so here is how I set them up.  The first runs Hyper-V with four VMs that are our domain controllers.  The second and third servers run VMWare VSphere and each host two virtual machines for the new application.  The server he needed to get additional space on was our domestic domain controller running in Hyper-V.

CAUTION!!!!

I highly suggest that you make a copy of your VHD file after you shut the guest machine down.  Backups are Gold!

Prepare the Guest

Your first step is to shut down the guest machine.  Next you need to increase the virtual disk so it will be presented to the guest when you turn it back on.  It’s very simple and here is how:

  1. Open Hyper-V Manager
  2. Select the desired Hyper-V server in the left pane
  3. Select the desired virtual machine in the center pane
  4. Select Edit Disk in the right pane
  5. The edit virtual disk wizard opens. Select next on the welcome page
  6. On the Locate Disk page click browse and select the virtual disk for your virtual machine
  7. On the Action page select Expand
  8. On the Configure Disk page change the disk size to the new desired size. Current and maximum sizes are provided in the window.

Prepare the VHD

We are going to use the tried and true diskpart.exe to expand the disk.  Remember that this is a system partition and the general rule is that system partitions cannot be expanded without a third party tool.  Let’s prove them wrong by using diskpart on the drive while the OS is not running.  There are three ways I can think of to do this.  The first is booting the machine to floppy and running diskpart from there.  I know this can be done, but I personally have never been successful and have turned to third parties for the solution.  However, this is a virtual machine and not physical so I have other means of running diskpart on the drive without the OS running.  That leads me to the second option of attaching the drive to another virtual machine as a secondary drive.  You could then run diskpart on that partition from the other virtual machine.  The third option is what I used and will describe here.  It should be noted that Windows Server 2008 and Windows 7 can mount VHD drives natively and will not require the tool I will be using.  Here’s how we do it:

  1. Download Virtual Server 2005 R2 SP1 from HERE
  2. Install Virtual Server using the custom option and select ONLY the VHD Mount
  3. Open a command prompt
  4. Type vhdmount /p /f <Fully Qualified Path to your VHD File>
  5. Type diskpart.exe
  6. Type List Volume
  7. Type Select Volume <2 or whatever volume number is your VHD>
  8. Type Detail Volume to verify the free space and that your selected the correct drive
  9. Type Extend
  10. Type Detail Volume to verify the free space is now zero and the size is what you expect
  11. Type Exit
  12. Type vhdmount /u <Fully Qualified Path to your VHD File>

Start up your virtual machine and you should now see your boot partition extended!

Every so often I get a call from a user saying he is trying to access some reports I wrote for him in SSRS 2005 and he gets the following error:

Cannot find or load System.EnterpriseServices.dll version=2.0.0

I’m not a .NET expert so the first thing I do is Boogle it.  You will get a ton of hits on this error, but none of them talk about the solution or cause I found.  Most of them tell you to copy c:\windows\microsoft.net\framework\v2.0subversion\system.enterpriseservices.dll to c:\windows\assembly.  All this does is register the missing DLL and put it back into the GAC (Global Assembly Cache).  The good news is that this method can save you from having to re-install the .Net Framework.  If you find that you do need to re-install, then I would suggest to first try re-applying the latest .Net Framework service pack first.

Although this may fix the issue, it did not explain why it kept happening on this system and at no defined interval.  What I finally figured out is that it happens every time Windows Update has downloaded a .NET Framework Service Pack and is ready to install it.  I still cannot explain how or why this would unregister the DDL from the GAC, but once I install the updates, Bingo!

Want to speed up your AD replication?  You might want to if users call your helpdesk for a password reset, try to login right after the reset, and they still get denied.  Maybe you use some sort of identity management software or web site automation where users can update things like title or phone number, and they don’t see their changes for awhile.  That might be acceptable in some environments, but certainly not in all of them.

AD has something called Urgent Replication where certain events like account lockouts replicate immediately, as opposed to the default replication interval.  What if your network has very large pipes across the forest and you can afford to have everything replicated immediately?  Keep in mind that large network pipes might not be necessary in every scenario.  Enabling change notifications means constant updates, but they are small in size.  On the other hand, using the default replication interval means less traffic, but larger amounts of data.  It is up to you to decide what is best for your environment.

So what are Change Notifications and how do I enable them?  Enabling Change Notifications tells AD that all attributes are to be considered urgent replication.  Instead of a domain controller queuing up all the changes it receives and then replicating them at its defined replication interval, it replicates all changes as they occur.  Here is how you can enable them:

  1. Open ADSI edit
  2. Connect to and expand the Configuration container
  3. Navigate to Sites-> Inter-Site Transports container
  4. Select CN=IP – Note you cannot enable change notification for SMTP links
  5. Right click and select properties for each site link object for the sites you wish to enable
  6. Select the “Options” property
  7. In the edit attribute box, if the value is <not set> then change it to 1.  If it contains a value, you must get the new value by performing a Boolean BITWISE-OR calculation on the old value.  This would be old_value BITWISE-OR 1.

 

The above will enable change notifications on all connection object in those sites that are managed by the KCC.  If you have created any manual connection objects, which are not managed by the KCC they will not inherit the change notification setting from the site settings.  You will have to set each of those individually.  Here is how:

  1. Open ADSI edit
  2. Connect to and expand the Configuration container
  3. Navigate to Sites-> My sitename with manual connections-> Servers-> My Server-> NTDS Settings
  4. Right click and select properties for each manual connection object in this folder.
  5. Select the “Options” property.  Note that if the value is 1 then it is an intrasite connection object and owned by the KCC.  If the value is 5 then it is an intersite connection object and owned by the KCC.  If it is one of these values and owned by the KCC then do NOT change it.  It should be changed at the site level instead, otherwise if you change the value on a connection object that is owned by the KCC you force it out KCC control and the KCC will no longer manage it.
  6. In the edit attribute box, change the value to 12.

 

How much of a difference can this really make?  Well mileage will certainly vary according to network and forest architecture.  I implemented this for a large world wide fortune 100 company with large network pipes.  Here are the total convergence times across each geographic region and also forest wide.

EMEA

Before – 24 minutes 25 seconds

After – 48 seconds

Asia Pacific

Before – 9 minutes 28 second

After – 51 seconds

North America

Before – 25 minutes 35 seconds

After – 58 seconds

Entire Forest

Before – 58 minutes 4 seconds

After – 2 minutes 57 seconds

A couple of years ago I had a group that used a sharepoint web front end that created AD users on the fly in the backend. The problem is that people would either not use it again after the first login, or they would just signup again if they forgot their credentials. Although all of that COULD have been handled by the developers on the front end, it was not and my concern was AD. For the sake of a clean AD, additional replication overhead, and SOX compliancy, unused accounts needed to be removed. Of course let’s not forget the security implications.

It was the application owners’ responsibility to maintain the accounts, but without any AD knowledge they needed a dummied down way to clean up the accounts. At that time I was still learning VBScript and decided to kick it up a notch and write my script in an HTA. I swear my scripts are much cleaner these days. I’m not going to go over all the code, but please leave any comments if you have questions. After you copy the code and save it as an .HTA you will need to change the LDAP paths according to your AD, the maximum age for enabled accounts, and the maximum age for disabled accounts. The reason for querying whether the account is disabled or not is so you can do something like disable an account that is 30 days past and delete it if more than 60 days past. You should also know that I use the LastLogonTimeStamp attribute since it is replicated to all domain controllers. Conversely the LastLogon attribute is not replicated and will vary from DC to DC. For more on the workings of the LastLogonTimeStamp attribute and its replication frequency (14 days) see this TechNet article.

This HTA will not only show you your unused accounts, but will let you save it in a spreadsheet, selectively disable, enable, or delete the accounts, and let you save your changes to a spreadsheet.  Just for reference you can also find this script in the Microsoft Scripting Guys’ Script Repository HERE.  Don’t panic, I didn’t steal it; I submitted it to them to add to their community submitted scripts.

Download File

If you have ever worked in a company with a split DNS name space or one that has gone through a merger, you have probably dealt with the DNS suffix search list.  This list allows a user to put “companyweburl” in their browser address and it actually resolve.  This works because Windows will cycle through the DNS suffix search list appending each suffix to what was typed into the address bar until it finds a site.  If the list contains contoso.com and litware.com then the OS will attempt companyweburl.contoso.com first.  If it gets a response from that site then off you go.  If it does not then it tries companyweburl.litware.com.

To set the suffix search list, open the properties of your network connection and then open the TCP/IP properties.  Now click Advanced and go to the DNS tab.  Here you can set your suffix list as shown.

DNS Suffix Search List

DNS Suffix Search List

There are two other places you can view your current suffix search list.  The first is by opening a command prompt and typing in “ipconfig /all”.  The second is in the registry and can be found in this location:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters

In a large environment making this change on all the clients can be daunting, but there are several solutions.  I won’t go into all the solutions, but VBScript or PowerShell scripts being deployed through domain group policy or user logons are good ones.  The most obvious solution is to just make the change by deploying a domain group policy.  This method has a catch in that it sets itself in a different registry key than if you set it locally through the GUI.  If a GPO pushes the setting then it takes precedence over the local configuration, but you can still set it in the GUI.  This makes you think you are changing it when you really are not.  This is a field engineer troubleshooting disaster.   The only good news is that an “ipconfig /all” will show what is actively being used.  Deploying this setting with a GPO puts its changes in the registry in the following location:

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient

It should be noted that this setting is only available in GPOs where AD is running Windows Server 2003 or greater.  Here is the path where you can find the setting in a GPO.

Computer Configuration → Policies(If you’re running Windows Server 2008) → Administrative Templates → Network → DNS Client → DNS Suffix Search List

Here is an example.  A GPO has been deployed to Machine1 setting the DNS Suffix Search List to “contoso.com”.  On the top you can see that “litware.com” is the only suffix set in the GUI.  On the bottom you can see from an “ipconfig /all” that the suffix search list only has “contoso.com”

DNS Suffix Search List in the GUI

DNS Suffix Search List in the GUI

Actual Current DNS Suffix
Actual Current DNS Suffix

As you can imagine, there is bound to be a very frustrated desktop engineer.  Since the GPO and GUI put their settings in different registry keys you never see the GPO settings in the GUI.  For this reason I would warn against using this GPO setting.  I recommend the following work around solutions.

  • VBScript or PowerShell deployed via logon script
  • VBScript or PowerShell deployed via GPO startup or logon script
  • GPO using a direct registry change to the local GUI registry key