0

我正在使用 USB 的路径(假设插入一个驱动器)而不是驱动器号将文件复制到 USB。我需要这样做,因为我正在使用它一次克隆 52 个 USB。

这是找到路径前缀的地方:

$usb = Get-Volume | where {$_.DriveType -eq "Removable" }
$usb.Path

当与文件名的其余部分连接时,它会变成:

\\?\Volume{df4d4042-9133-11e9-9a6b-48a472473e67}\RDC_2.1.1_ALL.dmg

当我Copy-Item在工作之外打电话时,一切正常并正常复制。当我Copy-Item在 PowerShell 作业中调用时,它会失败并抱怨路径。这对我来说没有任何意义。

有人可以告诉我为什么我的功能copyFilesSync可以正常工作,而copyFiles不能正常工作吗?

为简单起见,我将脚本缩减为仅重现此问题的元素。$filestoCopyJSON1和之间没有实际区别$filestoCopyJSON2。交换实际文件没有任何区别。我只需要两个文件名,这样我就可以背靠背运行这两个函数,而且它们不会复制同一个文件:

$filestoCopyJSON1 = '[
    {
        "FromFile":  "C:\\dev\\VMware-player-12.1.1-3770994.exe",
        "ToFile":  "\\\\?\\Volume{df4d4042-9133-11e9-9a6b-48a472473e67}\\VMware-player-12.1.1-3770994.exe"
    }
]'

$filestoCopyJSON2 = '[
    {
        "FromFile":  "C:\\dev\\RDC_2.1.1_ALL.dmg",
        "ToFile":  "\\\\?\\Volume{df4d4042-9133-11e9-9a6b-48a472473e67}\\RDC_2.1.1_ALL.dmg"
    }
]'

function copyFiles($filestoCopy){
    Write-Host "Copying $($filestoCopy.Count)"
    $copyblock = {
        $copy = $args[0]
        Write-Host "$($copy.FromFile)" "$($copy.ToFile)"
        Copy-Item "$($copy.FromFile)" "$($copy.ToFile)"
        $resultHash = Get-FileHash -LiteralPath "$($copy.ToFile)"
    }

    foreach ($filetoCopy in $filestoCopy) {
        Start-Job -ScriptBlock $copyblock -ArgumentList @($filetoCopy)
    }

    Write-Host "Waiting on copying..."
    Get-Job | Wait-Job
    Write-Host "Files Copied"
}

function copyFilesSync($filestoCopy){
    foreach ($filetoCopy in $filestoCopy) {
        Copy-Item "$($filetoCopy.FromFile)" "$($filetoCopy.ToFile)"
        $resultHash = Get-FileHash -LiteralPath "$($filetoCopy.ToFile)"
    }
}

Remove-Job -Name *
Write-Host "Sync File Copy"

copyFilesSync -filestoCopy $(ConvertFrom-JSON -InputObject $filestoCopyJSON1)

Write-Host "Async File Copy"
copyFiles -filestoCopy $(ConvertFrom-JSON -InputObject $filestoCopyJSON2)
Receive-Job -Name *

这将产生以下输出:

PS C:\WINDOWS\system32> C:\dev\Test.ps1
同步文件复制
异步文件复制
复印 1

Id 名称 PSJobTypeName 状态 HasMoreData 位置命令
-- ---- ------------- ----- ------------ -------- --------
207 Job207 BackgroundJob Running True localhost ...
等待复制...
207 Job207 BackgroundJob 已完成 True localhost ...
复制的文件
C:\dev\RDC_2.1.1_ALL.dmg \\?\卷{df4d4042-9133-11e9-9a6b-48a472473e67}\RDC_2.1.1_ALL.dmg
路径中的非法字符。
    + CategoryInfo : NotSpecified: (:) [Copy-Item], ArgumentException
    + FullyQualifiedErrorId:System.ArgumentException,Microsoft.PowerShell.Commands.CopyItemCommand
    + PSComputerName:本地主机

Copy-Item不在作业中的第一个文件成功完成。作业中的异步Copy-Item运行失败,出现错误。

4

1 回答 1

0

我相信这是 Powershell Jobs 或 Copy-Item 中的错误。我不确定是哪个。我能够通过使用后台运行空间而不是作业来绕过这一点。因此,以下异步代码运行良好:

     function copyFiles($filestoCopy){
        Write-Host "Copying $($filestoCopy.Count)" 
        $copyblock = {
            $filestoCopy = $args[0]
            foreach($filetoCopy in $filestoCopy){
                Copy-Item "$($filetoCopy.FromFile)" "$($filetoCopy.ToFile)"
                $resultHash = Get-FileHash -LiteralPath "$($filetoCopy.ToFile)"

                if($filetoCopy.FromFileHash -ne $resultHash.hash){
                    Write-Host "File $($copy.ToFile) Failed.. trying again" 
                    Copy-Item "$($filetoCopy.FromFile)" "$($filetoCopy.ToFile)"
                }    
            }
        }

        $newPowerShell = [PowerShell]::Create().AddScript($copyblock).AddArgument($filestoCopy)
        $job = $newPowerShell.BeginInvoke()


        Write-Host "Waiting on copying..." 
        While (-Not $job.IsCompleted) {}
        $result = $newPowerShell.EndInvoke($job)
        $newPowerShell.Dispose()
        Write-Host "Files Copied" 
    }
于 2019-06-20T19:11:26.010 回答