Task Scheduler program writes to literal folder named %LOCALAPPDATA%

I have a .NET executable (that I created) which uses Microsoft's Active Directory Service Interfaces (via System.DirectoryServices.AccountManagement) to do LDAP queries. Internally to ADSI, it downloads the Active Directory schema and stores it locally. It's supposed to store this schema in a folder at %LOCALAPPDATA%\Microsoft\Windows\SchCache\.

When I schedule this executable in Task Scheduler on Windows Server 2012 R2 and set it to run as "UserA" even if that user is not logged in, the program runs but it tries to write the above cache file into a folder literally named %LOCALAPPDATA%\Microsoft\Windows\SchCache\ within the start-in folder of the scheduled task (which is intentionally set to the folder of my executable). In other words, it's writing into something like C:\MyApp\%LOCALAPPDATA%\Microsoft\Windows\SchCache\. I had to give UserA explicit write permissions to this folder to allow the program to run properly.

I've watched the task's process with Process Monitor and it's immediately going to that folder. It's not as if it first tries something in C:\Users\ but failed.

When I log into the server as my own user and manually run the executable as UserA by using Run as a different user, the executable runs and successfully writes the cache file into C:\Users\UserA\AppData\Local\Microsoft\Windows\SchCache\.

Why is this happening with Task Scheduler and what can I do to fix it? I imagine it may have to do with Task Scheduler executing the program in the context of UserA but not initialaizing %LOCALAPPDATA% as an environment variable. On a whim I tried setting Run with highest privileges on the task, but that didn't change the outcome.

6

3 Answers

I believe that there is a bug in Windows 7 / 2012 scheduled tasks, so that they do not see the correct environment variables for the user they are running as:

To confirm this is occurring, you could run SET>test.txt in a batch file in a scheduled task, in the same user context. When I try this, it does not show the correct, full set of environment variables for the specified user; i.e. not the same set you see if you run the same command (or batch file) when actually logged in as that user. (Even more confusingly, this depends on whether the user is currently logged in or not when the scheduled task runs; if they are logged in, then the task does see the correct variables.)

I think this behaviour is not documented or intended, and is a bug in the way Windows Server 2012 (maybe just R2?) scheduled tasks are handled.

NB This applies to the PATH variable too, so scheduled tasks can only see executables which are on the default path, or in the current directory, or with a fully specified path. Calling anything which is on the specified user's path, but not on the default path, will give a hard-to-debug (since it works in testing!) error.

This is a consequence of the way that Windows handles user accounts. When a user account isn't logged in, their user registry hive - the key under HKEY_USERS that normally gets mapped as HKEY_CURRENT_USER - is not mounted. That hive (which is stored in a file, in each user's profile, called NTUSER.DAT) stores nearly all per-user data, including per-user environment variables. Windows also has system environment variables - some variables, such as PATH, are present in both locations and get merged - so those will show up even if the user's registry hive isn't mounted. None of the user-specific ones will, though.

I don't know if Task Scheduler handled this scenario differently in other Windows versions. It could be smart enough to mount the user's hive before running a task as that user. In Win7 / 2012R2, it apparently is not.

To fix this, you need to ensure the user's registry hive is mounted. The simplest way to do this is just to make sure the user is logged in, since a logged-in user's hive is always mounted. Lacking that, you can try mounting the hive yourself (the API is RegLoadKey but I've never tried invoking it for this).

11

This is a bug in Windows Server 2012 R2 and 8.1; Microsoft has documented it in KB 2968540.

The problem has been fixed and hotfix KB 3133689 is available. This hotfix does resolve the problem.

Scheduled tasks that are run by using UBPM don't have sufficient environment variables such as APPDATA, USERPROFILE, or TEMP when the corresponding process is started.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like