$pdfFolder = 'C:\path\to\folders\here'
# Get all subfolders - note the -Directory switch (PSv3+)
$Completed = Get-ChildItem $pdfFolder -Recurse -Directory
# Pipe the subfolders to ForEach-Object, invoke the
# script with & (avoid Invoke-Expression), and pass the subfolder
# at hand as an argument.
$Completed | ForEach-Object {
& "C:\path\where\scriptis\script.ps1" $_
}
As for what you tried:
Get-ChildItem $pdfFolder -Recurse
This command returns not just folders (directories), but also files. To limit the output to folders, pass switch -Directory (PSv3+).
ForEach-Object ($Completed) { ... }
You're confusing the syntax of the foreach loop with the syntax of the pipeline-based ForEach-Object cmdlet.
The cmdlet expects input from the pipeline, so you must use
$Completed | ForEach-Object { ... } instead.
Also note that unless you truly need to collect all subfolders in an array first, you can simply pipe your Get-ChildItem call directly to ForEach-Object.
Invoke-Expression -Command "C:\path\where\scriptis\script.ps1"
Invoke-Expression should be avoided, because it is rarely the right tool and can be a security risk.
All you need to invoke a script by its quoted and/or stored-in-a-variable file path is to use &, the call operator, as shown above.