1

C# WinForm から呼び出せるようにしたいリモート処理を利用する一連の完全に機能する powershell スクリプトがあります。ここに私がこれまでに持っているコードがあります

    private void button1_Click(object sender, EventArgs e)
    {
        _runspace = RunspaceFactory.CreateRunspace();
        _runspace.Open();
        _ps = PowerShell.Create();

        _ps.Runspace = _runspace;

        var output = new PSDataCollection<PSObject>();
        output.DataAdded += DataAdded;

        _ps.AddScript(@"C:\projects\Acme\trunk\PowerShell\deploy-qa-p5.ps1");
        _invokeResult = _ps.BeginInvoke<PSObject, PSObject>(null, output);

    }

このコードを実行すると、リモート セッションに対して実行することを意図したスクリプト内のすべての powershell コマンドが、実際にはローカル PC で実行されていることがわかります。

たとえば、このコードを Powershell.exe から直接実行すると、リモート サーバーからアプリケーションがアンインストールされます。上記の C# コードから実行すると、この同じコードがローカル マシン上のアプリケーションをアンインストールします。

Invoke-Command -Session $remoteSession -scriptblock $uninstallScript -ArgumentList $applicationGuid

ここでも、C# コードで参照されているまったく同じ PS スクリプトを powershell.exe から直接実行すると、リモート サーバーに対して期待どおりに動作します。

グーグルで、C# からリモート実行空間を作成する方法を見つけました。ただし、その場合、PS スクリプトを大幅にリファクタリングして、C# に移動するリモート コードを引き出す必要があります。PS スクリプトをスタンドアロン モードで (つまり、powershell.exe から直接) 実行できるようにする必要があるため、これは実行可能なソリューションではありません。

PSスクリプトを再調整する必要のないこの問題の解決策を誰か提案できますか?

4

1 に答える 1

-1

オブジェクトを作成するときは、リモートrunspacenを作成するためRunspaceにオブジェクトを渡す必要があります。WSManConnectionInfoこのMSDNの記事には、これを行う方法の詳細が記載されています。このトピックの例とは異なり、リモーティングエンドポイントを指定できるパラメーターを受け取るWSManConnectionInfoコンストラクターを使用するようにしてください。

_runspace = RunspaceFactory.CreateRunspace("http://ComputerName:5985/wsman");

申し訳ありませんが、質問を読み間違えました。たまたまリモーティングを実行するスクリプトを呼び出すと、PowerShellコンソールから呼び出す場合と同じように機能するはずです。次のわずかに変更されたバージョンは、自宅のワークグループで問題なく機能します。

private void button1_Click(object sender, EventArgs e)
{
    _runspace = RunspaceFactory.CreateRunspace();
    _runspace.Open();
    _ps = PowerShell.Create();

    _ps.Runspace = _runspace;

    var output = new PSDataCollection<PSObject>();
    //output.DataAdded += DataAdded;

    var netCreds = new System.Net.NetworkCredential("Keith", Settings.Default.Password);
    var creds = new PSCredential(netCreds.UserName, netCreds.SecurePassword);

    _ps.AddScript("param($creds) Invoke-Command -cn Kids-PC -Scriptblock {hostname} -Credential $creds").AddArgument(creds);
    _invokeResult = _ps.BeginInvoke<PSObject, PSObject>(null, output);
    _invokeResult.AsyncWaitHandle.WaitOne();
    _ps.EndInvoke(_invokeResult);
    textBox1.Text = output[0].ToString();
}

ところで、なぜDataAddedスクリプトの出力コレクションに追加したのかわかりませんか?私はそれをコメントアウトしました。また、ドメインではなくワークグループに所属しているため、資格情報を渡す必要があります。

これをデバッグするには、失敗したときにデバッガーの_ps.Streams.Errorオブジェクトを確認します。一番下までスクロールして開きResults Viewます。

于 2012-09-03T16:44:24.047 に答える