dsGetDcNameA 函式 (dsgetdc.h)
DsGetDcName 函式會傳回指定網域中的域控制器名稱。 此函式會接受其他域控制器選取準則,以指出具有特定特性的域控制器喜好設定。
語法
DSGETDCAPI DWORD DsGetDcNameA(
[in] LPCSTR ComputerName,
[in] LPCSTR DomainName,
[in] GUID *DomainGuid,
[in] LPCSTR SiteName,
[in] ULONG Flags,
[out] PDOMAIN_CONTROLLER_INFOA *DomainControllerInfo
);
參數
[in] ComputerName
Null 終止字串的指標,指定要處理此函式的伺服器名稱。 一般而言,此參數為 NULL,表示使用本機電腦。
[in] DomainName
Null 終止字串的指標,指定要查詢之網域或應用程式分割區的名稱。 此名稱可以是 DNS 樣式名稱,例如,fabrikam.com 或一般樣式的名稱,例如 Fabrikam。 如果指定了 DNS 樣式名稱,可以使用或不含尾端句號來指定名稱。
如果 Flags 參數包含 DS_GC_SERVER_REQUIRED 旗標, DomainName 必須是樹系的名稱。 在此情況下,如果 DomainName 指定不是樹系根目錄的名稱,DsGetDcName 就會失敗。
如果 Flags 參數包含 DS_GC_SERVER_REQUIRED 旗標且 DomainName 為 NULL,DsGetDcName 會嘗試在 ComputerName 所識別電腦的樹系中尋找全域編錄,如果 ComputerName 為 NULL,則為本機電腦。
如果 DomainName 為 NULL ,且 Flags 參數不包含 DS_GC_SERVER_REQUIRED 旗標, 則 ComputerName 會設定為 ComputerName 所識別電腦之主域的預設功能變數名稱。
[in] DomainGuid
GUID 結構的指標,指定查詢網域的 GUID。 如果 DomainGuid 不是 NULL ,而且找不到 DomainName 或 ComputerName 所指定的網域, DsGetDcName 會嘗試在 DomainGuid 指定的網域中找到域控制器。
[in] SiteName
Null 終止字串的指標,指定傳回之域控制器實際存在之網站的名稱。 如果此參數為 NULL,DsGetDcName 會嘗試傳回站台中與 ComputerName 所指定電腦月臺最接近的域控制器。 根據預設,此參數應該是 NULL。
[in] Flags
包含一組旗標,提供用來處理要求的其他數據。 此參數可以是下列值的組合。
DS_AVOID_SELF
從域控制器呼叫時,指定傳回的域控制器名稱不應該是目前的計算機。 如果目前的機器不是網域控制站,則會忽略此旗標。 此旗標可用來取得網域中另一個域控制器的名稱。
DS_BACKGROUND_ONLY
如果未指定 DS_FORCE_REDISCOVERY 旗標,此函式會使用快取的域控制器數據。 如果快取的數據超過 15 分鐘,快取會藉由 Ping 域控制器重新整理。 如果指定此旗標,即使快取的數據已過期,仍會避免此重新整理。 如果 定期呼叫 DsGetDcName 函式,應該使用此旗標。
DS_DIRECTORY_SERVICE_PREFERRED
DsGetDcName 會嘗試尋找支援目錄服務函式的域控制器。 如果不支援目錄服務的域控制器無法使用, DsGetDcName 會傳回非目錄服務域控制器的名稱。 不過, DsGetDcName 只會在嘗試尋找目錄服務域控制器逾時之後傳回非目錄服務域控制器。
DS_DIRECTORY_SERVICE_REQUIRED
要求傳回的域控制器支援目錄服務。
DS_DIRECTORY_SERVICE_6_REQUIRED
要求傳回的域控制器執行 Windows Server 2008 或更新版本。
DS_DIRECTORY_SERVICE_8_REQUIRED
要求傳回的域控制器執行 Windows Server 2012 或更新版本。
DS_FORCE_REDISCOVERY
強制忽略快取的域控制器數據。 未指定 DS_FORCE_REDISCOVERY 旗標時, DsGetDcName 可能會傳回快取的域控制器數據。 如果指定此旗標, DsGetDcName 將不會使用快取的資訊, (如果有任何存在) ,而是會改為執行全新的域控制器探索。
此旗標不應該在正常情況下使用,因為使用快取的域控制器資訊具有較佳的效能特性,並協助確保所有應用程式一致地使用相同的域控制器。 只有在應用程式判斷 DsGetDcName 所傳回的域控制器 (呼叫時,才應該使用此旗標,) 無法存取。 在此情況下,應用程式應該使用此旗標重複 DsGetDcName 呼叫,以確保忽略任何) 且探索到可連線的域控制器時, (未使用的快取資訊。
DS_GC_SERVER_REQUIRED
要求傳回的網域控制站是此網域為根目錄之網域樹系的全域資料目錄伺服器。 如果設定此旗標且 DomainName 參數不是 NULL, 則 DomainName 必須指定樹系名稱。 此旗標無法與 DS_PDC_REQUIRED 或 DS_KDC_REQUIRED 旗標結合。
DS_GOOD_TIMESERV_PREFERRED
DsGetDcName 會嘗試尋找可靠的時間伺服器的域控制器。 Windows Time 服務可以設定為將一或多個域控制器宣告為可靠的時間伺服器。 如需詳細資訊,請參閱 Windows Time 服務 檔。 此旗標僅供 Windows Time 服務使用。
DS_IP_REQUIRED
此參數表示域控制器必須有IP位址。 在此情況下,DsGetDcName 會將域控制器的因特網通訊協議位址放在 DomainControllerInfo 的 DomainControllerAddress 成員中。
DS_IS_DNS_NAME
指定 DomainName 參數是 DNS 名稱。 此旗標無法與 DS_IS_FLAT_NAME 旗標結合。
指定 DS_IS_DNS_NAME 或 DS_IS_FLAT_NAME。 如果未指定任何旗標, DsGetDcName 可能需要較長的時間才能尋找域控制器,因為它可能必須同時搜尋 DNS 樣式和一般名稱。
DS_IS_FLAT_NAME
指定 DomainName 參數是一般名稱。 此旗標無法與 DS_IS_DNS_NAME 旗標結合。
DS_KDC_REQUIRED
要求傳回的網域控制站目前正在執行 Kerberos 金鑰發行中心 (Kerberos Key Distribution Center) 服務。 此旗標無法與 DS_PDC_REQUIRED 或 DS_GC_SERVER_REQUIRED 旗標結合。
DS_ONLY_LDAP_NEEDED
指定傳回的伺服器是 LDAP 伺服器。 傳回的伺服器不一定是域控制器。 伺服器不會隱含其他服務。 傳回的伺服器不一定具有可寫入 的組態 容器,也不一定具有可寫入 的架構 容器。 傳回的伺服器不一定用來建立或修改安全策略。 此旗標可與 DS_GC_SERVER_REQUIRED 旗標搭配使用,以傳回同時裝載全域編錄伺服器的LDAP伺服器。 傳回的全局編錄伺服器不一定是域控制器。 伺服器不會隱含其他服務。 如果指定此旗標,則會忽略 DS_PDC_REQUIRED、 DS_TIMESERV_REQUIRED、 DS_GOOD_TIMESERV_PREFERRED、 DS_DIRECTORY_SERVICES_PREFERED、 DS_DIRECTORY_SERVICES_REQUIRED和 DS_KDC_REQUIRED 旗標。
DS_PDC_REQUIRED
要求傳回的網域控制站是該網域的網域主控站。 此旗標無法與 DS_KDC_REQUIRED 或 DS_GC_SERVER_REQUIRED 旗標結合。
DS_RETURN_DNS_NAME
指定 DomainControllerName 和 DomainControllerInfo 的 DomainName 成員中傳回的名稱應該是 DNS 名稱。 如果 DNS 名稱無法使用,則會傳回錯誤。 這個旗標不能使用 DS_RETURN_FLAT_NAME 旗標來指定。 此旗標表示 DS_IP_REQUIRED 旗標。
DS_RETURN_FLAT_NAME
指定 DomainControllerName 和 DomainControllerInfo 的 DomainName 成員中傳回的名稱應該是一般名稱。 如果無法使用一般名稱,則會傳回錯誤。 這個旗標不能使用 DS_RETURN_DNS_NAME 旗標來指定。
DS_TIMESERV_REQUIRED
要求傳回的網域控制站目前正在執行 Windows Time 服務 (Windows Time Service)。
DS_TRY_NEXTCLOSEST_SITE
指定此旗標時, DsGetDcName 會嘗試在與呼叫端相同的站台中尋找域控制器。 如果找不到這類域控制器,它會找到可提供拓撲資訊的域控制器,並呼叫 DsBindToISTG 以取得系結句柄,然後透過 UDP 呼叫 DsQuerySitesByCost 以判斷「下一個最接近的網站」,最後快取找到的網站名稱。 如果該站台中找不到任何域控制器, DsGetDcName 會回復尋找域控制器的預設方法。
如果這個旗標與輸入參數 SiteName 中的非 NULL 值搭配使用,則會擲 回ERROR_INVALID_FLAGS 。
此外,搭配 使用DS_TRY_NEXT_CLOSEST_SITE 的搜尋種類是網站特定的,因此,如果搭配 DS_PDC_REQUIRED使用,則會忽略此旗標。 最後,搭配使用 DS_RETURN_FLAT_NAME 時,會忽略DS_TRY_NEXTCLOSEST_SITE,因為使用 NetBIOS 解析名稱,但找到的域控制器網域不一定符合用戶端加入的網域。
DS_WRITABLE_REQUIRED
要求傳回的域控制器可寫入;也就是說,裝載目錄服務的可寫入複本。
DS_WEB_SERVICE_REQUIRED
要求傳回的域控制器目前正在執行 Active Directory Web 服務。
[out] DomainControllerInfo
PDOMAIN_CONTROLLER_INFO值的指標,這個值會接收DOMAIN_CONTROLLER_INFO結構的指標,其中包含所選取域控制器的相關數據。 此結構是由 DsGetDcName 配置。 當不再需要時,呼叫端必須使用 NetApiBufferFree 函式釋放結構。
傳回值
如果函式傳回域控制器數據,則會 ERROR_SUCCESS傳回值。
如果函式失敗,傳回值可以是下列其中一個錯誤碼。
備註
DsGetDcName 函式會傳送至 ComputerName 所指定遠端電腦上的 Netlogon 服務。 如果 ComputerName 為 NULL,則會在本機電腦上處理函式。
DsGetDcName 不會確認傳回的域控制器名稱是實際域控制器或全域編錄的名稱。 如果需要相互驗證,呼叫端必須執行驗證。
DsGetDcName 不需要任何特定存取指定的網域。 根據預設,此函式不會確保傳回的域控制器目前可供使用。 相反地,呼叫端應該嘗試使用傳回的域控制器。 如果域控制器無法使用,呼叫端應該再次呼叫 DsGetDcName 函式,並指定 DS_FORCE_REDISCOVERY 旗標。
回應時間
使用 DsGetDcName 時,請注意下列計時詳細數據:- DsGetDcName 進行網路呼叫,可能需要幾秒鐘到一分鐘的時間,視網路流量、拓撲、DC 負載等等而定。
- 不建議從UI或其他計時關鍵線程呼叫 DsGetDcName 。
- DC 定位器會使用優化邏輯來儘快提供DC資訊。 它也會使用站臺上的快取資訊來連絡最接近的DC。
域控制器黏性注意事項
在 Active Directory 網域服務 中,域控制器定位器函式的設計目的是在用戶端找到慣用的域控制器之後,除非該域控制器停止回應或重新啟動客戶端,否則用戶端不會尋找另一個域控制器。 這稱為「域控制器黏性」。 由於工作站通常會在幾個月內運作,而不會發生問題或重新啟動,因此這種行為的一個非預期結果是,如果特定域控制器停止維護,則所有連線到它的用戶端都會將其連線轉移至另一個域控制器。 但是,當域控制器備份時,用戶端不會因為用戶端不經常重新啟動而重新連線到它。 這可能會導致負載平衡問題。先前,此問題最常見的解決方案是在每部使用 旗標定期呼叫 DsGetDcNameDS_FORCE_REDISCOVERY
的用戶端電腦上部署腳本。 這是一些麻煩的解決方案,因此 Windows Server 2008 和 Windows Vista 引進了導致域控制器黏性問題的新機制。
每當 DsGetDcName 從其快取中擷取域控制器名稱時,它會檢查此快取專案是否已過期,如果是,則會捨棄該域控制器名稱,並嘗試重新探索域控制器名稱。 快取專案的生命週期是由下列登錄機碼中的值所控制
\ HKEY_LOCAL_MACHINE系統\CurrentControlSet\服務\Netlogon\參數\ForceRediscoveryInterval
及
\ HKEY_LOCAL_MACHINE軟體\政策\微軟\Netlogon\參數\ForceRediscoveryInterval
這些登錄機碼中的值類型為 REG_DWORD。 他們會在 DsGetDcName 嘗試重新探索域控制器名稱之前,以秒為單位指定長度。 默認值為 43200 秒, (12 小時) 。 如果 ForceRediscoveryInterval 登錄專案的值設定為 0,用戶端一律會執行重新探索。 如果此值設定為 4294967295,則快取永遠不會過期,而且會繼續使用快取的域控制器。 建議您不要將 ForceRediscoveryInterval 登錄項目設定為小於 3600 秒的值, (60 分鐘) 。
DsGetDcName 中的 ETW 追蹤
若要開啟 DsGetDcName 的 ETW 追蹤,請建立下列登錄機碼:\ HKEY_LOCAL_MACHINE系統\CurrentControlSet\服務\DCLocator\跟蹤
索引鍵的結構如下:
String ProcessName
DWORD PID <optional>
ProcessName 必須是完整名稱,包括您想要取得追蹤信息的進程延伸。 只有在有多個具有相同名稱的進程存在時,才需要 PID。 如果已定義,則只會啟用具有該 PID 的進程進行追蹤。 您無法只追蹤 3 個 (或更多) 具有相同名稱的進程。 當有多個具有相同進程名稱的實例存在且未指定 PID 時,您可以啟用一個實例或所有實例 (,所有實例都會啟用以追蹤) 。
例如,這會追蹤所有 App1.exe 和 App2.exe 實例,但只有 PID 為 999 的 App3.exe 實例:
App1.exe
App2.exe
App3.exe
PID 999
執行下列命令以啟動追蹤工作階段:
tracelog.exe -start <sessionname> -guid #cfaa5446-c6c4-4f5c-866f-31c9b55b962d -f <filename> -flag <traceFlags>
sessionname 是針對追蹤會話指定的名稱。 DCLocator 追蹤提供者的 guid 是 “cfaa5446-c6c4-4f5c-866f-31c9b55b962d”。 filename 是寫入事件之記錄檔的名稱。 traceFlags 是下列一或多個旗標,表示要追蹤的區域:
旗標 | 十六進位值 | Description |
---|---|---|
DCLOCATOR_MISC | 0x00000002 | 其他偵錯 |
DCLOCATOR_MAILSLOT | 0x00000010 | Mailslot 訊息 |
DCLOCATOR_SITE | 0x00000020 | 網站 |
DCLOCATOR_CRITICAL | 0x00000100 | 重要錯誤 |
DCLOCATOR_SESSION_SETUP | 0x00000200 | 信任網域維護 |
DCLOCATOR_DNS | 0x00004000 | 名稱登錄 |
DCLOCATOR_DNS_MORE | 0x00020000 | 詳細資訊名稱註冊 |
DCLOCATOR_MAILBOX_TEXT | 0x02000000 | 詳細資訊信箱訊息 |
DCLOCATOR_SITE_MORE | 0x08000000 | 詳細信息網站 |
執行下列命令以停止追蹤工作階段:
tracelog.exe -stop <sessionname>
sessionname 與啟動工作階段時所使用的名稱相同。
注意
dsgetdc.h 標頭會將 DsGetDcName 定義為別名,根據 UNICODE 預處理器常數的定義,自動選取此函式的 ANSI 或 Unicode 版本。 混合使用編碼中性別名與非編碼中性的程序代碼,可能會導致編譯或運行時間錯誤不符。 如需詳細資訊,請參閱 函式原型的慣例。
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | Windows Vista |
最低支援的伺服器 | Windows Server 2008 |
目標平台 | Windows |
標頭 | dsgetdc.h |
程式庫 | NetApi32.lib |
Dll | NetApi32.dll |