I've been using the below code to combine all the .pdf files in each child directory into one pdf. It saves the new combined pdf in the child folder as the child folders name. Which is great, but then i have to manually move all those newly created files out to the parent folder. Here is the current code:
$pdftk = "C:\SymLinks\Combine\pdftk.exe"
$inputFolder = "I:\Fort Gibson-DONE"
gci $inputfolder -r -include *.pdf | sort-object | group DirectoryName | % {& $PDFtk $_.group CAT OUTPUT "$($_.Name)\$($_.Name | Split-Path -Leaf).pdf" verbose}
I've tried piping out to Move-Item with:
$pdftk = "C:\SymLinks\Combine\pdftk.exe"
$inputFolder = "I:\Fort Gibson-DONE"
gci $inputfolder -r -include *.pdf | sort-object | group DirectoryName | % {& $PDFtk $_.group CAT OUTPUT "$($_.Name)\$($_.Name | Split-Path -Leaf).pdf" verbose} | % {mv $_.FullName $_.Directory.Parent.FullName }
But it isn't working. It says this:
Move-Item : Cannot bind argument to parameter 'Path' because it is null.
At I:\CombineFortGibson.ps1:3 char:170
+ ... rbose} | % {mv $_.FullName $_.Directory.Parent.FullName }
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Move-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.MoveItemCommand
I'm not sure how to move the newly created PDF out to the parent folder.
I feel I need to store the $.FullName and $.Directory.Parent.FullName to a variable and then feed those variables to move-item. But i'm not sure how to do that. Variables don't seem to work with pdftk very well.
I am using Powershell 4.0 as of today and previously I was using Powershell 2.0 when I was trying PDFTK with variables.
[moving my comment to an answer]
I suggested having PDFtk write the output file where you want it, instead of putting it somewhere else and then moving it, e.g. changing to:
OUTPUT "$($_.Name | Split-Path -Parent)\$($_.Name | Split-Path -Leaf).pdf"
The reason your original move-item approach, and your try with $_.Directory.Parent
, didn't work is because the types you are working with change through your script. Questioning "what type of thing is this?" is way important in PowerShell because it's so casual about typing, especially where you use $_
because there's nothing in the name to help show what's happening. (Use Get-Member
or $thing.GetTYpe()
to find out what type of thing something is).
gci
outputs [system.io.fileinfo]
type things, they have filesystem information like .Directory.Parent
and .FullName
and .DirectoryName
and more.
group DirectoryName
outputs [GroupInfo]
containers, one for each group. That type has none of the filesystem parts, just a Name for the group, and the things in the group.
Here:
$PDFtk $_.group CAT OUTPUT "$($_.Name)\..
$_.Group
is all the things in the group, and $_.Name
is the group name, as a [string]
type.
$_.Directory.Parent
doesn't work because [GroupInfo]
lacks filesystem information, only the things in the group have that.
Your first approach with move-item
has the same kind of problem:
| % {mv $_.FullName $_.Directory.Parent.FullName }
$_
is each line of text coming out of PDFtk. I don't know what that looks like, but it's probably some kind of "processing files, found 10 pages, writing output file" kind of status messages, all those will be [string]
type lines of text, and carry no filesystem-aware information from earlier in the pipeline.