How to reach unreachable or copy files to RDP

Consider that usecase: I need to send a dll file to production environment to patch some bugs

I have a RDP access to production environment. All good? No! I do have RDP access to that environment but drive sharing and Internet is disabled on it. How can I transfer files in this case?!

I came up with an interesting solution… Use clipboard. But how to transfer binary file via clipboard?! Convert it to Base64! Gotcha!

This idea works as a charm.

The following script we are using locally

function ConvertTo-Base64Clipboard
{
    param
    (
        [string] $FilePath
    )
    
   [Convert]::ToBase64String((Get-Content -Path $FilePath -Encoding Byte)) | clip
}

This one – on production server

function Get-Clipboard
{
    PowerShell -NoProfile -Sta -Command `
    {
        Add-Type -AssemblyName PresentationCore
        [Windows.Clipboard]::GetText()
    }
}

function ConvertFrom-Base64Clipboard
{
    param
    (
        [string] $FilePath
    )
    
   [Convert]::FromBase64String((Get-Clipboard)) | Out-File -FilePath $FilePath -Encoding Byte
}

Voila!

This idea is not new, I found similar here and here

UPD: forgot to mention performance, conversion is taking time. So I reckon if you need to transfer multiple files, archive them into zip first and then transfer this archive file. Zip is natively supported by modern versions of Windows.

I am not sure about limitations of clipboard length. Some BCL API makes me think that it could be int.MaxValue. This gives us 2gb of base64, or 2gb * 3/4 = 1.5gb of binary data. So that should be more than enough.

There is also a way to rewrite Get-ClipboardText which doesn’t require running separate PowerShell process in STA mode

function Get-ClipboardText
{
    Add-Type -AssemblyName System.Windows.Forms
    $tb = New-Object System.Windows.Forms.TextBox
    $tb.Multiline = $true
    $tb.MaxLength = [int]::MaxValue
    $tb.Paste()
    $tb.Text
}

This works a bit faster

UPD2: Those scripts were written from memory, and later on I found couple of mistakes.

So I will provide final correct versions of the scripts

function ConvertTo-Base64Clipboard
{
    param
    (
        [string] $FilePath
    )
    
   [Convert]::ToBase64String((Get-Content -Path $FilePath -Encoding Byte)) | clip
}

and

function Get-Clipboard
{
    Add-Type -AssemblyName System.Windows.Forms
    $tb = New-Object System.Windows.Forms.TextBox
    $tb.Multiline = $true
    $tb.MaxLength = [int]::MaxValue
    $tb.Paste()
    $tb.Text
}

function ConvertFrom-Base64Clipboard
{
    param
    (
        [string] $FilePath
    )
    
   [Convert]::FromBase64String((Get-Clipboard)) | Set-Content -Path $FilePath -Encoding Byte
}

Part 2

Advertisements

About mnaoumov

Senior .NET Developer in Readify
This entry was posted in Uncategorized. Bookmark the permalink.

8 Responses to How to reach unreachable or copy files to RDP

  1. Mike Chaliy says:

    Ctrl+C on host, Ctrl+V on remote computer works for me.

  2. mnaoumov says:

    Is that working for binary files as well?

  3. mnaoumov says:

    I mean is Ctrl+C, Ctrl+V works for binary files? What editor you use? Production server has only notepad and wordpad 🙂 PowerShell Remoting won’t work because prod environment has paranoid security settings and everything is disabled there

  4. Miachel you are the champ of powershell and git hoos 🙂

  5. Pingback: Efficient Base64 conversion in PowerShell | mnaoumov.NET

  6. Pingback: How to reach unreachable or copy files to RDP – Part 2 | mnaoumov.NET

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s