我需要使用PowerShell将文件从Azure VM上的某个位置复制到本地计算机。例如,在本地计算机上的VM到C:\ tmp上的C:\ tmp
应用程序是使用System Automation的c#。目前我使用的方法。
using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline(//Some SQL that pulls files from database to C:\tmp);
var results = pipeline.Invoke();
}
我目前使用的powershell只返回每个文件的get-content,在循环中将其返回到c#,每次都写入文件。然而,这是非常低效的。
答案 0 :(得分:1)
这是正确的想法,但是在执行此操作时将文件块化更有效。 Powershell目前没有本地方法来执行此操作,因此您必须编写一些代码。有两个部分,远程PowerShell部分用于在服务器上存储文件,而C#部分用于重新组装块并执行powershell。
远程PowerShell部分:
$streamChunks = New-Object System.Collections.Generic.List[byte[]]
$buffer = New-Object byte[] 1024
[IO.FileStream] $fileStream = $null
try
{
$targetPath = # FILE TO GET
$fileStream = [IO.File]::OpenRead($targetPath)
[int] $bytesRead = 0
while (($bytesRead = $fileStream.Read($buffer, 0, 1024)) -gt 0)
{
$chunk = New-Object byte[] $bytesRead
[Array]::Copy($buffer, $chunk, $bytesRead)
$streamChunks.Add($chunk)
}
Write-Output $streamChunks
}
finally
{
if ($fileStream -ne $null)
{
$fileStream.Dispose()
$fileStream = $null
}
};
请注意,此脚本将由本地计算机上的运行空间调用:
Pipeline pipeline = runspace.CreatePipeline(command); // command is powershell above
Collection<PSObject> results = pipeline.Invoke();
重新组装块的C#部分:
using (FileStream fileStream = new FileStream(localPath, FileMode.OpenOrCreate, FileAccess.Write))
{
foreach (PSObject result in results)
{
if (result != null)
{
byte[] chunk = (byte[])result.BaseObject;
if (chunk != null)
{
fileStream.Write(chunk, 0, chunk.Length);
}
}
}
}