PowerShell Scripts Searcher | Quisitive
PowerShell Scripts Searcher
June 19, 2018
Matthew Dowst
I’ve written a function that I can use to search all the PowerShell scripts on my computer for a specific word or phrase.

If you are like me, then you are writing PowerShell scripts for pretty much everything nowadays, and even if you aren’t like me, chances are you still have a bunch of PowerShell scripts saved on your computer. I can’t tell you how many times I’m writing a script, and I realize that I’ve already written something similar. However, at my last count, I had closed to 4,000 PowerShell scripts on my computer. As you can imagine finding the one I’m thinking about can be kind of difficult. So, that is why I’ve written a function that I can use to search all the PowerShell scripts on my computer for a specific word or phrase.

All you have to do is pass the string to search for and the folder to look in. It will then find all the ps1 and psm1 files in that folder. Then it will check each one for the string you specified. For all matches, it will display the full path to the script and the last time it was written to.

PowerShell Scripts

If you don’t supply a value for path it will default to the path of your user profile. You can also specify whether or not to perform a recursive search. By default, the search is not recursive, meaning it will only search the folder provided in the path, and not the sub-folders. If you provide the Recurse parameter it will also search the sub-folders.

PowerShell Scripts

You can also use the -Verbose parameter to display the lines that matched your string in each of the files it found.

PowerShell Scripts

You can download the most current version of the script from my GitHub Gist or copy it from below.

Function Search-PSScripts{
<#
.SYNOPSIS
Use to search the text inside PowerShell scripts for a particular string
.PARAMETER SearchString
The string to search for inside the script file
    
.PARAMETER Path
The folder path to search for PowerShell files in. Default to userprofile if not specified.
.PARAMETER Recurse
Indicates that this function gets the items in the specified locations and in all child items of the locations.
.EXAMPLE 
Search-PSScripts -searchString "Get-Help" -recurse
Description
-----------
This command searches all of the script files in the user's profile path and its subdirectories.
.EXAMPLE 
Search-PSScripts -searchString "Invoke-WebRequest" -path 'C:\Scripts' -recurse
Description
-----------
This command searches all of the script files in the current directory and its subdirectories.
.EXAMPLE 
Search-PSScripts -searchString "Invoke-WebRequest" -path 'C:\Scripts' 
Description
-----------
This command searches only the script files in the current directory.
#>
    [cmdletbinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]$SearchString, 
	    [Parameter(Mandatory=$false)]
        [string]$Path = $env:USERPROFILE,
        [Parameter(Mandatory=$false)]
        [switch]$Recurse
    )

    $filter = "*.ps1","*.psm1"

    # Confirm path is valid
    if(!(Test-Path $Path)){
        throw "'$Path' is not a valid folder or is not accessible."
    }

    # Get the name of this script to exclude it
    $Invocation = (Get-Variable MyInvocation -Scope 1).Value;

    
    $progressParam = @{
        Activity = "Search for PowerShell Script in $Path"
        Status = "Depending on the number of scripts this may take some time"
        PercentComplete = 0
        id = 1
        }
    Write-Progress @progressParam
    
    # Get all files in the path
    if($Recurse){
        $fileList = Get-ChildItem $Path -Recurse -include $filter -Exclude $Invocation.MyCommand -File
    } else {
        $Path = (Join-Path $Path '*.*')
        $fileList = Get-ChildItem $Path -include $filter -Exclude $Invocation.MyCommand -File
    }

    [System.Collections.Generic.List[PSObject]] $results = @()
    $progress=1
    # Check each file for the string pattern
    Foreach($file in $fileList){
        $progressParam = @{
            Activity = "Search for '$SearchString' - $progress of $(@($fileList).count)"
            Status = "Found: $(@($results).count)"
            PercentComplete = $(($progress/$($fileList.count))*100)
            id = 1
            }
        Write-Progress @progressParam
        $progress++
        $found = Select-String -Path $file.fullname -pattern $SearchString 
        if($found){
            Write-Verbose ($found | Out-String)
            $results.Add(($file | Select-Object LastWriteTime, FullName))
        }
    }
    Write-Progress -Activity "Done" -Id 1 -Completed

    # Return found scripts sorted by last write time
    $results | sort LastWriteTime
}