PowerShell
Powershellリモート処理
サーチ…
備考
PowerShell Remotingの有効化
PowerShellリモーティングは、リモートで接続するサーバーで最初に有効にする必要があります。
Enable-PSRemoting -Force
このコマンドは次の処理を行います。
- 次のタスクを実行するSet-WSManQuickConfigコマンドレットを実行します。
- WinRMサービスを開始します。
- WinRMサービスのスタートアップの種類を自動に設定します。
- 任意のIPアドレスで要求を受け入れるリスナーを作成します(存在しない場合)。
- WS-Management通信のファイアウォール例外を有効にします。
- Microsoft.PowerShellおよびMicrosoft.PowerShell.Workflowセッション構成が登録されていない場合は、登録します。
- 64ビットコンピュータにMicrosoft.PowerShell32セッション構成が登録されていない場合は、登録します。
- すべてのセッション構成を有効にします。
- すべてのセッション構成のセキュリティ記述子を変更して、リモートアクセスを許可します。
- 上記の変更を有効にするために、WinRMサービスを再起動します。
ドメイン以外の環境の場合のみ
ADドメイン内のサーバーの場合、PSリモート認証はKerberos( 'Default')またはNTLM( 'Negotiate')を介して行われます。ドメイン以外のサーバーへのリモートアクセスを許可する場合は、2つの方法があります。
HTTPS(証明書生成が必要)を介したWSMan通信を設定するか、ベースラインで証明書を送信する基本認証を有効にするか64エンコード(基本的にプレーンテキストと同じですので注意してください)。
どちらの場合でも、リモートシステムをWSManの信頼できるホストリストに追加する必要があります。
基本認証の有効化
Set-Item WSMan:\localhost\Service\AllowUnencrypted $true
そして、あなたから接続したいコンピュータ上で、あなたがに接続しているコンピュータを信頼することを教えなければなりません。
Set-Item WSMan:\localhost\Client\TrustedHosts '192.168.1.1,192.168.1.2'
Set-Item WSMan:\localhost\Client\TrustedHosts *.contoso.com
Set-Item WSMan:\localhost\Client\TrustedHosts *
重要 :接続する方法でアドレス指定されたコンピュータを信頼するようにクライアントに指示する必要があります(たとえば、IP経由で接続する場合は、ホスト名ではなくIPを信頼する必要があります)
PowerShell経由でリモートサーバーに接続する
ローカルコンピュータの資格情報を使用する:
Enter-PSSession 192.168.1.1
リモートコンピュータでの資格情報の入力を求めるプロンプト
Enter-PSSession 192.168.1.1 -Credential $(Get-Credential)
リモートコンピュータでコマンドを実行する
Powershellリモーティングが有効になったら(Enable-PSRemoting)リモートコンピュータで次のようにコマンドを実行できます。
Invoke-Command -ComputerName "RemoteComputerName" -ScriptBlock {
Write host "Remote Computer Name: $ENV:ComputerName"
}
上記のメソッドは、一時セッションを作成し、コマンドまたはスクリプトブロックが終了した直後にそれを閉じます。
セッションを開いたままにしておき、後で他のコマンドを実行するには、まずリモートセッションを作成する必要があります。
$Session = New-PSSession -ComputerName "RemoteComputerName"
次に、リモートコンピュータでコマンドを呼び出すたびに、このセッションを使用できます。
Invoke-Command -Session $Session -ScriptBlock {
Write host "Remote Computer Name: $ENV:ComputerName"
}
Invoke-Command -Session $Session -ScriptBlock {
Get-Date
}
異なる資格情報を使用する必要がある場合は、 -Credential
パラメータを使用して追加することができます。
$Cred = Get-Credential
Invoke-Command -Session $Session -Credential $Cred -ScriptBlock {...}
リモーティングシリアル化の警告
注意:
リモーティングは、リモートシステム上のPowerShellオブジェクトをシリアル化し、リモートセッションの終了時にそれらを逆シリアル化します。つまり、トランスポート中にXMLに変換され、すべてのメソッドが失われます。
$output = Invoke-Command -Session $Session -ScriptBlock {
Get-WmiObject -Class win32_printer
}
$output | Get-Member -MemberType Method
TypeName: Deserialized.System.Management.ManagementObject#root\cimv2\Win32_Printer
Name MemberType Definition
---- ---------- ----------
GetType Method type GetType()
ToString Method string ToString(), string ToString(string format, System.IFormatProvi...
通常のPSオブジェクトのメソッドはありますが、
Get-WmiObject -Class win32_printer | Get-Member -MemberType Method
TypeName: System.Management.ManagementObject#root\cimv2\Win32_Printer
Name MemberType Definition
---- ---------- ----------
CancelAllJobs Method System.Management.ManagementBaseObject CancelAllJobs()
GetSecurityDescriptor Method System.Management.ManagementBaseObject GetSecurityDescriptor()
Pause Method System.Management.ManagementBaseObject Pause()
PrintTestPage Method System.Management.ManagementBaseObject PrintTestPage()
RenamePrinter Method System.Management.ManagementBaseObject RenamePrinter(System.String NewPrinterName)
Reset Method System.Management.ManagementBaseObject Reset()
Resume Method System.Management.ManagementBaseObject Resume()
SetDefaultPrinter Method System.Management.ManagementBaseObject SetDefaultPrinter()
SetPowerState Method System.Management.ManagementBaseObject SetPowerState(System.UInt16 PowerState, System.String Time)
SetSecurityDescriptor Method System.Management.ManagementBaseObject SetSecurityDescriptor(System.Management.ManagementObject#Win32_SecurityDescriptor Descriptor)
引数の使用法
引数をリモートスクリプティングブロックのパラメータとして使用するには、 Invoke-Command
ArgumentList
パラメータを使用するか、 $Using:
構文$Using:
ます。
名前のないパラメータ(Scriptblockに渡された順序)でArgumentList
を使う:
$servicesToShow = "service1"
$fileName = "C:\temp\servicestatus.csv"
Invoke-Command -Session $session -ArgumentList $servicesToShow,$fileName -ScriptBlock {
Write-Host "Calling script block remotely with $($Args.Count)"
Get-Service -Name $args[0]
Remove-Item -Path $args[1] -ErrorAction SilentlyContinue -Force
}
名前付きパラメータでのArgumentList
使用:
$servicesToShow = "service1"
$fileName = "C:\temp\servicestatus.csv"
Invoke-Command -Session $session -ArgumentList $servicesToShow,$fileName -ScriptBlock {
Param($serviceToShowInRemoteSession,$fileToDelete)
Write-Host "Calling script block remotely with $($Args.Count)"
Get-Service -Name $serviceToShowInRemoteSession
Remove-Item -Path $fileToDelete -ErrorAction SilentlyContinue -Force
}
$Using:
構文:
$servicesToShow = "service1"
$fileName = "C:\temp\servicestatus.csv"
Invoke-Command -Session $session -ScriptBlock {
Get-Service $Using:servicesToShow
Remove-Item -Path $fileName -ErrorAction SilentlyContinue -Force
}
PSSessionsを自動的にクリーンアップするためのベストプラクティス
New-PSsession
コマンドレットを使用してリモートセッションを作成すると、現在のPowerShellセッションが終了するまでPSSessionが保持されます。 PSSession
と関連するすべてのリソースは、現在のPowerShellセッションが終了するまで、引き続き使用されることを意味します。
複数のアクティブなPSSessions
は、特に1つのPowerShellセッションで数百のPSSessions
を作成する長時間実行または相互リンクされたスクリプトの場合、リソースのPSSessions
になります。
各PSSession
が使用終了後に明示的に削除することをおPSSession
します。 [1]
次のコードテンプレートは、上記の目的を達成するためにtry-catch-finally
しています。エラー処理と安全な方法を組み合わせて、作成されたPSSessions
が使用終了時にすべて削除されるようにします。
try
{
$session = New-PSsession -Computername "RemoteMachineName"
Invoke-Command -Session $session -ScriptBlock {write-host "This is running on $ENV:ComputerName"}
}
catch
{
Write-Output "ERROR: $_"
}
finally
{
if ($session)
{
Remove-PSSession $session
}
}
参考文献:[1] https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/new-pssession