1

リモートマシン上にあるPS1スクリプトを、C#ランスペースを介して別のリモートマシンに対して実行できるようにする必要があります。

これが何を意味するのかを明確にするために:私が作成しているサービスはサーバーAにあります。それは以下の方法を使用してサーバーBへのリモートランスペースを作成します。ランスペースを介して、サーバーCにあるスクリプトをサーバーBに対して呼び出そうとしています。それが役立つ場合は、現在サーバーAはサーバーCですが、常にそうであるとは限りません。

リモート呼び出しを行うために使用しているメソッドは次のとおりです。

internal Collection<PSObject> RunRemoteScript(string remoteScript, string remoteServer, string scriptName, out bool scriptSuccessful)
    {
        bool isLocal = (remoteServer == "localhost" || remoteServer == "127.0.0.1" || remoteServer == Environment.MachineName);

        WSManConnectionInfo connectionInfo = null;

        if (!isLocal)
        {
            connectionInfo = new WSManConnectionInfo(new Uri("http://" + remoteServer + ":5985"));
        }

        PsHostImplementation myHost = new PsHostImplementation(scriptName);

        using (Runspace remoteRunspace = (isLocal ? RunspaceFactory.CreateRunspace(myHost) : RunspaceFactory.CreateRunspace(myHost, connectionInfo)))
        {
            remoteRunspace.Open();
            using (PowerShell powershell = PowerShell.Create())
            {
                powershell.Runspace = remoteRunspace;

                Pipeline pipeline = remoteRunspace.CreatePipeline();

                pipeline.Commands.AddScript(remoteScript);

                Collection<PSObject> results = pipeline.Invoke();

                remoteRunspace.Close();

                scriptSuccessful = myHost.ScriptSuccessful;
                return results;
            }
        }
    }

「remoteScript」は、実行したいPowershellスクリプトに設定されています。例えば:

"& \"\\\\remoteserveraddress\\PathToScript\\Install.ps1\" -Parameter;Import-Module Modulename;CustomCommand-FromModule -parameter(s) -ErrorAction stop"

スクリプトを実行するリモートマシンを使用している場合は、PowerShellコンソールで次のコマンドを実行できます。

& "\\remoteserverC\PathToScript\Install.ps1" -Parameter

ただし、c#ランスペースを介して実行しようとすると、これは単に機能しません。

「remoteScript」へのパラメータとして以下を送信すると、次のようになります。

"& \"\\\\remoteserverC\\PathToScript\\Install.ps1\" -Parameter"

次のエラーが発生します。

'\ remoteserverC \ PathToScript \ Install.ps1'という用語は、コマンドレット、関数、スクリプトファイル、または操作可能なプログラムの名前として認識されません。名前のスペルを確認するか、パスが含まれている場合は、パスが正しいことを確認して、再試行してください。

'&'を使用した場合と使用しない場合、およびパラメーターを使用した場合と使用しない場合を試しました。「\\remoteserver\ ... \ Install.ps1」ではなく、リモートマシン「c:\ ... \ Install.ps1」に直接存在するスクリプトをすでに呼び出すことができますが、できることは非常に有益です。リモートスクリプトを直接呼び出す。

私はグーグルとここスタックオーバーフローで多くのページを検索しましたが、この問題を克服するのに役立つものを見つけることができませんでした。どんな助けでもいただければ幸いです!ありがとう!

4

1 に答える 1

2

私はこれを直接機能させることは決してなく、リモートで作業しているときにUNCアドレスを使用して3台目のマシンにアクセスできないセキュリティの「機能」のようです。ただし、自分にとってうまく機能する回避策を見つけることができました。

\\ server \ shareアドレスに直接呼び出そうとする代わりに、スクリプトを実行しようとしているマシンのネットワークドライブを、スクリプトがあるマシンの共有に動的にマップします。(Aからリモートで実行し、BのドライブをCの共有にマップします)。次に、そのドライブを介してスクリプトを呼び出します。これは魅力のように機能します。この文字列は、上記のRunRemoteScriptメソッドに渡すものです。

"$net = new-object -ComObject WScript.Network;" +
"if(!($net.EnumNetworkDrives() -contains \"S:\"))" +
    "{Write-Host \"S: Drive Not Currently Mapped. Mapping to \\\\" + RemoteServerC + "\\Share.\";" +
    "$net.MapNetWorkDrive(\"S:\",\"\\\\" + RemoteServerC + "\\Share\",$false,\"username\",\"password\")};" +
"Get-PSDrive | Write-Verbose;" +
"& \"S:\\PathToScript\\Install.ps1\" -noPrompt;"

RemoteServerCは、ユーザー構成ファイルで定義されている、私が渡す変数です。

これは、誰かが必要とする場合のPowerShellスクリプトと同じコードです(RemoteServerCを、前に設定する必要のあるPowerShell変数、またはハードコードに置き換えます。

$net = new-object -ComObject WScript.Network
if(!($net.EnumNetworkDrives() -contains "S:"))
{  Write-Host "S: Drive Not Currently Mapped. Mapping to \\remoteserverC\Share."
   $net.MapNetWorkDrive("S:","\\remoteserverC\Share",$false,"username","password")
}
Get-PSDrive | Write-Verbose
& "S:\\PathToScript\\Install.ps1\" -noPrompt;"

まず、ドライブをマップできるようにオブジェクトを設定しました。次に、リモートマシンに「s」ドライブがすでにマップされているかどうかを確認します。そうでない場合は、このサービスを実行するためにActive Directoryに設定した名前とパスワードを使用して、共有をリモートマシンの「s」ドライブにマップします。

使用可能なドライブのリストをPowerShellに再ロードさせるように見えるため、Get-PSDriveコマンドを含めました。これは、PowerShellセッションでこれを初めて実行しようとしたときにのみ問題になるようです(C Sharpを使用すると、本当に必要かどうかはわかりませんが、安全のために含めました)。どうやら、Powershellは、MapNetworkDriveを使用している場合、作成されたのと同じセッションでドライブの追加を認識しません。

于 2012-04-03T17:58:32.990 に答える