Powershell 文件通过流传输到远程机器失败
Powershell File Transfer to Remote Machine Via Stream Fails
我正在尝试通过 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();
上面的代码在尝试在本地复制此文件时有效。但是当试图通过会话将此文件复制到远程计算机时,出现以下错误:
Cannot process argument transformation on parameter 'inputStream'. Cannot convert the "System.IO.FileStream" value of type "Deserialized.System.IO.FileStream" to type "System.IO.FileStream". + CategoryInfo : InvalidData: (:) [], ParameterBindin...mationException + FullyQualifiedErrorId : ParameterArgumentTransformationError + PSComputerName : RemoteMachineName
我在互联网上的任何地方都找不到对 class "Deserialized.System.IO.FileStream" 的任何引用。我的猜测是流在传输到远程计算机时正在序列化,这就是导致问题的原因。
有谁知道如何正确执行此操作或有更好的方法来传输此文件?最终文件很大,所以我不能在 运行 内存不足的情况下将它们读入字节数组。另外,我必须使用指定的凭据并且传输必须加密。
远程会话中的对象被拆除,通过网络发送,然后重建。某些类型可以重建为活动对象,而其他类型是您怀疑的反序列化版本。有博客posthere that explains it.
请注意,无论使用 HTTP 还是 HTTPS 协议,初始身份验证后 PSRemoting always encrypted 使用 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'
然后我使用 Get-FileHash 来确认文件复制成功。
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
我正在尝试通过 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();
上面的代码在尝试在本地复制此文件时有效。但是当试图通过会话将此文件复制到远程计算机时,出现以下错误:
Cannot process argument transformation on parameter 'inputStream'. Cannot convert the "System.IO.FileStream" value of type "Deserialized.System.IO.FileStream" to type "System.IO.FileStream". + CategoryInfo : InvalidData: (:) [], ParameterBindin...mationException + FullyQualifiedErrorId : ParameterArgumentTransformationError + PSComputerName : RemoteMachineName
我在互联网上的任何地方都找不到对 class "Deserialized.System.IO.FileStream" 的任何引用。我的猜测是流在传输到远程计算机时正在序列化,这就是导致问题的原因。
有谁知道如何正确执行此操作或有更好的方法来传输此文件?最终文件很大,所以我不能在 运行 内存不足的情况下将它们读入字节数组。另外,我必须使用指定的凭据并且传输必须加密。
远程会话中的对象被拆除,通过网络发送,然后重建。某些类型可以重建为活动对象,而其他类型是您怀疑的反序列化版本。有博客posthere that explains it.
请注意,无论使用 HTTP 还是 HTTPS 协议,初始身份验证后 PSRemoting always encrypted 使用 AES-256。
根据
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'
然后我使用 Get-FileHash 来确认文件复制成功。
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