简体   繁体   English

在远程powershell会话c#运行空间期间复制文件

[英]Copy file during remote powershell session c# runspace

I need to copy a file from a location on an Azure VM to my local computer using powershell.我需要使用 powershell 将文件从 Azure VM 上的某个位置复制到我的本地计算机。 eg C:\\tmp on the VM to C:\\tmp on my local machine例如,虚拟机上的 C:\\tmp 到我本地机器上的 C:\\tmp

The application is c# using System Automation.该应用程序是使用系统自动化的 c#。 Currently I use the method.目前我使用该方法。

    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();
    }

The powershell I use at the moment just return get-content for each file, returns it to c# in a loop, writing to file each time.我目前使用的 powershell 只是为每个文件返回 get-content,在循环中将其返回给 c#,每次写入文件。 However this is very inefficient.然而,这是非常低效的。

This is the right idea, however it is more efficient to chunk the file when you do this.这是正确的想法,但是在执行此操作时将文件分块更有效。 Powershell does not currently have a native way to do this, so you have to write some code. Powershell 目前没有本地方式来执行此操作,因此您必须编写一些代码。 There are two parts, the remote powershell part to chunk the file on the server, and the C# part to re-assemble the chunks and execute the powershell.有两个部分,远程 powershell 部分用于将服务器上的文件分块,C# 部分用于重新组装块并执行 powershell。

The remote powershell part:远程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 
    }
};

Note that this script will be invoked by a runspace on your local machine:请注意,此脚本将由本地计算机上的运行空间调用:

Pipeline pipeline = runspace.CreatePipeline(command); // command is powershell above
Collection<PSObject> results = pipeline.Invoke();

The C# part to re-assemble the chunks:重新组装块的 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);
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM