web-dev-qa-db-ja.com

C#からPowerShellスクリプトファイル(example.ps1)を呼び出すには

次のコードを使用して、C#からスクリプトlocalwindows.ps1を実行してみました。

               PSCredential credential = new PSCredential(userName, securePassword);
                WSManConnectionInfo connectionInfo = new WSManConnectionInfo(false, "machineName", 5985, "/wsman", shellUri, credential);
                using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
                {

                    runspace.Open();
                    String file = "C:\\localwindows.ps1";
                    Pipeline pipeline = runspace.CreatePipeline();
                    pipeline.Commands.AddScript(file);
                    pipeline.Commands.Add("Out-String");
                    Collection<PSObject> results = pipeline.Invoke();
                }

ただし、例外が発生します: '用語' C:\ localwindows.ps1 'は、コマンドレット、関数、スクリプトファイル、または操作可能なプログラムの名前として認識されません。

だから私は以下を試しました:

PSCredential credential = new PSCredential(userName, securePassword);
WSManConnectionInfo connectionInfo = new WSManConnectionInfo(false, "machineName", 5985, "/wsman", shellUri, credential);
using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
{

    runspace.Open();

    using (PowerShell powershell = PowerShell.Create())
    {
        powershell.Runspace = runspace;           

        PSCommand new1 = new PSCommand();
        String machinename = "machinename";
        String file = "C:\\localwindows.ps1";
        new1.AddCommand("Invoke-Command");
        new1.AddParameter("computername", machinename);
        new1.AddParameter("filepath", file);         


        powershell.Commands = new1;
        Console.WriteLine(powershell.Commands.ToString());
        Collection<PSObject> results = powershell.Invoke();

     }

「パス 'C:\ localwindows.ps1'が存在しないため、見つかりません。」というエラーが表示されます。

ただし、ローカルマシンのPowerShellからコマンド 'Invoke-Command -ComputerName "machineName" -filepath C:\ localwindows.ps1'を使用すると、リモートマシンに新しいアカウントが作成されます。

C#からスクリプトlocalwindows.ps1を呼び出す方法は?コマンド 'Invoke-Command -ComputerName "machineName" -filepath C:\ localwindows.ps1'をC#で実行する方法は?

スクリプトlocalwindows.ps1は

$comp = [adsi]“WinNT://machinename,computer”
$user = $comp.Create(“User”, "account3")
$user.SetPassword(“change,password.10")
$user.SetInfo()
7
cmm user

実際には、呼び出しスタイルは機能するはずです。しかし、どちらの例でも、スクリプトc:\localwindows.ps1ローカルコンピュータに存在する必要があります。 Invoke-Commandの場合、ローカルコンピューターからリモートコンピューターにコピーされます。

Invoke-Commandの場合、スクリプトがリモートコンピューターに既に存在し、スクリプトをコピーする必要がない場合は、FilePathパラメーターを削除して次を追加します。

new1.AddParameter("Scriptblock", ScriptBlock.Create(file));
4
Keith Hill

.NETからWinRMを介してPowershellを実行する簡単な方法を説明する記事があります http://getthinktank.com/2015/06/22/naos-winrm-windows-remote-management-through- net /

コードをコピーするだけの場合は、コードは1つのファイルに含まれています。また、System.Management.Automationへの参照を含むNuGetパッケージでもあります。

信頼できるホストを自動管理し、スクリプトブロックを実行し、ファイルを送信することもできます(これは実際にはサポートされていませんが、回避策を作成しました)。戻り値は常にPowershellからの生のオブジェクトです。

// this is the entrypoint to interact with the system (interfaced for testing).
var machineManager = new MachineManager(
    "10.0.0.1",
    "Administrator",
    MachineManager.ConvertStringToSecureString("xxx"),
    true);

// for your specific issue I think this would be easier
var results = machineManager.RunScript(
    File.ReadAllText("C:\\LocalWindows.ps1"));

// will perform a user initiated reboot.
machineManager.Reboot();

// can run random script blocks WITH parameters.
var fileObjects = machineManager.RunScript(
    "{ param($path) ls $path }",
    new[] { @"C:\PathToList" });

// can transfer files to the remote server (over WinRM's protocol!).
var localFilePath = @"D:\Temp\BigFileLocal.nupkg";
var fileBytes = File.ReadAllBytes(localFilePath);
var remoteFilePath = @"D:\Temp\BigFileRemote.nupkg";
machineManager.SendFile(remoteFilePath, fileBytes);

これが役立つ場合は、回答としてマークしてください。自動化されたデプロイメントでこれをしばらく使用しています。問題を見つけたらコメントを残してください。

0
wlscaudill