July 27, 2026
Clipboard-Safe File Transfer With PowerShell Chunks
In restricted RDP or VM sessions, normal file transfer is sometimes unavailable. Downloads may be blocked, uploads may be disabled, shared…

By chokri hammedi
2 min read
In restricted RDP or VM sessions, normal file transfer is sometimes unavailable. Downloads may be blocked, uploads may be disabled, shared folders may not exist, and drag-and-drop may fail. In those cases, the clipboard can still be useful as a text-only transport.
The approach is to convert the file to base64, split it into clipboard-safe chunks, copy the chunks out, reconstruct the file on another machine, and verify integrity with SHA256.
Why Chunking Helps
Copying a full binary as one large base64 blob is fragile. Large clipboard payloads can be truncated or corrupted, especially over RDP, browser consoles, or VM viewers.
Chunking makes the transfer easier to control:
- Each text file stays below a chosen clipboard-safe size.
- Chunks are numbered and can be copied in order.
- A manifest records the expected file size, chunk count, and SHA256.
- The final hash confirms whether the reconstructed file is intact.
PowerShell Sender
On the Windows side, use built-in PowerShell and .NET APIs:
$File = "C:\tool.exe"
$ClipboardSafeChars = 524288
$OutDir = Join-Path $env:TEMP "chunks"
Remove-Item -Recurse -Force $OutDir -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Path $OutDir -Force | Out-Null
$bytes = [IO.File]::ReadAllBytes($File)
$b64 = [Convert]::ToBase64String($bytes)
$total = [int][Math]::Ceiling($b64.Length / $ClipboardSafeChars)
$sha256 = (Get-FileHash $File -Algorithm SHA256).Hash
@"
FILE=$([IO.Path]::GetFileName($File))
RAW_SIZE=$($bytes.Length)
BASE64_SIZE=$($b64.Length)
CHUNK_CHARS=$ClipboardSafeChars
CHUNKS=$total
SHA256=$sha256
"@ | Out-File -Encoding ascii -FilePath (Join-Path $OutDir "manifest.txt")
for ($i = 0; $i -lt $total; $i++) {
$start = $i * $ClipboardSafeChars
$len = [Math]::Min($ClipboardSafeChars, $b64.Length - $start)
$chunk = $b64.Substring($start, $len)
$num = ($i + 1).ToString("000")
$tot = $total.ToString("000")
$name = "$num`_of_$tot.txt"
$chunk | Out-File -Encoding ascii -FilePath (Join-Path $OutDir $name)
}
Write-Host "Created $total chunks in $OutDir"
Write-Host "Chunk chars: $ClipboardSafeChars"
Write-Host "SHA256: $sha256"$File = "C:\tool.exe"
$ClipboardSafeChars = 524288
$OutDir = Join-Path $env:TEMP "chunks"
Remove-Item -Recurse -Force $OutDir -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Path $OutDir -Force | Out-Null
$bytes = [IO.File]::ReadAllBytes($File)
$b64 = [Convert]::ToBase64String($bytes)
$total = [int][Math]::Ceiling($b64.Length / $ClipboardSafeChars)
$sha256 = (Get-FileHash $File -Algorithm SHA256).Hash
@"
FILE=$([IO.Path]::GetFileName($File))
RAW_SIZE=$($bytes.Length)
BASE64_SIZE=$($b64.Length)
CHUNK_CHARS=$ClipboardSafeChars
CHUNKS=$total
SHA256=$sha256
"@ | Out-File -Encoding ascii -FilePath (Join-Path $OutDir "manifest.txt")
for ($i = 0; $i -lt $total; $i++) {
$start = $i * $ClipboardSafeChars
$len = [Math]::Min($ClipboardSafeChars, $b64.Length - $start)
$chunk = $b64.Substring($start, $len)
$num = ($i + 1).ToString("000")
$tot = $total.ToString("000")
$name = "$num`_of_$tot.txt"
$chunk | Out-File -Encoding ascii -FilePath (Join-Path $OutDir $name)
}
Write-Host "Created $total chunks in $OutDir"
Write-Host "Chunk chars: $ClipboardSafeChars"
Write-Host "SHA256: $sha256"
Chunk Directory
The output directory contains ordered text files plus a manifest:
001_of_004.txt
002_of_004.txt
003_of_004.txt
004_of_004.txt
manifest.txt001_of_004.txt
002_of_004.txt
003_of_004.txt
004_of_004.txt
manifest.txt
The chunk files can be opened and copied through the clipboard one by one. If the original names are preserved, sorting by filename keeps the order correct.
Linux Receiver
After copying the chunks to the Linux side, concatenate them in order, remove whitespace, base64-decode, and verify the hash:
cat 1.txt 2.txt 3.txt 4.txt | tr -d '\r\n ' > out.b64
base64 -d out.b64 > recovered.exe
sha256sum recovered.execat 1.txt 2.txt 3.txt 4.txt | tr -d '\r\n ' > out.b64
base64 -d out.b64 > recovered.exe
sha256sum recovered.exe
Result:
92804faaab2175dc501d73e814663058c78c0a042675a8937266357bcfb96c50 recovered.exe92804faaab2175dc501d73e814663058c78c0a042675a8937266357bcfb96c50 recovered.exeThe hash should match the SHA256 value from the Windows manifest.
Choosing a Chunk Size
The chunk size depends on how stable the clipboard path is.
Useful values:
- 32768 very safe, more chunks
- 262144 balanced
- 524288 fewer chunks, still practical
- 1048576 fewer chunks, but more likely to fail over unstable clipboard sync
For this test, 524288 characters created four chunks and transferred cleanly.
Why This Works
The clipboard is not a file transfer mechanism, but it can reliably carry bounded text. Base64 makes binary data text-safe. Numbered chunks preserve order. The manifest records what should be reconstructed. SHA256 confirms whether the final result is correct.
This method is useful for constrained lab environments, isolated VM workflows, and restricted remote sessions where normal file movement is not available.