Whencreated что это за атрибут

от admin

Как узнать, кто и когда создал пользователя в Active Directory?

16.11.2022
useritpro
directoryActive Directory, PowerShell, Windows Server 2016
commentsкомментариев 8

В этой статье мы рассмотрим: как узнать дату создания пользователя в Active Directory; как с помощью PowerShell получить из журнала событий контроллера домена информацию о том, кто создал аккаунт пользователя и время последнего входа пользователя в домен. Такие задачи часто возникают при аудите учетных записей пользователей в Active Directory, поиске и удалении неиспользуемых объектов, или сборе статистики.

Как узнать дату создания пользователя в Active Directory?

Вы можете получить дату созданию любого объекта Active Directory (пользователя, компьютера или группы) через графическую консоль ADUC (не забудьте включить опцию Advanced Features в меню View).

консоль ADUC дата создания объекта в Active Directory

  1. Найдите нужного пользователя в дереве AD вручную или с помощью поиска;
  2. Откройте свойства пользователя и перейдите на вкладку Object;
  3. Дата создания объекта в Active Directory указана в поле Created.

Это же значение можно получить из встроенного редактора атрибутов AD (атрибут whenCreated).

атрибут whencreated у объектов AD

Чтобы получить дату создания аккаунта пользователя через PowerShell, воспользуйтесь командлетом Get-ADUser из модуля AD PowerShell:

Get-ADUser a.novak –properties name,whencreated|select name,whencreated

Get-ADUser PowerShell - когда был создан пользователь в active directory - атрибут whencreated

Получить список пользователей, недавно созданных в Active Directory с помощью PowerShell

С помощью простого PowerShell скрипта вы можете вывести список пользователей, созданных недавно в Active Directory. Для этого нужно с помощью командлета Get-ADUser выбрать всех пользователей и отфильтровать их по значению атрибута whencreated. Например, следующий PowerShell код выведет пользователей, созданных в Active Directory за последние 24 часа:

$lastday = ((Get-Date).AddDays(-1))
$filename = Get-Date -Format yyyy.MM.dd
$exportcsv=”c:\ps\new_ad_users_” + $filename + “.csv”
Get-ADUser -filter <(whencreated -ge $lastday)>–properties whencreated | Select-Object Name, UserPrincipalName, SamAccountName, whencreated | Export-csv -path $exportcsv

В этом примере список учетных записей AD сохраняется в CSV файл с текущей датой в качестве имени. С помощью планировщика Windows вы можете настроить ежедневный запуска такого скрипта. В результате в указанном каталоге будут накапливаться файлы, содержащие информацию о дате создания новых учетных записей. В отчет можно добавить любые другие атрибуты пользователя из Active Directory (см. статью об использовании Get-ADUser).

Отчет со списком пользователей, созданных в Active Directory за последние 24 часа

Как узнать, кто создал пользователя в Active Directory?

Если в вашем домене Active Directory несколько администраторов, или вы делегировали в AD права на создание и редактирование учетных записей пользователей другим сотрудникам (например, отделу кадров), вам может понадобится информация о том, что именно создал в Active Directory определенный аккаунт пользователя. Эту информацию можно получить из журналов безопасности контроллеров домена Active Directory.

Когда вы создаете нового пользователя в домене, в журнале безопасности контроллера домена (только того DC, на котором создавалась учетная запись) появляется событие с кодом EvenId 4720 от источника User Account Management (на DC должна быть включена политика аудита Audit account management в политике Default Domain Controller Policy).

В описании этого события содержится строка A user account was created. В поле Subject указана учетная запись, под которой была создана новая учетка пользователя AD (выделена на скриншоте ниже). Имя нового пользователя указано в поле New Account.

событие 4720 от User Account Management - A user account was created

Скрипт для выгрузки всех событий создания аккаунтов из журнала контроллера домена за последние 24 часа может выглядеть следующим образом:

$Report = @()
$time = (get-date) — (new-timespan -hour 24)
Get-WinEvent -FilterHashtable @| Foreach <
$event = [xml]$_.ToXml()
if($event)
<
$Time = Get-Date $_.TimeCreated -UFormat «%Y-%m-%d %H:%M:%S»
$CreatorUser = $event.Event.EventData.Data[4].»#text»
$NewUser = $event.Event.EventData.Data[0].»#text»
$objReport = [PSCustomObject]@<
User = $NewUser
Creator = $CreatorUser
DC = $event.Event.System.computer
CreationDate = $Time
>
>
$Report += $objReport
>
$Report

кто создал аккаунт пользователя в домене Active Directory

На выходе у нас получился объект $Report, содержащий информацию о том, кто создал пользователя, когда создал и на каком DC.

Можно экспортировать содержимое отчета в CSV файл:

$filename = Get-Date -Format yyyy.MM.dd
$exportcsv=”c:\ps\ad_users_creators” + $filename + “.csv”
$Report | Export-Csv $exportcsv -append -NoTypeInformation -Delimiter «,»

Но чаще всего приходится проверять журналы события на всех контроллерах домена. Список всех DC можно получить с помощью командлета Get-ADDomainController. Затем останется проверить на каждом из них событие 4720 и создать результирующий отчет:

$Report = @()
$time = (get-date) — (new-timespan -hour 24)

Для получения информации о дате создания пользователя в Azure AD через PowerShell можно использовать такой метод.

Get AdUser Creation Date

In this article, we will discuss how to use the Get-AdUser cmdlet to get aduser creation date, how to get aduser created between dates and get ad user by Creation date in PowerShell.

Use the Get-Member cmdlet to get Get-AdUser full list of properties, methods, and members.

The output of the above command will list aduser all properties and methods available.

Get AdUser Creation Date

To get creation date of aduser, we will be using whenCreated properties.

Syntax to get aduser create date is

Let’s understand with an example to get aduser account creation date as below

In the above PowerShell script example,

it will return Toms active directory user account creation date.

The output of the above command is as given below

Get AdUser Creation Date

Get AdUser Creation Date

Get-AdUser Creation Date using ADUC

You can get active directory user account creation date using Active Directory Users and Computers ( ADUC) snap-in. It provides a GUI interface to manage users, groups, and computers.

Follow the below steps to know when was the active directory user account was created

  • Click on Start menu >> Select Run
  • Type dsa.msc and hit enter
  • It will open Active Directory Users and Computers mmc snap-in
  • Select OU >> Select User >> Right click on User >> click Attributes editor
  • Scroll down in attributes editor for whenCreated property

For example, in the below example, it gets the creation date for ad user Aron.

Get-AdUser Creation Date using ADUC

Get-AdUser Creation Date using ADUC

Note: In the large-scale active directory, using ADUC to get an aduser creation date is very tedious. Prefer the PowerShell script to get all ad user creation dates.

Get all Ad User Creation Date

You can get all ad user creation date using the get aduser filter parameter and whenCreated property.

get aduser filter * parameter gets all active directory users. Use the below command to get all aduser creation dates and ad users sort by creation date

The above command gets the creation date for all active directory users. It gets aduser sort by creation date using Sort-Object as given below

Cool Tip: How to find a list of adusers passwords never expires!

Get AdUser Created between dates

You can find an active directory user accounts created within x days using the date manipulation and comparing it with the aduser creation date.

For example, to get an aduser created in the last 30 days, run the below command

In the above PowerShell script,

$prvDate variable contains 30 days before the date, calculated using the current date and add -30 days to it.

In the second command, it uses the Get-AdUser filter parameter to get all ad users creation date was greater than 30 days and returns the list of ad user sort by creation date.

Cool Tip: How to use Get-Date to get current date time in PowerShell!

Conclusion

I hope the above article is helpful to you to get aduser creation date using Get-AdUser whenCreated property and using the get-aduser filter parameter to filter aduser objects.

We have discussed how you can get all aduser accounts by creation date and sort by creation date.

You can find more topics about PowerShell Active Directory commands and PowerShell basics on the ShellGeek home page.

whenCreated vs createTimeStamp

WhenCreated attribute was implemented first, and to be complaint with LDAP standards the createTimeStamp was added later on as constructed attribute, the data is really stored only once in the Active Directory database.

Both attributes are replicated to all DC’s, the createTimeStamp should not be replicated to the Global Catalog server since the isMemberOfPartialAttributeSet property of the attribute is not TRUE. However, you can also get a value from the GC.

Active Directory Cookbook, 3rd Edition by Laura E. Hunter, Robbie Allen

Get full access to Active Directory Cookbook, 3rd Edition and 60K+ other titles, with a free 10-day trial of O’Reilly.

There are also live events, courses curated by job role, and more.

Chapter 4. Searching and Manipulating Objects

4.0. Introduction

Active Directory is based on the Lightweight Directory Access Protocol (LDAP) and supports the LDAP version 3 specification defined in RFC 2251. And while many of the AD tools and interfaces, such as ADSI, abstract and streamline LDAP operations to make things easier, any good AD administrator or developer must have a thorough understanding of LDAP to fully utilize Active Directory. This chapter will cover some of the LDAP-related tasks you may need to perform when working with Active Directory, along with other tasks related to searching and manipulating objects within the directory.

The Anatomy of an Object

The Active Directory schema is composed of a hierarchy of classes that define the types of objects that can be created within Active Directory, as well as the different attributes that they can possess. These classes support inheritance , which enables developers to reuse existing class definitions for more than one type of object; for example, the description attribute is available with every type of AD object, but the attribute itself is only defined once within the schema. At the top of the inheritance tree is the top class, from which every class in the schema is derived. Table 4-1 contains a list of some of the attributes that are available from the top class, and subsequently are defined on every object that is created in Active Directory.

Table 4-1. Common attributes of objects

RDN attribute for most object classes, also referred to as the common name .

Timestamp when the object was created. See Recipe 4.26 for more information.

Multivalued attribute that can be used as a generic field for storing a description of the object. Although this attribute is multivalued, objects such as users and groups can only have one value populated due to legacy support requirements.

Name of the object displayed in administrative interfaces.

Distinguished name of the object.

Timestamp when the object was last changed by the local server. See Recipe 4.26 for more information.

RDN of the object. The value of this attribute will mirror the naming attribute (e.g., cn , ou , dc ).

Security descriptor assigned to the object.

Used as a grouping mechanism for objects with a similar purpose (e.g., Person ).

List of classes from which the object’s class was derived.

Globally unique identifier for the object.

Update sequence number (USN) assigned by the local server after the last change to the object (can include creation).

USN assigned by the local server when the object was created.

4.1. Viewing the RootDSE

Problem

You want to view attributes of the RootDSE, which can be useful for discovering basic information about a forest, domain, or domain controller without hardcoding the name of a particular naming context into a query.

Solution

Using a graphical user interface

Open LDP from the Windows Support Tools. (LDP is installed by default on a Windows Server 2008 domain controller.)

From the menu, select Connection→Connect.

For Server, enter a domain controller, domain name, or leave blank to do a serverless bind.

For Port, enter 389.

The contents of the RootDSE will be shown in the right pane.

Using a command-line interface

To display the RootDSE of a domain controller using AdFind, use the following syntax:

You’ll see results similar to the following (truncated for readability):

Using VBScript

Using PowerShell

Discussion

The RootDSE was originally defined in RFC 2251 as part of the LDAPv3 specification. It is not part of the Active Directory namespace per se. It is a synthetic object that is maintained separately by each domain controller.

The RootDSE can be accessed anonymously using LDP; the command-line and VBScript solutions use the credentials of the currently logged-on user unless you specify an alternate username and password. In the CLI and VBScript solutions, serverless binds were used against the RootDSE. In that case, the DC Locator process is used to find a domain controller in the domain you authenticate against. This can also be accomplished with LDP by not entering a server name from the Connect dialog box.

The RootDSE is key to writing portable AD-enabled applications. It provides a mechanism to programmatically determine the distinguished names of the various naming contexts (among other things), which means that you do not need to hardcode that information in scripts and programs. Here is an example from LDP when run against a Windows Server 2003–based domain controller:

Using VBScript

All attributes of the RootDSE were retrieved and displayed. Typically, you will need only a few of the attributes, in which case you’ll want to use Get or GetEx as in the following example:

Or if want to get an object based on the DN of one of the naming contexts, you can call GetObject using an ADsPath:

Using PowerShell

The PowerShell code in this example makes use of the foreach command, which allows you to take a collection of objects (in this case, the properties of RootDSE), and perform the same action on each one.

See Also

RFC 2251, MS KB 219005 (Windows 2000: LDAPv3 RootDSE), MSDN: IADsPropertyEntry, MSDN: IADsProperty Value, MSDN: IADs::Get, and MSDN: IADs::GetEx

4.2. Viewing the Attributes of an Object

Problem

You want to view one or more attributes of an object.

Solution

Using a graphical user interface

Open LDP from the Windows Support Tools or from the Windows Server 2008 command prompt.

From the menu, select Connection→Connect.

For Server, enter the name or IP address of a domain controller or domain that contains the object.

For Port, enter 389.

From the menu, select Connection→Bind.

Enter credentials of a user who can view the object (if necessary).

From the menu, select View→Tree.

For BaseDN, type the DN of the object you want to view.

For Scope, select Base.

Using a command-line interface

To obtain a list of attributes for a particular object using DSQuery, use the following syntax:

For Windows 2000, use this command:

To query for an object using AdFind, use the following syntax:

For example, querying for the administrator user object produces the following output:

Using VBScript

Using PowerShell

Discussion

Objects in Active Directory are made up of a collection of attributes. Attributes can be single- or multivalued. Each attribute also has an associated syntax that is defined in the schema. See Recipe 10.7 for a complete list of syntaxes.

Using a graphical user interface

You can customize the list of attributes returned from a search with LDP by modifying the Attributes: field under Options→Search. To include all attributes, enter an asterisk ( * ). To modify the default subset of attributes that are returned, enter a semicolon-separated list of attributes. You can also use the numeric attribute ID instead of the attribute name, such as using 1.1 in place of distinguishedName .

Using a command-line interface

The -attr option for the dsquery command accepts a whitespace-separated list of attributes to display. Using an asterisk ( * ) will return all default attributes.

For the enumprop command, you can use the /ATTR option and a comma-separated list of attributes to return. In the following example, only the name and whenCreated attributes are returned:

When using AdFind, you have several shortcut switches to reduce the amount of typing you need to do. If you are searching for an object in the default container, you can use the –default switch rather than something like –b dc=contoso,dc=com . Likewise, if you are querying the Configuration NC, you can use the –config switch, -root for the root partition, or –schema for the Schema partition. If you want to query a subcontainer of one of these partitions, you can add the –rb switch, which stands for Relative Base .

Using VBScript

The DisplayAttributes function prints the attributes that contain values for the object passed in. After using GetObject to bind to the object, the IADs::GetInfo method was used to populate the local property cache with all of the object’s attributes from AD. To print each value of a property, you have to know its type or syntax. The ADsType method returns an integer from the ADSTYPEENUM enumeration that corresponds with a particular syntax (e.g., Boolean ). Based on the syntax, you call a specific method (e.g., Boolean) that can properly print the value. If you didn’t incorporate this logic and tried to print all values, using the CaseIgnoreString method for example, an error would get generated when the script encountered an octet string because octet strings (i.e., binary data) do not have a CaseIgnoreString representation.

The values from the ADSTYPEENUM enumeration are stored in key/value pairs in a dictionary object (i.e., Scripting.Dictionary ). In the dictionary object, the key for the dictionary is the ADSTYPEENUM integer and the value is a textual version of the syntax. The dictionary object was used to print the textual syntax of each attribute. You iterated over all the properties in the property cache using IADsPropertyList and IADsPropertyEntry objects, which are instantiated with the IADsPropertyList::Item method.

The DisplayAttributes function is used throughout the book in examples where the attributes for a given type of object are displayed.

Using PowerShell

The PowerShell example in this recipe can also make use of the free Quest Active Directory cmdlets, specifically the Get-QADObject cmdlet.

See Also

Chapter 1 for more information about the Quest Active Directory cmdlets, Recipe 10.7, MSDN: IADsPropertyEntry, MSDN: IADsPropertyList, MSDN: ADSTYPEENUM, MSDN: IADs::GetInfo, and Chapter 20 of Active Directory , Fourth Edition, Brian Desmond et al. (O’Reilly).

4.3. Counting Objects in Active Directory

Problem

You want to retrieve the number of directory objects that meet the result of an LDAP query.

Solution

Using a graphical user interface

Open LDP from the Windows Support Tools.

From the menu, select Connection→Connect.

For Server, enter the name or IP address of a domain controller or domain that contains the object.

For Port, enter 389.

From the menu, select Connection→Bind.

Enter credentials of a user who can view the object (if necessary).

From the menu, select Browse→Search.

Enter the base DN, scope, and the LDAP filter of the objects that you’re looking for.

Click on Options and remove the checkmark next to Display Results. This will display the number of objects returned by the query without displaying the details of the items that are returned.

Click OK and then click Run to perform the query.

Using a command-line interface

To retrieve a count of objects that match a particular query, use the following syntax:

For example, retrieving the number of user objects in the adatum.com domain would use the following syntax:

Using VBScript

Using PowerShell

The following example will query Active Directory for a list of user objects, and return the count:

Discussion

Using VBScript

The VBScript solution uses the RecordCount property of an ADO Recordset, which contains the number of records that were returned by a particular query. The script listed here does not enable paging, so it will not work if more than 1,000 records will be returned by a query unless you specify the «Page size» property of the connection object, similar to the following:

Using PowerShell

The PowerShell code here can be shortened to a single line through the use of parentheses, as follows:

4.4. Using LDAP Controls

Problem

You want to use an LDAP control as part of an LDAP operation.

Solution

Using a graphical user interface

Open LDP from the Windows Support Tools.

From the menu, select Options→Controls.

For the Windows Server 2003 version of LDP, select the control you want to use under Load Predefined. The control should automatically be added to the list of Active Controls.

For the Windows 2000 version of LDP, you’ll need to type the object identifier (OID) of the control under Object Identifier.

Enter the value for the control under Value.

Select whether the control is server- or client-side under Control Type.

Check the box beside Critical if the control is critical.

Click the Check-in button.

At this point, you will need to invoke the LDAP operation (e.g., Search) that will use the control. In the dialog box for any operation, be sure that the “Extended” option is checked before initiating the operation.

Using a command-line interface

The AdFind and AdMod utilities will enable a number of LDAP controls, either by default or through the use of various command-line switches. For example, the –showdel switch will invoke the Show Deleted Objects LDAP control, and -stats will invoke the Show Stats control.

Using VBScript

None of the ADSI automation interfaces directly expose LDAP controls. That means they cannot be utilized from VBScript. On the other hand, many of the controls, such as paged searching or deleting a subtree, are wrapped within their own ADSI methods that can be used within VBScript.

Any LDAP-based API, such as the Perl Net::LDAP modules, can be used to set controls as part of LDAP operations.

Using PowerShell

You can leverage LDAP controls within the current version of PowerShell by setting various properties on a DirectorySearcher object, such as the Tombstone property to return deleted objects, the ReferralChasing property, etc. For example, the following code will search for deleted objects that have an objectClass of computer :

Discussion

LDAP controls were defined in the LDAPv3 specification as a way to extend LDAP and its operations without breaking the protocol. Many controls have been implemented, some of which are used when searching the directory (e.g., paged searching, Virtual List View [VLV], finding deleted objects, and attribute scoped query), and some are needed to do certain modifications to the directory (e.g., cross-domain object moves, tree delete, and permissive modify). Controls can be marked as critical, which means they must be processed with the request or an error is returned. If an unsupported control is not flagged as critical, the server can continue to process the request and ignore the control.

The complete list of controls supported by Active Directory is included in Table 4-2.

Table 4-2. LDAP controls supported by Active Directory

Permit No-Opt Modify

Allows duplicate adds of the same value for an attribute or deletion of an attribute that has no values to succeed (normally, it would fail in that situation).

Return Deleted Objects

Used to inform the server to return any deleted objects that matched the search criteria.

Cross Domain Move

Used to move objects between domains.

Set change notifications

Used by clients to register for notification of when changes occur in the directory.

Used to inform the server to return after directory modifications have been written to memory, but before they have been written to disk. This can speed up processing of a lot of modifications.

Security Descriptor Flags

Used to pass flags to the server to control certain security descriptor options.

Used to delete portions of the directory tree, including any child objects.

Verify Name Existence

Used to target a specific GC server that is used to verify DN-valued attributes that are processed during addition or modification operations.

No referrals generated

Informs the server not to generate any referrals in a search response.

Domain or phantom scope

Used to pass flags to the server to control search options.

Used to return statistics about an LDAP query. See Recipe 15.10 for an example.

Attribute Scoped Query

Used to force a query to be based on a specific DN-valued attribute. This control is new to Windows Server 2003. See Recipe 4.8 for an example.

Used to return an object’s GUID and SID (for security principals) as part of its distinguished name.

Used to pass the SID of a security principal in order to query constructed attributes such as ms-DS-Quota-Effective and ms-DS-Quota-Used .

Instructs the server to return search results in “pages.”

Used to find objects that have changed over a period of time.

Server-side Sort Request

Used to inform the server to sort the results of a search.

Server-side Sort Response

Returned by the server in response to a sort request.

Used to request a virtual list view of results from a search. This control is new to Windows Server 2003.

Response from a server returning a virtual list view of results from a search. This control is new to Windows Server 2003.

See Also

Recipe 4.8, Recipe 15.10, RFC 2251 (Lightweight Directory Access Protocol [v3]) for a description of LDAP controls, MSDN: Extended Controls, and MSDN: Using Controls

4.5. Using a Fast or Concurrent Bind

Problem

You want to perform an LDAP bind using a concurrent bind, also known as a fast bind. Concurrent binds are typically used in situations where you need to authenticate a lot of users, and those users either do not need to directly access the directory or else the directory access is done with another account.

Solution

This capability was added in Windows Server 2003.

Using a graphical user interface

Open LDP from the Windows Support Tools.

From the menu, select Connection→Connect.

For Server, enter the name of a DC.

For Port, enter 389.

From the menu, select Options→Connection Options.

Under Option Name: select LDAP_OPT_F*_CONCURRENT_BIND.

Click the Set button.

From the menu, select Connection→Bind.

Enter credentials of a user.

Discussion

Unlike simple binding, concurrent binding does not generate a security token or determine a user’s group memberships during the authentication process. It only determines if the authenticating user has a valid enabled account and password, which makes it much faster than a typical bind. This is usually used pro grammatically for AD-enabled applications to improve the speed of AD authentication; it’s not something that you’ll typically do on the fly. Concurrent binding is implemented as a session option that is set after you establish a connection to a domain controller, but before any bind attempts are made. After the option has been set, any bind attempt made with the connection will be a concurrent bind.

Читать:
Strokescribe что это за программа

There are a couple of caveats when using concurrent binds. First, you cannot enable signing or encryption, which means that all data for concurrent binds will be sent over the network in clear text. Secondly, because the user’s security token is not generated, access to the directory is done anonymously and access restrictions are based on the ANONYMOUS LOGON principal.

It is worth mentioning that there is another type of bind—a fast bind—which has been available since Windows 2000, but it is completely different from the procedure just described. This fast bind is implemented within ADSI, and simply means that when you fast bind to an object, the objectClass attribute for the object is not retrieved; therefore, the object-specific IADs class interfaces are not available. For example, if you bound to a user object using an ADSI fast bind, then only the basic IADs interfaces would be available, not the IADsUser interfaces.

This is the complete list of interfaces that are available for objects retrieved with fast binds:

You must use the IADsOpenDSObject::OpenDSObject interface to enable fast binds. If you call IADsContainer::GetObject on a child object of a parent you used a fast bind with, the same fast bind behavior applies. Unlike concurrent binds, ADSI fast binds do not impose any restrictions on the authenticating user. This means that the object-specific IADs interfaces will not be available. Also, no check is done to verify the object exists when you call OpenDSObject .

ADSI fast binds are useful when you need to make a lot of updates to objects that you know exist (perhaps from an ADO query that returned a list of DNs) and you do not need any IADs-specific interfaces. Instead of two trips over the network per object binding, there would only be one.

See Also

MSDN: Using Concurrent Binding and MSDN: ADS_AUTHENTICATION_ENUM

4.6. Connecting to an Object GUID

Problem

You want to bind to a container using its Globally Unique Identifier (GUID).

Solution

Using a graphical user interface

Open LDP from the Windows Support Tools.

From the menu, select Connection→Connect.

For Server, enter the name of a domain controller (or leave blank to do a serverless bind).

For Port, enter 389.

From the menu, select Connection→Bind.

Enter credentials of a user.

From the menu, select Browse→Search.

For BaseDN, enter the GUID of the object that you’re searching for in the following format:

For Scope, select the appropriate scope.

For Filter, enter an LDAP filter.

Using a command-line interface

Using VBScript

Using PowerShell

Discussion

Each object in Active Directory has a GUID associated with it, stored in the objectGUID attribute. The GUID is for most purposes a unique identifier that retains its value even if an object is updated, renamed, or moved. This makes the GUID the preferable means of binding to an object, rather than hardcoding a reference to an object name that might change or by using a potentially complex LDAP query.

See Also

For a more in-depth discussion of the objectGUID attribute, see “GUIDs, or Having Unique in the Name Doesn’t Make It So” (http://blog.joeware.net/2005/06/19/42/), MSDN: IADs.GUID, MSDN: Using objectGUID to Bind to an Object, and Recipe 4.7

4.7. Connecting to a Well-Known GUID

Problem

You want to connect to LDAP using one of the well-known GUIDs in Active Directory.

Solution

Using a graphical user interface

From the menu, select Connection→Connect.

For Server, enter the name of a domain controller (or leave blank to do a serverless bind).

For Port, enter 389.

From the menu, select Connection→Bind.

Enter credentials of a domain user.

From the menu, select View→Tree.

For the DN, enter:

where <WKGUID> is the well-known GUID that you want to connect to, and <DomainDN> is the distinguished name of a domain.

Click OK. In the lefthand menu, you can now browse the container corresponding to the well-known GUID that you specified.

Using a command-line interface

To enumerate the well-known GUIDs in the Domain NC, use the following syntax:

To display the WKGUIDs in the Configuration NC, replace –default with –config in the previous syntax.

To connect to a well-known GUID in the Domain NC using AdFind, use the following syntax:

Because of additional security settings attached to the Deleted Objects container, if you specify this GUID you must also use the –showdel switch in adfind .

Using VBScript

Using PowerShell

Discussion

The domain NC in Active Directory contains a number of well-known GUIDs that correspond to containers that exist in every AD implementation. These GUIDs are stored as wellKnownObjects attributes within the <DomainDN> object, and allow administrators and developers to consistently connect to critical containers even if they are moved or renamed. The <DomainDN> container possesses the following objects that correspond to well-known GUIDs:

CN=Microsoft,CN=Program Data, <DomainDN>

CN=Deleted Objects, <DomainDN>

OU=Domain Controllers, <DomainDN>

The Configuration NC adds these additional WKGUIDs:

CN=NTDS Quotas,CN=Confguration, <ForestRootDN>

CN=Deleted Objects,CN=Configuration, <ForestRootDN>

See Also

MSDN: Binding to Well-Known Objects Using WKGUID

4.8. Searching for Objects in a Domain

Problem

You want to find objects in a domain that match certain criteria.

Solution

Using a graphical user interface

Open LDP from the Windows Support Tools.

From the menu, select Connection→Connect.

For Server, enter the name of a domain controller (or leave blank to do a serverless bind).

For Port, enter 389.

From the menu, select Connection→Bind.

Enter credentials of a user.

From the menu, select Browse→Search.

For BaseDN, type the base distinguished name where the search will start. (You can leave this blank if you wish to connect to the domain NC as the base DN.)

For Scope, select the appropriate scope.

For Filter, enter an LDAP filter.

Using a command-line interface

To run a query using the built-in DSQuery tool, use the following syntax:

To retrieve the SAM account name for all user objects within the adatum.com domain, for example, use the following syntax:

To run a query using adfind , use the following syntax:

Querying for SAM account names of user objects with adfind takes the following syntax:

Both DSQuery and AdFind assume a default search scope of subtrees; you only need to specify the search scope if you want to use a different one.

Using VBScript

Using PowerShell

The following example will search for user objects within an Active Directory domain using the Quest get-QADObject cmdlet:

Another option is to use the DirectorySearcher class from the .NET Framework, as follows:

Discussion

Most tools that can be used to search Active Directory require a basic understanding of how to perform LDAP searches using a base DN, search scope, and search filter, as described in RFC 2251 and 2254. The base DN is where the search begins in the directory tree. The search scope defines how far down in the tree to search from the base DN. The search filter is a prefix notation string that contains equality comparisons of attribute and value pairs.

The scope can be base , onelevel (or one ), or subtree (or sub ). A base scope will only match the base DN, onelevel will only match objects that are contained directly under the base DN, and subtree will match everything from the base DN and any objects beneath it.

There are no LDAP query scopes that will walk backward “up” the tree.

The search filter syntax is a powerful way to represent simple and complex queries. For example, a filter that matches all of the user objects would be (&(objectclass=user)(objectcategory=Person)) . For more information on filters, see RFC 2254.

Using a graphical user interface

To customize the list of attributes returned for each matching object, look at the GUI discussion in Recipe 4.2.

Using a command-line interface

<AttrList> should be a space-separated list of attributes to return. To return all attributes that have been populated with a value, leave this field blank or use an asterisk ( * ).

Using VBScript

The VBScript solution uses ADO to perform the search. When using ADO, you must first create a connection object with the following three lines:

At this point you can pass parameters to the Execute method, which will return a ResultSet object. You can iterate over the ResultSet by using the MoveFirst and MoveNext methods.

See Recipe 4.9 for more information on specifying advanced options in ADO like the page size.

Using PowerShell

A DirectorySearcher can be further customized by modifying additional properties related to the directory search, such as $objSearcher.SearchScope = [System.DirectoryServices.SearchScope]::OneLevel to specify a One Level LDAP search.

See Also

Recipe 4.2 for viewing attributes of objects, Recipe 4.9 for setting advanced ADO options, RFC 2251 (Lightweight Directory Access Protocol [v3]), RFC 2254 (Lightweight Directory Access Protocol [v3]), MSDN: Searching with ActiveX Data Objects (ADO), and for a good white paper on performing queries with LDAP, see http://www.microsoft.com/windows2000/techinfo/howitworks/activedirectory/ldap.asp

4.9. Searching the Global Catalog

Problem

You want to perform a forest-wide search using the global catalog.

Solution

Using a graphical user interface

Open LDP from the Windows Support Tools.

From the menu, select Connection→Connect.

For Server, enter the name of a global catalog server.

For Port, enter 3268.

From the menu, select Connection→Bind.

Enter the credentials of a user.

From the menu, select Browse→Search.

For BaseDN, type the base distinguished name of where to start the search.

For Scope, select the appropriate scope.

For Filter, enter an LDAP filter.

Using a command-line interface

To query the global catalog using DSQuery, use the following syntax:

To run a query using AdFind, use the following syntax:

Using VBScript

Using PowerShell

To query the global catalog using the Quest AD cmdlets, use the following syntax to create the global catalog connection, and then use get-QADObject as described in previous recipes:

To query the global catalog using the DirectorySearcher class, use the following syntax:

Discussion

The global catalog facilitates forest-wide searches. When you perform a normal LDAP search over port 389, you are searching against a particular partition within Active Directory, whether that is the Domain naming context, Configuration naming context, Schema naming context, or an application partition. If you have multiple domains in your forest, this type of search will not search against all domains but only the domain that you specify.

The global catalog, by contrast, contains a subset of the attributes for all objects in the forest (excluding objects in application partitions). Think of it as a subset of all the naming contexts combined. Every object in the directory will be contained in the global catalog (except for objects contained within application partitions), but only some of the attributes of those objects will be available. For that reason, if you perform a global catalog search and do not get values for attributes you were expecting to, make sure those attributes are included in the global catalog, also known as the partial attribute set (PAS). See Recipe 10.15 for more information on adding information to the PAS. As an alternative, you can query a DC within the domain containing the object to return a list of all attributes configured for that object.

Using a graphical user interface

The only difference between this solution and Recipe 4.8 is that the port has changed to 3268, which is the standard GC port.

Using a command-line interface

The only difference between this solution and Recipe 4.8, both for DSQuery and AdFind, is the addition of the -gc flag.

Using VBScript

The only difference between this solution and Recipe 4.8 is that the strBase variable changed to use the GC: progID :

See Also

Recipe 4.8 for searching for objects, Recipe 10.15, and MSDN: Searching with ActiveX Data Objects (ADO)

4.10. Searching for a Large Number of Objects

Problem

Your search is returning exactly 1,000 objects, which is only a subset of the objects you expected, and you want it to return all matching objects.

Solution

You might notice that searches with large numbers of matches stop displaying after 1,000. By default, domain controllers return a maximum of 1,000 entries from a search unless paging is enabled. This is done to prevent queries from consuming excessive resources on domain controllers by retrieving the results all at once instead of in pages or batches. The following examples are variations of Recipe 4.8, which will show how to enable paging and return all matching entries.

Using a graphical user interface

Open LDP from the Windows Support Tools.

From the menu, select Connection→Connect.

For Server, enter the name of a domain controller (or leave blank to do a serverless bind).

For Port, enter 389.

From the menu, select Connection→Bind.

Enter the credentials of a user.

From the menu, select Browse→Search.

For BaseDN, type the base distinguished name of where the search will start. (You can leave this blank if you wish to connect to the domain NC as the base DN.)

For Scope, select the appropriate scope.

For Filter, enter an LDAP filter.

Click Options to customize the options for this query.

For Timeout(s), enter a value such as 10.

For Page size, enter the number of objects to be returned with each page (e.g., 1,000).

Under Search Call Type, select Paged.

Click OK and then Run to perform the query. A page of results (i.e., 1,000 entries) will be displayed each time you click Run until all results have been returned.

Using a command-line interface

Using VBScript

Using PowerShell

Discussion

Paged searching support is implemented via an LDAP control. LDAP controls were defined in RFC 2251 and the Paged control in RFC 2696. Controls are extensions to LDAP that were not built into the protocol, so not all directory vendors support the same ones.

In Active Directory, you can change the default maximum page size of 1,000 by modifying the LDAP query policy. See Recipe 4.27 for more information.

If you need searches to return hundreds of thousands of entries, Active Directory will return a maximum of only 262,144 entries even when paged searching is enabled. This value is defined in the LDAP query policy and can be modified like the maximum page size (see Recipe 4.27).

Using a graphical user interface

A word of caution when using LDAP to display a large number of entries—by default, only 2,048 lines will be displayed in the right pane. To change that value, go to Options→General and change the Line Value under Buffer Size to a larger number.

Using a command-line interface

The only difference between this solution and Recipe 4.8 is the addition of the -limit 0 flag. With -limit set to 0 , paging will be enabled according to the default LDAP query policy; matching objects will be returned within those parameters. If -limit is not specified, a maximum of 100 entries will be returned.

AdFind enables paged searches by default; it will return any number of objects from a query without any modification.

Using VBScript

To enable paged searching in ADO, you must instantiate an ADO Command object. A Command object allows for various properties of a query to be set, such as size limit, time limit, and page size. See MSDN for the complete list.

Using PowerShell

To enable paged searches in PowerShell, you will need to modify the PageSize property of the DirectorySearcher object.

The get-QADObject cmdlet also includes a –PageSize switch that will indicate the maximum results that should be returned, with a default value of 50. Similar to the –limit switch in dsquery , invoking this switch will cause paging to be enabled according to the default LDAP query policy.

See Also

Recipe 4.8 for searching for objects, Recipe 4.27 for viewing the default LDAP policy, RFC 2251 (Lightweight Directory Access Protocol [v3]), RFC 2696 (LDAP Control Extension for Simple Paged Results Manipulation), and MSDN: Searching with ActiveX Data Objects (ADO)

4.11. Searching with an Attribute-Scoped Query

This recipe requires the Windows Server 2003 forest functional level or better.

Problem

You want to perform a search using an individual value within a multivalued attribute as part of the search criteria. An attribute-scoped query can do this in a single query, instead of the previous method, which required multiple queries.

Solution

Using a graphical user interface

Follow the steps in Recipe 4.4 to enable an LDAP control.

Select the Attribute Scoped Query control (you can select controls by name with the Windows Server 2003 and Windows Server 2008 version of LDP). For the Windows 2000 version of LDP, add a control with an OID of 1.2.840.113556.1.4.1504.

For Value, enter the multivalued attribute name (e.g., member ).

Click the “Check in” button.

From the menu, select Browse→Search.

For BaseDN, type the DN of the object that contains the multivalued attributes.

For Scope, select Base.

For Filter, enter an LDAP filter to match against the objects that are part of the multivalued DN attribute.

Warning

Attribute-scoped queries can only be performed using a Base scope.

Using a command-line interface

AdFind allows attribute-scoped queries by using the -asq switch; for example:

Using VBScript

You cannot use attribute-scoped queries with ADSI, ADO, and VBScript. In an ADO search, you can use the ADSI Flags property as part of a Connection object to set the search preference, but there is no way to set the attribute that should be matched, which must be included as part of the LDAP control.

Using PowerShell

The Quest AD cmdlets will allow you to perform an attribute-scoped query as follows:

You can also use the native ADSI methods in PowerShell:

Discussion

When dealing with group objects, you may have encountered the problem where you wanted to search against the members of a group to find a subset or to retrieve certain attributes about each member. This normally involved performing a query to retrieve all of the members, and additional queries to retrieve whatever attributes you needed for each member. This was less than ideal, so an alternative was developed for Windows Server 2003.

With an attribute-scoped query, you can perform a single query against the group object and return whatever properties you need from the member’s object, or return only a subset of the members based on certain criteria. Let’s look at the LDAP search parameters for an attribute-scoped query:

The value to set for this control should be the DN attribute that you want to iterate over (e.g., member ).

This must be the DN of the object that contains the DN attribute (e.g., cn=Domain Admins,cn=users,dc=adatum,dc=com ).

This must be set to Base to query only the group object itself.

The filter will match against objects defined in the Control Value. For example, a filter of (objectClass=user) would match user objects only. You can also use any other attributes that are available with those objects. The following filter would match all user objects that have a department attribute equal to “Sales”:

This should contain the list of attributes to return for the objects matched in the DN attribute.

When performing an attribute-scoped query against a member attribute, it’s important to remember that primary group membership is handled as a special case; as such you may experience unpredictable results in this situation.

See Also

Recipe 4.4, MSDN: Performing an Attribute Scoped Query, and MSDN: Searching with ActiveX Data Objects (ADO)

4.12. Searching with a Bitwise Filter

Problem

You want to search against an attribute that contains a bit flag , which requires you to use a bitwise filter to perform the search.

Solution

Using a graphical user interface

Open LDP from the Windows Support Tools.

From the menu, select Connection→Connect.

For Server, enter the name of a domain controller (or leave blank to do a serverless bind).

For Port, enter 389.

From the menu, select Connection→Bind.

Enter credentials of a user.

From the menu, select Browse→Search.

For BaseDN, type the base distinguished name of where the search will start. (You can leave this blank if you wish to connect to the domain NC as the base DN.)

For Scope, select the appropriate scope.

For the Filter, enter the bitwise expression, such as the following, which will find all universal groups:

Using a command-line interface

The following query finds universal groups in the adatum.com domain by using a bitwise AND filter:

The following query finds disabled user accounts in the adatum.com domain by using a bitwise AND filter:

You can also perform queries that use bitwise filters using AdFind. The following will find all disabled user accounts in the adatum.com domain:

Similarly, the following will return all universal groups in the adatum.com domain using a bitwise filter:

Using VBScript

Using PowerShell

Discussion

Many attributes in Active Directory are composed of bit flags. A bit flag is often used to encode properties about an object into a single attribute. For example, the groupType attribute on group objects is a bit flag that is used to determine the group scope and type.

The userAccountControl attribute on user and computer objects is used to describe a whole series of properties, including account status (i.e., enabled or disabled), account lockout, password not required, smartcard authentication required, etc.

The searchFlags and systemFlags attributes on attributeSchema objects define, among other things, whether an attribute is constructed, indexed, and included as part of Ambiguous Name Resolution (ANR).

To search against these types of attributes, you need to use bitwise search filters. There are two types of bitwise search filters you can use, one that represents a logical OR and one that represents a logical AND. This is implemented within a search filter as a matching rule . A matching rule is simply a way to inform the LDAP server (in this case, a domain controller) to treat part of the filter differently. Here is an example of what a matching rule looks like:

The format is ( attributename:MatchingRuleOID:=value ), though AdFind allows you to use an easier syntax for bitwise queries. As mentioned, there are two bitwise matching rules, which are defined by OIDs. The logical AND matching rule OID is 1.2.840.113556.1.4.803 and the logical OR matching rule OID is 1.2.840.113556.1. 4.804. These OIDs instruct the server to perform special processing on the filter. A logical OR filter will return success if any bit specified by value is stored in attributename . Alternatively, the logical AND filter will return success if all bits specified by value match the value of attributename . Perhaps an example will help clarify this.

To create a normal user account, you have to set userAccountControl to 514. The number 514 was calculated by adding the normal user account flag of 512 together with the disabled account flag of 2 (512 + 2 = 514). If you use the following logical OR matching rule against the 514 value, as shown here:

then all normal user accounts (flag 512) OR disabled accounts (flag 2) would be returned. This would include enabled user accounts (from flag 512), disabled computer accounts (from flag 2), and disabled user accounts (from flag 2). In the case of userAccountControl , flag 2 can apply to both user and computer accounts, which is why both would be included in the returned entries.

One of the benefits of bitwise matching rules is that they allow you to combine a bunch of comparisons into a single filter. In fact, it may help to think that the OR filter could also be written using two expressions:

Just as before, this will match userAccountControl attributes that contain either the 2 or 512 flags; we’re performing two OR operations against the same value, first ORing the value against 2, then against 512.

For the logical AND operator, similar principles apply. Instead of any of the bits in the flag being a possible match, all of the bits in the flag must match for it to return a success. If the userAccountControl example was changed to use logical AND, it would look like this:

In this case, only normal user accounts that are also disabled would be returned. The same filter could be rewritten using the & operator instead of | as in the following:

An important subtlety to note is that when you are comparing only a single bit flag value, the logical OR and logical AND matching rule would return the same result. So if you wanted to find any normal user accounts you could search on the single bit flag of 512 using either of the following:

Using PowerShell

Searching on a bitwise operator in PowerShell is done using a DirectorySearcher object with the appropriate LDAP filter, as you can see. In future chapters we will look at individual AD cmdlets that “mask” the bitwise search into a more human-readable operation, such as the Enable-QADUser and Disable-QADUser Quest cmdlets.

See Also

MSDN: Enumerating Groups by Scope or Type in a Domain, MSDN: Determining Which Properties Are Non-Replicated, Constructed, Global Catalog, and Indexed, and MS KB 305144 (How to Use the UserAccountControl Flags to Manipulate User Account Properties)

Похожие статьи