Run powershell script for each folder with subfolders

Viewed 3485

I have a few scripts that I need to run against a dozen folders all with a relative path. I'm trying to solve this with a master script to run for each folder in that path, one folder at a time. The folders are all children of the "here" folder in the below path. I can't seem to get the syntax right, but I think I'm close :)

Is there a more efficient way to run a script against the contents of every folder in a directory, one folder at a time?

$pdfFolder = 'C:\path\to\folders\here'
$Completed = Get-ChildItem $pdfFolder -Recurse

ForEach-Object ($Completed){
Invoke-Expression -Command "C:\path\where\scriptis\script.ps1"
}`
1 Answers
$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.

Related