One small client has a Server 2012 R2 Essentials domain controller and a few Windows 7 desktops. It’s a wired, mostly gigabit network. Some desktops, especially those that have are behind a couple switches, often have problems confirming that they are on the domain, so they come up on the Public network, which messes up RDP connections.
The problem, of course, is that the Network Location Awareness (NLA) service can’t determine that the machine is on a domain, so it falls back to Public:
Several articles suggest changing the NLA service to “Automatic (Delayed Start)”. That’s has not been enough in this environment.
At least one article suggests restarting the NLA service. That doesn’t work because the Network List Service depends on the NLA service, and the Network List Service, for some reason, can’t be stopped.
The only sure way that I have found to force the NLA service to re-detect the domain is to stop and restart the network adapter. In fact I have script a RestartNetworkAdapter.cmd on many computers to do just that:
netsh interface set interface "Ethernet" disabled
netsh interface set interface "Ethernet" enabled
pause
Using a script allows doing this even when connected remotely, but it’s awkward and you have to customize the interface name for each PC.
Digging into NLA
Today I decided to dig into this further to see if I could come up with a better solution.
Then I found this TechNet blog article on how the NLA service works. The big news to me in that article is this: “If the Connection Specific DNS Name matches the HKEY_Local_Machine\Software\Microsoft\Windows\CurrentVersion\Group Policy\History\NetworkName registry key then the machine will attempt to contact a Domain Controller via LDAP.”
I checked that registry key and it in fact contained the correct value, let’s say “mydomain.local”.
But how/where is the Connection Specific DNS Name set? This article offers guidance: you can set it in the adapter’s DNS properties.
Note that this can also be set in group policy: Computer Configuration > Administrative Templates > Network > DNS Client > Connection-specific DNS suffix. When set in group policy, it overrides the value set in this dialog, but it is not displayed in this dialog.
By the way, the Primary DNS suffix for the computer is set in System Properties when you specify the computer name. When you click the More button, you’ll see this dialog:
You can also override that in group policy: Computer Configuration Administrative Templates > Network DNS Client > Primary DNS suffix. The Primary DNS Suffix defaults, sensibly, to the domain name. However the TechNet article cited above wants us to match Connection-specific adapter settings, hence the update above.
I had already set a fixed IP address for the primary DNS server, pointing to the domain controller. This is critical for all kinds of domain-based stuff (group policy, etc.). However I did not have “DNS suffix for this connection” filled in. I’d already seen (using ipconfig from a command prompt) that this machine is using both IPv4 and IPv6 to talk to the domain controller. So I added the “mydomain.local” string to both IPv4 and IPv6 profiles of the adapter. Voila! After a reboot, the machine immediately came up on with a Domain profile:
Well, that worked two times out of three. But still it sometimes comes up Public. Is there anything else I can do to help it be more reliable? The only other idea I have at this point is to make the NLA service dependent on having an active network connection. Can’t hurt, right? I ran the following from an administrative command prompt:
sc qtriggerinfo NlaSvc
sc triggerinfo NlaSvc start/networkon stop/networkoff
sc qtriggerinfo NlaSvc
Three more reboots and the machine has come up as Domain each time.
However on another machine, those two changes weren’t enough. Wait, this machine still had NLA service set to Automatic. After changing it to “Automatic (Delayed Start)”, this machine also rebooted directly to the Domain profile. To set Automatic (Delayed Start) from the command line, run:
sc qc NlaSvc
sc config NlaSvc start= delayed-auto
sc qc NlaSvc
Note that the space after the equal sign (=) is intentional and required.
TL;DR
To (hopefully) fix NLA issues:
1. Set the NLA service to “Automatic (Delayed Start)” and only when the network is available:
sc config NlaSvc start= delayed-auto
sc triggerinfo NlaSvc start/networkon stop/networkoff
sc qc NlaSvc
sc qtriggerinfo NlaSvc
2. Set the Connection Specific DNS Name to match the domain controller’s local domain. Run ncpa.cpl
and do this in the iPv4 and IPv6 properties of the network adapter (see screen shots above). There might be a way to script this, but it would require enumerating network adapters, so I’ll just do it manually for now. Update: this can be set in Group Policy. See above.
Update April 14, 2018
Unfortunately, all of these settings are still not always enough to get Network Location Awareness to detect the domain profile. I still frequently find myself restarting the network adapter to get it to re-detect the location. (On some machines, it is possible to to restart only the NLA service.)
If you run a remote monitoring tool, see this post for a script that will alert you when the profile is not what you expect: Script to Check Current Firewall Profile.
Update July 5, 2018 – Network Issues?
It occurred to me that this NLA issue could be a more general issue with the client not being able to contact the domain controller. On one machine with this issue, at startup, in the System event log, I have a NETLOGON 5719 error, “This computer was not able to set up a secure session with a domain controller….” I was reminded of an issue eight years ago relating to switch configuration: Gigabit Switch Spanning Tree Causes Slow Logon.
It helped then to set ports connected directly to computers to Fast Link on the Dell switch. Unfortunately, that option is not available in the UI of the new UniFi switch. However as suggested in this Reddit thread, I was able to change the Spanning Tree priority to 8192 to identify the UniFi switch as the root switch. Alas, that alone was not enough to solve the NLA issue; the machine still comes up as Public most of the time.
Update February 5, 2019 – Startup Script
I’m now running the following script on affected machines to restart the NLA service. Copy and paste this as RestartNLAService.cmd, then add a Scheduled Task, Trigger as a Startup task with a 1-minute delay, Conditions limited to any Network connection being available. Use at your own risk!
@echo off REM 01/21/2019 REM Restart the NLA service to force re-detecting that computer is on a domain. REM Unlike restarting the network adapter, this does not completely disconnect from network. REM Can run this from a Scheduled Task at Startup. Run as SYSTEM, 1 minute delay, only run REM if "Any Connection" available. REM %0 is the name of the batch file. REM ~dp gives you the drive and path of the specified argument, with trailing \. set ScriptPath=%~dp0 REM ~nx gives you the filename and extension only. set ScriptName=%~nx0 REM Clever approach to redirect stdout and stderr for a group of commands REM See http://stackoverflow.com/a/13400446/550712: > "%ScriptPath%\RestartNLAService.log" 2>&1 ( echo ======================== echo Current firewall profile echo ======================== netsh advfirewall monitor show currentprofile echo ======================= echo Restart the NLA service echo ======================= echo Stop the Network Connected Devices, Network List, and Network Location Awareness services net stop ncdautosetup net stop netprofm net stop nlasvc echo Start the NLA service net start nlasvc echo Network Connected Devices and Network List services are Manual start, so will be started if needed echo. echo ======================== echo Updated firewall profile echo ======================== netsh advfirewall monitor show currentprofile ) type "%ScriptPath%\RestartNLAService.log" REM Do not put a PAUSE here, since this will run from a scheduled task
Update March 10, 2020
If you need to quickly change a network adapter from Public to Private (e.g. because Public is blocked in the server’s firewall and the stupid workstation won’t change to Domain), see this post.
Update May 20, 2023
I hate to extend what is already a confusing list of options for this persistent issue, but I’ve come across a completely different solution posted by someone who seems to understand the inner workings of domain controllers and NLA. This comes courtesy of a comment in a German thread that one of the commenters on this post mentioned.
Normally I’ve experienced the NLA issue on workstations. But after setting up a new Windows Server 2022 domain controller, I found that it could not recognize itself as a DC on reboot; I had to restart the network adapter every time. This post suggests three registry modifications to adjust caching and domain detection. They immediately solved the issue on the Server 2022 machine. From the context, it sounds like it should work on a workstation as well, but I have not tested that.
I’m reproducing the entire post here, with full credit to Microsoft vendor Sunny Qi:
Hi,
Thanks for posting in Q&A platform.
After machine reboots, before NIC adapter initializes, NLASVC would attempt detection of domain, if the detection was failed, then this information will be cached and even though NIC gets initialized, the machine still apply the cached information and hence machine detects unidentified network.
Please try to modify the following registry keys to see if the issue can be resolved:
First, disable Domain Discovery negative cache by adding the NegativeCachePeriod registry key to following subkey:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetLogon\Parameters
Name: NegativeCachePeriod
Type: REG_DWORD
Value Data: 0 (default value: 45 seconds; set to 0 to disable caching)If issue doesn’t resolve, furtherly disable DNS negative cache by adding the MaxNegativeCacheTtl registry key to the following subkey:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters
Name: MaxNegativeCacheTtl
Type: REG_DWORD
Value Data: 0 (default value: 5 seconds; set to 0 to disable caching)Note: This registry key disables the Domain detection negative cache. NLA normally detect Domain multiple times at network setup (triggered by route change, IP address change etc). But if the first time detection failed with negative result (such as ERROR_NO_SUCH_DOMAIN), this negative result gets cached in netlogon, and will be reused in next time NLA domain discovery.
There is also another registry key we need add:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters
Add a DWORD parameter :AlwaysExpectDomainController
Set value to:1
Note: This registry key alters the behavior when NLA retries domain detection.
Best Regards,
Sunny
A couple of comments asked for further information about the AlwaysExpectDomainController value. One commenter shared, “Here’s what I got from another rep in a support request: ‘AlwaysExpectDomainController is for the device to send continuously the SRV query requesting the LDAP to the domain controller until it gets an answer.'”
To implement the above, save this as a .reg file and import. Use at your own risk!
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters] "NegativeCachePeriod"=dword:00000000 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters] "MaxNegativeCacheTtl "=dword:00000000 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters] "AlwaysExpectDomainController"=dword:00000001
For me the fix was to un-select IPv6 and it changed automatically to domain network.
@sach, how/where did you “un-select IPv6”? Interesting theory that IPv6 could be inhibiting NLA in some cases. Bear in mind that turning off IPv6 is not always a good idea, especially on servers, and if you do decide to do it, it requires registry changes. MSKB 929852 has some details.
Found that the above was also not 100% reliable (Did not want to rely on script).
Have found that adding the following seemed to help in my case from an Elevated Command Prompt:
sc config NlaSvc depend= NSI/RpcSs/TcpIP/Dhcp/Eventlog/Netlogon
The change from default is to add a requirement to wait for the Netlogon service to be running.
The other dependencies are default but as the command erases all previous entries these are added first to preserve them.
@Chris Mason, thanks, interesting idea. I would have thought that making NlaSvc depend on having a network connection would be enough (using triggerinfo), but a Netlogon dependency may take it a step further, requiring that a secure channel to the domain controller be open.
For reference, to check the service dependencies and triggers:
sc qc NlaSvc
sc qtriggerinfo NlaSvc
By the way, on a machine where I’m pretty sure I set up the network trigger, its gone now. I wonder if these customizations are erased when one applies a Windows 10 “feature update” (e.g. I just updated 1909 to 2004).
We fight this quite often on server 2019 OS’s. Def frustrating
This a great effort,
I fight this issue since almost 1 year
We have tried all the solution on the web > with no luck !!
Is there any possible solution or update for this nightmare.
Hello all, my final fix was to add Netlogon, DNS, and NTDS as a dependency to NLA. There should be some others there by default – NSI/RpcSs/TcpIp/Dhcp/Eventlog.
To get to there, on a new 2019 server with AD and DNS services, I tied with no luck
* setting IPv4 prefixpolices high than IPv6
* add domain suffix to connection and use suffix to register connection
* setting the DNS to itself instead of 127.0.0.1
* adding just the Netlogon dependency
* changing NLA to auto-delayed service startup
Hopefully, like everyone else here, my hours spent will help someone else. It’s insane this has been happening on a server OS for years.
Thank you so much. This fixes the issue without any reboot or reset.
For years, I’ve been going into the Connection’s Properties, unchecking IPv6, clicking OK, then going back into Properties, and re-checking IPv6, clicking OK. That will switch the network connection to mydomain.local every time, without rebooting, as long as the WseClientMonitorSvc service is running.
The occurrences weren’t very frequent, so not a huge issue. However, a client with a server running WS2016E has a new Dell laptop that connects to the WiFi and goes to Public every time you reboot. I tried:
sc config NlaSvc depend= NSI/RpcSs/TcpIP/Dhcp/Eventlog/Netlogon/Dnscache
Rebooted and it came up as Public, but within a minute, it switched to Domain all by itself. Great! Unfortunately, while typing this message, it switched back to Public. And now, it’s switched back to Domain.
It’s connected to a UniFi AP (UAP-AC-LR) and the controller dashboard shows a “WiFi Experience” that’s consistently between 96-100%. However, while I was typing, the laptop disappeared from the UniFi’s Clients view for a second or two, then re-appeared. It’s done that 3 times in the last few minutes, and every time it happens, the laptop’s connection switches between Public an Domain.
So it looks like it’s randomly dropping the WiFi connection and toggling between Public and Domain every time that happens. If I can resolve the WiFi issue, then I hope this fixes the Public/Domain issue… we’ll see.
I’ve written an extended script that addresses this issue.
The forum is in German, but the script is in English. The advanced script can be found here:
https://administrator.de/forum/server-2019-frische-dom%C3%A4ne-privates-netzwerk-neustart-470794.html
Danke Michael. Eine gute Deutschübung :).
For those interested in Michael’s script, look for the post by Michael.H on 15.05.2021 at 16:28. The Google translated version does not translate his instructions for creating a task. The key parts: run with elevated privileges at startup, delayed by 1 minute, then every five minutes forever. End if it runs over 1 minute.
After examining the script and instructions, key differences to my script above:
– It only runs on Backup or Primary Domain Controllers. Looks like you could include member servers and member workstations by modifying line 26.
– It only restarts the nlasvc if the machine is not currently on the Domain.
– Rather than stop dependent services individually uses
net stop /y nlasvc
to force the stop of dependent services.– It logs restarts to a text file so you can check how often a restart is required.
– And as mentioned above, its task set to run every five minutes indefinitely.
The bug still exists in the brand new Windows Server 2022. I had to rewrite a part of my script for Windows Server 2019 to guarantee functionality in version 2022.
The updated code can be found here
https://administrator.de/forum/server-2019-frische-dom%C3%A4ne-privates-netzwerk-neustart-470794.html
at the bottom of the page.
I deleted the new status check after restarting the NlaSvc service as the status is not updated in the same CLI instance. So the check is useless.
I received a potentially helpful comment on this issue, suggesting that one can
1) Open Device manager (only on AD DC)
2) Select Network Adapters
3) Switch to Disable WAN Miniport (IP), and WAN miniport (IPV6)
No idea if that works, but wanted to pass it along.
To the commenter: thanks for your suggestion. Sorry I’m not checking the blog at 3am to instantly approve your comments, haha.
I can confirm that disabling the WAN miniport (IP) and WAN miniport (IPV6) works on Windows Server 2022 to stick with the domain network type.
I can confirm that disabling the WAN miniport (IP) and WAN miniport (IPV6) works on Windows Server 2019 to stick with the domain network type.
I also confirm – it works on Server 2019! (Disable WAN miniport (IP) and WAN miniport (IPV6)). Thank you!
Interesting that these WAN Miniport suggestions are all about servers. In fact, the original suggestion was to only do this on a domain controller. My main issue has always been desktop clients.
Restarting the nlasvc service causes the network to constant “identifying” (and Net profile is Public). Only restarting the IP Helper service (iphlpsvc) makes the network immediately identified as a “Domain”. (Windows Server 2016 as VM on Hyper-V and also the same behaviour on HV Host). If I make IP Helper Service depend on nlasvc then restarting nlasvc correctly sets “domain” net profile.
@Mariusz, thanks for the comment. On my Server 2016, the IP Helper Service sounds like it is for IPv6 connections? “Provides tunnel connectivity using IPv6 transition technologies (6to4, ISATAP, Port Proxy, and Teredo), and IP-HTTPS.” I’m surprised that it would affect awareness of the domain. Are you using IPv6 for LAN connections, or maybe for defining the DNS server in the NIC properties? Also, is your server a domain controller?
We do not use IPv6 addressing, however, the protocols are enabled (default settings). We do not use any kind of tunneling or VPN on this server. I even uninstalled ESET FS to rule it out. I don’t understand where the dependence of network profile detection on the IP Helper service comes from. The same thing happens on other servers, e.g. Windows Server 2019.
I’ve just posted a lengthy update (at the end of the original post above) with a possible new solution to this issue. The German thread that @Michael Huck shared led me to a Microsoft thread where a “Microsoft Vendor” lists three registry changes that adjust caching and detection of the domain controller. I have only tested this briefly on ONE Server 2022 machine, so if you choose to try it, test it carefully in your own environment, and post here with your results.
Here’s the Microsoft forum thread:
https://learn.microsoft.com/en-us/answers/questions/400385/network-location-awareness-not-detecting-domain-ne?source=docs