Windows

如何以程式方式創建新的 Windows 使用者配置文件?

  • December 28, 2018

我正在為要執行的 Windows 服務創建一個(本地)使用者。我有充分的理由不想使用網路服務、本地服務或本地系統。

我通過創建使用者net user foobar "Abcd123!" /add- 這工作正常。

此時,c:\users\foobar不存在。

如果創建使用者的主目錄,則在使用者登錄(或更準確地說)或使用者所要的服務啟動之前,Windows 會在隔壁創建一個名為的使用者配置文件c:\users\foobar-{gibberish/SID/whatever}- 這不是一個可預測的名稱。

我需要使用者的主目錄包含諸如.ssh目錄之類的東西,a .gitconfig- 類似的工具(不限於那些工具)假設它將是一個人使用它們,因此使用者配置進入內部~/...。通常,來自 Unix 遺產的工具。

實際問題

那麼 - 是否有一種程式方式(最好是 PowerShell 或開箱即用的命令行)來告訴 Windows 為本地使用者創建使用者配置文件?

或者,還有其他解決方法嗎?

我還沒有嘗試的事情:

  • 一個 NSSM 啟動/預掛鉤,它將文件從其他地方復製到使用者配置文件目錄中,該目錄希望在此時存在,這得益於Windows啟動服務,創建使用者配置文件,然後在啟動前將控制權交給執行掛鉤的 NSSM 包裝器。
  • 將服務的 USERPROFILE 環境變數設置為實際使用者配置文件目錄以外的位置。這讓我覺得很危險,但也可以正常工作。

其他上下文:

  • Windows Server 2016,桌面體驗。

    • 不能使用核心/納米。
  • 沒有活動目錄在播放。不會有。

  • 這些是本地使用者。

  • 我通過 Ansible 執行此操作,它在 Windows 事物的引擎蓋下使用 PowerShell。特別是帶有 Ansible 2.7.5的win_user模組。

  • 我不想創建一個C:\users\default(相當於/etc/skel),因為有幾個不同的服務使用者,並且一個尺寸不會適合所有人。這也不會影響創建使用者配置文件的時間,只會影響其中的內容。

  • 我正在使用NSSM來管理服務。

我嘗試過的事情

  • 啟動服務並允許 Windows 創建目錄

    • 我不想這樣做,因為該服務在啟動之前需要秘密,所以如果我在我的圖像烘焙過程中這樣做,我將需要清理它們,並確保我的服務不這樣做烘烤階段的任何工作。我想避免這兩個繁瑣的部分。

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

引用自:https://serverfault.com/questions/946882