使用PowerShell凭据而不提示输入密码

时间:2011-06-04 21:56:47

标签: powershell powershell-remoting

我想重新启动属于某个域的远程计算机。我有一个管理员帐户,但我不知道如何在powershell中使用它。

我知道有一个Restart-Computer cmdlet,我可以传递凭据,但如果我的域名是mydomain,我的用户名为myuser,密码为{{1}什么是正确的语法使用它?

我需要安排重启,所以我不必输入密码。

9 个答案:

答案 0 :(得分:191)

Get-Credential的问题在于它始终会提示输入密码。然而,有一种解决方法,但它涉及将密码存储为文件系统上的安全字符串。

以下文章解释了这是如何工作的:

  

Using PSCredentials without a prompt

总之,您创建了一个用于存储密码的文件(作为加密字符串)。以下行将提示输入密码,然后将其作为加密字符串存储在c:\mysecurestring.txt中。你只需要这样做一次:

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

无论您在PowerShell命令上看到-Credential参数,都意味着您可以传递PSCredential。所以在你的情况下:

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

您可能需要不同的-Authentication切换值,因为我不了解您的环境。

答案 1 :(得分:68)

还有另一种方式,但是......

如果您在SCRIPT文件中没有通过密码,请不要这样做 (在脚本中存储密码不是一个好主意,但我们中的一些人只是想知道如何。)

好的,那是警告,这是代码:

$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将获得John Doe的凭据,密码为“ABCDEF”。

替代方法是准备好使用密码:

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

答案 2 :(得分:29)

关于存储凭据,我使用两个函数(通常在从我的配置文件加载的模块中):

#=====================================================================
# 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
}

这一个:

#=====================================================================
# 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
}

你这样使用它:

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

如果凭据文件不存在,则会在第一时间提示您,此时它会将凭据存储在XML文件中的加密字符串中。第二次运行该行时,xmlfile就会出现并自动打开。

答案 3 :(得分:9)

我必须从需要不同凭据的远程服务器运行SCOM 2012功能。我通过将密码解密函数的输出作为输入传递给ConvertTo-SecureString来避免使用明文密码。为清楚起见,此处未显示。

我喜欢强烈输入我的声明。 $ strPass的类型声明正常工作。

[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 :(得分:3)

如果您要安排重新启动,可以使用以下两种方法。

首先,您可以使用具有连接和重新启动其他计算机所需权限的凭据在一台计算机上创建任务。这使得调度程序负责安全地存储凭证。重启命令(我是一个Powershell家伙,但这个更干净。)是:

SHUTDOWN /r /f /m \\ComputerName

在本地计算机上创建计划任务以远程重新启动另一计划任务的命令行将是:

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"

我更喜欢第二种方式,您可以使用当前凭据创建与远程计算机上的系统帐户一起运行的计划任务。

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

这也适用于GUI,只需输入SYSTEM作为用户名,将密码字段留空。

答案 5 :(得分:0)

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

以这种方式存储密码要非常小心......它不像......那样安全。

答案 6 :(得分:0)

我看到了一个使用Import / Export-CLIXML的示例。

对于您要解决的问题,这些是我最喜欢的命令。而使用它们的最简单方法是。

$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

因此,如果文件在本地不存在,它将提示输入凭据并将其存储。这将使用一个[pscredential]对象而不会出现问题,并将凭据隐藏为安全字符串。

最后,像平常一样使用凭据。

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

安全注意事项

Securely store credentials on disk

  

在阅读解决方案时,起初您可能会警惕在磁盘上存储密码。   谨慎对待硬盘是很自然的(也是谨慎的做法)   敏感信息,Export-CliXml cmdlet使用以下命令加密凭据对象:   Windows标准数据保护API。这样可以确保只有您的用户帐户可以   正确解密其内容。同样,ConvertFrom-SecureString cmdlet也   加密您提供的密码。

编辑:只需重新阅读原始问题即可。只要您将[pscredential]初始化到硬盘上,上述命令就可以使用。就是说,如果将其放到脚本中并运行脚本,它将创建该文件,然后在无人值守的情况下运行脚本将非常简单。

答案 7 :(得分:0)

解决方案

$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

用于构建机器
在前面的代码中,用build-machine

的秘密(“从日志中隐藏”)环境变量替换用户名和密码值 通过添加

测试结果

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

您会看到

# Results
test-domain
test-login
test-password

答案 8 :(得分:-3)

为什么不尝试非常简单的事情?

使用psexec命令&#39; shutdown / r / f / t 0&#39;和CMD的PC列表。