Comment puis-je créer par programme le profil d'un nouvel utilisateur Windows?

20

Je crée un utilisateur (local) pour qu'un service Windows s'exécute en tant que. J'ai de bonnes raisons de ne pas vouloir utiliser NETWORK SERVICE, LOCAL SERVICE ou LOCAL SYSTEM.

Je crée l'utilisateur via net user foobar "Abcd123!" /add- cela fonctionne très bien.

À ce stade, c:\users\foobarn'existe pas.

Si je crée le répertoire personnel de l'utilisateur, avant que l'utilisateur ne se connecte (ou, plus pertinemment) ou que le service auquel l'utilisateur s'adresse démarre, Windows crée un profil utilisateur à côté appelé c:\users\foobar-{gibberish/SID/whatever}- ce n'est pas un nom prévisible.

J'ai besoin que le répertoire personnel de l'utilisateur contienne des choses comme un .sshrépertoire, un .gitconfig- des outils comme celui-ci (non limité à ces outils) qui supposent que ce sera une personne qui les utilisera, et donc la configuration utilisateur va à l'intérieur ~/.... Habituellement, les outils d'un héritage Unix.

Question réelle

Donc - existe-t-il une méthode de programmation (de préférence PowerShell ou une ligne de commande prête à l'emploi) pour indiquer à Windows de créer le profil utilisateur pour un utilisateur local?

Ou, toute autre solution de contournement?

Choses que je n'ai pas encore essayées:

  • Un NSSM start / pre hook qui copie des fichiers d'ailleurs dans le répertoire de profil utilisateur qui, nous l'espérons, existe à ce stade grâce au démarrage de Windows du service, créant le profil utilisateur puis remettant le contrôle au wrapper NSSM exécutant le hook avant le démarrage.
  • Définition de la variable d'environnement USERPROFILE pour que le service soit différent du répertoire de profil utilisateur réel. Cela me semble dangereusement hors-piste, mais cela pourrait aussi bien fonctionner.

Autre contexte:

  • Windows Server 2016, expérience de bureau.
    • Impossible d'utiliser Core / Nano.
  • Il n'y a pas de répertoire actif en jeu. Il n'y en aura pas.
  • Ce sont des utilisateurs locaux.
  • Je fais cela via Ansible, qui utilise PowerShell sous le capot pour les choses Windows. Plus précisément le module win_user , avec Ansible 2.7.5.
  • Je ne veux pas créer un C:\users\default(l'équivalent de /etc/skel), car il existe plusieurs utilisateurs de services différents et une taille unique ne conviendra pas à tous. Cela n'affecte pas non plus la création du profil utilisateur, juste ce qu'il contiendra lorsqu'il le sera.
  • J'utilise NSSM pour gérer les services.

Les choses que j'ai essayées

  • démarrer le service et autoriser Windows à créer le répertoire
    • Je ne veux pas faire cela, car le service nécessite des secrets avant de démarrer, et donc si je le fais dans mon processus de création d'image, je devrai ensuite les nettoyer, et aussi m'assurer que mon service ne fait pas tout travail pendant la phase de cuisson. Je veux éviter ces deux morceaux délicats.
Peter Mounce
la source
1
Avez-vous vérifié les options net user(par exemple /HOMEDIRou /PROFILEPATH)? . Tu vois net user /help. D'après ma compréhension (non testée), vous pouvez créer un répertoire pour l'utilisateur et le définir comme homedir avec le /HOMEDIRcommutateur.
Sven
Puis-je vous demander quel cas d'utilisation avez-vous pour éviter Active Directory? Les choses seraient beaucoup plus faciles avec AD. Juste curieux.
Ondrej Tucny
J'évite la MA parce que les machines sont éphémères; les durées de vie sont mesurées en heures, pas en jours. Les machines hébergent des environnements de construction de salles blanches. Jongler avec les machines dans et hors d'une AD au fur et à mesure qu'elles vont et viennent ne vaut pas la peine (voir aussi medium.com/palantir/active-directory-as-code-e9666a2e548d si vous êtes intéressé à le faire).
Peter Mounce
@Sven yes - malheureusement, aucun de ceux-ci ne crée le profil lui-même, même s'ils définissent le chemin.
Peter Mounce

Réponses:

23

Windows peut créer un profil utilisateur à la demande, à l'aide de l' API CreateProfile

Cependant, si vous ne souhaitez pas créer d'exécutable pour effectuer cette opération, vous pouvez appeler l'API dans PowerShell. D'autres l'ont déjà fait: exemple sur github .

Partie pertinente du code:

$methodName = 'UserEnvCP'
$script:nativeMethods = @();

Register-NativeMethod "userenv.dll" "int CreateProfile([MarshalAs(UnmanagedType.LPWStr)] string pszUserSid,`
  [MarshalAs(UnmanagedType.LPWStr)] string pszUserName,`
  [Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszProfilePath, uint cchProfilePath)";

Add-NativeMethods -typeName $MethodName;

$localUser = New-Object System.Security.Principal.NTAccount("$UserName");
$userSID = $localUser.Translate([System.Security.Principal.SecurityIdentifier]);
$sb = new-object System.Text.StringBuilder(260);
$pathLen = $sb.Capacity;

Write-Verbose "Creating user profile for $Username";
try
{
    [UserEnvCP]::CreateProfile($userSID.Value, $Username, $sb, $pathLen) | Out-Null;
}
catch
{
    Write-Error $_.Exception.Message;
    break;
}
Swisstone
la source
Merci beaucoup, cela fonctionne pour moi. Remarque pour les autres - les fonctions Register-NativeMethod et Add-NativeMethods sont dans l'essentiel lié.
Peter Mounce le
17

Tout ce que vous devez faire est d'exécuter une commande en tant qu'utilisateur, Windows créera le profil:

psexec.exe -u foobar -p Abcd123! cmd.exe /c exit

https://docs.microsoft.com/en-us/sysinternals/downloads/psexec

Greg Askew
la source
1
Donc, ce qui se passe ici est psexec censé se connecter à localhost sous le nom d'utilisateur et le mot de passe spécifiés avec -uet -pet lancer cmdjuste pour quitter immédiatement. Ai-je manqué quelque chose ? Cela semble quelque peu contre-intuitif - la connexion au système avec un nom d'utilisateur et un mot de passe inexistants devrait être une erreur. Comment ça marche ?
Sergiy Kolodyazhnyy
1
@SergiyKolodyazhnyy: Pourquoi pensez-vous que c'est un nom d'utilisateur et un mot de passe inexistants? C'est le même que celui utilisé dans la question, évidemment à titre d'exemple ...
Ben Voigt
1
@BenVoigt Eh bien, j'ai raté la partie supérieure de la question. Je pensais qu'OP voulait également créer l'utilisateur et c'est ce que cette réponse était censée faire. Cette dernière partie du commentaire est donc un malentendu.
Sergiy Kolodyazhnyy
@BenVoigt Bien que j'ai encore une question. OP a mentionné "Je ne veux pas créer C: \ users \ default". D'où proviendrait le profil de l'utilisateur lorsque cette méthode est utilisée et comment Windows saurait-il créer des répertoires préconfigurés spécifiques sinon C:\users\defaults?
Sergiy Kolodyazhnyy
1
@SergiyKolodyazhnyy: OP assez sûr signifie qu'il ne veut pas personnaliser C: \ Users \ Default ... pas qu'il sera entièrement manquant. Windows créera le répertoire personnel C: \ Users \ foobar en copiant à partir de la vanille ordinaire C: \ Users \ default, puis une fois qu'il existe, OP peut appliquer sa sauce spéciale à C: \ Users \ foobar où cela n'affectera aucun autre utilisateurs.
Ben Voigt