首页 > 解决方案 > 在保持文件夹结构的同时复制 PDF

问题描述

所以我试图复制所有文件夹并保留仅包含 pdf 的结构。我不确定是否有办法做到这一点,我已经设法让一些脚本工作。

但是,当我运行它时,它会复制所有文件夹,即使它们中没有 PDF。另外我注意到我的脚本无法检查文件夹并在下一个目录中创建。例如:

C:\temp 复制一次显示 C:\temp。
如果我要再次运行脚本,它现在会显示 C:\temp\temp

以下是我的代码:

$Criteria = *.pdf
$Trial = c:\temp\folders.txt
$Server = \\file
$Path = homedrives\home
$des = $Path
$safe = Get-Content $Trial
$safe | ForEach-Object {
    #find drive-delimeter
    $first = $_.IndexOf("\\");
    if ($first -eq 1) {
        #stripe it
        $newdes = Join-Path -Path $des -ChildPath @($_.Substring(0,1)+$_.Substring(2))[0]    
    } else {
        $newdes = Join-Path -Path $des -ChildPath $_
    }
    $err = 0
    $fr = 0
    $folder = Split-Path -Path $newdes -Parent
    #check if folder exists"
    $void = Get-Item $folder -ErrorVariable err -ErrorAction SilentlyContinue
    if ($err.Count -ne 0) {
        #create when it doesn't
        $void = New-Item -Path $folder -ItemType Directory -Force
    }  
    #$void = Copy-Item -Path $_ -destination $newdes  -Force -Verbose
    $void = Copy-Item -Path $_ -destination $newdes -Filter $Criteria -Recurse -Force  -ErrorVariable fr -ErrorAction SilentlyContinue
    $CR = "`r`n"
    $RR = $fr[0].CategoryInfo.TargetName.ToString()
   "List of PDF's that Failed To Copy" + $CR + "--------------------------------------------------------------" + $CR + $RR | Out-file -Append $Er
    Write-Host $_
}
Write-Host $newdes

标签: powershellcopydirectory

解决方案


好的,看起来我已经破解了它,以供将来参考,我的代码实际上使用用户输入来确定位置,然后选择用户请求的标准,然后只复制具有定义扩展名的文件。它复制文件夹结构而不复制,尽管 Windows 的文件名限制仍然存在,但会生成一个错误日志,显示无法复制的文件。感谢您在这件事上提供的所有帮助。

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null -ErrorAction Stop
$Server = "\\" + [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a Server to search", "Server Choice")
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null -ErrorAction Stop
$Choice = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a File Path to search", "File Path Choice")  + "\"
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null -ErrorAction Stop
$Ext = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a File type i.e. *.PST", "Location Choice") 
#$Ext.ToUpper()
$Criteria = "*." + $Ext
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null -ErrorAction Stop
#$FPath = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a path to copy to", "Location Choice") 
$Path = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a folder to store the data", "Path Choice") + "\"
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null -ErrorAction Stop
#$Name = [Microsoft.VisualBasic.Interaction]::InputBox("Please choose a filename", "File Name Choice")
$Search = $Server +"\"+ $Choice 
$FileName = $Path
$Info = $Path + "FileCopy.txt"
$Trial = $Path + "Folders.txt"
$Type = $Path + "$Ext's.txt"
$Er= $Path + "Failed Copying.txt"
$Trial2 = $Path + "Folders.txt"
#$Server2 = "\" + $Server
#$File = $Path + $Name
if( -Not (Test-Path -Path $Path ) )
{
    New-Item -ItemType directory -Path $Path |out-null
}
Else{
    [System.Windows.MessageBox]::Show('The directory already exists','Error','Ok','Error') 
    -ErrorAction SilentlyContinue
}
$properties = @(
    'Directory'
    ' '
    'Name'
    ' '
    @{
        Label = 'Size'
        Expression = {
            if ($_.Length -ge 1GB)
            {
                '{0:F2} GB' -f ($_.Length / 1GB)
            }
            elseif ($_.Length -ge 1MB)
            {
                '{0:F2} MB' -f ($_.Length / 1MB)
            }
            elseif ($_.Length -ge 1KB)
            {
                '{0:F2} KB' -f ($_.Length / 1KB)
            }
            else
            {
                '{0} bytes' -f $_.Length
            }
        }
        }
        $result = Get-ChildItem -Path $Search -Recurse -Include $Criteria -ErrorAction SilentlyContinue
  ) | Out-Null
  $Result
#Get-ChildItem -Path $Search -Recurse -Include *.pst -ErrorAction SilentlyContinue |
$Folders = (get-childitem -Path $Search | where-object { $_.PSIsContainer }).Count

If (Test-Path $Search) {
    <#Write-Host
    Write-Host "Listing All  Found In $Path" -ForegroundColor "Yellow"
    Write-Host "=========================================" -ForegroundColor "Yellow"#>

    Add-Type -assembly System.Windows.Forms

    ## -- Create The Progress-Bar
    $ObjForm = New-Object System.Windows.Forms.Form
    $ObjForm.Text = "Progress-Bar of searched folders"
    $ObjForm.Height = 100
    $ObjForm.Width = 500
    $ObjForm.BackColor = "White"

    $ObjForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle
    $ObjForm.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen

    ## -- Create The Label
    $ObjLabel = New-Object System.Windows.Forms.Label
    $ObjLabel.Text = "Starting. Please wait ... "
    $ObjLabel.Left = 5
    $ObjLabel.Top = 10
    $ObjLabel.Width = 500 - 20
    $ObjLabel.Height = 15
    $ObjLabel.Font = "Tahoma"
    ## -- Add the label to the Form
    $ObjForm.Controls.Add($ObjLabel)

    $PB = New-Object System.Windows.Forms.ProgressBar
    $PB.Name = "PowerShellProgressBar"
    $PB.Value = 0
    $PB.Style="Continuous"

    $System_Drawing_Size = New-Object System.Drawing.Size
    $System_Drawing_Size.Width = 500 - 40
    $System_Drawing_Size.Height = 20
    $PB.Size = $System_Drawing_Size
    $PB.Left = 5
    $PB.Top = 40
    $ObjForm.Controls.Add($PB)

    ## -- Show the Progress-Bar and Start The PowerShell Script
    $ObjForm.Show() | Out-Null
    $ObjForm.Focus() | Out-NUll
    $ObjLabel.Text = "Starting. Please wait ... "
    $ObjForm.Refresh()

    Start-Sleep -Seconds 1
 Out-Null
    ## -- Execute The PowerShell Code and Update the Status of the Progress-Bar

    $result = Get-ChildItem -Path $Search -Recurse -Include $Criteria -ErrorAction SilentlyContinue 
    $Counter = 0
    ForEach ($Item In $Result) {
        ## -- Calculate The Percentage Completed
        $Counter++
        [Int]$Percentage = ($Counter/$Result.Count)*100
        $PB.Value = $Percentage
        $ObjLabel.Text = "Scanning $Folders Folders For $Criteria in $Search"
        #$ObjLabel.Text = "Found $counter $Criteria in $Search"
        $ObjForm.Refresh()
        Start-Sleep -Milliseconds 150
        # -- $Item.Name
        #"`t" + $Item.Path

    }

    $ObjForm.Close()
    #Write-Host "`n"
}
Else {
    #Write-Host
    #Write-Host "`t Cannot Execute The Script." -ForegroundColor "Yellow"
    #Write-Host "`t $Search Does Not Exist in the System." -ForegroundColor "Yellow"
    #Write-Host
}
Out-Null
Sort-Object -Property DirectoryName |

Format-Table -Property $properties |

out-file $Info



$Search| out-file -Append $Trial 
#$Search | Out-File -Append $Trial2


$result | out-file -Append $Info

$result | Select Name | out-file -Append $Type
$CR = "`r`n"
"List of PDF's that Failed To Copy" + $CR + $CR + "--------------------------------------------------------------" | Out-file $Er
$des = $Path
#$PDFs= get-content $Type
$safe = Get-Content $Trial
#$Ten = @($Criteria)
$safe | ForEach-Object{
    #find drive-delimeter
    $first=$_.IndexOf("\\");

    if($first -eq 0){
        #stripe it
    $newdes=Join-Path -Path $des -ChildPath @($_.Substring(0,1)+$_.Substring(2))[0]    
        }
        $newdes=Join-Path -Path $des -ChildPath $_
    $err=0
    $fr=0
    $folder=Split-Path -Path $newdes -Parent
    $folders=Split-Path -Path $newdes -leaf
    #$fy = $folder + "\" +$folders
    #check if folder exists"
   $void=Get-Item $newdes -ErrorVariable err  -ErrorAction SilentlyContinue #-verbose
   If(!(Test-Path -Path $newdes) ){
    $err=1
   }
     if($err.Count -ne 0){
        #create when it doesn't
        $void=New-Item -Path $folder -ItemType Directory #-verbose
        } 
            #$void=Copy-Item -Path $_ -destination $newdes  -Force -Verbose
            $void=Copy-Item -Path $_ -destination $folder -Filter $Criteria -Recurse -Container -Force -ErrorVariable fr  -ErrorAction SilentlyContinue -verbose
            write-host "------------------------------------------------------- Break -------------------------------------------------------" -ForegroundColor Green
            foreach($re in $fr){
            $RR = $re[0].CategoryInfo.TargetName.ToString()
            $X5 = $re[0].CategoryInfo.Reason.ToString()
            $X6 = $re[0].TargetObject.DirectoryName.ToString()
            $X6 + $CR + $X5 + "---" + $RR + $CR | Out-file -Append $Er
            }
    write-host "`n" $_
    }
    write-host "`n------------------------------------------------------- End of Script -------------------------------------------------------" -ForegroundColor Blue`

推荐阅读