Alguns recursos do PowerShell ao usar contas de usuário

Eu pensei que era muito bom em PowerShell, mas nunca tive que trabalhar com credenciais de usuário. No entanto, agora estou em busca de emprego e, em uma das entrevistas, recebi uma tarefa de teste para escrever um script que deveria:

  1. Verifique a disponibilidade e o status (ativado / desativado) da conta do usuário.
  2. Verifique se a conta está incluída no grupo Administradores
  3. Se não houver uma conta, crie uma conta e adicione-a ao grupo de administradores, marque as caixas "Negar alteração de senha por usuário" e "Senha não expirada"
  4. Se a conta existir, mas estiver desativada ou não estiver incluída no grupo Administradores, ative a conta e adicione-a ao grupo Administradores, marque as caixas ao lado de "Negar alteração de senha pelo usuário" e "Senha não expirada"
  5. O script não deve depender do idioma do sistema operacional.


Eu pensei que não havia nada complicado, e a primeira coisa que decidi verificar foi o usuário Admin no meu computador. Sem pensar duas vezes, dirigi um comando:

Get-User admin 

E então eu recebi um erro

Get-User : "Get-User" , , .

Um pouco surpreso, porque não reconheci um comando tão útil e descobri que o comando Get-User funciona apenas no console do Powershell para Exchange. Para trabalhar com usuários locais, você deve usar Get-Localuser e para usuários do domínio Get-Aduser . Percebendo meu erro, eu dirigi:

 Get-Localuser admin 

E tem uma resposta

 Name Enabled Description ---- ------- ----------- Admin True     / 

Bem, agora não é grande coisa verificar se o usuário está lá ou não, mas aqui novamente eu estava esperando outra captura. Usar a instrução condicional if else não se mostrou tão fácil.

O fato é que, se o usuário está no sistema, a saída não é o valor verdadeiro, mas todo um conjunto de dados, com o nome e a descrição do usuário, esta conta está ativada ou não. E se não houver usuário, o PowerShell lança um erro. Depois de passear pela Internet, descobri que, para esses fins, é melhor usar o operador try catch .

 $user = 'admin' try { Get-LocalUser $user -ErrorAction Stop | Out-Null write-host  $user  -foregroundcolor Green } Catch { write-host  $user  -foregroundcolor Red } 

Adicionei a variável $ user para facilitar a alteração de nomes de usuários em todo o script. A parada ErrorAction é necessária para que o script não seja interrompido nesta etapa devido a um erro. Assinar separa as etapas do pipeline e Out-Null oculta a saída de texto de erro. Também adicionei a saída de texto com destaque, para a conveniência de verificar o script.

Em seguida, queria verificar se a conta está ativada ou desativada. Como eu já disse, o comando Get-LocalUser produz um conjunto inteiro de dados e, para verificação, eu precisava selecionar apenas um parâmetro Enabled com o valor true ou false. Para fazer isso, usei o seguinte comando:

 (Get-LocalUser $user).enabled 

Depois de garantir que funcione, fiz a seguinte verificação e adicionei um comando de habilitação do usuário.

 $user = 'admin' if ((Get-LocalUser $user).enabled -eq "True") { write-host    -foregroundcolor Green } else { write-host    -foregroundcolor Red Enable-LocalUser $user write-host    -foregroundcolor Green } 

Para habilitar o usuário, é naturalmente necessário executar o console com direitos de administrador.

No segundo parágrafo da tarefa, foi necessário determinar se o usuário é membro do grupo de administradores. Para verificar se um usuário está em um grupo específico, existe um comando Get-LocalGroupMember. No entanto, o nome do grupo de administradores varia do idioma do sistema operacional. Portanto, eu tive que usar o SID padrão S-1-5-32-544. Eu também verifiquei através de uma tentativa de captura.

 $user = 'admin' try { Get-LocalGroupMember -SID S-1-5-32-544 -Member $user -ErrorAction Stop | Out-Null write-host  $user     -foregroundcolor Green } Catch { write-host  $user      -foregroundcolor Red Add-LocalGroupMember -SID S-1-5-32-544 -Member $user write-host  $user     -foregroundcolor Green } 

Se o usuário não for um membro do grupo, os administradores serão adicionados a ele.
No estágio seguinte, tive a tarefa de determinar se o usuário tem a configuração de alteração de senha desativada ou não. Então me deparei com outras armadilhas. O fato é que, se o usuário tiver uma senha ilimitada, o parâmetro PasswordExpires não retornará nenhum valor. E se esta caixa de seleção estiver desativada, usuários diferentes terão uma data de alteração de senha diferente. Eu ainda tinha uma maneira de sair dessa situação:

 if ((Get-LocalUser $user).PasswordExpires -eq $null) { write-host      -foregroundcolor Green } else { write-host     -foregroundcolor Red set-LocalUser $user -PasswordNeverExpires:$true write-host      -foregroundcolor Green } 

Em seguida, eu precisava criar um usuário. Eu também não esperava que uma captura estivesse me esperando aqui. Ao criar um usuário com o comando

 new-LocalUser -User $user -password P@ssW0rD! 

Erro retornado:

"Password". "P@ssW0rD!" "System.String" "System.Security.SecureString".

O fato é que o parâmetro -password deve usar SecureString, em vez da sequência de texto usual. Para fazer isso, criei a variável $ password e a converti em proteção.

 $password = convertto-securestring "P@ssW0rD!" -asplaintext -force 

E o próprio script para criar um usuário e adicioná-lo ao grupo de administradores

 new-LocalUser -User $user -password $password -PasswordNeverExpires:$true -AccountNeverExpires:$true Add-LocalGroupMember -SID S-1-5-32-544 -Member $user 

O script finalizado que leva em consideração todas as condições que obtive dessa maneira:

 $user = 'admin' $password = convertto-securestring "P@ssW0rD!" -asplaintext -force try { Get-LocalUser $user -ErrorAction Stop | Out-Null cls write-host  $user  -foregroundcolor Green if ((Get-LocalUser $user).enabled -eq "True") { write-host    -foregroundcolor Green } else { write-host    -foregroundcolor Red Enable-LocalUser $user write-host    -foregroundcolor Green } if ((Get-LocalUser $user).PasswordExpires -eq $null) { write-host      -foregroundcolor Green } else { write-host     -foregroundcolor Red set-LocalUser $user -PasswordNeverExpires:$true write-host      -foregroundcolor Green } try { Get-LocalGroupMember -SID S-1-5-32-544 -Member $user -ErrorAction Stop | Out-Null write-host  $user     -foregroundcolor Green } Catch { write-host  $user      -foregroundcolor Red Add-LocalGroupMember -SID S-1-5-32-544 -Member $user write-host  $user     -foregroundcolor Green } } Catch { cls write-host  $user  -foregroundcolor Red new-LocalUser -User $user -password $password -PasswordNeverExpires:$true -AccountNeverExpires:$true Add-LocalGroupMember -SID S-1-5-32-544 -Member $user write-host  $user       -foregroundcolor Green } 

Post scriptum

No entanto, armazenar a senha do administrador em um script não é a melhor prática de segurança. Para fazer isso, você pode usar o hash da senha, não a senha em si.

 $user = 'admin1' $hash = "01000000d08c9ddf0115d1118c7a00c04fc297eb0100000048baf1b47a72d845b4eeda8659da9fd70000000002000000000010660000000100002000000004d2a3bf03aac92c2e172dc002d1fe8759da4655850462aface5c25f52921e05000000000e8000000002000020000000bfa652b6f7cc6845e3cee1831b54ab93dc272d0b2203024c3de8bc4789a2698a10000000923fb50dcf01125913534d0c1ba6d827400000002757df7d8a8b39c8e84b81323acff1d72419580a0022cf610926e5f081a2e895320088d482eb407f8157aad82f091abee7427b357e871d12238a8f74131238e7" $hash $password = ConvertTo-SecureString -String $hash $password new-LocalUser -User $user -password $password -PasswordNeverExpires:$true -AccountNeverExpires:$true Add-LocalGroupMember -SID S-1-5-32-544 -Member $user 

Para obter um hash de senha, você pode usar o seguinte script

 $Secure = Read-Host -AsSecureString $Secure $hash = ConvertFrom-SecureString -SecureString $Secure $hash 

O que solicita uma senha do teclado.

E um pequeno bônus para exibir todos os registros desativados

 Get-LocalUser | Where-Object {$_.enabled -eq $false} 

Espero que o tempo que passei ajude alguém em seu trabalho. E para si mesmo será útil não esquecer essa experiência inestimável.

Source: https://habr.com/ru/post/pt418859/


All Articles