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.

todos olham para mim
fonte
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.

Kev
fonte
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
Jeroen Landheer
fonte
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.

Winfred
fonte
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)
Bruce Gavin
fonte
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.

Nathan Hartley
fonte
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 ...

MockMyBeret
fonte
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.

ScriptingDad
fonte
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
it3xl
fonte
-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.

Loop de raiz
fonte
Esse é um caso específico. O ponto não está gerando uma janela de login em nenhum cenário aleatório.
Overmind