2015-06-16 91 views
2

我需要使用PowerShell將文件從Azure虛擬機上的位置複製到本地計算機。例如VM上的C:\ tmp到本地機器上的C:\ tmp在遠程PowerShell會話期間複製文件c#運行空間

應用程序是使用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的只是換來的內容爲每個文件,它返回到C#在循環中,寫每一次文件。然而這是非常低效的。

回答

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); 
      } 
     } 
    } 
} 
相關問題