ドメインに属するリモートコンピュータを再起動したいのですが。管理者アカウントを持っていますが、PowerShellからそれを使用する方法がわかりません。
Restart-Computer
コマンドレットがあり、資格情報を渡すことができることはわかっていますが、私のドメインが例えば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
スイッチ値が必要になるかもしれません。
別の方法がありますが、...
スクリプトファイルにパスワードを入れたくない場合は、これを行わないでください(パスワードをスクリプトに格納するのはお勧めできませんが、私たちはただ知っているのが好きです。)
わかりました、それは警告でした、ここにコードがあります:
$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
は、パスワードが "ABCDEF"のJohn Doeからの資格情報を持ちます。
パスワードを使用可能にする代替手段
$password = convertto-securestring -String "notverysecretpassword" -AsPlainText -Force
資格情報の保存に関しては、2つの関数を使用します(通常、私のプロファイルからロードされたモジュール内にあります)。
#=====================================================================
# 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ファイル内の暗号化されたストリングに保管されます。 2回目にその行を実行すると、xmlfileがそこにあり、自動的に開かれます。
別の認証情報を必要とするリモートサーバーから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)
再起動をスケジュールしている場合、これを行うことができる2つの方法があります。
最初に、別のマシンに接続して再起動するために必要な権限を持つ資格情報を使用して、1台のマシンでタスクを作成できます。これにより、スケジューラがクレデンシャルを安全に保存する責任を負います。再起動コマンド(私は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"
現在の資格情報を使用して、リモートコンピュータのシステムアカウントで実行されるスケジュールされたタスクを作成するという2番目の方法をお勧めします。
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と入力し、パスワードフィールドを空白のままにします。
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
セキュリティ上の注意:
ソリューションを読むとき、あなたは最初にディスクにパスワードを保存することに用心するかもしれません。ハードドライブに機密情報をあふれさせるのに用心するのは自然でありながら慎重ですが、Export-CliXmlコマンドレットはWindows標準のData Protection APIを使用して資格情報オブジェクトを暗号化します。これにより、自分のユーザーアカウントだけがその内容を正しく復号化できるようになります。同様に、ConvertFrom-SecureStringコマンドレットも指定したパスワードを暗号化します。
編集:元の質問を読み直すだけです。 [pscredential]
をハードディスクに初期化している限り、上記はうまくいきます。それはあなたがあなたのスクリプトにそれを落として、それがそのファイルを作成してからスクリプトを無人で実行することが簡単になるならスクリプトを実行するならばそれはそうです。
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
この方法でパスワードを保存することには十分注意してください。
ソリューション
$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