web-dev-qa-db-fra.com

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

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 point, c:\users\foobar n'existe pas.

Si [~ # ~] i [~ # ~] crée le répertoire personnel de l'utilisateur, avant que l'utilisateur ne se connecte (ou, plus pertinemment) ou le service auquel l'utilisateur est destiné 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 éléments comme un .ssh répertoire, un .gitconfig - des outils comme celui-ci (non limités à 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 dire à Windows de créer le profil utilisateur pour un utilisateur local?

Ou, d'autres solutions de contournement?

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

  • Un hook NSSM start/pre qui copie des fichiers ailleurs dans le répertoire de profil utilisateur qui avec un peu de chance existe à ce stade grâce à Windows démarrage du service, création du profil utilisateur puis remise du 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 d'Active Directory 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.
20
Peter Mounce

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;
}
23
Swisstone

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

17
Greg Askew