PoshCode Logo PowerShell Code Repository

Send-File.ps1 by Lee Holmes 3 years ago
embed code: <script type="text/javascript" src="http://PoshCode.org/embed/2216"></script>download | new post

From Windows PowerShell Cookbook (O’Reilly) by Lee Holmes

  1. ##############################################################################
  2. ##
  3. ## Send-File
  4. ##
  5. ## From Windows PowerShell Cookbook (O'Reilly)
  6. ## by Lee Holmes (http://www.leeholmes.com/guide)
  7. ##
  8. ##############################################################################
  9.  
  10. <#
  11.  
  12. .SYNOPSIS
  13.  
  14. Sends a file to a remote session.
  15.  
  16. .EXAMPLE
  17.  
  18. PS >$session = New-PsSession leeholmes1c23
  19. PS >Send-File c:\temp\test.exe c:\temp\test.exe $session
  20.  
  21. #>
  22.  
  23. param(
  24.     ## The path on the local computer
  25.     [Parameter(Mandatory = $true)]
  26.     $Source,
  27.  
  28.     ## The target path on the remote computer
  29.     [Parameter(Mandatory = $true)]
  30.     $Destination,
  31.  
  32.     ## The session that represents the remote computer
  33.     [Parameter(Mandatory = $true)]
  34.     [System.Management.Automation.Runspaces.PSSession] $Session
  35. )
  36.  
  37. Set-StrictMode -Version Latest
  38.  
  39. ## Get the source file, and then get its content
  40. $sourcePath = (Resolve-Path $source).Path
  41. $sourceBytes = [IO.File]::ReadAllBytes($sourcePath)
  42. $streamChunks = @()
  43.  
  44. ## Now break it into chunks to stream
  45. Write-Progress -Activity "Sending $Source" -Status "Preparing file"
  46. $streamSize = 1MB
  47. for($position = 0; $position -lt $sourceBytes.Length;
  48.     $position += $streamSize)
  49. {
  50.     $remaining = $sourceBytes.Length - $position
  51.     $remaining = [Math]::Min($remaining, $streamSize)
  52.  
  53.     $nextChunk = New-Object byte[] $remaining
  54.     [Array]::Copy($sourcebytes, $position, $nextChunk, 0, $remaining)
  55.     $streamChunks += ,$nextChunk
  56. }
  57.  
  58. $remoteScript = {
  59.     param($destination, $length)
  60.  
  61.     ## Convert the destination path to a full filesytem path (to support
  62.     ## relative paths)
  63.     $Destination = $executionContext.SessionState.`
  64.         Path.GetUnresolvedProviderPathFromPSPath($Destination)
  65.  
  66.     ## Create a new array to hold the file content
  67.     $destBytes = New-Object byte[] $length
  68.     $position = 0
  69.  
  70.     ## Go through the input, and fill in the new array of file content
  71.     foreach($chunk in $input)
  72.     {
  73.         Write-Progress -Activity "Writing $Destination" `
  74.             -Status "Sending file" `
  75.             -PercentComplete ($position / $length * 100)
  76.  
  77.         [GC]::Collect()
  78.         [Array]::Copy($chunk, 0, $destBytes, $position, $chunk.Length)
  79.         $position += $chunk.Length
  80.     }
  81.  
  82.     ## Write the content to the new file
  83.     [IO.File]::WriteAllBytes($destination, $destBytes)
  84.  
  85.     ## Show the result
  86.     Get-Item $destination
  87.     [GC]::Collect()
  88. }
  89.  
  90. ## Stream the chunks into the remote script
  91. $streamChunks | Invoke-Command -Session $session $remoteScript `
  92.     -ArgumentList $destination,$sourceBytes.Length

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me