Я использую Terraform с Google Cloud для создания хостов Windows Server Core 2019 для использования с Jenkins. Я хочу установить некоторое программное обеспечение, например Git, OpenJDK и другие, используяСовок, и начатьJAR агента Дженкинсакак системная служба, работающая под локальным jenkins
пользователем.
Я настраиваю их с помощью скриптов PowerShell, предоставляемых с помощью metadata
ключей типа sysprep-specialize-script-ps1
и windows-startup-script-ps1
:
Моя проблема в том, что я создаю локальных пользователей с помощью Powershell следующим образом:
New-LocalUser -Name $Username `
-Description $Description `
-Password $Password `
-PasswordNeverExpires `
-AccountNeverExpires
И я создаю службу агента Jenkins с помощью Windows Service Wrapper: 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)
Эта проблема не возникает, если я сначала вхожу в 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
На основе ответов на связанный вопросесть три способа (которые выглядят наиболее многообещающими):
ИспользоватьAPI CreateProfile
Использовать 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
инструмент.