私はGoogle CloudでTerraformを使用して、Jenkinsで使用するWindows Server Core 2019ホストを作成しています。Git、OpenJDKなどのソフトウェアをインストールしたいのですが、スクープ、そしてジェンキンスエージェント JARローカル ユーザーの下で実行されるシステム サービスとしてjenkins
。
次metadata
のようなキーを介して提供される PowerShell スクリプトを使用して設定しています:sysprep-specialize-script-ps1
windows-startup-script-ps1
https://cloud.google.com/compute/docs/startupscript#windows_instances 用のスタートアップ スクリプトの提供
私の問題は、Powershell を使用して次のようにローカル ユーザーを作成していることです。
New-LocalUser -Name $Username `
-Description $Description `
-Password $Password `
-PasswordNeverExpires `
-AccountNeverExpires
そして、Windows Service Wrapper を使用して Jenkins エージェント サービスを作成します。 出典: github.com
しかし、最初に 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 を使用してユーザーにログインすると発生しません。RDPjenkins
は最初のログイン時にユーザー プロファイルを作成します。これにより、サービスが正しく開始されると考えられます。
サービスが正しく開始できるように、手動でそのユーザーにログインせずに、ユーザーとそのプロファイルを作成する方法を見つけようとしています。セットアップおよび起動 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
リンクされた質問からの回答に基づく最も有望と思われる方法は 3 つあります。
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
道具。