我將 Terraform 與 Google Cloud 結合使用來建立 Windows Server Core 2019 主機以與 Jenkins 一起使用。我想使用 Git、OpenJDK 等來安裝一些軟體舀,然後啟動Jenkins 代理 JAR作為在本地用戶下運行的系統服務jenkins
。
我使用透過和metadata
等鍵提供的 PowerShell 腳本來設定它們:sysprep-specialize-script-ps1
windows-startup-script-ps1
https://cloud.google.com/compute/docs/startupscript#providing_a_startup_script_for_windows_instances
我的問題是我正在使用 Powershell 建立本地用戶,如下所示:
New-LocalUser -Name $Username `
-Description $Description `
-Password $Password `
-PasswordNeverExpires `
-AccountNeverExpires
我使用 Windows Service Wrapper 建立一個 Jenkins Agent 服務: https://github.com/winsw/winsw
但是當我嘗試在不先登入 Jenkins 用戶的情況下運行它時,我得到了:
2020-08-26 14:49:57,760 INFO - Starting the service with id 'JenkinsAgent'
2020-08-26 14:49:57,823 FATAL - WMI Operation failure: ServiceLogonFailure
WMI.WmiException: ServiceLogonFailure
at WMI.WmiRoot.BaseHandler.CheckError(ManagementBaseObject result)
at WMI.WmiRoot.InstanceHandler.Invoke(Object proxy, MethodInfo method, Object[] arguments)
at WinSW.Program.<Run>g__Start|2_2(<>c__DisplayClass2_0& )
at WinSW.Program.Run(String[] argsArray, IWinSWConfiguration descriptor)
at WinSW.Program.Main(String[] args)
如果我先使用 RDP 登入用戶,則不會發生此問題jenkins
,這會在首次登入時建立用戶設定檔。我認為這就是允許服務正確啟動的原因。
我試圖弄清楚如何建立用戶及其個人資料,而無需手動登入該用戶,以便服務可以正確啟動。安裝和啟動 PS 腳本以使用者身分執行,這可能是使用、或等標誌以使用者身分執行命令以建立其設定檔失敗的SYSTEM
原因。Start-Process
Invoke-Command
Start-Job
-Credential
jenkins
我在嘗試運行命令或以exit
用戶jenkins
身份運行時遇到問題,如下所示:
[localhost] The background process reported an error with the following message: .
+ CategoryInfo : OpenError: (localhost:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : 2100,PSSessionStateBroken
我究竟做錯了什麼?
有沒有更好的方法來實現我想要做的事情?
如何建立本地用戶和它的配置檔案以便我創建的服務啟動?
答案1
基於連結問題的答复有三種方法(看起來最有希望):
使用 Powershell 作為這個答案中所描述的- 你會找到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;
}
- 使用
psexec
實用程式 這看起來是一個簡單的方法,但我不確定它是否適用於 Ansible。psexec.exe -u foobar -p Abcd123! cmd.exe /c exit
這是更多資訊關於psexec
工具。