我正在使用 Terraform 和 Google Cloud 创建用于 Jenkins 的 Windows Server Core 2019 主机。我想使用舀,然后启动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
用户,则不会发生此问题,因为 RDP 会在首次登录时创建用户配置文件。我认为这就是服务能够正确启动的原因。
我正在尝试弄清楚如何创建用户及其个人资料,而无需手动登录该用户,以便服务可以正确启动。设置和启动 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
工具。