PowerShellを使用して、リモートホストで多くの機能を実行して情報を収集する予定です。
リモートホストの名前としてパラメータを指定してgetcontentfileという関数を実行するだけで、ファイルのコンテンツをリモートで取得する例を次に示します。
function getcontentfile
{
[CmdletBinding()]
param($hostname)
$info = Get-Content "C:\fileinfo.xml"
write-Host $info
}
この関数は、リモートホストに関する情報をPowerShellのローカルインスタンスに返す必要があります。このスクリプトを変更してそれを行うにはどうすればよいですか?
最初に、情報を返すためにWrite-Host
を使用しないでください(これは、両方の色とのみがインタラクティブに動作することを本当に望んでいない限り、常にtrueです)ローカルで)。
出力を関数の戻り値にします。
function getcontentfile
{
[CmdletBinding()]
param($hostname)
$info = Get-Content "C:\fileinfo.xml"
$info
}
次に、ターゲットシステムでPSHリモート処理を有効にします。Enable-PSRemoting
の- help を参照してください。
3番目に、コマンドをリモートで実行します。
Invoke-Command -computer comp1,comp2 -ScriptBlock { Get-Content "C:\fileinfo.xml" }
これにより、2台のコンピューター上のファイルの内容が返され、結果を分離して-AsJob
を追加すると、Job
コマンドレットで個別にクエリできるジョブオブジェクトが返されます(gcm -noun job
for forリスト、Receive-Job
をメモして、ジョブの結果を取得します)。
リモートマシンでローカルにロードされた関数を実行できます。
Invoke-Command -ComputerName Comp1 -cred $cred -ScriptBlock ${function:get-contentfile } -argumentlist "ParameterA", "ParameterB"
最初のオプションは Powershell 2.0 Remoting を有効にすることです。
個人的には、パワフルではありますが、リモート処理にはあまり興味がなかったので、WMIを使用するスクリプトを作成し、cmd.exeでプロセスを作成してから、stdoutとstderrをログファイルにパイプして、それを読み取れるようにしました。
スクリプトはログファイルをリモートコンピューターに残します。そのため、単純にget-content \\remotecomputer\c$\remoteExec.log
で読み取ることができます。
<#
.SYNOPSIS
Remotely executes a command and logs the stdout and stderr to a file on the
remote computer.
.DESCRIPTION
This script accepts three parameters (one optional) and executes a program on
a remote computer. It will verify connectivity and optionally (verifyPath) the
existence of the program to be executed. If either verifications fail, it will
not attempt to create the process on the remote computer.
.EXAMPLE
.\remoteExec.ps1 -program "dir" -args "c:\" -computerName "SEANC"
.EXAMPLE
.\remoteExec "C:\Windows\SysWOW64\msiexec.exe" "/i c:\a.msi /passive /log c:\a-install.log" SEANC C:\Windows\Temp\remote.log -verifyPath
.PARAMETER computerName
The name of the computer on which to create the process.
.PARAMETER program
The command to run on the remote computer.
.PARAMETER args
The command arguments.
.PARAMETER log
The file to which the stderr and stdout generated by the command will be redirected.
This is a local path on the remote computer.
.PARAMETER verifyPath
Switch to enforce path verification.
#>
param(
[parameter(Mandatory=$true)] [string]$program,
[parameter(Mandatory=$false)][string]$args = "",
[parameter(Mandatory=$true)] [string]$computerName,
[parameter(Mandatory=$false)][string]$log = "C:\remoteExec.log",
[parameter(Mandatory=$false)][switch]$verifyPath = $false
)
if (-not (Test-Connection $computerName -Quiet -Count 1))
{
return Write-Error "Unable to connect to $computerName."
}
if ($verifyPath -and (-not (Test-Path \\$computerName\$($program.replace(":","$")) -PathType Leaf))) {
return Write-Error "Path $program does not exist on $computerName."
}
try {
$remoteWmiProcess = [wmiclass]"\\$computerName\root\cimv2:win32_process"
$remoteProcess = $remoteWmiProcess.create(
"cmd.exe /c `"$program $args > $log 2>&1`""
)
} catch {
return Write-Error ("Unable to create process through WMI.");
}
if ($remoteProcess.returnValue -ne 0) {
return Write-Error ("FAILED on $computerName with return code: " + $remoteProcess.returnValue)
} else {
return ("Successful trigger on $computerName; returned: " + $remoteProcess.returnValue)
}
EDIT:この例では、スクリプトはremoteExec.ps1と呼ばれ、それを使用してリモートPowerShellプロセスを作成し、コマンド(askerとはしようとする):
.\remoteExec.ps1 -program "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -verifyPath -computerName "computer1" -args "-command Get-ChildItem C:\"
次に、次のコマンドでログを読み取ることができます。
Get-Content \\computer1\C$\remoteExec.log
簡単に言えば、それはできません。
通常、Invoke-Command
を使用して、リモートコンピューターでコマンドを実行します。このコマンドは、スクリプトブロックまたはPowerShellスクリプトにすることができます。これらのアプローチはどちらも、ローカルコンピューターに存在する変数や関数に到達して使用することはできません。つまり、事前に関数を読み込んでリモートコンピューターでアクセスできるようにすることはできません。
あなたがしなければならないことは、リモートコンピュータにそれらを取得し、そこからロードすることです。共通の共有を作成し、PowerShellスクリプトをその共有に展開します。