hantsbay
hantsbay

Reputation: 13

Powershell - Applying a looped function to subdirectories

I am new to Powershell and am struggling a bit. I have obtained an example of the sort of function I want to use and adapted it partially. What I want is for it to loop through each subdirectory of C:\Test\, and combine just the PDFs in each subdirectory together (leaving the resulting PDF in each subdirectory).

At the moment I can get it to comb through the subdirectories, but it then combines the contents of all subdirectories into one giant PDF in the top level directory, which is not what I want. I feel like maybe I need to use an array of sorts but I don't know Powershell well enough yet.

BTW this uses PDFSharp - a .Net library.

Function PDFCombine {            
$filepath = 'C:\Test\'
$filename = '.\Combined' #<--- ???                   

$output = New-Object PdfSharp.Pdf.PdfDocument            
$PdfReader = [PdfSharp.Pdf.IO.PdfReader]            
$PdfDocumentOpenMode = [PdfSharp.Pdf.IO.PdfDocumentOpenMode]                        

foreach($i in (gci $filepath *.pdf -Recurse)) {            
    $input = New-Object PdfSharp.Pdf.PdfDocument            
    $input = $PdfReader::Open($i.fullname, $PdfDocumentOpenMode::Import)            
    $input.Pages | %{$output.AddPage($_)}            
}                        

$output.Save($filename)            
}

Upvotes: 1

Views: 706

Answers (2)

Frode F.
Frode F.

Reputation: 54881

Your question was unclear about how many levels you need to go down. You can try this (untested). It goes one level down from $filepath, gets all pdf files in that folder and it's subfolders and combines them into Subfoldername-Combined.pdf:

Function PDFCombine {            
    $filepath = 'C:\Test\'

    $PdfReader = [PdfSharp.Pdf.IO.PdfReader]
    $PdfDocumentOpenMode = [PdfSharp.Pdf.IO.PdfDocumentOpenMode]

    #Foreach subfolder(FIRST LEVEL ONLY!)
    Get-ChildItem $filepath | Where-Object { $_.PSIsContainer } | Foreach-Object {
        #Create new ouput pdf-file
        $output = New-Object PdfSharp.Pdf.PdfDocument
        $outfilepath = Join-Path $_.FullName "$($_.Name)-Combined.pdf"

        #Find and add pdf files in subfolders
        Get-ChildItem -Path $_.FullName -Filter *.pdf -Recurse | ForEach-Object {
            #$input = New-Object PdfSharp.Pdf.PdfDocument #Don't think this one's necessary           
            $input = $PdfReader::Open($_.fullname, $PdfDocumentOpenMode::Import)            
            $input.Pages | %{ $output.AddPage($_) }
        }

        #Save
        $output.Save($outfilepath)
    }                      

}

So you should get this:

c:\Test\Folder1\Folder1-Combined.pdf #should include all pages in Folder1 and ANY subfolders below)
c:\Test\Folder2\Folder2-Combined.pdf #should include all pages in Folder2 and ANY subfolders below)
#etc.

If you need it to create a combined pdf for every subfolder(not only the first level), then you could try this(untested):

Function PDFCombine {            
    $filepath = 'C:\Test\'

    $PdfReader = [PdfSharp.Pdf.IO.PdfReader]
    $PdfDocumentOpenMode = [PdfSharp.Pdf.IO.PdfDocumentOpenMode]

    #Foreach subfolder with pdf files
    Get-ChildItem -Path $filepath -Filter *.pdf -Recurse | Group-Object DirectoryName | ForEach-Object {
        #Create new ouput pdf-file
        $output = New-Object PdfSharp.Pdf.PdfDocument
        $outfilepath = Join-Path $_.Name "Combined.pdf"

        #Find and add pdf files in subfolders
        $_.Group | ForEach-Object {
            #$input = New-Object PdfSharp.Pdf.PdfDocument #I don't think you need this
            $input = $PdfReader::Open($_.fullname, $PdfDocumentOpenMode::Import)            
            $input.Pages | %{ $output.AddPage($_) }
        }

        #Save
        $output.Save($outfilepath)

        #Remove output-object
        Remove-Variable output
    }                      

}

Upvotes: 1

Lo&#239;c MICHEL
Lo&#239;c MICHEL

Reputation: 26150

not tested ...

Function PDFCombine {            
$filepath = 'C:\Test\'
$filename = '.\Combined' #<--- ???                   

$output = New-Object PdfSharp.Pdf.PdfDocument            
$PdfReader = [PdfSharp.Pdf.IO.PdfReader]            
$PdfDocumentOpenMode = [PdfSharp.Pdf.IO.PdfDocumentOpenMode]                        
$lastdir=""

foreach($i in (gci $filepath *.pdf -Recurse)) {            

    $input = New-Object PdfSharp.Pdf.PdfDocument            
    $input = $PdfReader::Open($i.fullname, $PdfDocumentOpenMode::Import)            
    $input.Pages | %{$output.AddPage($_)}   
    if ($lastdir -ne $_.directoryname){
        $lastdir=$_.directoryname
        $output.Save("$lastdir\$filename") 
        $output = New-Object PdfSharp.Pdf.PdfDocument  
    }
}                        


}

Upvotes: 1

Related Questions