我想重新启动属于某个域的远程计算机。我有一个管理员账户,但不知道如何在powershell中使用它。
我知道有一个Restart-Computer
cmdlet,而且可以传递凭证,但如果我的域是例如mydomain
,我的用户名是myuser
,密码是mypassword
,正确的语法是什么?
我需要安排重启以便无需输入密码。
我想重新启动属于某个域的远程计算机。我有一个管理员账户,但不知道如何在powershell中使用它。
我知道有一个Restart-Computer
cmdlet,而且可以传递凭证,但如果我的域是例如mydomain
,我的用户名是myuser
,密码是mypassword
,正确的语法是什么?
我需要安排重启以便无需输入密码。
Get-Credential
的问题在于它会一直提示输入密码。然而有一种方法可以解决这个问题,但它需要将密码作为安全字符串存储在文件系统中。
以下文章解释了如何实现:
简单来说,您需要创建一个文件来存储您的密码(以加密字符串形式)。下面这行代码将提示输入并将其作为加密字符串保存在 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
开关值。
ConvertTo-SecureString "password" -AsPlainText -Force
иҝӣиЎҢж“ҚдҪңгҖӮ - x0n$password = ConvertTo-SecureString "password" -AsPlainText -Force
的意思是将字符串 "password" 转换为安全字符串,并强制将其视为纯文本格式。 - Akira Yamamoto还有一种方法,但是......
如果您不想将密码存储在脚本文件中,请勿使用此方法。 (在脚本中存储密码并不是一个好主意,但我们中的一些人只是想知道如何做。)
好的,那就是警告,下面是代码:
$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
关于存储凭据,我使用两个函数(通常在从我的配置文件加载的模块中):
#=====================================================================
# 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文件已存在并将自动打开。我需要从一个需要不同凭据的远程服务器上运行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)
如果您要安排重新启动任务,有两种方法可以实现。
首先,您可以使用具有连接和重启其他计算机所需权限的凭据在一台计算机上创建一个任务。这样,调度程序负责安全地存储凭据。重新启动命令(我是 Powershell 专家,但此方法更加简洁)如下:
SHUTDOWN /r /f /m \\计算机名
在本地计算机上创建一个定期重新启动远程计算机的命令行为:
SCHTASKS /Create /TN "重启服务器" /TR "shutdown.exe /r /f /m \\计算机名" /SC ONCE /ST 00:00 /SD "12/24/2012" /RU "域\用户名" /RP "密码"
我更喜欢第二种方式,它使用当前凭据在远程计算机上创建以系统帐户身份运行的定期任务。
SCHTASKS /Create /TN "重启服务器" /TR "shutdown.exe /r /f" /SC ONCE /ST 00:00 /SD "12/24/2012" /RU SYSTEM /S 计算机名
这也可以通过 GUI 实现,只需将用户名输入 SYSTEM,将密码字段留空即可。
我看到一个使用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命令使用Windows标准数据保护API加密凭据对象。这确保只有您的用户帐户才能正确解密其内容。同样,ConvertFrom-SecureString命令还会加密您提供的密码。
编辑:重新阅读原始问题。如果您已将[pscredential]初始化到硬盘,则上述内容将起作用。也就是说,如果您将其放入脚本并运行一次该脚本,它将创建该文件,然后无人值守地运行该脚本将变得简单。
这是我使用的方法,对我很有效。
$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 = 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
$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
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
不要将加密密码存储在文本文件中,可以将其存储在凭据保险库中。 在以下示例中,用户仅在第一次提示输入密码,之后密码将从凭据保险库中检索。
# 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)