通过流将Powershell文件传输到远程计算机失败

通过流将Powershell文件传输到远程计算机失败,powershell,file-transfer,Powershell,File Transfer,我正在尝试通过Powershell将文件从本地计算机传输到远程计算机。我正在运行Powershell 3.0版,无法升级Powershell 我必须使用指定的凭据创建远程会话 以下是我正在使用的代码: # $credential variable created and set elsewhere $command = { param( [System.IO.FileStream]$inputStream, [string]$filePath, [string]$fileName )

我正在尝试通过Powershell将文件从本地计算机传输到远程计算机。我正在运行Powershell 3.0版,无法升级Powershell

我必须使用指定的凭据创建远程会话

以下是我正在使用的代码:

# $credential variable created and set elsewhere

$command = {
param( [System.IO.FileStream]$inputStream, [string]$filePath, [string]$fileName )

    $writeStream = [System.IO.File]::Create( "$filePath\$fileName" );
    $inputStream.Seek(0, [System.IO.SeekOrigin]::Begin);
    $inputStream.CopyTo( $writeStream );
    $writeStream.Close();
    $writeStream.Dispose();
}

$readStream = [System.IO.File]::OpenRead( "C:\temp\tempfile.txt" );
$path = "C:\temp";
$file = "test.txt";

$session = New-PSSession -ComputerName RemoteMachineName -UseSSL -Credential $credential;

# this works when copying the file/stream locally
Invoke-Command -ArgumentList $readStream, $path, $file -ScriptBlock $command
# this does not work when copying the file/stream remotely
Invoke-Command -Session $session -ArgumentList $readStream, $path, $file -ScriptBlock $command

$readStream.Close();
$readStream.Dispose();
试图在本地复制此文件时,上述代码起作用。但是,当试图通过会话将此文件复制到远程计算机时,出现以下错误:

无法处理参数“inputStream”上的参数转换。无法将类型为“反序列化的.System.IO.FileStream”的“System.IO.FileStream”值转换为类型为“System.IO.FileStream”。+CategoryInfo:InvalidData:(:)[],ParameterBindin…mationException+FullyQualifiedErrorId:ParameterArgumentTransformationError+PSComputerName:RemoteMachineName

我在internet上的任何地方都找不到对类“反序列化的.System.IO.FileStream”的任何引用。我的猜测是,流在传输到远程机器时正在被序列化,这就是导致问题的原因


是否有人知道如何正确执行此操作,或者有更好的方法传输此文件?最后一个文件很大,所以我不能在内存不足的情况下将它们读入字节数组。此外,我必须使用指定的凭据,并且传输必须加密。

远程会话中的对象将被拆除,通过线路发送,然后重建。某些类型可以重建为活动对象,而其他类型则是您怀疑的反序列化版本。有一篇博文

请注意,无论使用HTTP或HTTPS协议,在初始身份验证后,PSRemoting都与AES-256一起使用

从这个答案开始,我颠倒了这个过程,通过线路发送1MB块,并将它们写入远程机器上的流。因为它使用您已经建立的任何会话,所以它应该满足您的需求。也许可以对其进行优化,但我在1GB文件上运行了一些基本测试,结果和预期的一样

function UploadSingleFile {
    param(
        [System.Management.Automation.Runspaces.PSSession] $RemoteSession,
        [string] $RemoteFile,
        [string] $LocalFile,
        [int] $ChunkSize = 1mb
    )
    $FileInfo = Get-Item -LiteralPath $LocalFile
    $FileStream = $FileInfo.OpenRead()
    try {
        $FileReader = New-Object System.IO.BinaryReader $FileStream
        try {
            for() {
                $Chunk = $FileReader.ReadBytes($ChunkSize)
                if($Chunk.Length) {
                        Invoke-Command -Session $RemoteSession -ScriptBlock {
                        param(
                            [string] $RemoteFile,
                            [byte[]] $Chunk
                        )
                        $FileStream = [System.IO.FileStream]::new($RemoteFile, [System.IO.FileMode]::Append, [System.IO.FileAccess]::Write)
                        $FileStream.Write($Chunk, 0, $Chunk.Length)
                        $FileStream.Close()      
                    } -ArgumentList $RemoteFile, $Chunk
                } else {
                    break;
                }
            }
        } finally {
            $FileReader.Close();
        }
    } finally {
        $FileStream.Close();
    }
}
调用:

$session = New-PSSession -ComputerName ComputerOne -UseSSL -Credential $credential
UploadSingleFile -Session $session -RemoteFile 'c:\temp\Destination.bin' -LocalFile 'C:\temp\source.bin'
然后,我使用GetFileHash确认文件复制成功

PS C:\> Get-FileHash C:\temp\source.bin

Algorithm       Hash                                                                   Path                                                                                                                                                                                               
---------       ----                                                                   ----                                                                                                                                                                                               
SHA256          C513BFBCF4501A06BCC5F6F7A589532F7D802AA2C032D88143B0A31C1CFBD5F4       C:\temp\source.bin                                                                                                                                                                                   



PS C:\> Get-FileHash '\\ComputerOne\c$\temp\Destination.bin'

Algorithm       Hash                                                                   Path                                                                                                                                                                                               
---------       ----                                                                   ----                                                                                                                                                                                               
SHA256          C513BFBCF4501A06BCC5F6F7A589532F7D802AA2C032D88143B0A31C1CFBD5F4       \\ComputerOne\c$\temp\Destination.bin

这是一个棘手的问题。通常我会使用SMB管理共享,但您必须使用SMB 3.0+进行加密。您可以在传输之前加密文件,使用类似DPAPI和用户密钥的东西(两面都有)。我猜你是说你不能从文件中获取内容?也许把文件分成几个部分,直到它符合你提到的字节数组?这看起来不错。让我试试,然后再给你回复。也谢谢你的帮助链接。这是经过一些修改的。谢谢你的帮助,分块是最好的选择。