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