Public/Find-PSUFilesContainingText.ps1


function Find-PSUFilesContainingText {
<#
.SYNOPSIS
    Searches files for a specific text string.
 
.DESCRIPTION
    Recursively or non-recursively searches files in a directory for a given text string, with options to filter by extension and exclude certain file types.
 
.PARAMETER SearchPath
    Directory to search.
 
.PARAMETER SearchText
    Text to search for in files.
 
.PARAMETER FileExtension
    Only search files with this extension.
 
.PARAMETER ExcludeExtensions
    Array of file extensions to exclude.
 
.PARAMETER NoRecurse
    If specified, search only the top-level directory.
 
.EXAMPLE
    Find-PSUFilesContainingText -SearchPath 'C:\Projects' -SearchText 'TODO'
 
.NOTES
    Author: Lakshmanachari Panuganti
    File Creation Date: 2025-06-27
#>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [ValidateScript({
            if (-Not (Test-Path -Path $_)) {
                throw "Directory path '$_' does not exist."
            }
            return $true
        })]
        [string]$SearchPath,

        [Parameter(Mandatory)]
        [string]$SearchText,

        [Parameter()]
        [string]$FileExtension,

        [Parameter()]
        [string[]]$ExcludeExtensions = @('exe','dll','msi','bin','jpg','png','zip','iso','img','sys'),

        [Parameter()]
        [switch]$NoRecurse
    )

    if ($FileExtension) {
        Write-Verbose "Searching for '*.$FileExtension' files in '$SearchPath' containing text: '$SearchText'..."
        $filter = "*.$FileExtension"
    } else {
        Write-Verbose "Searching all files in '$SearchPath' containing text: '$SearchText'..."
        $filter = "*"
    }

    if ($NoRecurse) {
        Write-Verbose "Recursion disabled. Searching only in the top-level directory."
        $files = Get-ChildItem -Path $SearchPath -File -Filter $filter -ErrorAction SilentlyContinue
    } else {
        Write-Verbose "Recursively searching subdirectories..."
        $files = Get-ChildItem -Path $SearchPath -Recurse -File -Filter $filter -ErrorAction SilentlyContinue
    }

    # Exclude files with specified extensions
    $files = $files | Where-Object {
        $ext = $_.Extension.TrimStart('.').ToLower()
        -not ($ExcludeExtensions -contains $ext)
    }

    $matchedFiles = foreach ($file in $files) {
        if (Select-String -Path $file.FullName -Pattern $SearchText -Quiet) {
            $file.FullName
        }
    }

    if ($matchedFiles) {
        $matchedFiles
    } else {
        if ($FileExtension) {
            Write-Warning "⚠️ No *.$FileExtension files found containing '$SearchText' in '$SearchPath'."
        } else {
            Write-Warning "⚠️ No files found containing '$SearchText' in '$SearchPath'."
        }
    }
}