web-dev-qa-db-ja.com

プログラムで新しいWindowsユーザーのプロファイルを作成するにはどうすればよいですか?

Windowsサービスを実行するための(ローカル)ユーザーを作成しています。 NETWORK SERVICE、LOCAL SERVICE、またはLOCAL SYSTEMを使用したくない理由は十分にあります。

私はNet User foobar "Abcd123!" /addを介してユーザーを作成します-これは正常に動作します。

この時点では、c:\users\foobarは存在しません。

[〜#〜] i [〜#〜]がユーザーのホームディレクトリを作成する場合、ユーザーがログオンする前に(またはより適切に)またはユーザーが対象とするサービスが起動すると、Windowsはc:\users\foobar-{gibberish/SID/whatever}というユーザープロファイルを隣に作成します-これは予測可能な名前ではありません。

ユーザーのホームディレクトリに.sshディレクトリ、.gitconfigなどのツール(これらのツールに限定されない)を含める必要があります。これらのツールは、それらを使用する人であると想定し、ユーザー設定は~/...内にあります。通常、UNIXの遺産に由来するツール。

実際の質問

それで、ローカルユーザーのユーザープロファイルを作成するようにWindowsに指示するプログラム的な(できればPowerShell、またはすぐに使えるコマンドライン)方法はありますか?

または、他の回避策はありますか?

私がまだ試していないこと:

  • 他の場所からうまくいけば存在するユーザープロファイルディレクトリにファイルをコピーするNSSM開始/事前フックWindowsサービスを開始し、ユーザープロファイルを作成して、起動前にフックを実行するNSSMラッパーに制御を渡します。
  • サービスのUSERPROFILE環境変数を、実際のユーザープロファイルディレクトリ以外の場所に設定します。これは私を危険にさらされていないゲレンデとして攻撃しますが、うまくいくかもしれません。

その他のコンテキスト:

  • Windows Server 2016、デスクトップエクスペリエンス。
    • Core/Nanoは使用できません。
  • 活動中のActive Directoryはありません。ありません。
  • これらはローカルユーザーです。
  • 私はこれをWindowsの内部でPowerShellを使用しているAnsible経由で行っています。具体的には、Ansible 2.7.5の win_user モジュールです。
  • C:\users\default/etc/skelに相当)を作成したくありません。これは、いくつかの異なるサービスユーザーがあり、1つのサイズではすべてに対応できないためです。これは、ユーザープロファイルの作成時にも影響しません。作成時に何が含まれるかだけです。
  • [〜#〜] nssm [〜#〜] を使用してサービスを管理しています。

私が試したもの

  • サービスを開始し、Windowsがディレクトリを作成できるようにする
    • サービスを起動する前にシークレットが必要なため、これを実行したくないので、イメージベイクプロセス内でこれを実行する場合は、クリーンアップする必要があります。また、サービスが実行しないことを確認します。ベーキング段階での作業。私はこれらの厄介なビットの両方を避けたいです。
20
Peter Mounce

Windowsは CreateProfile APIを使用してオンデマンドでユーザープロファイルを作成できます

ただし、この操作を実行する実行可能ファイルを作成しない場合は、PowerShellでAPIを呼び出すことができます。他の人はすでにそれを行っています: githubの例

コードの関連部分:

$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

そのユーザーとしてコマンドを実行するだけで、Windowsがプロファイルを作成します。

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

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

17
Greg Askew