157

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

我知道有一个Restart-Computercmdlet 并且我可以传递凭据,但是如果我的域是例如mydomain,我的用户名是myuser,我的密码是mypassword使用它的正确语法是什么?

我需要安排重新启动,这样我就不必输入密码。

4

12 回答 12

210

问题Get-Credential是它总是会提示输入密码。然而,有一种方法可以解决这个问题,但它涉及将密码作为安全字符串存储在文件系统上。

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

在没有提示的情况下使用 PSCredentials

总之,您创建一个文件来存储您的密码(作为加密字符串)。以下行将提示输入密码,然后将其存储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开关值,因为我不知道您的环境。

于 2011-06-05T00:51:20.863 回答
72

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

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

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

$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
于 2012-02-07T18:54:51.823 回答
30

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

#=====================================================================
# 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 文件中的加密字符串中。第二次运行该行时,xml 文件就在那里并且会自动打开。

于 2011-06-05T04:47:41.963 回答
10

我必须从需要不同凭据的远程服务器运行 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)
于 2013-11-08T01:39:27.860 回答
4

如果您要安排重新启动,这里有两种方法可以做到这一点。

首先,您可以使用具有连接和重新启动另一台计算机所需权限的凭据在一台计算机上创建任务。这使得调度程序负责安全地存储凭据。重启命令(我是一个 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 作为用户名,将密码字段留空。

于 2012-07-09T17:27:57.427 回答
2

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

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

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

因此,如果该文件在本地不存在,它将提示输入凭据并存储它们。这将[pscredential]毫无问题地获取一个对象,并将凭据隐藏为安全字符串。

最后,像往常一样使用凭证。

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

安全注意事项

在磁盘上安全地存储凭据

阅读解决方案时,您可能首先对在磁盘上存储密码持谨慎态度。虽然小心谨慎地在硬盘上乱扔敏感信息是很自然的(也是谨慎的),但 Export-CliXml cmdlet 使用 Windows 标准数据保护 API 加密凭证对象。这可确保只有您的用户帐户才能正确解密其内容。同样,ConvertFrom-SecureString cmdlet 也会加密您提供的密码。

编辑:只需重新阅读原始问题。只要您已将[pscredential]硬盘初始化,上述操作就可以正常工作。也就是说,如果您将其放入脚本中并在创建该文件后运行该脚本,然后在无人看管的情况下运行该脚本将很简单。

于 2018-09-03T13:16:57.343 回答
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

以这种方式存储密码时要非常小心……它不如……安全

于 2013-05-21T18:28:21.383 回答
1

解决方案

$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

对于构建机器
在前面的代码中,将用户名和密码值替换为构建机器的秘密(“从日志中隐藏”)环境变量

测试结果

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

你会看到

# Results
test-domain
test-login
test-password
于 2019-06-26T11:31:06.650 回答
0

如果下面的代码可能对某人有所帮助。

function Get-RemoteConnection()
{
    //$serverIp can be passed as a parameter of the function.
    //I just make it static for testing. 
    $serverIp = '192.168.100.137'
    Enable-PSRemoting -Force
    Set-Item wsman:\localhost\client\trustedhosts $serverIp
    Restart-Service WinRM
    #Set credentials needed for remote installation
    $userName = "administrator"
    $password = ConvertTo-SecureString "2020core0515" -AsPlainText -Force
    $cred = New-Object System.Management.Automation.PSCredential -ArgumentList ($userName, $password)
    $session = New-PSSession -ComputerName $serverIp -Credential $cred

    $a = Invoke-Command -Session $session -ScriptBlock {  Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3" | Select-Object DeviceID, @{label='UsedPercent'; expression={[Math]::Round((($_.size - $_.freespace) / $_.size) * 100, 2)}} }

    Write-Host $a

    return $session
}

function Delete-RemoteConnection($session)
{
    Disconnect-PSSession $session | Out-Null
    Disable-WSManCredSSP -Role Client
}
于 2021-12-06T01:31:47.653 回答
0

这就是我使用和为我工作的东西。

$User="Domain\Username"
$Password=[Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('VABlAHMAdABQAGEAcwBzAHcAbwByAGQA'))

$SecurePassword = New-Object -TypeName System.Security.SecureString
$Password.ToCharArray() | ForEach-Object {$SecurePassword.AppendChar($_)}

$Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $SecurePassword

并获得 VABlAHMAdABQAGEAcwBzAHcAbwByAGQA 我这样做:

编码 $EString 表示加密字符串,$DString 表示解密字符串

$EString = Read-Host "Type Text to Encode" -AsSecureString
$BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($EString)
$DString=[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
$Encoded=[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($DString))

$Encoded # VABlAHMAdABQAGEAcwBzAHcAbwByAGQA
$DString # TestPassword

这样我就可以在脚本上输入我想要的任何密码,而不会太麻烦。

于 2021-12-11T15:55:09.707 回答
0

您可以将其存储在凭证保险库中,而不是将加密密码存储在文本文件中。在以下示例中,仅第一次提示用户输入密码,然后从凭证库中检索密码。

# Load the Windows Runtime Class
[Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime]
$Vault = New-Object Windows.Security.Credentials.PasswordVault

$RESOURCE = "myresource"
$USERNAME = "myuser"

try {
    $credentials = $Vault.Retrieve($RESOURCE,$USERNAME)
    $pwd = $credentials.Password | ConvertTo-SecureString -Key (1..16)
    }
catch {
    $pwd = Read-Host "please enter your password:" -AsSecureString
    $Encrypted = ConvertFrom-SecureString -SecureString $pwd -Key (1..16)
    $credentials = new-object -Type Windows.Security.Credentials.PasswordCredential -ArgumentList $RESOURCE,$USERNAME,$Encrypted
    $Vault.Add($credentials)
    }

$cred = New-Object System.Management.Automation.PsCredential($USERNAME,$pwd)
于 2022-01-17T13:16:00.803 回答
-3

你为什么不尝试一些非常简单的事情呢?

使用带有命令“shutdown /r /f /t 0”的 psexec 和来自 CMD 的 PC 列表。

于 2015-01-29T17:20:39.243 回答