Copying files to and from remote sessions

Those of you running Windows 10 or Server vNext (I’ve yet check WMF 5.0 RTM on other operating systems after it was pulled by Microsoft from DownloadCenter), may have missed the inclusion of new parameters for Copy-Item, which allow to copying of files to a remote session and from a remote session. These are names ToSession and FromSession respectively.

Oddly, Microsoft do not appear to have updated their help to provide information on this. You’ll only notice it if you use Get-Command or alternatively tab through Copy-Item.

What’s nice is that PowerShell 5 is not required to be installed on the system for which we have created a remote session.

Usage is simply a case of providing a valid value of PSSession type to the ToSession or FromSession parameters, in addition to your standard Path and Destination parameters.

Examples are below :

Copy Remote Sessions

Unfortunately at present, FromSession and ToSession are mutually exclusive, preventing the possibility of being able to directly copy from one remote session to another.


Using Local Functions on Remote Computers

30/12/2015 – UPDATE : Scriptblock code changed to better llustrate use of multiple local functions used in combination with other code on the remote system, after feedback from Aleksandar Nikolić &  Tommy Maynard. Thanks guys. 🙂

I came across a situation recently where I needed my remote computers to use some functions that were part of a project I was working on. I wanted to use them in various parts of a scriptblock passed from Invoke-Command. Options with Invoke-Command did not allow for this though. You have the mutial exclusive -file and -scriptblock  parameters.

I prefer to keep my functions as separate files as opposed to their inclusion in a module.Loaded functions are stored within the FUNCTION PowerShell provider, and because of this, cmdlets such as Get-ChildItem can be used with them.

I noticed the Name property of items in FUNCTION: always have the name of the function, and the Definition property the actual code.  To convert this to the exact text of the function as we normally see it, should just require some string concatentation  All we were missing was the word Function, and surrounding braces to create a string equivalent of the function. We’d also add new line characters as well for formatting purposes.

This could be done using the format:

Function {`r`n item.definition `r`n}`r`n

This is the function developed below:

function Get-FunctionString
[Parameter(Mandatory = $true)][System.Array] $Function

[string]$strFunctions = $null
$items = Get-ChildItem Function:\ | Where Name -in $Function

ForEach ($item in $items)
$strFunctions += "Function $($item.Name) { `r`n $($item.Definition) `r`n }`r`n"



It takes as a parameter an array, which is filtered against items provided by the Function PowerShell provider.  Then, the function text itself is comprised and concatenated to a string variable, $strFunctions.

At the beginning of our script, we define a string array containing the names of the functions that we wish to used for use remotely. In the below case, I had functions called Get-ServerList and Confirm-ValidSource.

$functions = @('Get-ServerList','Confirm-ValidSource')

Then, the function we created earlier is invoked to return a string of the text from these functions.

$FunctionString = Get-FunctionString -Function $functions

With this variable defined, I can create a new scriptblock of the string of functions above within the remote session, and then dot source it to make all these functions available.


Invoke-Command -ComputerName $item -ScriptBlock {
    $scriptblock = [System.Management.Automation.ScriptBlock]::Create($using:FunctionString)
    . $scriptblock
    $x = Get-ServerList
    If ($x) 
        ForEach ($obj in $x) 
            $y = Confirm-ValidSource($obj)
            If ($y) 
                Write-Output -InputObject "The server $obj has a valid source"
                Write-Output -InputObject "The server $obj does not have a valid source"

For those of using PowerShell Studio, ensure the array of strings variable ($functions in this case) is defined in globals.ps1, and that for each function part of your project, the property CommandExtension is set to True.

Thanks for reading, and feel free to provide feedback.