Windows Server 2008 Protection from Accidental Deletion

By Richard Siddaway, Microsoft Practice Leader, Centiq Ltd

With each new version of the Windows Server Operating System there are new possibilities for automation to help make the administrator’s job easier. Automation brings increased efficiencies but also brings the possibility of bigger mistakes. Additionally no amount of automation can protect us against human error. This is very true when working with Active Directory.

When working with Active Directory it is possible to include an extra account to delete or to get distracted and select the wrong account to delete for instance. Good administrators will double check everything and have procedures to ensure this sort of thing does not happen. Eventually a mistake is made and the wrong account is deleted. There is another scenario where the act is a deliberate and malicious action. This case is more difficult to guard against as if you do not trust your administrators, who can you trust ?

It would be better if the system prevented this sort of mistake in the first place. It is possible to use the delegation of permissions on the Active Directory to control who has permissions to delete accounts. However this is performed, at some point one or more administrators will have the permissions to perform a delete. There is a small but finite chance that at some stage a mistake will be made and an account will deleted that should not have been.

In an ideal world you would be able to stop this happening.

Active Directory in Windows 2008 introduces a number of new features including:

· Prevention of an object being accidentally deleted

· Snapshot backup of Active Directory database

· Ability to mount a snapshot side by side with a live Active Directory

· Read Only Domain Controllers

· Fine grained password policies

· Attribute editor built into Active Directory Users and Computers (i.e. ADSIEdit is built into Active Directory Users and Computers MMC).

These topics all deserve articles in their own right. In this article I will describe the functionality that can be used to prevent accidental deletion of Active Directory objects. It should be noted that the functionality described is based on the IDS3 post Beta 3 release of Windows Server 2008 (build 6001). It is possible that some functionality may change in the production release of Windows Server 2008.

The functionality to prevent accidental deletion is not based on a new attribute in Active Directory. It is enabled by ticking a check box on the Object tab of the particular object you wish to protect. The Object tab is only visible when the Advanced Features option is selected from the View menu of Active Directory Users and Computers.

<

When the tick box is checked the permissions on the object are changed.

A “Deny” permission is created which stops deletion of the object.

This is good because we can now stop the object from being subject to an accidental deletion. If an administrator tries to delete the object from within the MMC an error message is displayed.

Attempting to circumvent the MMC and delete the object from the command line will also fail

In this case using a PowerShell cmdlet to perform the deletion causes a “General access denied error”. Similar results are obtained if the deletion is attempted with a PowerShell script or VBScript.

If the object really is destined for deletion the administrator has to first remove the protection from accidental deletion in the MMC and then perform the deletion. This gives us a system of protection from accidental damage but it will not protect against the malicious act of a rogue administrator. Organisations need to ensure that their procedures are written and applied to minimise the possibility of a rogue administrator damaging their environment.

There are a number of points to note about using the protection from accidental deletion functionality. The first is that the protection does not get automatically applied to any existing child objects in the OU to which protection is applied. This means that in an OU with existing child OUs, users, groups or computers only the parent OU is protected from accidental deletion.

The second point regards creation of new objects in a protected OU. Only some objects automatically have protection applied:

· New OUs are automatically set to be protected

· New users are not protected

· New groups are not protected

· New computers are not protected

Summarising what we have discovered so far:

· We can protect individual objects from accidental deletion

· Protection does not automatically flow from an OU to the objects contained in that OU

· Once an OU is protected the protection will be passed onto new child OUs but not to other objects

Applying the protection manually to each object in our Active Directory is not a scalable solution. We need a method to automate the application of the protection. Windows Server 2008 ships with PowerShell as an optional install. Unfortunately the functionality to access the security permissions of Active Directory objects does not currently exist within PowerShell. However, as PowerShell can access the .NET framework we can use .NET functionality to set the security permissions on the Active Directory objects as shown in the following script.

$ou = [ADSI]"LDAP://ou=Thunderbirds,dc=starking,dc=org"

$sec = $ou.psbase.ObjectSecurity

## set the rights and control type

$act = [System.Security.AccessControl.AccessControlType]::Deny

$adrights = [System.DirectoryServices.ActiveDirectoryRights]::Delete

$adrights2 = [System.DirectoryServices.ActiveDirectoryRights]::DeleteTree

## who does this apply to

$who = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList "", "Everyone"

# stop delete

$newrule1 = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $who, $adrights, $act

$sec.AddAccessRule($newrule1)

$ou.psbase.CommitChanges()

# stop deletetree

$newrule2 = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $who, $adrights2, $act

$sec.AddAccessRule($newrule2)

$ou.psbase.CommitChanges()

$ou = [ADSI]"LDAP://ou=Thunderbirds,dc=starking,dc=org"

#set the users in the OU

foreach ($child in $ou.psbase.children)

{

  $user = [ADSI]$child

  $sec = $user.psbase.ObjectSecurity

  $sec.AddAccessRule($newrule1)

  $user.psbase.CommitChanges()

  $sec.AddAccessRule($newrule2)

  $user.psbase.CommitChanges()

}

The script starts by getting a directory entry to the OU containing the objects you wish to protect. One of the properties of the object is the security. Note that the construction involving psbase is needed to access the object security. PowerShell does not always return the pure .NET object. In the case of Active Directory objects the PowerShell wrapper only returns a subset of the object’s properties. In order to access the other properties it is necessary to access the underlying object which is achieved by using a construction of object.psbase.property.

The second step is to construct the security permissions you wish to apply. This is performed by using the System.Security.AccessControl.AccessControlType and System.Directoryservices.ActiveDirectoryRights enumerations. The .NET documentation gives full details of the contents of these enumerations.

A System.Security.Principal.NTAccount object is used to define to whom the permissions apply. In this case it is the Everyone group. The two new rules are applied to the containing OU.

As a second stage the children of the OU have the rules applied to ensure the OU and its contents are protected from deletion. The script could be turned into a function into which the OUs to be protected are fed or an iterative pass through the directory could be used if the whole of AD was to be protected.

IMPORTANT.

AFTER running the script if you examine the child objects you will notice the following:

· The parent OU has the check box set and is protected

· If none of the child objects have protection set the check box will NOT be set in the GUI and protection will NOT be applied to the child objects

· If you then MANUALLY check the protection box in the GUI then protection will be applied to that object AND ALL OTHER child objects will have protection applied

· If any of the child objects had protection applied application of the script will cause protection to be applied to all child objects touched by the script and the GUI will show the check boxes as set

If you then attempt to delete the parent OU or a child object you will receive the warning message discussed above.

It is important to remember that the functionality will only show in the Windows Server 2008 administration toolset. If you introduce a Windows Server 2008 Domain Controller into an environment where all the other DCs are Windows Server 2003 you will only be able to manage this functionality from the Windows Server 2008 machine. It will be necessary to ensure all administrative personnel are aware of this functionality in order to prevent unnecessary calls for help when objects apparently cannot be deleted.

 

Protection from Accidental Deletion is a very useful piece of Active Directory functionality that should be used when Windows Server 2008 becomes available. It should help to make life a little easier for administrative personnel. Using PowerShell and simple .NET functionality we can apply the protection to our existing objects and simply apply it to new objects if we are using a scripted approach to user creation. This is a very useful piece of functionality that is easy to apply and I would recommend it to Active Directory administrators for serious consideration.