web-dev-qa-db-ja.com

PowerShell関数をリモートで実行するにはどうすればよいですか?

PowerShellを使用して、リモートホストで多くの機能を実行して情報を収集する予定です。

リモートホストの名前としてパラメータを指定してgetcontentfileという関数を実行するだけで、ファイルのコンテンツをリモートで取得する例を次に示します。

function getcontentfile 
{
    [CmdletBinding()]
    param($hostname)
    $info = Get-Content "C:\fileinfo.xml"
    write-Host $info
}

この関数は、リモートホストに関する情報をPowerShellのローカルインスタンスに返す必要があります。このスクリプトを変更してそれを行うにはどうすればよいですか?

7
Aimar

最初に、情報を返すために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をメモして、ジョブの結果を取得します)。

4
Richard

リモートマシンでローカルにロードされた関数を実行できます。

Invoke-Command -ComputerName Comp1 -cred $cred -ScriptBlock ${function:get-contentfile } -argumentlist "ParameterA", "ParameterB"
4
icnivad

最初のオプションは 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

3
Sean C.

簡単に言えば、それはできません。

通常、Invoke-Commandを使用して、リモートコンピューターでコマンドを実行します。このコマンドは、スクリプトブロックまたはPowerShellスクリプトにすることができます。これらのアプローチはどちらも、ローカルコンピューターに存在する変数や関数に到達して使用することはできません。つまり、事前に関数を読み込んでリモートコンピューターでアクセスできるようにすることはできません。

あなたがしなければならないことは、リモートコンピュータにそれらを取得し、そこからロードすることです。共通の共有を作成し、PowerShellスクリプトをその共有に展開します。

0
splattered bits