Ezine 208 PowerShell -Recurse

Introduction to PowerShell Scripting -Recurse

When you want a PowerShell command to search sub-directories then -recurse is a life saver.  In other contexts this concept is called iteration, or sub-directory recursion.  One cmdlet which benefits from the -recurse parameter is Get-Childitem.

Topics for PowerShell -Recurse Parameter

 ♣

This Week’s Secret

In addition to my desire to get people started with PowerShell, my aim is to create a resource of simple examples so intermediate scripters can get a refresher on a cmdlet or parameter that they haven’t used for a while.

Recurse is not a word you are likely to utter very often, yet we soon learn that it means repeat an instruction, or drill down to a sub-directory.  I want to highlight this parameter because it caught me out.  Although I appended -recurse directly after the path, it did not drill down to the sub-directory, in fact it had no effect!  What went wrong?

The technical explanation was -recurse only works on leaf objects.  In plain English, if you specify an extension, for example: Get-ChildItem C:\Users\*.doc -recurse, then it has no effect.  But if you specify just the parent folder, Get-ChildItem C:\Users\ -recurse, then you get a listing of the files under C:\Users.  Ah yes, to get the desired filter append -include *.doc.  If this paragraph was gobbledy gook, just work your way through my examples below

Example 1 Get-ChildItem -recurse

Our mission is to list all the Windows files under the Program Files folder.  It was the positioning of -recurse that gave me my biggest headache.  My tactical error was to try and introduce -recurse into a long statement.  What I should have done was take my own advice and build up gradually like this:-

Stage 1 The Problem: The PowerShell script lists files only in the top level directory.

# PowerShell with just Get-ChildItem (no recurse)
Clear-Host
Get-ChildItem -path "C:\Program Files\"

Note 1: Get-Childitem is the equivalent of dir.  In fact PowerShell creates an alias called dir, thus this old command still works on the command line.

Stage 2 The Solution: -Recurse drills down and finds lots more files.

# PowerShell -recurse parameter
Clear-Host
Get-ChildItem -path "C:\Program Files\" -recurse

Note 2:  The key to -recurse is the position, it has to be directly after the directory.  In this example I have explicitly used -path to define the location.

Stage 3a Precise Solution:  -Recurse with a filter and wildcard* on the directory name.

# PowerShell -recurse parameter
Clear-Host
$Directory = "C:\Program Files\Windows*"
Get-ChildItem -path $Directory -recurse

Note 3: I wanted to highlight the path be assigning it to a variable, and thus make it easier for you to change the path to suit your task.

Stage 3b Filter for Executables

# PowerShell -recurse parameter with -include
Clear-Host
$Directory = "C:\Program Files\Windows*"
Get-ChildItem -path $Directory -recurse -include *.exe

Stage 3c  Neatly Sorted

# PowerShell -recurse parameter sorted!
Clear-Host
$Directory = "C:\Program Files\Windows*"
Get-ChildItem -path $Directory -recurse -include *.exe `
| Sort-Object Name | Format-Table Name, Fullname -auto

 

See more on Get-ChildItem parameters.

Guy Recommends: The Free IP Address Tracker (IPAT) IP Tracker

Calculating IP Address ranges is a black art, which many network managers solve by creating custom Excel spreadsheets.  IPAT cracks this problem of allocating IP addresses in networks in two ways:

For Mr Organized there is a nifty subnet calculator, you enter the network address and the subnet mask, then IPAT works out the usable addresses and their ranges. 

For Mr Lazy IPAT discovers and then displays the IP addresses of existing computers. Download the Free IP Address Tracker

Troubleshooting PowerShell -recurse

The problem with the -recurse parameter is that it only works where the object has leaf items, for example:
C: \Windows\  -recurse.  My point is, I was caught out by trying C: \Windows\*.dll -recurse.

To see my point try these two examples:

# PowerShell recurse finds executables under the Windows folder
Clear-Host
$Path = "C:\Windows\*.exe"
$WinExe = Get-ChildItem $Path -recurse
$WinExe.count

Note 4:  The answer was only about 17.  This script lists .exe files only in the actual Windows folder.  -recurse is useless here.

# PowerShell script to find ALL executables under Windows folder
Write-Host "Waiting for -recurse …"
$Path = "C:\Windows\"
$WinExe = Get-Childitem $Path -recurse -errorAction SilentlyContinue `
| Where-Object {$_.Extension -match "exe"}
Clear-Host
$WinExe.count

Note 5:  Expected answer over 2,000.  -recurse does its job.  ‘Where-Object’ plays its role in filtering.  Alternatively, you could employ the -include parameter.

Scope of the -recurse Parameter

While -recurse works nicely for the above Get-Childitem, I emphasise CHILDitem.  I could neither get it to work with Get-Item, nor could I see -recurse amongst the parameters listed for plain Get-Item.

Research: Find PowerShell -recurse Cmdlets

Clear-Host
Get-Command -CommandType cmdlet `
| where { $_.parameters.keys -contains "recurse"}

Incidentally, Get-Childitem | Get-Member does not, repeat not, list -recurse.  This is because -recurse is a parameter, or what I call a switch.  Get-Member lists methods and properties, but not parameters, to see more about -recurse you need:
Get-Help Get-Childitem.

Engineer's Toolset v10Guy Recommends: SolarWinds Engineer’s Toolset v10

This Engineer’s Toolset v10 provides a comprehensive console of 50 utilities for troubleshooting computer problems.  Guy says it helps me monitor what’s occurring on the network, and each tool teaches me more about how the underlying system operates.

There are so many good gadgets; it’s like having free rein of a sweetshop.  Thankfully the utilities are displayed logically: monitoring, network discovery, diagnostic, and Cisco tools.  Try the SolarWinds Engineer’s Toolset now!

Download your fully functional trial copy of the Engineer’s Toolset v10

Problems with -recurse, and how to overcome them

Case Study

The mission is to list all files containing the word ‘Microsoft’ in the Windows folder or its sub-folders.  For this we use the select-string pattern matching command.

The problem is that this script does not work.  All that happens is that we get an error: Cannot find path… Path does not exist.

# PowerShell -recurse example
Clear-Host
$i=0
$Path = "C:\Windows"
$Full = Get-ChildItem $Path -recurse
$StringText = "Microsoft"
$List = select-string -pattern $StringText $Full
foreach ($file in $List) {$file.Path; $i++}
$i

The Solution: Add the -include parameter

Clear-Host
$i=0
$Path = "C:\Windows"
$Full = Get-ChildItem $Path -include *.txt -recurse
$StringText = "Microsoft"
$List = select-string -pattern $StringText $Full
foreach ($file in $List) {$file.Path; $i++}
$i

Note 7:  When we add -include *.txt the cmdlet works as initially planned.  Actually, you could swap the famous *.* for *.txt, thus : -include *.*

Note 8: -include only works when you also append the -recurse parameter.

Note 9: -include applies to the filename and extension.  Where I made a mistake was thinking that -include would apply to the path.

Simplification

There is no reason why you cannot simplify the above example by removing at least two of the variables, especially on a production script.  The only reason that I employed $Path and $StringText is that when I am creating a script I like to isolate and control each step of the way.

$i=0
$Full = Get-ChildItem C:\windows -include *.txt -recurse
$List = select-string -pattern "Microsoft" $Full
foreach ($file in $List) {$file.Path; $i++}
$i

Summary of PowerShell -Recurse

-Recurse is a classic switch, which instructs PowerShell commands such as Get-ChildItem to repeat in sub directories.  Once you remember that -recurse comes directly after the directory, then it will serve you well in scripts that need to drill down to find information.

Guy Recommends: Tools4ever’s UMRAUMRA The User Management Resource Administrator

Tired of writing scripts? The User Management Resource Administrator solution by Tools4ever offers an alternative to time-consuming manual processes.

It features 100% auto provisioning, Helpdesk Delegation, Connectors to more than 130 systems/applications, Workflow Management, Self Service and many other benefits. Click on the link for more information onUMRA.

If you like this page then please share it with your friends

 


See more Microsoft PowerShell tasks:

PowerShell Home   • Shell Application   • New-Object   • PowerShell Add Printer   • PowerShell -com

PowerShell Logon Script  • Map Network Drive  • PowerShell Create Shortcut  • Free CSV Import Tool

Invoke-Expression   • Invoke-Command   • Invoke-Item   • PowerShell Expression v Command Mode

Please email me if you have a better example script. Also please report any factual mistakes, grammatical errors or broken links, I will be happy to correct the fault.