Usando credenciais do PowerShell sem ser solicitada uma senha


147

Gostaria de reiniciar um computador remoto que pertence a um domínio. Eu tenho uma conta de administrador, mas não sei como usá-la no PowerShell.

Sei que existe um Restart-Computercmdlet e que posso passar credenciais, mas se meu domínio for, por exemplo mydomain, meu nome de usuário myusere minha senha, mypasswordqual é a sintaxe correta para usá-lo?

Preciso agendar a reinicialização para não precisar digitar a senha.


Você deve ler este link
— atolamentos

O que significa get-credential domain01 \ admin01? O próximo comando é restart-computer -computername $ s -force -throttlelimit 10 -credential $ c. Isso significa que a get-credential recupera a senha sem solicitá-la?
— all eyez on me

Respostas:


202

O problema Get-Credentialé que ele sempre solicitará uma senha. No entanto, existe uma maneira de contornar isso, mas envolve armazenar a senha como uma string segura no sistema de arquivos.

O artigo a seguir explica como isso funciona:

Usando PSCredentials sem um prompt

Em resumo, você cria um arquivo para armazenar sua senha (como uma sequência criptografada). A linha a seguir solicitará uma senha e a armazenará c:\mysecurestring.txtcomo uma sequência criptografada. Você só precisa fazer isso uma vez:

read-host -assecurestring | convertfrom-securestring | out-file C:\mysecurestring.txt

Onde quer que você veja um -Credentialargumento em um comando do PowerShell, isso significa que você pode passar a PSCredential. Então, no seu caso:

$username = "domain01\admin01"
$password = Get-Content 'C:\mysecurestring.txt' | ConvertTo-SecureString
$cred = new-object -typename System.Management.Automation.PSCredential `
         -argumentlist $username, $password

$serverNameOrIp = "192.168.1.1"
Restart-Computer -ComputerName $serverNameOrIp `
                 -Authentication default `
                 -Credential $cred
                 <any other parameters relevant to you>

Você pode precisar de um -Authenticationvalor de switch diferente, porque eu não conheço seu ambiente.


23
Você também pode fazer ConvertTo-SecureString "password" -AsPlainText -Force.
— x0n 26/11/13

14
Só para deixar claro,$password = ConvertTo-SecureString "password" -AsPlainText -Force
— Akira Yamamoto

-Credential [nome de usuário] foi necessário nos parâmetros Read-Host para mim, caso contrário, o PowerShell simplesmente trava. Depois de passar -Credential para read-host, você será solicitado diretamente no console do PowerShell e a senha será armazenada corretamente. Obrigado!
— SEPHIROT

Estou tentando descobrir como fazer isso funcionar quando uso a função Send-MailMessage no PowerShell. Estou querendo armazenar as credenciais do meu usuário de e-mail e passar para que eu não precise continuar inserindo. Alguma idéia de como fazer isso?
— KangarooRIOT

@ user3681591 - eu recomendaria fazer uma nova pergunta em vez de fazer isso nos comentários. Obrigado.
— Kev

71

Existe outra maneira, mas ...

NÃO FAÇA ISTO SE NÃO QUER SUA SENHA NO ARQUIVO DE SCRIPT (não é uma boa ideia armazenar senhas em scripts, mas alguns de nós gostam de saber como).

Ok, esse foi o aviso, aqui está o código:

$username = "John Doe"
$password = "ABCDEF"
$secstr = New-Object -TypeName System.Security.SecureString
$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr

$cred terá as credenciais de John Doe com a senha "ABCDEF".

Meios alternativos para preparar a senha para uso:

$password = convertto-securestring -String "notverysecretpassword" -AsPlainText -Force

Obrigado. Isso é muito útil. No meu caso, eu estava criando um cmdlet do PowerShell personalizado que usa um nome de usuário e senha (como secureString). Internamente, o cmdlet chama vários outros cmdlets, alguns precisam apenas de um usuário e senha, mas um deles precisa de uma credencial; portanto, não preciso codificar a senha no meu script.
— BenR

20
Um pouco mais simples: $ password = convertto-securestring -String "notverysecretpassword" -AsPlainText -Force
— Sam

Estou tentando descobrir como fazer isso funcionar quando uso a função Send-MailMessage no PowerShell. Estou querendo armazenar as credenciais do meu usuário de e-mail e passar para que eu não precise continuar inserindo. Alguma idéia de como fazer isso?
— KangarooRIOT

@ user3681591 Isso seria Send-MailMessage -Credential $ cred (com US $ Cred criado como mostrado neste post)
— Jeroen Landheer

@JeroenLandheer Tentei sua resposta (obrigado por ajudar!), No entanto, não funcionou. Meu erro é: -Credencial: o termo '-Credencial' não é reconhecido como o nome de um cmdlet, função, arquivo de script ou programa operável.
— KangarooRIOT

29

Em relação ao armazenamento de credenciais, eu uso duas funções (normalmente em um módulo carregado no meu perfil):

#=====================================================================
# Get-MyCredential
#=====================================================================
function Get-MyCredential
{
param(
$CredPath,
[switch]$Help
)
$HelpText = @"

    Get-MyCredential
    Usage:
    Get-MyCredential -CredPath `$CredPath

    If a credential is stored in $CredPath, it will be used.
    If no credential is found, Export-Credential will start and offer to
    Store a credential at the location specified.

"@
    if($Help -or (!($CredPath))){write-host $Helptext; Break}
    if (!(Test-Path -Path $CredPath -PathType Leaf)) {
        Export-Credential (Get-Credential) $CredPath
    }
    $cred = Import-Clixml $CredPath
    $cred.Password = $cred.Password | ConvertTo-SecureString
    $Credential = New-Object System.Management.Automation.PsCredential($cred.UserName, $cred.Password)
    Return $Credential
}

E este:

#=====================================================================
# Export-Credential
# Usage: Export-Credential $CredentialObject $FileToSaveTo
#=====================================================================
function Export-Credential($cred, $path) {
      $cred = $cred | Select-Object *
      $cred.password = $cred.Password | ConvertFrom-SecureString
      $cred | Export-Clixml $path
}

Você usa assim:

$Credentials = Get-MyCredential (join-path ($PsScriptRoot) Syncred.xml)

Se o arquivo de credencial não existir, você será solicitado na primeira vez; nesse momento, ele armazenará as credenciais em uma sequência criptografada dentro de um arquivo XML. Na segunda vez em que você executa essa linha, o xmlfile está lá e será aberto automaticamente.


10

Preciso executar as funções do SCOM 2012 em um servidor remoto que exija uma credencial diferente. Evito senhas de texto não criptografado, transmitindo a saída de uma função de descriptografia de senha como entrada para ConvertTo-SecureString. Para maior clareza, isso não é mostrado aqui.

Eu gosto de digitar fortemente minhas declarações. A declaração de tipo para $ strPass funciona corretamente.

[object] $objCred = $null
[string] $strUser = 'domain\userID'
[System.Security.SecureString] $strPass = '' 

$strPass = ConvertTo-SecureString -String "password" -AsPlainText -Force
$objCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($strUser, $strPass)

4

Aqui estão duas maneiras de fazer isso, se você estiver agendando a reinicialização.

Primeiro, você pode criar uma tarefa em uma máquina usando credenciais com direitos necessários para conectar e reiniciar outra máquina. Isso torna o agendador responsável por armazenar com segurança as credenciais. O comando reboot (eu sou do tipo Powershell, mas isso é mais limpo.) É:

SHUTDOWN /r /f /m \\ComputerName

A linha de comando para criar uma tarefa agendada na máquina local, para reiniciar outra remotamente, seria:

SCHTASKS /Create /TN "Reboot Server" /TR "shutdown.exe /r /f /m \\ComputerName" /SC ONCE /ST 00:00 /SD "12/24/2012" /RU "domain\username" /RP "password"

Prefiro a segunda maneira, em que você usa suas credenciais atuais para criar uma tarefa agendada que é executada com a conta do sistema em uma máquina remota.

SCHTASKS /Create /TN "Reboot Server" /TR "shutdown.exe /r /f" /SC ONCE /ST 00:00 /SD "12/24/2012" /RU SYSTEM /S ComputerName

Isso também funciona através da GUI, basta digitar SYSTEM como o nome do usuário, deixando os campos da senha em branco.


1
read-host -assecurestring | convertfrom-securestring | out-file C:\securestring.txt
$pass = cat C:\securestring.txt | convertto-securestring
$mycred = new-object -typename System.Management.Automation.PSCredential -argumentlist "test",$pass
$mycred.GetNetworkCredential().Password

Tenha muito cuidado ao armazenar senhas dessa maneira ... não é tão seguro quanto ...


1

Eu vi um exemplo que usa Import / Export-CLIXML.

Esses são os meus comandos favoritos para o problema que você está tentando resolver. E a maneira mais simples de usá-los é.

$passwordPath = './password.txt'
if (-not (test-path $passwordPath)) {
    $cred = Get-Credential -Username domain\username -message 'Please login.'
    Export-Cli -InputObject $cred -Path $passwordPath
}
$cred = Import-CliXML -path $passwordPath

Portanto, se o arquivo não existir localmente, ele solicitará as credenciais e as armazenará. Isso exigirá um [pscredential]objeto sem problemas e ocultará as credenciais como uma sequência segura.

Finalmente, basta usar a credencial como você normalmente faz.

Restart-Computer -ComputerName ... -Credentail $cred

Nota sobre o Securty :

Armazene credenciais com segurança no disco

Ao ler a solução, você pode, inicialmente, desconfiar de armazenar uma senha no disco. Embora seja natural (e prudente) ser cauteloso ao deixar seu disco rígido com informações confidenciais, o cmdlet Export-CliXml criptografa objetos de credenciais usando a API de proteção de dados padrão do Windows. Isso garante que apenas sua conta de usuário possa descriptografar adequadamente seu conteúdo. Da mesma forma, o cmdlet ConvertFrom-SecureString também criptografa a senha que você fornece.

Editar: basta reler a pergunta original. O procedimento acima funcionará desde que você inicialize [pscredential]o disco rígido. Ou seja, se você soltar isso em seu script e executar o script, uma vez que ele criará esse arquivo e, em seguida, executar o script sem supervisão será simples.


1

Solução

$userName = 'test-domain\test-login'
$password = 'test-password'

$pwdSecureString = ConvertTo-SecureString -Force -AsPlainText $password
$credential = New-Object -TypeName System.Management.Automation.PSCredential `
    -ArgumentList $userName, $pwdSecureString

Para máquinas de compilação
No código anterior, substitua os valores de nome de usuário e senha por variáveis ​​de ambiente secretas ("ocultas dos logs") da sua máquina de compilação

Resultados do teste por

'# Results'
$credential.GetNetworkCredential().Domain
$credential.GetNetworkCredential().UserName
$credential.GetNetworkCredential().Password

e você verá

# Results
test-domain
test-login
test-password

-3

por que você não tenta algo muito simples?

use psexec com o comando 'shutdown / r / f / t 0' e uma lista de PCs do CMD.


Esse é um caso específico. O ponto não está gerando uma janela de login em nenhum cenário aleatório.
— Overmind
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.