# Copy-Item -ToSession but with C#

**URL:** <https://forums.powershell.org/t/copy-item-tosession-but-with-c/9831>\
**Category:** PowerShell Help\
**Created:** [December 8, 2017, 2:59pm UTC](https://forums.powershell.org/t/copy-item-tosession-but-with-c/9831 "2017-12-08T14:59:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jmathews](https://avatars.discourse-cdn.com/v4/letter/j/cdc98d/32.png) [@jmathews](https://forums.powershell.org/u/jmathews)\
**Post date:** [December 8, 2017, 2:59pm UTC](https://forums.powershell.org/t/copy-item-tosession-but-with-c/9831/1 "2017-12-08T14:59:29Z")

</div>

Hi all,

I’m looking to use C# to accomplish what Copy-Item with the -ToSession parameter does. PowerShell is my tool of choice but in this context I’m attempting to replace C# code that uses ftp to transfer a file. I’d like to basically call the Copy-Item command and pass it a PSSession object. I have 95% of this working and have managed to copy the file locally, but have hit a road block with the PSSession. I can’t seem to create one of type System.Management.Automation.Runspaces.PSSession. I’ve tried everything I have been able to find on the old interwebs but still can’t seem to get it to work. Below is a snippet of code and if anyone out there has done this, some help would be greatly appreciated.

Thanks,  
Justin

```
//Create a PowerShell object and load the New-PSSession command
PowerShell pshsession = PowerShell.Create();
pshsession.AddCommand("New-PSSession");
pshsession.AddParameter("ComputerName", computer);
pshsession.AddParameter("Credential", cred);

//Create a second PowerShell object and load the Copy-Item command
PowerShell localpsh = PowerShell.Create();
localpsh.AddCommand("Copy-Item");
localpsh.AddParameter("Path", "C:\\temp\\todo.txt");
localpsh.AddParameter("Destination", "C:\\temp\\todo.txt");
//The idea here is to create the PSSession as the parameter is called. I was hoping this would force it to type PSSession
//but it hasn't worked. I've also tried to implicitly convert it but I get an exception that it can't do that.
localpsh.AddParameter("ToSession", pshsession.Invoke());
localpsh.AddParameter("Force", true);
localpsh.Invoke();
```

---

<div class="post-metadata">

**Author:** ![donj](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/donj/32/137_2.png) [@donj](https://forums.powershell.org/u/donj)\
**Post date:** [December 12, 2017, 9:55am UTC](https://forums.powershell.org/t/copy-item-tosession-but-with-c/9831/2 "2017-12-12T09:55:35Z")

</div>

I hate to do this, but I think you’ve kind of exceeded this community’s purpose ;). We don’t get a lot of C# coders here.

My guess is that you can’t “copy” a PSSession object between PowerShell engines - that would require a level of marshaling that I suspect doesn’t exist. When we do this in the shell, we’re doing it inside a single engine, and persisting (usually) the PSSession in a variable within that engine’s VARIABLE: drive. That’s a lot harder to gin up in your own host.

---

<div class="post-metadata">

**Author:** ![jmathews](https://avatars.discourse-cdn.com/v4/letter/j/cdc98d/32.png) [@jmathews](https://forums.powershell.org/u/jmathews)\
**Post date:** [December 12, 2017, 10:35am UTC](https://forums.powershell.org/t/copy-item-tosession-but-with-c/9831/3 "2017-12-12T10:35:12Z")

</div>

Thanks for reply Don. I actually figured out a way to do this yesterday and if anyone is interested in it I’ve posted the code below. Now, I totally agree that this is way easier and should be done in PowerShell. For this case I ran into a problem that we wanted to solve with PowerShell but we already had a C# program that handled the “legacy” version of it along with a bunch of other stuff. I could have called a PS script that did it all but our first option was to have C# code that did the job for us. And I passes this of to a C# developer so if it looks terrible, then it probably is but he should be able to clean it up 🙂

-Justin

```
// Username and Password for the remote machine.
var userName = "DOMAIN\\USERNAME";
string pw = "MYSECRETPWASPLAINTEXT";

// Path to the files are to be copied
string path = "C:\\temp\\stuff.txt";

// Path on the remote machine where the files need to be placed
string destination = "C:\\temp\\mystuff.txt";

//ComputerName
string computerName = "REMOTESERVER"

// Creates a secure string for the password
SecureString securePassword = new SecureString();
foreach (char c in pw)
{
    securePassword.AppendChar(c);
}
securePassword.MakeReadOnly();

// Creates a PSCredential object
PSCredential creds = new PSCredential(userName, securePassword);

// Creates the runspace for PowerShell
Runspace runspace = RunspaceFactory.CreateRunspace();

// Create the PSSession connection to the remote machine.
PowerShell powershell = PowerShell.Create();
PSCommand command = new PSCommand();
command.AddCommand("New-PSSession");
command.AddParameter("ComputerName", computerName);
command.AddParameter("Credential", creds);
powershell.Commands = command;
runspace.Open(); powershell.Runspace = runspace;
Collection result = powershell.Invoke();

// Takes the PSSession object and places it into a PowerShell variable
powershell = PowerShell.Create();
command = new PSCommand();
command.AddCommand("Set-Variable");
command.AddParameter("Name", "ra");
command.AddParameter("Value", result[0]);
powershell.Commands = command;
powershell.Runspace = runspace;
powershell.Invoke();

// Calls the Copy-Item cmdlet as a script and passes the PSSession, Path and destination parameters to it
powershell = PowerShell.Create();
command = new PSCommand();
command.AddScript("Copy-Item -Path " + path + " -Destination " + destination + " -ToSession $ra");
powershell.Commands = command;
powershell.Runspace = runspace;
powershell.Invoke();
```

---

<div class="post-metadata">

**Author:** ![donj](https://sea1.discourse-cdn.com/flex019/user_avatar/forums.powershell.org/donj/32/137_2.png) [@donj](https://forums.powershell.org/u/donj)\
**Post date:** [December 12, 2017, 10:36am UTC](https://forums.powershell.org/t/copy-item-tosession-but-with-c/9831/4 "2017-12-12T10:36:31Z")

</div>

Another option would be to refactor the legacy C# code into a PowerShell cmdlet, which is pretty trivial in terms of work, usually. Then you’ve got a compiled module you can just load directly into the shell. Thanks for sharing the solution code!

---

<div class="post-metadata">

**Author:** ![dotnVo](https://avatars.discourse-cdn.com/v4/letter/d/4af34b/32.png) [@dotnVo](https://forums.powershell.org/u/dotnVo)\
**Post date:** [May 16, 2024, 8:37pm UTC](https://forums.powershell.org/t/copy-item-tosession-but-with-c/9831/5 "2024-05-16T20:37:02Z")

</div>


