PowerShell:从SMB共享中下载文件列表而不覆盖

时间:2017-10-27 19:11:51

标签: powershell smb

我想从远程网络共享下载预定义文件列表,而不会覆盖具有相同名称的本地文件。我有这个功能主要通过使用Bitstransfer模块在PowerShell中工作。您可以在代码中看到C:\ SMB \ paths.txt指向包含远程SMB路径的本地文件。

SMBBulkDownload.ps1:

Import-Module bitstransfer

foreach($line in Get-Content C:\SMBDump\paths.txt) {
    $sourcePath = $line
    $destPath = "C:\SMBDump\"
    Start-BitsTransfer -Source $sourcePath -Destination $destPath     
}

其中 C:\ SMB \ paths.txt 包含(示例代码段):

\\10.17.202.21\some\dir\app.config
\\10.19.197.68\some\dir\app.config
\\10.28.100.34\some\dir\Web.config

上面的代码正确下载文件如果他们有不同的文件名。在文件名相同的情况下,bitstransfer返回ACCESSDENIED错误。这可能是由于模块不支持同名文件副本,或者是由于同时复制具有相同名称的文件的竞争条件。这很不幸,因为我的工作需要批量下载许多名为相同的文件,例如App.Config,Web.Config等。

错误:

Start-BitsTransfer : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

有没有人有解决方案可以绕过这个同名文件复制块?理想情况下,我喜欢将带有冗余名称的文件复制到带有“_1”或“_2”或_后缀的同一目录中的解决方案。

2 个答案:

答案 0 :(得分:3)

假设你的错误植根于你的文件名理论中,那么就可以试试.....

您的路径都有一个唯一的组件:服务器IP地址或名称。我建议为每个地址创建一个子目录或将其附加到名称。

主机

在文件夹中组织的文件
foreach($line in Get-Content C:\SMBDump\paths.txt) {
    $hostName = ([uri]$line).Host
    $fileName = Split-Path $line -Leaf
    $destPath = "C:\SMBDump\$hostName-$fileName"
    Start-BitsTransfer -Source $sourcePath -Destination $destPath     
}

具有主机命名前缀

的同一文件夹中的文件
GET

这应该不会导致名称冲突,只要您的文件包含唯一值,就不应该存在任何争用。

答案 1 :(得分:1)

Matt的方法是保留唯一文件路径并允许您将文件追溯回其源服务器的方法。

要真正回答这个问题,您需要检查您要复制的文件是否存在,并更改路径以避免冲突。

Import-Module bitstransfer

foreach($line in Get-Content C:\SMBDump\paths.txt) {
    $sourcePath = $line
    $destPath = "C:\SMBDump\"      
    $fileName = Split-Path -Path $line -leaf

    if(Test-Path "$destPath$fileName"){
        $extension = [io.path]::GetExtension($fileName)
        $basename  = [io.path]::GetFileNameWithoutExtension($fileName)
        $i = 1

        do{
            $fileName  = "${basename}_$i$extension"
            if(-not (Test-Path "$destPath$fileName")){
                $next = $false
            }else{
                $next = $true
                $i++
            }

        }while($next -eq $true)

    }

    Start-BitsTransfer -Source $sourcePath -Destination "$destPath$fileName"    
}