DsGetDcNameW function (dsgetdc.h)
The DsGetDcName function returns the name of a domain controller in a specified domain. This function accepts additional domain controller selection criteria to indicate preference for a domain controller with particular characteristics.
Syntax
DSGETDCAPI DWORD DsGetDcNameW(
[in] LPCWSTR ComputerName,
[in] LPCWSTR DomainName,
[in] GUID *DomainGuid,
[in] LPCWSTR SiteName,
[in] ULONG Flags,
[out] PDOMAIN_CONTROLLER_INFOW *DomainControllerInfo
);
Parameters
[in] ComputerName
Pointer to a null-terminated string that specifies the name of the server to process this function. Typically, this parameter is NULL, which indicates that the local computer is used.
[in] DomainName
Pointer to a null-terminated string that specifies the name of the domain or application partition to query. This name can either be a DNS style name, for example, fabrikam.com, or a flat-style name, for example, Fabrikam. If a DNS style name is specified, the name may be specified with or without a trailing period.
If the Flags parameter contains the DS_GC_SERVER_REQUIRED flag, DomainName must be the name of the forest. In this case, DsGetDcName fails if DomainName specifies a name that is not the forest root.
If the Flags parameter contains the DS_GC_SERVER_REQUIRED flag and DomainName is NULL, DsGetDcName attempts to find a global catalog in the forest of the computer identified by ComputerName, which is the local computer if ComputerName is NULL.
If DomainName is NULL and the Flags parameter does not contain the DS_GC_SERVER_REQUIRED flag, ComputerName is set to the default domain name of the primary domain of the computer identified by ComputerName.
[in] DomainGuid
Pointer to a GUID structure that specifies the GUID of the domain queried. If DomainGuid is not NULL and the domain specified by DomainName or ComputerName cannot be found, DsGetDcName attempts to locate a domain controller in the domain having the GUID specified by DomainGuid.
[in] SiteName
Pointer to a null-terminated string that specifies the name of the site where the returned domain controller should physically exist. If this parameter is NULL, DsGetDcName attempts to return a domain controller in the site closest to the site of the computer specified by ComputerName. This parameter should be NULL, by default.
[in] Flags
Contains a set of flags that provide additional data used to process the request. This parameter can be a combination of the following values.
DS_AVOID_SELF
When called from a domain controller, specifies that the returned domain controller name should not be the current computer. If the current computer is not a domain controller, this flag is ignored. This flag can be used to obtain the name of another domain controller in the domain.
DS_BACKGROUND_ONLY
If the DS_FORCE_REDISCOVERY flag is not specified, this function uses cached domain controller data. If the cached data is more than 15 minutes old, the cache is refreshed by pinging the domain controller. If this flag is specified, this refresh is avoided even if the cached data is expired. This flag should be used if the DsGetDcName function is called periodically.
DS_DIRECTORY_SERVICE_PREFERRED
DsGetDcName attempts to find a domain controller that supports directory service functions. If a domain controller that supports directory services is not available, DsGetDcName returns the name of a non-directory service domain controller. However, DsGetDcName only returns a non-directory service domain controller after the attempt to find a directory service domain controller times out.
DS_DIRECTORY_SERVICE_REQUIRED
Requires that the returned domain controller support directory services.
DS_DIRECTORY_SERVICE_6_REQUIRED
Requires that the returned domain controller be running Windows Server 2008 or later.
DS_DIRECTORY_SERVICE_8_REQUIRED
Requires that the returned domain controller be running Windows Server 2012 or later.
DS_FORCE_REDISCOVERY
Forces cached domain controller data to be ignored. When the DS_FORCE_REDISCOVERY flag is not specified, DsGetDcName may return cached domain controller data. If this flag is specified, DsGetDcName will not use cached information (if any exists) but will instead perform a fresh domain controller discovery.
This flag should not be used under normal conditions, as using the cached domain controller information has better performance characteristics and helps to ensure that the same domain controller is used consistently by all applications. This flag should be used only after the application determines that the domain controller returned by DsGetDcName (when called without this flag) is not accessible. In that case, the application should repeat the DsGetDcName call with this flag to ensure that the unuseful cached information (if any) is ignored and a reachable domain controller is discovered.
DS_GC_SERVER_REQUIRED
Requires that the returned domain controller be a global catalog server for the forest of domains with this domain as the root. If this flag is set and the DomainName parameter is not NULL, DomainName must specify a forest name. This flag cannot be combined with the DS_PDC_REQUIRED or DS_KDC_REQUIRED flags.
DS_GOOD_TIMESERV_PREFERRED
DsGetDcName attempts to find a domain controller that is a reliable time server. The Windows Time Service can be configured to declare one or more domain controllers as a reliable time server. For more information, see the Windows Time Service documentation. This flag is intended to be used only by the Windows Time Service.
DS_IP_REQUIRED
This parameter indicates that the domain controller must have an IP address. In that case, DsGetDcName will place the Internet protocol address of the domain controller in the DomainControllerAddress member of DomainControllerInfo.
DS_IS_DNS_NAME
Specifies that the DomainName parameter is a DNS name. This flag cannot be combined with the DS_IS_FLAT_NAME flag.
Specify either DS_IS_DNS_NAME or DS_IS_FLAT_NAME. If neither flag is specified, DsGetDcName may take longer to find a domain controller because it may have to search for both the DNS-style and flat name.
DS_IS_FLAT_NAME
Specifies that the DomainName parameter is a flat name. This flag cannot be combined with the DS_IS_DNS_NAME flag.
DS_KDC_REQUIRED
Requires that the returned domain controller be currently running the Kerberos Key Distribution Center service. This flag cannot be combined with the DS_PDC_REQUIRED or DS_GC_SERVER_REQUIRED flags.
DS_ONLY_LDAP_NEEDED
Specifies that the server returned is an LDAP server. The server returned is not necessarily a domain controller. No other services are implied to be present at the server. The server returned does not necessarily have a writable config container nor a writable schema container. The server returned may not necessarily be used to create or modify security principles. This flag may be used with the DS_GC_SERVER_REQUIRED flag to return an LDAP server that also hosts a global catalog server. The returned global catalog server is not necessarily a domain controller. No other services are implied to be present at the server. If this flag is specified, the DS_PDC_REQUIRED, DS_TIMESERV_REQUIRED, DS_GOOD_TIMESERV_PREFERRED, DS_DIRECTORY_SERVICES_PREFERED, DS_DIRECTORY_SERVICES_REQUIRED, and DS_KDC_REQUIRED flags are ignored.
DS_PDC_REQUIRED
Requires that the returned domain controller be the primary domain controller for the domain. This flag cannot be combined with the DS_KDC_REQUIRED or DS_GC_SERVER_REQUIRED flags.
DS_RETURN_DNS_NAME
Specifies that the names returned in the DomainControllerName and DomainName members of DomainControllerInfo should be DNS names. If a DNS name is not available, an error is returned. This flag cannot be specified with the DS_RETURN_FLAT_NAME flag. This flag implies the DS_IP_REQUIRED flag.
DS_RETURN_FLAT_NAME
Specifies that the names returned in the DomainControllerName and DomainName members of DomainControllerInfo should be flat names. If a flat name is not available, an error is returned. This flag cannot be specified with the DS_RETURN_DNS_NAME flag.
DS_TIMESERV_REQUIRED
Requires that the returned domain controller be currently running the Windows Time Service.
DS_TRY_NEXTCLOSEST_SITE
When this flag is specified, DsGetDcName attempts to find a domain controller in the same site as the caller. If no such domain controller is found, it will find a domain controller that can provide topology information and call DsBindToISTG to obtain a bind handle, then call DsQuerySitesByCost over UDP to determine the "next closest site," and finally cache the name of the site found. If no domain controller is found in that site, then DsGetDcName falls back on the default method of locating a domain controller.
If this flag is used in conjunction with a non-NULL value in the input parameter SiteName, then ERROR_INVALID_FLAGS is thrown.
Also, the kind of search employed with DS_TRY_NEXT_CLOSEST_SITE is site-specific, so this flag is ignored if it is used in conjunction with DS_PDC_REQUIRED. Finally, DS_TRY_NEXTCLOSEST_SITE is ignored when used in conjunction with DS_RETURN_FLAT_NAME because that uses NetBIOS to resolve the name, but the domain of the domain controller found won't necessarily match the domain to which the client is joined.
DS_WRITABLE_REQUIRED
Requires that the returned domain controller be writable; that is, host a writable copy of the directory service.
DS_WEB_SERVICE_REQUIRED
Requires that the returned domain controller be currently running the Active Directory web service.
[out] DomainControllerInfo
Pointer to a PDOMAIN_CONTROLLER_INFO value that receives a pointer to a DOMAIN_CONTROLLER_INFO structure that contains data about the domain controller selected. This structure is allocated by DsGetDcName. The caller must free the structure using the NetApiBufferFree function when it is no longer required.
Return value
If the function returns domain controller data, the return value is ERROR_SUCCESS.
If the function fails, the return value can be one of the following error codes.
Remarks
The DsGetDcName function is sent to the Netlogon service on the remote computer specified by ComputerName. If ComputerName is NULL, the function is processed on the local computer.
DsGetDcName does not verify that the domain controller name returned is the name of an actual domain controller or global catalog. If mutual authentication is required, the caller must perform the authentication.
DsGetDcName does not require any particular access to the specified domain. By default, this function does not ensure that the returned domain controller is currently available. Instead, the caller should attempt to use the returned domain controller. If the domain controller is not available, the caller should call the DsGetDcName function again, specifying the DS_FORCE_REDISCOVERY flag.
Response Time
When using DsGetDcName be aware of the following timing details:- DsGetDcName makes network calls and can take from a few seconds up to one minute, depending on network traffic, topology, DC load, and so on.
- It is NOT recommended to call DsGetDcName from a UI or other timing critical thread.
- The DC Locator does use optimized logic to provide the DC information as quickly as possible. It also uses cached information at the site to contact the closest DC.
Notes on Domain Controller Stickiness
In Active Directory Domain Services, the domain controller locator function is designed so that once a client finds a preferred domain controller, the client will not look for another unless that domain controller stops responding or the client is restarted. This is referred to as "Domain Controller Stickiness." Because workstations typically operate for months without a problem or restart, one unintended consequence of this behavior is that if a particular domain controller goes down for maintenance, all of the clients that were connected to it shift their connections to another domain controller. But when the domain controller comes back up, no clients ever reconnect to it because the clients do not restart very often. This can cause load-balancing problems.Previously, the most common solution to this problem was to deploy a script on each client machine that
periodically called DsGetDcName using the
DS_FORCE_REDISCOVERY
flag. This was a somewhat cumbersome solution, so
Windows Server 2008 and Windows Vista introduced a new mechanism that caused issues with domain
controller stickiness.
Whenever DsGetDcName retrieves a domain controller name from its cache, it checks to see if this cached entry is expired, and if so, discards that domain controller name and tries to rediscover a domain controller name. The life span of a cached entry is controlled by the value in the following registry keys
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\ForceRediscoveryInterval
and
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Netlogon\Parameters\ForceRediscoveryInterval
The values in these registry keys are of type REG_DWORD. They specify the length in seconds before DsGetDcName should try to rediscover the domain controller name. The default value is 43200 seconds (12 hours). If the value of the ForceRediscoveryInterval registry entry is set to 0, the client always performs rediscovery. If the value is set to 4294967295, the cache never expires, and the cached domain controller continues to be used. We recommend that you do not set the ForceRediscoveryInterval registry entry to a value that is less than 3600 seconds (60 minutes).
ETW Tracing in DsGetDcName
To turn on ETW Tracing for DsGetDcName, create the following registry key:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\DCLocator\Tracing
The key will have a structure as follows:
String ProcessName
DWORD PID <optional>
ProcessName must be the full name including extension of the process that you want to get trace information for. PID is only required when multiple processes with the same name exist. If it is defined, then only the process with that PID will be enabled for tracing. It is not possible to trace only 2 out of 3 (or more) processes with the same name. You can enable one instance or all instances (when multiple instances with the same process name exist and PID is not specified, all instances will be enabled for tracing).
For example, this would trace all instances of App1.exe and App2.exe, but only the instance of App3.exe that has a PID of 999:
App1.exe
App2.exe
App3.exe
PID 999
Run the following command to start the tracing session:
tracelog.exe -start <sessionname> -guid #cfaa5446-c6c4-4f5c-866f-31c9b55b962d -f <filename> -flag <traceFlags>
sessionname is the name given for the trace session. The guid for the DCLocator tracing provider is "cfaa5446-c6c4-4f5c-866f-31c9b55b962d". filename is the name of the log file to which the events are written. traceFlags is one or more of the following flags which signify which areas to trace:
Flag | Hex Value | Description |
---|---|---|
DCLOCATOR_MISC | 0x00000002 | Miscellaneous debugging |
DCLOCATOR_MAILSLOT | 0x00000010 | Mailslot messages |
DCLOCATOR_SITE | 0x00000020 | Sites |
DCLOCATOR_CRITICAL | 0x00000100 | Important errors |
DCLOCATOR_SESSION_SETUP | 0x00000200 | Trusted Domain Maintenance |
DCLOCATOR_DNS | 0x00004000 | Name Registration |
DCLOCATOR_DNS_MORE | 0x00020000 | Verbose Name Registration |
DCLOCATOR_MAILBOX_TEXT | 0x02000000 | Verbose Mailbox Messages |
DCLOCATOR_SITE_MORE | 0x08000000 | Verbose sites |
Run the following command to stop the trace session:
tracelog.exe -stop <sessionname>
sessionname is the same name as the name you used when starting the session.
Note
The dsgetdc.h header defines DsGetDcName as an alias that automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that is not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for Function Prototypes.
Requirements
Requirement | Value |
---|---|
Minimum supported client | Windows Vista |
Minimum supported server | Windows Server 2008 |
Target Platform | Windows |
Header | dsgetdc.h |
Library | NetApi32.lib |
DLL | NetApi32.dll |