Como posso programaticamente fazer com que um novo perfil de usuário do Windows seja criado?


20

Estou criando um usuário (local) para que um serviço do Windows seja executado como. Tenho boas razões para não querer usar o SERVIÇO DE REDE, SERVIÇO LOCAL ou SISTEMA LOCAL.

Eu crio o usuário via net user foobar "Abcd123!" /add- isso funciona bem.

Neste ponto, c:\users\foobarnão existe.

Se eu criar o diretório inicial do usuário, antes que o usuário efetue logon (ou, mais pertinentemente) ou o serviço para o qual ele é iniciado, o Windows criará um perfil de usuário ao lado chamado c:\users\foobar-{gibberish/SID/whatever}- este não é um nome previsível.

Eu preciso que o diretório inicial do usuário contenha coisas como um .sshdiretório, a .gitconfig- ferramentas como essa (não limitadas a essas ferramentas) que fazem suposições de que será uma pessoa que as usa e, portanto, a configuração do usuário entra ~/.... Geralmente, ferramentas de uma herança Unix.

Pergunta real

Então - existe uma maneira programática (preferencialmente, PowerShell ou linha de comando pronta para uso) para dizer ao Windows para criar o perfil de usuário para um usuário local?

Ou, outras soluções alternativas?

Coisas que ainda não tentei:

  • Um NSSM start / pre hook que copia arquivos de outros lugares para o diretório de perfil de usuário que, esperançosamente, existe neste momento em virtude do Windows iniciar o serviço, criando o perfil de usuário e entregando o controle ao wrapper NSSM que está executando o hook antes da inicialização.
  • Definir a variável de ambiente USERPROFILE para o serviço estar em outro lugar que não seja o diretório de perfil do usuário real. Isso me parece perigosamente fora de pista, mas também pode funcionar bem.

Outro contexto:

  • Windows Server 2016, experiência na área de trabalho.
    • Não é possível usar o Core / Nano.
  • Não há diretório ativo em reprodução. Não haverá.
  • Estes são usuários locais.
  • Estou fazendo isso via Ansible, que está usando o PowerShell nos bastidores para coisas do Windows. Especificamente, o módulo win_user , com o Ansible 2.7.5.
  • Não quero criar um C:\users\default(o equivalente a /etc/skel), porque existem alguns usuários de serviço diferentes e um tamanho não serve para todos. Isso também não afeta quando o perfil do usuário é criado, exatamente o que estará nele quando estiver.
  • Estou usando o NSSM para gerenciar os serviços.

Coisas que eu tentei

  • iniciando o serviço e permitindo que o Windows crie o diretório
    • Eu não quero fazer isso, porque o serviço exige segredos antes de iniciar, e, se eu fizer isso dentro do meu processo de criação de imagens, precisarei limpá-los e também garantir que meu serviço não funcione qualquer trabalho durante a fase de cozimento. Eu quero evitar os dois pedaços complicados.

1
Você verificou as opções net user(por exemplo, /HOMEDIRou /PROFILEPATH)? . Veja net user /help. Do meu entendimento (não testado), você pode criar um diretório para o usuário e configurá-lo como homedir com a /HOMEDIRopção
Sven

Posso perguntar que caso de uso você tem que evita o Active Directory? As coisas seriam muito mais fáceis com o AD. Apenas curioso.
Ondrej Tucny

Estou evitando o AD porque as máquinas são efêmeras; as vidas úteis são medidas em horas, não em dias. As máquinas estão hospedando ambientes de construção de sala limpa. Fazer malabarismo com as máquinas dentro e fora de um AD, conforme elas vão e vem, simplesmente não vale a pena (consulte também medium.com/palantir/active-directory-as-code-e9666a2e548d se você estiver interessado em fazê-lo).
Peter Mounce

@Sven yes - infelizmente, nenhum deles faz com que o próprio perfil seja criado, mesmo que eles definam o caminho.
Peter Mounce

Respostas:


23

O Windows pode criar um perfil de usuário sob demanda, usando a API CreateProfile

No entanto, se não desejar criar um executável para executar esta operação, você poderá chamar a API no PowerShell. Outros já fizeram isso: exemplo no github .

Parte relevante do código:

$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;
}

Muito obrigado, isso funciona para mim. Nota para outras pessoas - as funções Register-NativeMethod e Add-NativeMethods estão na lista principal.
Peter Mounce 27/01

17

Tudo o que você precisa fazer é executar um comando como esse usuário, o Windows criará o perfil:

psexec.exe -u foobar -p Abcd123! cmd.exe /c exit

https://docs.microsoft.com/en-us/sysinternals/downloads/psexec


1
Então, o que está acontecendo aqui é psexec suposto para se conectar ao localhost sob nome de usuário e senha especificados com -ue -pe lançamento cmdapenas para sair imediatamente. Eu perdi alguma coisa ? Isso soa um pouco contra-intuitivo - conectar ao sistema com nome de usuário e senha inexistentes deve ser um erro. Como isso funciona ?
Sergiy Kolodyazhnyy

1
@SergiyKolodyazhnyy: Por que você acha que esse é um nome de usuário e uma senha inexistentes? É o mesmo usado na pergunta, obviamente, como um exemplo ...
Ben Voigt

1
@ BenVoigt Bem, eu perdi a parte superior da questão. Eu pensei que o OP também queria criar o usuário e é isso que essa resposta deveria fazer. Portanto, a última parte do comentário é um mal-entendido.
Sergiy Kolodyazhnyy

@BenVoigt Embora eu ainda tenha uma pergunta. O OP mencionou "Não quero criar C: \ users \ default". Então, de onde viria o perfil do usuário quando esse método for usado e como o Windows saberia criar diretórios pré-configurados específicos, se não C:\users\defaults?
Sergiy Kolodyazhnyy

1
@SergiyKolodyazhnyy: Certeza de que o OP significa que ele não deseja personalizar C: \ Users \ Default ... não que isso esteja totalmente ausente. O Windows criará o diretório inicial C: \ Users \ foobar, copiando da baunilha C: \ Users \ default e, uma vez que exista, o OP poderá aplicar seu molho especial a C: \ Users \ foobar, onde não afetará nenhum outro Comercial.
Ben Voigt
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.