如何以程式方式創建新的 Windows 使用者配置文件?
我正在為要執行的 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; }