Wie kann ich programmgesteuert die Erstellung eines neuen Windows-Benutzerprofils veranlassen?

20

Ich erstelle einen (lokalen) Benutzer, unter dem ein Windows-Dienst ausgeführt werden kann. Ich habe gute Gründe, warum ich NETWORK SERVICE, LOCAL SERVICE oder LOCAL SYSTEM nicht verwenden möchte.

Ich erstelle den Benutzer über net user foobar "Abcd123!" /add- das funktioniert gut.

Zu diesem Zeitpunkt c:\users\foobarexistiert nicht.

Wenn ich das Home-Verzeichnis des Benutzers erstelle, bevor sich der Benutzer anmeldet (oder sachdienlicher) oder der Dienst, für den der Benutzer gestartet wird, erstellt Windows ein Benutzerprofil nebenan mit dem Namen c:\users\foobar-{gibberish/SID/whatever}- dies ist kein vorhersehbarer Name.

Ich brauche das Home-Verzeichnis des Benutzers, um Dinge wie ein Verzeichnis zu enthalten .ssh, a .gitconfig- Tools wie dieses (nicht auf diese Tools beschränkt), die davon ausgehen, dass es sich um eine Person handelt, die sie verwendet, und so geht die Benutzerkonfiguration hinein ~/.... Normalerweise Tools aus einem Unix-Erbe.

Aktuelle Frage

Gibt es also eine programmgesteuerte (vorzugsweise PowerShell- oder Standardbefehlszeile) Möglichkeit, Windows anzuweisen, das Benutzerprofil für einen lokalen Benutzer zu erstellen?

Oder andere Problemumgehungen?

Dinge, die ich noch nicht ausprobiert habe:

  • Ein NSSM-Start / Pre-Hook, der Dateien von einer anderen Stelle in das Benutzerprofilverzeichnis kopiert, das hoffentlich zu diesem Zeitpunkt vorhanden ist, wenn Windows den Dienst startet, das Benutzerprofil erstellt und die Steuerung vor dem Start an den NSSM-Wrapper übergibt, der den Hook ausführt.
  • Festlegen der Umgebungsvariablen USERPROFILE für den Dienst, die sich nicht im tatsächlichen Benutzerprofilverzeichnis befindet. Dies scheint mir gefährlich abseits der Piste, könnte aber auch gut funktionieren.

Anderer Kontext:

  • Windows Server 2016, Desktop-Erfahrung.
    • Core / Nano kann nicht verwendet werden.
  • Es ist kein Active Directory im Spiel. Es wird nicht geben.
  • Dies sind lokale Benutzer.
  • Ich mache das über Ansible, das PowerShell unter der Haube für Windows-Dinge verwendet. Insbesondere das Modul win_user mit Ansible 2.7.5.
  • Ich möchte kein C:\users\default(äquivalent zu /etc/skel) erstellen , da es einige verschiedene Service-Benutzer gibt und eine Größe nicht für alle geeignet ist. Dies wirkt sich auch nicht darauf aus, wann das Benutzerprofil erstellt wird, sondern nur darauf, was darin enthalten ist, wenn es erstellt wird.
  • Ich verwende NSSM , um die Dienste zu verwalten.

Dinge, die ich versucht habe

  • Starten des Dienstes und Zulassen, dass Windows das Verzeichnis erstellt
    • Ich möchte dies nicht tun, da der Dienst vor dem Start Geheimnisse erfordert. Wenn ich dies also während des Image-Backvorgangs tue, muss ich sie bereinigen und sicherstellen, dass mein Dienst nicht funktioniert jegliche Arbeit während der Backphase. Ich möchte beides vermeiden.
Peter Mounce
quelle
1
Hast du die Optionen geprüft net user(zB /HOMEDIRoder /PROFILEPATH)? . Sehen net user /help. Nach meinem (nicht getesteten) Verständnis können Sie ein Verzeichnis für den Benutzer erstellen und dieses mit dem /HOMEDIRSchalter als homedir festlegen .
Sven
Darf ich fragen, welchen Anwendungsfall Sie haben, der Active Directory vermeidet? Mit AD wäre es viel einfacher. Nur neugierig.
Ondrej Tucny
Ich vermeide AD, weil die Maschinen kurzlebig sind. Die Lebensdauer wird in Stunden und nicht in Tagen gemessen. Die Maschinen hosten Reinraum-Build-Umgebungen. Das Jonglieren von Maschinen in und aus einem AD, wenn sie kommen und gehen, ist es einfach nicht wert (siehe auch medium.com/palantir/active-directory-as-code-e9666a2e548d, wenn Sie daran interessiert sind).
Peter Mounce
@Sven ja - leider wird von keinem das Profil selbst erstellt, auch wenn sie den Pfad festlegen.
Peter Mounce

Antworten:

23

Windows kann bei Bedarf mithilfe der CreateProfile- API ein Benutzerprofil erstellen

Wenn Sie jedoch keine ausführbare Datei erstellen möchten, um diesen Vorgang auszuführen, können Sie die API in PowerShell aufrufen. Andere haben es bereits getan: Beispiel auf Github .

Relevanter Teil des Codes:

$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
quelle
Vielen Dank, das funktioniert bei mir. Hinweis für andere - Die Funktionen Register-NativeMethod und Add-NativeMethods befinden sich in der verknüpften Übersicht.
Peter Mounce
17

Alles, was Sie tun müssen, ist einen Befehl als dieser Benutzer auszuführen, Windows wird das Profil erstellen:

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

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

Greg Askew
quelle
1
Was hier passiert, psexec soll sich mit localhost unter dem mit -uund angegebenen Benutzernamen und Passwort verbinden -pund starten cmd, um sofort zu beenden. Habe ich etwas vergessen ? Das klingt etwas unerklärlich - das Herstellen einer Verbindung zum System mit nicht vorhandenem Benutzernamen und Kennwort sollte ein Fehler sein. Wie funktioniert das ?
Sergiy Kolodyazhnyy
1
@SergiyKolodyazhnyy: Warum denkst du, dass es keinen Benutzernamen und kein Passwort gibt? Es ist das gleiche, das in der Frage verwendet wurde, offensichtlich als Beispiel ...
Ben Voigt
1
@BenVoigt Nun, ich habe den oberen Teil der Frage verpasst. Ich dachte, OP wollte auch den Benutzer erstellen, und genau das sollte diese Antwort tun. Der letzte Teil des Kommentars ist also ein Missverständnis.
Sergiy Kolodyazhnyy
@BenVoigt Obwohl ich noch eine Frage habe. OP erwähnte "Ich möchte nicht C: \ users \ default erstellen". Woher kommt also das Benutzerprofil, wenn diese Methode verwendet wird, und woher weiß Windows, dass bestimmte vorkonfigurierte Verzeichnisse erstellt werden müssen, wenn nicht von C:\users\defaults?
Sergiy Kolodyazhnyy
1
@SergiyKolodyazhnyy: Ziemlich sicher, dass OP bedeutet, dass er C: \ Users \ Default nicht anpassen möchte ... nicht, dass es gänzlich fehlen wird. Windows erstellt das Basisverzeichnis C: \ Users \ foobar durch Kopieren aus dem einfachen Vanille-Verzeichnis C: \ Users \ default. Sobald es vorhanden ist, kann OP seine spezielle Sauce auf C: \ Users \ foobar anwenden, ohne dass andere davon betroffen sind Benutzer.
Ben Voigt