Como devo inicializar uma nova conta local para um serviço do Windows?

Como devo inicializar uma nova conta local para um serviço do Windows?

Estou usando o Terraform com o Google Cloud para criar hosts do Windows Server Core 2019 para uso com Jenkins. Quero instalar alguns softwares como Git, OpenJDK e outros usandoColher, e inicie oAgente Jenkins JARcomo um serviço do sistema executado sob um jenkinsusuário local.

Estou configurando-os usando scripts do PowerShell fornecidos por meio de metadatachaves como sysprep-specialize-script-ps1e windows-startup-script-ps1:

https://cloud.google.com/compute/docs/startupscript#providing_a_startup_script_for_windows_instances

Meu problema é que estou criando usuários locais usando o Powershell assim:

New-LocalUser -Name $Username `
    -Description $Description `
    -Password $Password `
    -PasswordNeverExpires `
    -AccountNeverExpires

E eu crio um serviço Jenkins Agent usando o Windows Service Wrapper: https://github.com/winsw/winsw

Mas quando tento executá-lo sem fazer login primeiro no usuário Jenkins, recebo de volta:

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)

Esse problema não acontece se eu fizer login no jenkinsusuário pela primeira vez usando RDP, que cria o perfil do usuário no primeiro login. Presumo que é isso que permite que o serviço seja iniciado corretamente.

Estou tentando descobrir como posso criar um usuário e seu perfil sem precisar fazer login manualmente nesse usuário para que o serviço possa iniciar corretamente. Os scripts PS de configuração e inicialização estão sendo executados como SYSTEMusuário, o que pode ser o motivo pelo qual o uso de algo como Start-Process, Invoke-Commandou Start-Jobwith -Credentialsinalizador para executar um comando como jenkinsusuário para permitir que seu perfil seja criado falha.

Tive problemas ao tentar executar um comando ou apenas exitcomo jenkinsusuário:

[localhost] The background process reported an error with the following message: .
    + CategoryInfo          : OpenError: (localhost:String) [], PSRemotingTransportException
    + FullyQualifiedErrorId : 2100,PSSessionStateBroken

O que estou fazendo de errado?

Existe alguma maneira melhor de conseguir o que estou tentando fazer?

Como posso criar um usuário localcomseu perfil para que o serviço que eu crio seja iniciado?

Responder1

Com base nas respostas de uma pergunta vinculadaexistem três maneiras (que parecem mais promissoras):

  1. UsarAPI CriarProfile

  2. Use Powershell comodescrito nesta resposta- você encontraráexemplo no GitHub- neste caso você poderá definir o caminho do diretório inicial. Parte do código que define o caminho do perfil:

    $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;
    }
  1. Usar psexecutilitário Parece um método simples, mas não tenho certeza se será Ansible. psexec.exe -u foobar -p Abcd123! cmd.exe /c exit Aqui estámais informações sobrepsexecferramenta.

informação relacionada