I'm creating a (local) user for a Windows service to run as. I've got good reasons for not wanting to use NETWORK SERVICE, LOCAL SERVICE, or LOCAL SYSTEM.
I create the user via net user foobar "Abcd123!" /add
- this works fine.
At this point, c:\users\foobar
does not exist.
If I create the user's home directory, before the user either logs on (or, more pertinently) or the service that the user is for starts up, Windows creates a user-profile next-door called c:\users\foobar-{gibberish/SID/whatever}
- this is not a predictable name.
I need the user's home directory to contain things like a .ssh
directory, a .gitconfig
- tools like that (not limited to those tools) that make assumptions that it'll be a person using them, and so user-configuration goes inside ~/...
. Usually, tools from a Unix heritage.
Actual question
So - is there a programmatic (preferably, PowerShell, or out-of-the-box command-line) way to tell Windows to create the user-profile for a local user?
Or, any other workarounds?
Things I've yet to try:
- An NSSM start/pre hook that copies files from elsewhere into the user-profile directory that hopefully exists at this point by virtue of Windows starting the service, creating the user-profile then handing control to the NSSM wrapper running the hook before startup.
- Setting the USERPROFILE environment variable for the service to be somewhere other than the actual user-profile directory. This strikes me as dangerously off-piste but also might work fine.
Other context:
- Windows Server 2016, desktop experience.
- Can't use Core/Nano.
- There is no active directory in play. There won't be.
- These are local users.
- I'm doing this via Ansible, which is using PowerShell under the hood for Windows things. Specifically the win_user module, with Ansible 2.7.5.
- I don't want to create a
C:\users\default
(the equivalent of/etc/skel
), because there are a few different service-users and one size won't fit all. This also doesn't affect when the user-profile is created, just what will be in it when it is. - I'm using NSSM to manage the services.
Things I've tried
- starting the service and allowing Windows to create the directory
- I don't want to do this, because the service requires secrets before starting up, and so if I do this inside my image-baking process I'll then need to clean them up, and also make sure my service doesn't do any work during the baking phase. I want to avoid both of those fiddly bits.
Windows can create a user-profile on-demand, using the CreateProfile API
However, if don't want to create an executable to perform this operation, you can call the API in PowerShell. Others have already done it: example on github.
Relevant part of the code:
All you need to do is run a command as that user, Windows will create the profile:
psexec.exe -u foobar -p Abcd123! cmd.exe /c exit
https://docs.microsoft.com/en-us/sysinternals/downloads/psexec
This is a bit old of a thread but I came upon it while looking for a way to create a user's profile folder structure properly during a new image build script for specific customization that were not possible by GPO etc.
If you run a remote powershell Invoke-Command with the user's credentials, it will build the user profile folder under C:\Users if it doesn't already exist and you can then manipulate it and also the HKCU registry keys as needed.
This command does nothing but the exit command, but will create the user's profile if it doesn't already exist:
Invoke-Command -ComputerName $computerVar -ScriptBlock {exit} -Credential $credentialVar
Obviously the user's creds have to have the rights to connect remotely, and the OS firewall can't be blocking said connections but otherwise, this command will do what you are looking for at least.