7

I tried running a script localwindows.ps1 from C# using the following Code :

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();
}

                  

But getting exception :'The term 'C:\localwindows.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program.

So I tried the following :

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();
       
     }

I am getting the error : "Cannot find path 'C:\localwindows.ps1' because it does not exist."

But using command 'Invoke-Command -ComputerName "machineName" -filepath C:\localwindows.ps1' ,from powershell in local machine created a new account in the remote machine.

How to call the script localwindows.ps1 from C#? How to execute the command 'Invoke-Command -ComputerName "machineName" -filepath C:\localwindows.ps1' through C#?

The script localwindows.ps1 is

$comp = [adsi]“WinNT://machinename,computer”
$user = $comp.Create(“User”, "account3")
$user.SetPassword(“change,password.10")
$user.SetInfo()
whytheq
  • 34,466
  • 65
  • 172
  • 267
cmm user
  • 2,426
  • 7
  • 34
  • 48

2 Answers2

4

Actually your invocation style should work. But in both of your examples, the script c:\localwindows.ps1 must reside on the local computer. In the Invoke-Command case, it will be copied from the local computer to the remote computer.

If, in the Invoke-Command case, the script already exists on the remote computer and you don't need to copy it over, remove the FilePath parameter and add this:

new1.AddParameter("Scriptblock", ScriptBlock.Create(file));
Keith Hill
  • 194,368
  • 42
  • 353
  • 369
  • I tried the case pipeline.Commands.AddScript(System.IO.File.ReadAllText(file));. I am getting the error : 'Unexpected token '�WinNT://machineName�' in expression or statement.' Whereas the same script creates a local user account using with invoke-command. I tried the solution - pipeline.Commands.AddScript(System.IO.File.ReadAllText(". " + file)); The program was not able to locate the file. – cmm user Nov 25 '13 at 18:10
  • I tried - new1.AddParameter("Scriptblock", "{. " + file + "}"); I am getting the error - 'Cannot bind parameter 'ScriptBlock'. Cannot convert the "{ C:\localwindows.ps1}" value of type "System.String" to type "System.Management.Automation.ScriptBlock".' – cmm user Nov 25 '13 at 18:10
  • See the updated answer. I believe the crux of your problem is that the script is not on your local computer at the `c:\localwindows.ps1`. – Keith Hill Nov 25 '13 at 20:36
  • I used the command -'new1.AddParameter("Scriptblock", ScriptBlock.Create(file));'. I am still getting the following error - 'Cannot bind parameter 'ScriptBlock'. Cannot convert the "C:\localwindows.ps1" value of type "System.String" to type "System.Management.Automation.ScriptBlock".' – cmm user Nov 26 '13 at 05:21
  • The script C:\localwindows.ps1 is in my local machine. But still I get the error 'Unexpected token '�WinNT://machineName�'. I have added the script block to the content. – cmm user Nov 26 '13 at 05:24
  • 3
    Using the command - pipeline.Commands.AddScript(System.IO.File.ReadAllText(file)); - it worked fine. The issue was with script. I used single quotes instead of double quotes and it worked. – cmm user Nov 26 '13 at 05:43
  • such tiny annoying errors, consume so much time and confidence >_ – Awesome_girl Mar 22 '15 at 16:14
0

I've got an article that describes an easy way to run Powershell through WinRM from .NET at http://getthinktank.com/2015/06/22/naos-winrm-windows-remote-management-through-net/.

The code is in a single file if you want to just copy it and it's also a NuGet package that includes the reference to System.Management.Automation.

It auto manages trusted hosts, can run script blocks, and also send files (which isn't really supported but I created a work around). The returns are always the raw objects from 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);

Please mark as answer if this helps. I've been using this for a while with my automated deployments. Please leave comments if you find issues.

wlscaudill
  • 505
  • 4
  • 6