Tuesday, September 27, 2011

Why didnt my routing group connector get created?

Below I'm going to address a bug that exists from Exchange 2007 RTM to Exchange 2010 SP1 (as of this writing). Sometimes when you install Exchange 2010 in a new environment your routing group connector does not get created - colleagues of mine have seen this before.

This happens even when when you specify an Exchange 2003 server in the dialog box below during the Exchange 2010 setup wizard.



When it doesn't get created during the installation if you dig down through your system logs in event viewer you will notice event 1002 from the MSExchangeSetup. See below, pay attention to the bold text.

Log Name: Application
Source: MSExchangeSetup
Date: 27/09/2011 2:28:20 PM
Event ID: 1002
Task Category: Microsoft Exchange Setup
Level: Error
Keywords: Classic
User: N/A
Computer: exchange.domain.local
Description:
Exchange Server component Hub Transport Role failed.
Error: Error:
The following error was generated when "$error.Clear();
if ($roleLegacyRoutingServer -ne $null)
{
$lrs =

$roleLegacyRoutingServer;
$source = [String][System.Environment]::MachineName;

if ($lrs.Length -gt 31)


{
$lrs = $lrs.Substring(0, 31)
};

if ($source.Length -gt 31)
{


$source = $source.Substring(0, 31)
};

$name = $source + "-" + $lrs;
$result = (get-

routinggroupconnector where {$_.Name -eq $name});
if ($result -eq $null)
{
new-

RoutingGroupConnector -SourceTransportServers:$source -TargetTransportServers:$roleLegacyRoutingServer -Cost:1 -Name:$name -Bidirectional:

$false
};

$name = $lrs + "-" + $source;
$result = (get-routinggroupconnector where {$_.Name -eq

$name});
if ($result -eq $null)
{
new-RoutingGroupConnector -SourceTransportServers:

$roleLegacyRoutingServer -TargetTransportServers:$source -Cost:1 -Name:$name -Bidirectional:$false
};
};
" was

run: "Active Directory operation failed on dc.domain.local. This error is not retriable. Additional information: The name reference is invalid.
This may be caused by replication latency between Active Directory domain controllers.
Active directory response: 000020B5: AtrErr: DSID-03152395, #1:
0: 000020B5: DSID-03152395, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att

179130e2 (msExchTargetBridgeheadServersDN)
".

Active Directory operation failed on dc.domain.local. This error is not retriable. Additional information: The name reference is invalid.
This may be caused by replication latency between Active Directory domain controllers.
Active directory response: 000020B5: AtrErr: DSID-03152395, #1:
0: 000020B5: DSID-03152395, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att

179130e2 (msExchTargetBridgeheadServersDN)


A value in the request is invalid.


Error:
The following error was generated when "$error.Clear();
if ($roleLegacyRoutingServer -ne $null)
{
$lrs =

$roleLegacyRoutingServer;
$source = [String][System.Environment]::MachineName;

if ($lrs.Length -gt 31)


{
$lrs = $lrs.Substring(0, 31)
};

if ($source.Length -gt 31)
{


$source = $source.Substring(0, 31)
};

$name = $source + "-" + $lrs;
$result = (get-

routinggroupconnector where {$_.Name -eq $name});
if ($result -eq $null)
{
new-

RoutingGroupConnector -SourceTransportServers:$source -TargetTransportServers:$roleLegacyRoutingServer -Cost:1 -Name:$name -Bidirectional:

$false
};

$name = $lrs + "-" + $source;
$result = (get-routinggroupconnector where {$_.Name -eq

$name});
if ($result -eq $null)
{
new-RoutingGroupConnector -SourceTransportServers:

$roleLegacyRoutingServer -TargetTransportServers:$source -Cost:1 -Name:$name -Bidirectional:$false
};
};
" was

run: "Active Directory operation failed on dc.domain.local. This error is not retriable. Additional information: The name reference is invalid.
This may be caused by replication latency between Active Directory domain controllers.
Active directory response: 000020B5: AtrErr: DSID-03152395, #1:
0: 000020B5: DSID-03152395, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att

179130df (msExchSourceBridgeheadServersDN)
".

Active Directory operation failed on dc.domain.local. This error is not retriable. Additional information: The name reference is invalid.
This may be caused by replication latency between Active Directory domain controllers.
Active directory response: 000020B5: AtrErr: DSID-03152395, #1:
0: 000020B5: DSID-03152395, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att

179130df (msExchSourceBridgeheadServersDN)


A value in the request is invalid.


The following error was generated when "$error.Clear();
if ($roleLegacyRoutingServer -ne $null)
{
$lrs =

$roleLegacyRoutingServer;
$source = [String][System.Environment]::MachineName;

if ($lrs.Length -gt 31)


{
$lrs = $lrs.Substring(0, 31)
};

if ($source.Length -gt 31)
{


$source = $source.Substring(0, 31)
};

$name = $source + "-" + $lrs;
$result = (get-

routinggroupconnector where {$_.Name -eq $name});
if ($result -eq $null)
{
new-

RoutingGroupConnector -SourceTransportServers:$source -TargetTransportServers:$roleLegacyRoutingServer -Cost:1 -Name:$name -Bidirectional:

$false
};

$name = $lrs + "-" + $source;
$result = (get-routinggroupconnector where {$_.Name -eq

$name});
if ($result -eq $null)
{
new-RoutingGroupConnector -SourceTransportServers:

$roleLegacyRoutingServer -TargetTransportServers:$source -Cost:1 -Name:$name -Bidirectional:$false
};
};
" was

run: "Active Directory operation failed on dc.domain.local. This error is not retriable. Additional information: The name reference is invalid.
This may be caused by replication latency between Active Directory domain controllers.
Active directory response: 000020B5: AtrErr: DSID-03152395, #1:
0: 000020B5: DSID-03152395, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att

179130e2 (msExchTargetBridgeheadServersDN)
".

Active Directory operation failed on dc.domain.local. This error is not retriable. Additional information: The name reference is invalid.
This may be caused by replication latency between Active Directory domain controllers.
Active directory response: 000020B5: AtrErr: DSID-03152395, #1:
0: 000020B5: DSID-03152395, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att

179130e2 (msExchTargetBridgeheadServersDN)


A value in the request is invalid.


Error:
The following error was generated when "$error.Clear();
if ($roleLegacyRoutingServer -ne $null)
{
$lrs =

$roleLegacyRoutingServer;
$source = [String][System.Environment]::MachineName;

if ($lrs.Length -gt 31)


{
$lrs = $lrs.Substring(0, 31)
};

if ($source.Length -gt 31)
{


$source = $source.Substring(0, 31)
};

$name = $source + "-" + $lrs;
$result = (get-

routinggroupconnector where {$_.Name -eq $name});
if ($result -eq $null)
{
new-

RoutingGroupConnector -SourceTransportServers:$source -TargetTransportServers:$roleLegacyRoutingServer -Cost:1 -Name:$name -Bidirectional:

$false
};

$name = $lrs + "-" + $source;
$result = (get-routinggroupconnector where {$_.Name -eq

$name});
if ($result -eq $null)
{
new-RoutingGroupConnector -SourceTransportServers:

$roleLegacyRoutingServer -TargetTransportServers:$source -Cost:1 -Name:$name -Bidirectional:$false
};
};
" was

run: "Active Directory operation failed on dc.domain.local. This error is not retriable. Additional information: The name reference is invalid.
This may be caused by replication latency between Active Directory domain controllers.
Active directory response: 000020B5: AtrErr: DSID-03152395, #1:
0: 000020B5: DSID-03152395, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att

179130df (msExchSourceBridgeheadServersDN)
".

Active Directory operation failed on dc.domain.local. This error is not retriable. Additional information: The name reference is invalid.
This may be caused by replication latency between Active Directory domain controllers.
Active directory response: 000020B5: AtrErr: DSID-03152395, #1:
0: 000020B5: DSID-03152395, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att

179130df (msExchSourceBridgeheadServersDN)

A value in the request is invalid.




Now what is this bug?

The New-RoutingGroupConnector command will only connect to SMTP Virtual Servers that have a common name value of 1. What do I mean by this? In the Exchange 2010 source code the Exchange 2010 product team coded this powershell command to query:

"CN=1,CN=SMTP,CN=Protocols,CN=MERCURY,CN=Servers,CN=SHENTON PARK,CN=Administrative Groups,CN=EXORG,CN=Microsoft,Exchange,CN=Services,CN=Configuration,DC=YOURDOMAIN,DC=COM"

What is this object? This is your SMTP virtual server your administrators see in Exchange 2003 system manager. Any configuration changes made to this virtual server get updated on this Active Directory object in the configuration partition.



If an administrator creates new SMTP virutal servers then deletes the first SMTP virtual server that had a CN value of 1 the issue occurs. For example if I open ADSIEdit in my environment with the problem and navigate to the following location:

Configuration\services\Microsoft Exchange\Org Name\Administrative Groups\Exchange 2003 AG name\Servers\Exchange 2003 servername\Protocol\SMTP

I see that my CN is a value of 3.



To resolve this I performed the following steps:

1. Renamed CN=3 to CN=1 in ADSIEdit by right clicking the object.

2. Force replication to whichever DC your Exchange 2003 server is communicating to. You can find this out by running "nltest /dsgetdc:domain.local" on your Exchange 2003 server provided you have the 2003 support tools installed.

3. Restart the Simple Mail Transfer Service on your Exchange 2003 server - VERY IMPORTANT.

Note: If you manually try and use the New-RoutingGroupConnector in Exchange 2007/2010 shell after the installation is complete, it will also unless you correct the CN= value for your SMTP Virtual Server.

[FIXED] Exchange 2010 Single Server Installation Problems

Today I set out to perform a single Exchange 2003 server migration to a new Exchange 2010 server for approximately 200 users. What is a simple task for me had some bumps.

I installed setup my new Exchange 2010 server as a brick level deployment "all roles on one server".

I performed the following steps:
1. Installed the Exchange 2010 SP1 prerequisites for MBX, HT and CAS.
2. Installed the Microsoft Office 2010 filter packs
3. Performed the Schema update using setup.com /PrepareAD
4. Installed Exchange 2010 with all roles.

After installation completed successfully I rebooted the server. After the reboot I noticed I could not connect to Exchange 2010 using the console or shell. I checked to see if the powershell virutal directory existed... it did not.



For some reason only the mailbox role installed, even though the wizard said all roles were installed successfully. I went back and ran setup.exe again. I selected Hub Transport and Mailbox.. went through the install - rebooted. This time all roles existed. Although Exchange 2010 installed, it was unusable.

When I tried to perform powershell commands in the shell as an Exchange organisation administrator I received the following errors:

Exception calling "GetSteppablePipeline" with "1" argument(s): "The type initializer for 'Microsoft.Exchange.Configuration.Tasks.Task' threw an exception."
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException




Opening up Exchange Management Console I received the following error:

Initialization failed
The following error occured when retrieving user information for 'user account':
Unexpected error [0x17B26A98] while executing command 'Get-LogonUser'.




Resolution

To resolve the issue I performed the following steps:

1. Uninstalled Exchange 2010 SP1 from my new server
2. Rebooted
3. Installed Exchange 2010 SP1 client access server role
4. Rebooted
5. Tested exchange management console (EMC) and exchange management shell (EMS)
6. Installed Exchange 2010 SP1 hub transport role
7. Rebooted
8. Tested EMC and EMS
9. Installed Exchange 2010 SP1 mailbox role
10. Rebooted
11. Tested EMC and EMS

Only when installing in this order was I able to resolve the issue. Very weird, this is the only time I have experianced this behaviour.

Monday, September 26, 2011

RMS Shared Identity user FederatedEmail.4c1f4d8b-8179-4148-93bf-00a95fa1e042 not found

Today I was re-installing Exchange 2010 into an Active Directory forest which previously had Exchange 2010 installed. The schema was already extended with the Exchange 2010 SP1 schema extensions.

When installing Exchange 2010, installation of the Hub Transport role failed with the following error:

Error:
The following error was generated when "$error.Clear();
if ( ($server -eq $null) -and ($RoleIsDatacenter -ne $true) )
{
Update-RmsSharedIdentity -ServerName $RoleNetBIOSName
}
" was run: "RMS Shared Identity user FederatedEmail.4c1f4d8b-8179-4148-93bf-00a95fa1e042 not found.".


FederatedEmail.4c1f4d8b-8179-4148-93bf-00a95fa1e042 is a Exchange 2010 built in arbitration user account which must exist in every Exchange 2010 environment. The GUID never changes, it is always "4c1f4d8b-8179-4148-93bf-00a95fa1e042".

The setup failed because someone deleted this user account from Active Directory!

How can we get it back?

You have two ways to get this mailbox back. If you have a computer on your network with the Exchange 2010 management tools installed, you can create the user account using powershell with the following command:

New-Mailbox -Arbitration -Name FederatedEmail.4c1f4d8b-8179-4148-93bf-00a95fa1e042 -UserPrincipalName FederatedEmail.4c1f4d8b-8179-4148-93bf-00a95fa1e042@default_accepted_domain

For more information on this see Microsoft KB978776

What happens if you do not have exchange management shell installed on any computers? Well there is another way to get this account back. This account is originally created when you prepare the domain/schema. If you run setup.com /PrepareAD on your domain it will re-create this account for you. See below:



Thursday, September 22, 2011

Connecting to a single AD Object

This script lets you connect to an LDAP DC / LDS server and display attributes on objects:

Set oUser = GetObject("LDAP://localhost:10001/CN=Clint2,OU=TestOU,DC=test,DC=com")
oUser.GetInfo
wscript.echo oUser.Get("otherHomePhone")

Monday, September 19, 2011

A quick way to determine your bridgehead servers?

You want to determine which bridgehead servers have been elected in each Active Directory site to troubleshoot replication issues?

Use the following command:

repadmin /bridgeheads

Sunday, September 18, 2011

Windows Server Backup - DAG Environment

Windows Server Backup or wbadmin.exe cannot be used to backup passive databases in a Database Availability Group environment.

WSB does not back up Passive copies. It can only be used to back up Active copies. This is simply a limitation of the WSB plug-in. Also WSB is only designed to backup small Exchange 2010 environments that are not DAG members.

http://technet.microsoft.com/en-us/library/dd876874.aspx

Also – as indicated in the article, you have to back up the entire volume containing both the database/logs.

So essentially if you want to use WSB to take a full backup of *all* databases, you are looking at either moving all active copies to a single DAG member (for the backup), or using WSB locally on each DAG member that hosts active databases.

Please note, you can backup passive mailbox databases using WSB in a DAG environment as explained in the above article:

"If a server hosting the data being backed up is a member of a database availability group (DAG) and hosts both active and passive database copies, you must disable the Microsoft Exchange Replication service VSS writer. If the Microsoft Exchange Replication service VSS writer is enabled, the backup operation will fail."

Why would you want to use windows server backup to backup a DAG member? Possibly your primary backup product is failing and you want to test the VSS service using an alternative product? In this case you may use BETest.exe to test the VSS snapshot service.

Exchange 2003 Domain Rename with Exchange 2010

Domain Rename's are possible only with Exchange 2003. After you perform the Active Directory rename using the domain rename tool RENDOM, the next step is the fixup the Exchange 2003 attributes using a tool called XDR-Fixup.

XDR-Fixup is not supported on:
- Exchange 5.5
- Exchange 2000
- Exchange 2007
- Exchange 2010

What happens if you have an Exchange 2003 environment that you have just done an ADPrep to prepare the forest for Exchange 2010? Can you still proceed with an Exchange 2003 domain rename?

The answer here is no, the Exchange schema extensions must be that of Exchange 2003 SP2 (no higher).

Wednesday, September 14, 2011

ADAMSync Error -2146893813. Error code: 317

Today I discovered what may be a bug in ADAMSync, however I found a workaround. Let me go into detail sharing my findings with you. First... lets cover off my environment.

I have 4 forests, 10 domains. My AD LDS server is a member of subdomain.forest3.lan. Please see the diagram below.



- My LDS Server has multiple instances "LDS Databases" for each Active Directory domain. These instances are listening on 10001, 10002, 10003, 10004 etc... There is a 1 to 1 relationship between a single domain and its corresponding LDS instance.

- Each LDS Instance has only one application partition with the same distinguishedName mapping an Active Directory domain. For example dc=forest2,dc=lan or dc=bu2,dc=forest1,dc=lan.

- My ADAMSync configuration in each instance replicates the user class objects from Active Directory to "userProxy" class objects in each LDS Instance. Objects are successfully replicating.

- userProxy bind redirection is working successfully for all LDS Instances and the corresponding Active Directory domain (excluding forest4.lan due to no domain trusts existing). For more information on userProxy objects see http://clintboessen.blogspot.com/2011/04/userproxy-class-and-adam-lds.html

- There is no synchronization errors. I have validated all attributes declared in my adamsync.xml file are successfully synchronizing to the corresponding userProxy object in LDS for each user account.

- ADAMSync is successfully creating the same Organisational Unit structure matching that of LDS.

- The base distinguishedName of each LDS instance matches the base distinguishedName of the Active Directory domain.

- All child domains in forest1 synchronise using an ldapquery account located in the parent forest1.lan domain. This is configured in the XML file ldapquery and forest1.lan.

- forest2.lan synchronises using an account in forest2.lan

- forest3.lan synchronises using an account in subdomain.forest3.lan. No user accounts reside in the root domain forest3.lan. This is configured as an "empty root domain".

- forest4.lan synchronises using an account located in forest4.lan

The following Active Directory accounts were setup to make this solution work:

- subdomain.forest3.lan\LDSSVC. This account is only a member of "domain users" in subdomain.forest3.lan. This account has "Log on as service" rights assigned under "user rights assignments" on the LDS Server. This account provides the security context under which LDS Instance runs as a service. i.e. all LDS Services run as this account.

- subdomain.forest3.lan\LDSBoss. This account is only a member of "domain users" in subdomain.forest3.lan. During the installation of each LDS Instance using the "Active Directory Lightweight Directory Services Setup Wizard" this account was specified as the Administrator of each instance. This account has no access to the LDS Server itself, i.e. the account does not even have permissions to login to the LDS Server. It only has "Administrative privilages" inside each LDS Instance. All commands which manipulate LDAP data inside an LDS Instance such as ADAMSync must be run under the security context of this LDSBoss account.

- forest1.lan\ldapquery. This account is a member of "Domain Admins" and "Enterprise Admins"in the forest1.lan root domain. It is specified in the ADAMSync.xml file for each child domain in the forest1.lan forest. This account is used to perform LDAP Queries against the forest1.lan forest. If this account is not a Domain Admin or Enterprise Admin, ADAMSync fails to run.

- forest2.lan\ldapquery. This account is a member of "Domain Admins" in the forest2.lan domain. This is specified in the ADAMSync.xml file for the forest2.lan forest. It is used for LDAP queries against forest2.lan

- subdomain.forest3.lan\ldapquery. This account is a member of "Domain Admins" in the subdomain.forest3.lan domain. This is specified in the ADAMSync.xml file for the subdomain.forest3.lan forest. It is used for LDAP queries against subdomain.forest3.lan

- forest4.lan\ldapquery. This account is a member of "Domain Admins" in the forest4.lan domain. This is specified in the ADAMSync.xml file for the forest4.lan forest. It is used for LDAP queries against forest4.lan

So whats the bug you found clint?

I went and installed my ADAMSync XML configuration file running a command prompt under the security context of the user account SUBDOMAIN\LDSBoss with the following command:

adamsync /install localhost:10001 "C:\Windows\ADAM\AdamSync Configs\SUBDOMAIN\SUBDOMAIN-AdamSyncConf.XML" /passprompt

When prompted I entered the password for the subdomain.forest3.lan\ldapquery account which was specified in the ADAMSync XML file.

When I run ADAMSync.exe using my SUBDOMAIN\LDSBoss credentials (the credentials used to install the XML configuration file), the sync works successfully.

However I then created another account called SUBDOMAIN\boessenc_admin which I added to the configuration partition "Administrators" group in my LDS Instance. When I tried to sync using my SUBDOMAIN\boessenc_admin account the sync failed with ADAMSync.exe terminating. The following error is received:

Error occured fetching internationalized message number -2146893813. Error code: 317



Problem signature:
Problem Event Name: APPCRASH
Application Name: adamsync.exe
Application Version: 6.1.7600.16385
Application Timestamp: 4a5bc94c
Fault Module Name: ntdll.dll
Fault Module Version: 6.1.7600.16695
Fault Module Timestamp: 4cc7b325
Exception Code: c0000005
Exception Offset: 0000000000023b12
OS Version: 6.1.7600.2.0.0.272.7
Locale ID: 3081
Additional Information 1: dba5
Additional Information 2: dba5cead4302f0c0fa066ea618a55f8f
Additional Information 3: f135
Additional Information 4: f135fc65c6fa056fecabbbdf82720b5f


I created a memory dump of the ADAMSync process using the following MSDN article:
http://msdn.microsoft.com/en-us/library/bb787181.aspx

I submitted this memory dump to James Li from the Microsoft Directory Service Support Team. James analysed the memory dump carefully and suspects it might be caused by a bug in AdamSync.exe. Here is the stack information he provided me with:

00 00000000`0013e990 000007fe`fd479ce9 ntdll!RtlFormatMessageEx(
unsigned short * MessageFormat = 0x00000000`00000000,
unsigned long MaximumWidth = 0,
unsigned char IgnoreInserts = 0x10 '',
unsigned char ArgumentsAreAnsi = 0x00 '',
unsigned char ArgumentsAreAnArray = 0x00 '',
char ** Arguments = 0x00000000`0013f3b0,
unsigned short * Buffer = 0x00000000`ff7fb630,
unsigned long Length = 0x26d7,
unsigned long * ReturnLength = 0x00000000`0013f174,
struct _PARSE_MESSAGE_CONTEXT * ParseContext = 0x00000000`0013f1a8)+0x272

01 00000000`0013f110 000007fe`fd479a97 KERNELBASE!BaseDllFormatMessage(
unsigned char ArgumentsAreAnsi = 0x00 '',
unsigned long dwFlags = 0x1000,
void * lpSource = 0x00000000`0013f510,
unsigned long dwMessageId = 0x13d,
unsigned long dwLanguageId = 0x400,
unsigned short * lpBuffer = 0x00000000`ff7fb630,
unsigned long nSize = 0x2710,
char ** arglist = 0x00000000`0013f3b0)+0x239

02 00000000`0013f210 00000000`77024d88 KERNELBASE!FormatMessageW(
unsigned long dwFlags = 0,
void * lpSource = 0x00000000`ff7f91b0,
unsigned long dwMessageId = 0,
unsigned long dwLanguageId = 0xff797074,
unsigned short * lpBuffer = 0x00000000`ff7fb630,
unsigned long nSize = 0x2710,
char ** lpArguments = 0x00000000`0013f3b0)+0x37

03 00000000`0013f260 00000000`ff7942d0 kernel32!FormatMessageWStub(
unsigned long dwFlags = 0x13f510,
void * lpSource = 0x00000000`00002800,
unsigned long dwMessageId = 0,
unsigned long dwLanguageId = 0x5f7f20,
unsigned short * lpBuffer = 0x00000000`ff7fb630,
unsigned long nSize = 0x2710,
char ** lpArguments = 0x00000000`0013f3b0)+0x28


I continued investigating the issue... I then reinstalled the ADAMSync XML file by re-running the ADAMSync.exe process under SUBDOMAIN\boessenc_admin using the same command, and specifying the password for the SUBDOMAIN\ldapquery which was specified in the XML configuration file:

adamsync /install localhost:10001 "C:\Windows\ADAM\AdamSync Configs\SUBDOMAIN\SUBDOMAIN-AdamSyncConf.XML" /passprompt

I then ran the ADAMSync.exe program with the sync switch under the security context of SUBDOMAIN\boessenc_admin. It worked!

What did we learn?

Whatever account you used to install the ADAMSync.exe XML configuration file, i.e. the account the ADAMSync.exe process is running as during the config installation MUST also be used to perform the ADAMSync.exe synchronisation. If you attempt to perform a synchronisation using a different account other then the account used during the XML import, the ADAMSync.exe process will crash.

Forefront Threat Management Gateway - Workgroup Configuration with Exchange 2010

In this post I will give you some information around publishing Exchange 2010 with Forefront Threat Management Gateway (TMG) or ISA 2006 and weather or not these servers should have domain membership.

Microsoft's recommended deployment is that you add your TMG servers as members of your Active Directory domain. For the TMG setup whitepaper please see the following link. This whitepaper explains how to setup TMG step by step with domain membership.

http://download.microsoft.com/download/E/5/6/E56ACB6E-7BCC-40F1-8F18-E636B7BFE088/PublishingExchangeServer2010withForefront.doc

When Microsoft initially released Threat Management Gateway, it did not support workgroup configuration. It's a product that is designed to run as a member of your Active Directory domain and configuring it any other way results in significant loss in functionality and in some cases security. I managed to find a copy of the original release notes published by Microsoft which is available here... stating that TMG does not support workgroup configuration. http://technet.microsoft.com/en-us/library/cc487898.aspx

Previous versions of the product such as ISA2006 did support workgroup configuration and some companies implemented it in this method. There was an outcry and as a result Microsoft changed their stance on this and updated the product to support domain membership.

Can you publish Exchange 2010 using TMG without adding the Threat Management Gateway server as a member of your internal Active Directory domain? Yes you can, there are 3 ways to do this:

- Configure another Active Directory domain to hold TMG. Create a Transitive Forest Trust between your production forest and your TMG forest. Create domain local groups on the TMG Active Directory forest and nest any groups that require access rules inside the TMG forest’s domain local groups.

- Configure an internal PKI, if you want security you need to ensure you have an offline root stand-alone CA, and a subordinate enterprise issuing CA which is AD Integrated. Issue a digital certificate to each domain controller and configure your environment to support LDAP over SSL for AD Authentication. To configure your domain controllers to support LDAPS using SSL see http://support.microsoft.com/kb/321051

- Configure a RADIUS server on your internal network. Configure the TMG server as a RADIUS client to pass through authentication requests to the RADIUS server. The RADIUS server will then pass the authentication request through to Active Directory. You will not get Outlook Anywhere working if your using RADIUS authentication, see http://blogs.isaserver.org/pouseele/2007/02/06/a-quest-for-strong-user-authentication-with-rpc-over-http-services-and-isa-server-2006/

All three of these options have the following disadvantages:

- Will require additional servers weather its certificate authorities, radius servers or domain controllers to run a new AD forest.

- Will extend the project life cycle from an originally estimated 2 weeks to 4-8 weeks depending which of the 3 options you wish to go down.

- Increase complexity of your network and increase downtime periods should infrastructure fail as this is not a highly available deployment.

Neither of these solutions add any significant layer of security and are not seen as efficient solutions due to the Administrative overhead they create.

In a Microsoft whitepaper written by Greg Taylor "Publishing Outlook Anywhere Using NTLM Authentication With Forefront TMG or Forefront UAG", Greg dedicated a section around joining Forefront TMG/Forefront UAG to an Active Directory domain or leaving it workgroup. For a copy of this article see the following URL:

http://www.microsoft.com/download/en/details.aspx?id=22723

Here is an extract from Greg Taylors whitepaper:

"Domain Joining Forefront TMG/Forefront UAG or Leaving in a Workgroup"

In most organizations, the decision whether to domain join the server hosting Forefront TMG/Forefront UAG to your production domain may be one of the more contentious parts of the deployment.

For Forefront UAG deployments, the guidance is clear. Because Forefront UAG is not a firewall, it should be placed behind some other device that acts as a firewall on the corporate network. Also, it's recommended that Forefront UAG be domain joined to make authentication simple and flexible. Forefront TMG is installed on the Forefront UAG computer during installation, but that's done only to protect the host system and for the underlying functionality it provides to Forefront UAG.

Forefront TMG deployments are more complex to discuss because Forefront TMG is considered a firewall and can protect the network edge. Domain joining Forefront TMG offers many advantages: it allows certificate based authentication to be used at Forefront TMG, using Kerberos Constrained Delegation to communicate to Exchange; it allows easy use of Active Directory groups and user objects in publishing rules to restrict access; and it provides other benefits. For an impartial view on whether to domain join Forefront TMG, see Debunking the Myth that the ISA Firewall Should Not be a Domain Member. For more information about identifying your infrastructure design requirements, see Domain and workgroup requirements.


The link Greg Taylor mentions in his white paper "Debunking the Myth that the ISA Firewall Should Not be a Domain Member" by Thomas W Shinder, Microsoft MVP is an excellent read. Please view it here:

http://www.isaserver.org/tutorials/Debunking-Myth-that-ISA-Firewall-Should-Not-Domain-Member.html

In Thomas's article he mentions:

ISA/TMG that is a domain member machine is more secure and more flexible than a non-domain member machine and that they do themselves and their companies a disservice by not joining the ISA firewall to the domain. This is a significant issue and not something to be taken lightly because there is a serious security hit you take when you don’t join the ISA firewall to the domain.

He also covers in his article the primary reason companies go through all this effort of not joining the TMG/ISA server to the internal domain, compliance managers and external auditors that believe in this myth. He writes:

Should the ISA firewall array be placed in a domain or a workgroup? That is the question. Is it nobler to place the ISA firewall in a workgroup where you can avoid the catcalls of clueless compliance managers, "hardware" firewall know-nothings, or “network guys” who think of network security as "port opening and closing", or should you bear the slings and arrows of the same harridan housewives and carping screws for placing the ISA firewall in the domain, where you can get a higher level of overall security and substantially improve your security position?

The last article I would like to point you at is a TechNet article published by Microsoft around considerations when and when not you would place your TMG server as a member of your internal Active Directory domain. Please view this article here:

http://technet.microsoft.com/en-us/library/dd897048.aspx

I would like to finalise by saying majority of TMG deployments should all be a member of your Active Directory domain especially if your just publishing Exchange 2010. However there may be circumstances where your using your TMG server for things other then just Exchange and you may need to look at implementing TMG in a workgroup configuration.

Joining Forefront Threat Management Gateway 2010 to an Active Directory domain to publish Exchange 2010 services to the Internet is not a security threat to your network.

Monday, September 12, 2011

Access is Denied - Disabling SID Filtering

Today I had an issue where I received "Access is Denied" when disabling SID Filtering, even though my account had access.

Of course I checked my command prompt was running with administrative rights... check this is you have User Account Control (UAC) enabled.

I ran the netdom command with /quarantine:no and the correct syntax and received:

The command failed to complete successfully.

To get around this problem I established a UNC connection to the the PDC emulator in the destination forest. This resolved the problem. Please see the screenshot below:

Sunday, September 4, 2011

Access is Denied adding GPMC to MMC

Scenario: I have an administrators XP workstation. The administrator has a standard user account and an administrator account. I migrated his standard user account and administrator account to a new Active Directory forest. ADMT performed security translation on his profile. The administrator can successfully login to the new domain keeping his same profile and settings.

Problem: The administrator opens MMC using "run as" and specifies his administrative credentials in the source forest. He can access AD Users and Computers and make configuration changes. When he tries to add group policy management console (GPMC) to the MMC console he receives Access is Denied.



I used Sysinternals Process Monitor (Procmon.exe) and noticed it was having problems writing to a particular registry key.



I granted the administrator account full control over the profile using regedit.





This resolved the problem.

Wednesday, August 24, 2011

Manipulating Text Strings in VBScript

Here is a bunch of links that explain how to manipulate text strings in VBS.

Mid Function:
http://msdn.microsoft.com/en-us/library/wffts6k3(v=vs.85).aspx

Right Function:
http://msdn.microsoft.com/en-us/library/eh8fefz1(v=vs.85).aspx

Left Function:
http://msdn.microsoft.com/en-us/library/sk3xcs8k(v=vs.85).aspx

These functions are to determine how many characters are in the string:

LTrim; RTrim; and Trim Functions
http://msdn.microsoft.com/en-us/library/c623wz83(v=vs.85).aspx

Len Function
http://msdn.microsoft.com/en-us/library/dxsw58z6(v=vs.80).aspx

This website also has lots of handy commands for manipulating strings:

http://www.w3schools.com/VBscript/vbscript_ref_functions.asp

Monday, August 22, 2011

List all users in domain using LDAP and VBS

This sample code lists all users in a domain using LDAP, a more powerful connection then WinNT.

This script automatically binds to the default domain naming context:

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

objCommand.Properties("Page Size") = 1000

objCommand.CommandText = _
"<LDAP://domain.local/RootDSE>(objectCategory=User);Name,distinguishedName,sAMAccountName,legacyExchangeDN;Subtree"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst

Do Until objRecordSet.EOF
Wscript.Echo objRecordSet.Fields("Name").Value
Wscript.Echo objRecordSet.Fields("sAMAccountName").Value
Wscript.Echo objRecordSet.Fields("legacyExchangeDN").Value
objRecordSet.MoveNext
Loop

This script lets you manually bind to the domain/application partition.

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

objCommand.Properties("Page Size") = 1000

objCommand.CommandText = _
"<LDAP://domain.local/dc=domain,dc=local>(objectCategory=User);Name,distinguishedName,sAMAccountName,legacyExchangeDN;Subtree"
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst

Do Until objRecordSet.EOF
Wscript.Echo objRecordSet.Fields("Name").Value
Wscript.Echo objRecordSet.Fields("sAMAccountName").Value
Wscript.Echo objRecordSet.Fields("legacyExchangeDN").Value
objRecordSet.MoveNext
Loop

Another example of a similar script can be found on:

http://www.cruto.com/resources/vbscript/vbscript-examples/misc/searchad/Search-for-All-Users-Using-an-LDAP-Query.asp

Wednesday, August 10, 2011

Connecting to the configuration partition of an LDS Instance

LDS Instances like Active Directory also have a Configuration Partition and a Schema Partition. On TechNet it is documented:

By default, the security principal that you specify as the AD LDS administrator during AD LDS setup becomes a member of the Administrators group in the configuration partition.

http://technet.microsoft.com/en-us/library/cc731143.aspx

How do I get to the configuration partition in an LDS Instance?

Well if I connect to my application partition created during the LDS installation wizard and go to my Administrators, I can see nested inside is another Administrators group residing inside the Configuration Partition.



I can now connect to this using ADSIEdit.



Under the administrators group in the configuration partition I can find the account used when I installed the LDS Instance as per Microsoft documentation on TechNet.

ADAMSync Aging

In this post I will describe Aging with ADAMSync. If you configure ADAMSync to replicate your Active Directory information to an LDS Instance, without aging deleted data from Active Directory will never be removed from LDS. For example if you delete a user object from your Active Directory database, this object will not be deleted from the LDS Instance when you run the next sync.

The ADAMSync aging configuration is done under your ADAMSync XML configuration file.

<schedule>
<aging>
<frequency>0</frequency>
<num-objects>0</num-objects>
</aging>
<schtasks-cmd></schtasks-cmd>
</schedule>


The two configuration options you need to configure are frequency and num-objects.

Frequency:
http://technet.microsoft.com/en-us/library/cc737713.aspx

num-objects:
http://technet.microsoft.com/en-us/library/cc778153.aspx

Unfortunately the documentation on TechNet around these is very poor.

Frequency

- If it's set to "0", the Aging will be skipped, AdamSync will return the following informaiton:
a. Aging is skipped.
b. The times since the last sync.

- If it's larger than "0", system will compare its value with the number of times since the last sync:

a. If its value is larger than the number of times since the last sync, Aging will be skipped, and the number of the times since the last sync will be increased by 1.
b. if its value is not larger than the number of times since the last sync, Aging procedure will be called and the number of times since the last sync will be reset.

Examples:

- If the value is set to 0, aging will be not used.
- If the value is set to 1, the aging will be called each time during the sync.
- if it's set to 2, the aging will be called every two sync.

num-objects

num-objects is the number of objects that need to be aged per run. If you make this 0, it will always age all objects against Active Directory. If you make this 50, it will only age 50. When you perform the next sync, it will age the next 50. Don't worry all objects will eventually be aged... depends on how often you schedule task adamsync.exe to run!

Why was Aging developed?

Please read this fantastic article by Eric Fleischman which explains why Aging was developed by Microsoft in ADAMSync.

http://blogs.technet.com/b/efleis/archive/2006/10/28/change-visibility-in-the-directory-or-lack-there-of-aka-what-s-the-point-of-aging.aspx

Thankyou to James Li from the Directory Services Support Team at Microsoft for looking at the source code of ADAMSync.exe and explaining how the code works! This information was published with written permission from Microsoft via email.

Monday, August 8, 2011

How to find the server your DFS Namespace Client is talking to

When setting up Distributed File System Replication (DFSR) between multiple file servers, you may want to know which file server your DFS namesace client is communicating with.

To find this out use the DFSUTIL program with the pktinfo switch. Any ACTIVE TARGETSET servers are servers your workstation is currently talking to.

dfsutil /pktinfo



Alternatively you can right click in a DFS share under explorer and select Properties.



Hit the DFS Tab

Word Crashes Dell XPS 15z Laptop

I just got a new Dell XPS 15z laptop. Microsoft word however continiously crashes generating the following error in event viewer:

Log Name: Application
Source: Application Error
Date: 9/08/2011 9:42:22 AM
Event ID: 1000
Task Category: (100)
Level: Error
Keywords: Classic
User: N/A
Computer: Clint-PC
Description:
Faulting application name: WINWORD.EXE, version: 14.0.4762.1000, time stamp: 0x4bae25cd
Faulting module name: btmofficea.dll, version: 1.0.0.49, time stamp: 0x4d382a1a
Exception code: 0xc0000005
Fault offset: 0x00000000000065ff
Faulting process id: 0xd80
Faulting application start time: 0x01cc56359222c86d
Faulting application path: C:\Program Files\Microsoft Office\Office14\WINWORD.EXE
Faulting module path: C:\Program Files (x86)\Intel\Bluetooth\btmofficea.dll
Report Id: d2f29c37-c228-11e0-8b74-feb16a7ed552


This was caused by the bluetooth module that comes with the laptop. In word I went to file --> options. Under Add-Ins we see the bluetooth driver.



Under COM Add-ins click Go. Untick the send to bluetooth checkbox.

AD Delegation - How to set default permissions for new group policy objects

When setting up Active Directory delegation, you want administrators to be able to maintain Group Policy without being a Domain Admin. If you read TechNet, Microsoft tells you to use Group Policy Creator Owners, please see:

http://technet.microsoft.com/en-us/library/cc776858.aspx

Lets test it. We have a user named Jess. Jess is only a member of the domain users group. We add Jess to "Group Policy Creator Owners". Jess creates a group policy object called "Jess's Policy". Great, it worked. If we look at the permissions of "Jess's Policy" in group policy management console (GPMC), we see that she has permissions to the group policy object.



Jess does not have permissions to modify or edit any other group policy objects.

The problem with Group Policy Creator Owners

Lets say you have 10 administrators that need to make group policy changes. You add the 10 administrators to Group Policy Creator Owners. One administrator creates a group policy object. The others cannot read or modify the group policy object as only the administrator that created the group policy object owns it. The administrator that created the group policy object must remember to grant the other administrators access to the group policy object. This process needs to re-occur every time an administrator creates a new group policy object.

I don't know why Microsoft recommends to use this approach for group policy delegation as it is not feasible.

The Solution

Change the template permissions in Active Directory!

By default whenever you create a new GPO the following Active Directory system groups are granted access:
- Authenticated Users
- Domain Admins
- Enterprise Admins
- ENTERPRISE DOMAIN CONTROLLERS
- SYSTEM

These permissions are the "default" permission template for newly created group policy objects. We can add additional custom groups to this template by modifying the Active Directory Schema Partition.

To do this use ADSIEdit and connect to the Schema Partition.

View the properties for CN=Group-Policy-Contrainer



The defaultSecurityDescriptor attribute contains the security template for all new group policy objects. By default the defaultSecurityDescriptor looks like this:

D:P(A;CI;RPWPCCDCLCLOLORCWOWDSDDTSW;;;DA)(A;CI;RPWPCCDCLCLOLORCWOWDSDDTSW;;;EA)(A;CI;RPWPCCDCLCLOLORCWOWDSDDTSW;;;CO)(A;CI;RPWPCCDCLCLORCWOWDSDDTSW;;;SY)(A;CI;RPLCLORC;;;AU)(OA;CI;CR;edacfd8f-ffb3-11d1-b41d-00a0c968f939;;AU)(A;CI;LCRPLORC;;;ED)

Schema permissions are written by using the Security Descriptor Definition Language (SDDL).

Note: These SID's will be different in your environment as the beginning of a SID is unique to the given domain.

The beginning of each ACL states what permissions are set over the group or username entry. The second part shows the SID of the group/user account.

I have created a group called AD-GPO-M that I want to add to the template permissions to ensure they get applied to all new group policy objects. We added the following to the end of my SDDL on the defaultSecurityDescriptor attribute. This is the SID that is append to the AD-GPO-M security group.

(A;CI;RPWPCCDCLCLOLORCWOWDSDDTSW;;;S-1-5-21-1445357118-337764505-1417137283-24392)

On the CN=Group-Policy-Contrainer Active Directory object, the defaultSecurityDescriptor attribute now reads:

D:P(A;CI;RPWPCCDCLCLOLORCWOWDSDDTSW;;;DA)(A;CI;RPWPCCDCLCLOLORCWOWDSDDTSW;;;EA)(A;CI;RPWPCCDCLCLOLORCWOWDSDDTSW;;;CO)(A;CI;RPWPCCDCLCLORCWOWDSDDTSW;;;SY)(A;CI;RPLCLORC;;;AU)(OA;CI;CR;edacfd8f-ffb3-11d1-b41d-00a0c968f939;;AU)(A;CI;LCRPLORC;;;ED)(A;CI;RPWPCCDCLCLOLORCWOWDSDDTSW;;;S-1-5-21-1445357118-337764505-1417137283-24392)



Now when I created a new group policy object (GPO) called "Test PCI Member Server" the following permissions were granted by default:



This has now given your non-domain admins who are a member of this group permissions to administer this new group policy object.

For any existing group policy objects they will not currently have access, however you can reset permissions to default which will pull the permissions down from the defaultSecurityDescriptor attribute.



Where are these permissions set?

Permissions for your group policy objects are maintained in two locations.
- Active Directory
- SYSVOL policies container

Whenever you make a change to permissions on a group policy object in group policy management console (GPMC) it will modify permissions on both the Active Directory object and SYSVOL.

In Active Directory the group policy objects are stored under your domain partition --> System --> Policies.



Caution for Multi-Domain Forest

In a multi-domain forest, your administrator account may reside in a Child Domain. You may be nested in the Schema Admins group in the forest root domain. When you use ADSIEdit to modify the CN=Group-Policy-Contrainer on the schema partition you may receive the following error:

Operation failed. Error code: 0x202b
A referral was returned from the server.

0000202B: RefErr: DSID-030A0B09, data 0, 1 access points
ref 1:




I found you need to connect to the schema master in your forest root domain to make this change in ADSIEdit. This resolved the problem.


Wednesday, August 3, 2011

Single Instance Storage (SIS) gone

In previous versions of Exchange 2003-2007 there was a feature called SIS (Single Instance Storage). This meant if an email was sent to multiple mailboxes in a distribution group, it would only get stored in a mailbox database once. When designing database layout it was recommended you group users of a similar operational role under the same mailbox database. This ensures when emails are sent to distribution groups, the email is only stored in the database once.

In Exchange 2010, SIS has now been removed to help improve performance allowing low cost disk to be utilized. This was one of the key factors in reducing disk I/O on the Exchange database.

The decision behind this was around using low cost TIER2 SATA disk, who cares if emails are stored multiple times inside a database?

Have a read of Ross Smith IV's article explaining this in more detail:

http://blogs.technet.com/b/exchange/archive/2010/02/22/3409361.aspx

Thursday, July 28, 2011

ADMT Unable to create or merge object

I am performing domain migration and I ran into the following problem error in the migration logs for a user account:

2011-07-29 13:37:35 WRN1:7665 Unable to create or merge object 'CN=Joe Blow,OU=My Users,DC=domain,DC=local' as another instance of ADMT is currently creating or merging the same object.

I had started migrating Joe Blow to the new forest using ADMT but then realised I hadn't started the Password Export Server on the source domain so I hit "Stop" to stop the migration. I then went and started Password Export Server and tried to migrate the account again. This is where I received the above error.

What happened was ADMT recorded in the ADMT migration SQL database that the account is currently locked as its undergoing migration.

I am using SQL Express 2005 on my ADMT 3.2 server on Windows Server 2008 R2. I went and downloaded SQL Management Studio Express 2005 from here:

http://www.microsoft.com/download/en/details.aspx?id=8961

I then found the location in the ADMT database where the account was locked. It is under the table dbo.LockedObjects.



After deleting this record I was able to successfully migrate the user.

Wednesday, July 27, 2011

Making Domain Controllers cover more then one site

When designing Active Directory sites and services, usually you decide which Active Directory site objects you want to place your domain controllers. Sites are usually mapped to physical locations but can also be logical depending on your design.

However, there is a registry key on domain controllers that allows a domain controller to be authoritative for more then one site object in Active Directory. This registry key is known as SiteCoverage.

For more information about this please see:

http://technet.microsoft.com/en-us/library/cc937924.aspx

ADMT is unable to connect to domain controller. 0x80070005

I am performing cross forest migration from 2 AD forests, multiple domains into a new AD forest. When I added one of the domains within a source forest I received the following error:

ADMT is unable to connect to domain controller
\\domaincontroller.sourcedomain.local, in domain sourcedomain.local. Access is denied.
(0x80070005)




Morgan Che posted up multiple causes for this error on the following forum thread:

http://social.technet.microsoft.com/Forums/en/winserverMigration/thread/f0e341f2-d00c-4bf7-925f-250af8530440

I had a different problem to the ones mentioned on the above forum thread. One of my forests was setup with whats called a single labelled domain name. ADMT was having difficulties communicating with all domains within the single labelled forest.

To resolve this on the ADMT server I needed to add a DWORD registry key "AllowSingleLabelDnsDomain" with a decimal value of 1.



ADMT was then able to communicate with all domains in the forest which had a single labelled root domain.

For more information on this registry key please see:

http://support.microsoft.com/kb/300684

Thursday, July 21, 2011

Understanding how "Log On To" works

In this article we will be having a look at how the Log On To list is populated. This is the list in windows XP/2003 where users can select which domain they are logging into from a drop down list.

I decided to blog this as I spent a morning working out how this worked, and there is little documentation on the Internet.

So where does this list come from?

The logon list is stored from a DomainCache registry key located under:

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\DomainCache



How does this list populate?

Windows populates the DomainCache registry key from a file called C:\WINDOWS\system32\config\netlogon.ftl.



The DomainCache registry key gets updated from netlogon.ftl as part of the computer boot process and whenever a remote desktop connection is established based on my testing.

Here I added a string record to the DomainCache called CLINTY pointing at a fake domain called clint.local. I then locked my PC, you can see it appear in the list.



If I remote desktop my machine or reboot the PC, it repopulates the DomainCache from netlogon.ftl. Here I remote desktoped my PC, you can see in process monitor it did the repopulation.



When it repopulated the DomainCache from netlogon.ftl, it deleted my CLINTY record.

What populates netlogon.ftl?

The netlogon.ftl file is populated from Active Directory by the netlogon service - I think this occurs when the system boots... but I'm not sure.

Where in Active Directory does netlogon.ftl populate from?

It the defaultNamingContext partition under the System container. It populates from the TrustedDomain object types.



You can also query this information using nltest or a VBScript:

nltest /domain_trusts



Here is a copy of the VB Script used in the above screenshot.

' This code prints the trusts for the specified domain.
' ------ SCRIPT CONFIGURATION ------
strDomain = "wfi.wan"
' ------ END CONFIGURATION ---------

' Trust Direction Constants taken from NTSecAPI.h
set objTrustDirectionHash = CreateObject("Scripting.Dictionary")
objTrustDirectionHash.Add "DIRECTION_DISABLED", 0
objTrustDirectionHash.Add "DIRECTION_INBOUND", 1
objTrustDirectionHash.Add "DIRECTION_OUTBOUND", 2
objTrustDirectionHash.Add "DIRECTION_BIDIRECTIONAL", 3

' Trust Type Constants - taken from NTSecAPI.h
set objTrustTypeHash = CreateObject("Scripting.Dictionary")
objTrustTypeHash.Add "TYPE_DOWNLEVEL", 1
objTrustTypeHash.Add "TYPE_UPLEVEL", 2
objTrustTypeHash.Add "TYPE_MIT", 3
objTrustTypeHash.Add "TYPE_DCE", 4

' Trust Attribute Constants - taken from NTSecAPI.h
set objTrustAttrHash = CreateObject("Scripting.Dictionary")
objTrustAttrHash.Add "ATTRIBUTES_NON_TRANSITIVE", 1
objTrustAttrHash.Add "ATTRIBUTES_UPLEVEL_ONLY", 2
objTrustAttrHash.Add "ATTRIBUTES_QUARANTINED_DOMAIN", 4
objTrustAttrHash.Add "ATTRIBUTES_FOREST_TRANSITIVE", 8
objTrustAttrHash.Add "ATTRIBUTES_CROSS_ORGANIZATION", 16
objTrustAttrHash.Add "ATTRIBUTES_WITHIN_FOREST", 32
objTrustAttrHash.Add "ATTRIBUTES_TREAT_AS_EXTERNAL", 64

set objRootDSE = GetObject("LDAP://" & strDomain & "/RootDSE")
set objTrusts = GetObject("LDAP://cn=System," & _
objRootDSE.Get("defaultNamingContext") )

objTrusts.Filter = Array("trustedDomain")
Wscript.Echo "Trusts for " & strDomain & ":"

for each objTrust in objTrusts

for each strFlag In objTrustDirectionHash.Keys
if objTrustDirectionHash(strFlag) = objTrust.Get("trustDirection") then
strTrustInfo = strTrustInfo & strFlag & " "
end If
next

for each strFlag In objTrustTypeHash.Keys
if objTrustTypeHash(strFlag) = objTrust.Get("trustType") then
strTrustInfo = strTrustInfo & strFlag & " "
end If
next

for each strFlag In objTrustAttrHash.Keys
if objTrustAttrHash(strFlag) = objTrust.Get("trustAttributes") then
strTrustInfo = strTrustInfo & strFlag & " "
end If
next

WScript.Echo " " & objTrust.Get("trustPartner") & " : " & strTrustInfo
strTrustInfo = ""
next

Disable SID Filtering - Access is denied.

I went and attempted to disable SID Filtering over some trust links to prepare for SID History during domain migration using the following command:

netdom trust TrustingDomainName /domain: TrustedDomainName /quarantine:No /userD: domainadministratorAcct /passwordD: domainadminpwd

http://technet.microsoft.com/en-us/library/cc772816.aspx

When doing this I got the following error (click to enlarge):



After research I found the cause. “Network access: Allow anonymous SID/name translation” was set to disabled on the Trusted Domain. This this should be enabled on domain controllers – please see http://technet.microsoft.com/en-us/library/cc728431.aspx.

To disable SID Filtering you must Enable anonymous SID/name translation on your Default Domain Controllers GPO for the Trusted Domain.

I set it to enabled. This policy is located under:

Computer Configuration\Windows Settings\Security Settings\Local Policies\Security Options\



After this the problem was resolved:



Note: Access is denied can also be caused if you use NetBIOS names instead of FQDN's for the domain names.

Monday, July 18, 2011

Microsoft Sync Toy - Perfect for Home Users

Today I stumbled across a fantastic little application called Sync Toy. Perfect for home users who want to backup data to a external drive on a regular basis, between computers or to mapped drive pointing to a cloud provider such as Windows Live.

SyncToy 2.1 is a free application that synchronizes files and folders between locations. Typical uses include sharing files, such as photos, with other computers and creating backup copies of files and folders.

It is so easy to use, I think my mum could do it.

Here I have setup synchronization of My Documents to my Microsoft Windows Live SkyDrive cloud account to ensure my documents are backed up at all times. This is a free service. This also allows me to sync the files down to any new computer I work on.

Z:\ is mapped to windows live cloud account.

Please click to enlarge:



As of this writing the latest version of SyncToy is 2.1. The x86 and x64 version is available from here:

http://www.microsoft.com/download/en/details.aspx?id=15155

Note: If you wish to setup a drive letter mapped to your Windows Live SkyDrive service please see the following link:

http://www.addictivetips.com/microsoft-office/map-local-drive-letter-to-live-skydrive-using-office-2010/

Thursday, July 7, 2011

Bind to AD using Alternative Credentials VBS

Below is a VBS Script by MVP Richard L. Mueller which I found very useful. It shows you how to connect to Active Directory using alternative credentials.

Please view his original post here:
http://www.rlmueller.net/ADOAltCredentials.htm

Option Explicit

Dim objRootDSE, strDNSDomain, adoCommand, adoConnection
Dim strBase, strFilter, strAttributes, strQuery, adoRecordset
Dim strDN, strUser, strPassword, objNS, strServer

Const ADS_SECURE_AUTHENTICATION = &H1
Const ADS_SERVER_BIND = &H200

' Specify a server (Domain Controller).
strServer = "MyServer"

' Specify or prompt for credentials.
strUser = "MyDomain\TestUser"
strPassword = "xyz12345"

' Determine DNS domain name. Use server binding and alternate
' credentials. The value of strDNSDomain can also be hard coded.
Set objNS = GetObject("LDAP:")
Set objRootDSE = objNS.OpenDSObject("LDAP://" & strServer & "/RootDSE", _
strUser, strPassword, _
ADS_SERVER_BIND Or ADS_SECURE_AUTHENTICATION)
strDNSDomain = objRootDSE.Get("defaultNamingContext")

' Use ADO to search Active Directory.
' Use alternate credentials.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Properties("User ID") = strUser
adoConnection.Properties("Password") = strPassword
adoConnection.Properties("Encrypt Password") = True
adoConnection.Properties("ADSI Flag") = ADS_SERVER_BIND _
Or ADS_SECURE_AUTHENTICATION
adoConnection.Open "Active Directory Provider"
Set adoCommand.ActiveConnection = adoConnection

' Search entire domain. Use server binding.
strBase = "
' Search for all users.
strFilter = "(&(objectCategory=person)(objectClass=user))"

' Comma delimited list of attribute values to retrieve.
strAttributes = "distinguishedName"

' Construct the LDAP query.
strQuery = strBase & ";" & strFilter & ";" _
& strAttributes & ";subtree"

' Run the query.
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute

' Enumerate the resulting recordset.
Do Until adoRecordset.EOF
' Retrieve values.
strDN = adoRecordset.Fields("distinguishedName").Value
Wscript.Echo strDN
adoRecordset.MoveNext
Loop

' Clean up.
adoRecordset.Close
adoConnection.Close

List all OU's and Sub OU's using VBS

Simple Script to list all OU's and Sub OU's using a VBScript

On Error Resume Next

Const ADS_SCOPE_SUBTREE = 2

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE

objCommand.CommandText = _
"SELECT Name FROM 'LDAP://ou=finance,dc=fabrikam,dc=com' WHERE objectCategory='user'"
Set objRecordSet = objCommand.Execute

objRecordSet.MoveFirst
Do Until objRecordSet.EOF
Wscript.Echo objRecordSet.Fields("Name").Value
objRecordSet.MoveNext
Loop

Wednesday, July 6, 2011

The replication scope could not be set. For more information, see "DNS zone replication in Active Directory

When configuring the DNS zones to replicate to all domains in the forest, instead of all domains just in the current domain the following error was experianced:

"The replication scope could not be set. For more information, see "DNS zone replication in Active Directory" in Help and Support. The error was:

There was a server failure.


To understand where DNS is stored in Active Directory please see:

http://clintboessen.blogspot.com/2010/02/active-directory-dns-zone-locations.html

When trying to connect to the DNS Domain Partition Zone using ADSI Edit (following the above article) the following error was received:

Operation failed. Error code: 0x202b
A referral was returned from the server.

0000202B: RefErr: DSID-03100742, data 0, 1 access points
ref 1 : 'DomainDnsZones.domain.local'




It turned out that the partitions "DomainDNSZones" and "ForestDNSZones" were a lost cause. To fix this you need to perform the following steps:

1. use NTDSUtil to remove the replicas for both ForestDNSZone and DomainDNSZone. Wait for replication. Verify the changes took place then delete each of the partitions.

2. After the deletion has processed to all domain controllers, go into DNS Management and change the Zone to Forest Level/Domain Level. Active Directory will automatically recreate the partition within Active Directory. These new AD application partitions will automatically replicate to all DNS servers. These will then be accessible through ADSI Edit.

It may take over 30 minutes to get to synchronise the DNS zone around - AD is very slow when it comes to DNS.

After this no errors are showing up in the DNS or Active Directory event logs, diagnostics come back clean.