A PowerShell Recursive Function

I was recently in a position where I was asked to provide an example of a PowerShell recursive function. Unfortunately, I didn’t have time to do that as it was a part of a written, and timed test. Sadly, I didn’t even really have time to review the other 50-some answers I had already provided. I mostly knew that might happen.

Anyway, the challenge has been eating at me, so why not write an example and share it. It’ll be good for you, as it will be for me too. It’s out there, but it’s not often utilized that I’m aware. A recursive function is a function that calls, or invokes, itself. For real. We’re not referring to a function, or cmdlet, that includes a Recurse parameter. Now that said, it’s possible that some of these commands, with that parameter do this (call themselves), but I’ve yet to take a look to see for sure.

After you see today’s example, you’ll begin to understand why you might prefer to do things this way. If you can wrap your head around the concept, you’ll understand that it can reduce a portion of code writing on your part. Join me at https://tommymaynard.com to finish this article. Here’s the direct link.

≥ Tommy Maynard (Twitter: @thetommymaynard)

About Tommy Maynard

IT Pro. Passionate for #PowerShell, #AWS (certified x2), & all things automation. I'm not done learning. Author in #PSConfBook. Writes at https://powershell.org.

2 thoughts on “A PowerShell Recursive Function

  1. KenStr42

    Hey Tommy,
    I created this function to go through a few folders that collect stuff over time (Downloads, temp, etc) and clean out anything older than 30 days. There is a param to check subdirectories. When enabled it will iterate through all subfolders, deleting all files that meet the date criteria. Any empty folders will be deleted. Console feedback is included along with logging to a custom event log. Both of these elements are optional. I just like having feedback and a record of deletions. I included code on calling the script and checking for the custom log. Thx

    ###
    function DeleteOldItems ($path, [bool]$checkSubDir) {
    function RemoveIt ($itemName, $itemLastWriteTime) {
    try {
    Remove-Item -Path $itemName -Force -Confirm:$false -ErrorAction Stop
    Write-EventLog -LogName “Delete Old Items” -Source “MyDeletedItems” -EventId 4001 -EntryType Information
    -Message "$itemName deleted successfully.
    nnLast Write Time: $itemLastWriteTime"
    Write-Host "$itemName deleted successfully." -ForegroundColor Green -NoNewline
    Write-Host "$itemLastWriteTime" -ForegroundColor Magenta
    }
    catch [System.Exception] {
    Write-Host "ERROR: $($_.exception.message)" -ForegroundColor Yellow
    Write-EventLog -LogName "Delete Old Items" -Source "MyDeletedItems" -EventId 4002 -EntryType Warning

    -Message “ERROR: $($_.exception.message)”
    }
    finally {}
    }

    $dateToCheck = (Get-Date).AddDays(-30)
    $files = Get-ChildItem -Path $path -File
    $directories = Get-ChildItem -Path $path -Directory

    if ($checkSubDir) {
    foreach ($dir in $directories) {
    Write-Host “SUBFOLDER: $($dir.fullname)” -ForegroundColor Cyan
    DeleteOldItems -path $dir.FullName -checkSubDir $true

    if ($null -eq (Get-ChildItem $dir.FullName)) {
    Write-host “$($dir.fullname) is empty and will be deleted.” -ForegroundColor Magenta
    RemoveIt -itemName $dir.FullName -itemLastWriteTime $dir.LastWriteTime
    }
    }
    }

    foreach ($file in $files) {
    if ($file.LastWriteTime -le $dateToCheck)
    {RemoveIt -itemName $file.FullName -itemLastWriteTime $file.LastWriteTime}
    }

    }

    ### Script Entry ###
    #Requires -RunAsAdministrator
    if (![System.Diagnostics.EventLog]::Exists(“Delete Old Items”)) {
    New-EventLog -LogName “Delete Old Items” -Source “MyDeletedItems” -ErrorAction SilentlyContinue
    Write-Host “‘Delete Old Items’ log has been created successfully” -ForegroundColor Green
    }

    $paths = “C:\Users\Ken\Downloads, “E:\TEST”, $env:Temp
    foreach ($path in $paths) {
    DeleteOldItems -path $path -checkSubDir $true
    }
    #Read-Host “Press any key to exit”

  2. KenStr42

    Forgot to mention the recursion piece to this. The DeleteOldItems is called inside itself when checking subdirs. It will actually iterate to the last subfolder first and works it way back to the parent. Super handy. Thx

Comments are closed.