Skip to main content

Search for key words in PowerShell help files

One of my students from a PowerShell class a few weeks back was wondering if he could search PowerShell help files for key words and have those words highlighted in the help file.  This week I decided to tackle this one and here are the results.
Below is a screen shot of the function Search-Help
image
Please take the time to read through the help file.  The code below is presented as a function that can be turned into a module and added to your PowerShell profile.
This code is provided as is and without warranty or support.

Function Search-Help
{
[CmdletBinding(HelpUri = 'http://get-help-jason-yoder.blogspot.com/2012/10/search-help.html')]

Param(
    # Parameter $Cmdlet
    # The name of the parameter that you want to get help on.
    [Parameter(Mandatory=$true)]$Cmdlet,

    # Parameter $Words
    # The name of the parameter that you want to get help on.   
    [Parameter(Mandatory=$true)][String[]]$Words,

    # Parameter $Detailed
    # Parse the detailed help file of the cmdlet.
    [Switch]$Detailed,

    # Parameter $Detailed
    # Parse the full help file of the cmdlet.
    [Switch]$Full,

    # Parameter $MoreHighlight
    # Changes the highlighted text to a different
    # color set to make the search items stand out
    # better.
    [Switch]$MoreHighlight,

    # Parameter $ExactMatch
    # Changes the default behavior of the algorithm to
    # look for an exact match as opposed to a match
    # containing the query.
    [Switch]$ExactMatch

)
  
    # Supporting Function Compare-Strings -------------------------------------
    # Send this function:
    # 1: The word to examine.
    # 2: The word you want to see if it is in the first.
    # * and ? are acceptable wild car characters.
    # This function will return $TRUE is the $TestString contains the pattern
    # from $TestWord.  This function is the default behavior of the cmdlet.
    Function Compare-Strings
    {
    Param(
        [String]$TestString,
        [String]$TestWord
    )

        # Set the Return flag data
        [Boolean] $MatchFound = $False

        # Break the $TestString into a Cahr array
        $CharArray = $TestString.ToCharArray()

        # Loop through the CharArray, adding one character to the
        # Search to see if it matches.

        # The sting that holds the value to be tested.
        $TestArray = $Null

        # Controls the inner While loop and adds characters to be tested.
        $Index = 0

        # Controls the outer while loop and determines which characters
        # from the left to start the comparison with.
        $OuterIndex = 0

        Do
        {
            $Index = $OuterIndex
            Do
            {
                # Add a character to the test string
                $TestArray += $CharArray[$Index]
                If($TestArray -like $TestWord)
                {
                    $MatchFound = $True
                }
           
                # Increment the control variable.
                $Index++
           
            } While ($Index -Lt $TestString.length)

            # Clear the TestArray
            $TestArray = $Null
           
            # Increment the control variable
            $OuterIndex++
       
        } While ($OuterIndex -lt $TestString.length)
       
        # Return the data to the calling command.
        Write-Output $MatchFound
    }
    # End Supporting Function Compare-Strings ---------------------------------

    # Supporting Function Compare-StringsExact --------------------------------
    # Send this function:
    # 1: The word to examine.
    # 2: The word you want to see if it is in the first.
    # This function will return TRUE only if there is an exact match. 
    Function Compare-StringsExact
    {
    Param(
        [String]$TestString,
        [String]$TestWord
    )
        # Set the Return flag data
        [Boolean] $MatchFound = $False
       
        If($TestString -eq $TestWord)
        {
            $MatchFound = $True
        }

        # Test to see if a match is made by removing any end punctuation.
        If($TestString -match "\w*")
        {
            If($Matches.Values -eq $TestWord)
            {
                $MatchFound = $True
            }
        }
       
        # Return the data to the calling command.
        Write-Output $MatchFound       

    }
    # End Supporting Function Compare-StringsExact ----------------------------

    # get the help file from PowerShell.
    If($Detailed)
        {$HelpData = (Get-Help $Cmdlet -Detailed) | Out-String -Stream}
    ElseIf($Full)
        {$HelpData = Get-Help $Cmdlet -Full | Out-String -Stream}
    Else
        {$HelpData = Get-Help $Cmdlet | Out-String -Stream}


    # Set a counter to keep track of how many matches are found.
    $MatchCounter = 0

    # Validate the phrase that was sent to remove
    # any solo "*" or "?".
    $SearchPhrase = @()
    $Wordss = $Words.split(",")
    $InvalidItems = @()
    Foreach ($Item in $Wordss)
    {
        If (($Item -ne "*") -and ($Item -ne "?") -and (($Item.ToCharArray())[0] -ne "*") -and (($Item.ToCharArray())[0] -ne "?"))
        {
            $SearchPhrase += $Item
        }
        Else
        {
            $InvalidItems += $Item
        }
    }
    
    # Cycle through each line of the help file.   
    Foreach ($Item in $HelpData)
    {

        # Split each line into its individual words.           
        $StringData = $Item.Split()
       
        # Cycle through every word in the current help file line.
        ForEach ($DataItem in $StringData)
        {
            # Set this flag to $True is a match is found.
            $Found = $False
           
            # Cycle through each searchword.
            foreach ($Item in $SearchPhrase)
            {
                # Use the correct function depending on if the $ExactMatch flag is set.
                If ($ExactMatch)
                {
                   $ReturnedMatch = Compare-StringsExact $DataItem $Item
                }
                Else {$ReturnedMatch = Compare-Strings $DataItem $Item}
           
                If ($ReturnedMatch){$Found = $True}
            }
          
                # If the $Found flag is set to $True, then display the word
                # in highlighted text.  If not, display the word using the
                # current color settings in the shell.
                If ($Found)
                {
                    If (-Not $MoreHighlight)
                    {
                        Write-Host "$DataItem" -ForegroundColor Magenta -BackgroundColor DarkBlue -NoNewline
                        Write-Host " " -NoNewline
                    }
                    Else
                    {
                        Write-Host "$DataItem" -ForegroundColor Green -BackgroundColor DarkGreen -NoNewline
                        Write-Host " " -NoNewline
                    }
                    # Incriment the $MatchCounter.
                    $MatchCounter++
                }
                Else
                {
                    Write-Host "$DataItem " -NoNewline
                }
           
        }
        # This adds a carriage return to the line to ensure the output resembles
        # the original help file as much as possible.
        Write-Host ""
    }

    # Write an extra line of data to the end of the help file to let the user
    # know if a match was found.
    Write-Host "-- Search Results: -------------------------------------------------------------"
    If ($MatchCounter -gt 0)
    {
        Write-Host "Your search returned " -NoNewline
        Write-Host "$MatchCounter" -ForegroundColor Green -BackgroundColor DarkBlue  -NoNewline
        Write-Host " matches."
        Write-Host "Items searched for:"
        foreach ($Item in $SearchPhrase)
        {
            Write-Host $Item -ForegroundColor Green -BackgroundColor DarkBlue
        }
        If($InvalidItems.count -gt 0)
        {
            Write-Host "Invalid search items removed from the query:"
            foreach ($Item in $InvalidItems)
            {
                Write-Host $Item -ForegroundColor Red -BackgroundColor DarkBLue
            }
        }
    }
    Else
    {
        Write-Host "No matches were found."
    }
<#
.SYNOPSIS
Searches PowerShell help files for specific words.

.DESCRIPTION
Searches through PowerShell help files for words and highlights those words in the actual help files. 
The default setting for this cmdlet is to search for the pattern specified in the WORDS parameter in each word of the help file.

.PARAMETER Cmdlet
The cmdlet or About file that you want to search for specific words.

.PARAMETER Words
Comma separated list of words that you want to search for.  The words can contain * and ? characters but cannot start with a * or ? character.

.PARAMETER Detailed
Searches the cmdlets detailed help file.

.PARAMETER Full
Searches the cmdlets full help file.

.PARAMETER MoreHighlight
Displays the queried words in a higher contrast color scheme which may make the output more readable to some users.

.PARAMETER ExactMatch
This will change the pattern recognition to an exact match (not case sensitive).  Wildcard characters are not accepted.

.EXAMPLE
Search-Help Get-Date -Words Date

Returns the standard help file for the cmdlet Get-Date and highlights all words that match or contains "Date".

.EXAMPLE
Search-Help Get-Process P*ess, more, t?pe -MoreHighlight

Returns the standard help file for the cmdlet Get-Date and highlights all words that match or contains "Date" as well as "P*ess" and "T?py"
The "*" character is a wild card character that allows for multiple characters to exists in its place.
The "?" character is a wild card character that allows for a single character to exists in its place.
The highlighted words will also be returned in greater contrast.

.EXAMPLE
Search-Help About_Comparison_Operators "-Match"

Returns the help file for About_Comparison_Operators with all words matching or contains "-Match" highlighted.

.EXAMPLE
Search-Help Get-Process -detailed Process

Returns the detailed help file for the cmdlet Get-Date and highlights all words that match or contains "Date".

.EXAMPLE
Search-Help Get-Process -Words Process -ExactMatch

Returns the standard help file for Get-Process with all words that exactly match "Process" highlighted.

.NOTES
This cmdlet sends customized output to the host one line at a time.  For this reason, standard object output for PowerShell is not utilized.

.LINK
Online Version: http://get-help-jason-yoder.blogspot.com/2012/10/search-help.html
Get-Help
#>
}

Comments

Popular posts from this blog

Adding a Comment to a GPO with PowerShell

As I'm writing this article, I'm also writing a customization for a PowerShell course I'm teaching next week in Phoenix.  This customization deals with Group Policy and PowerShell.  For those of you who attend my classes may already know this, but I sit their and try to ask the questions to myself that others may ask as I present the material.  I finished up my customization a few hours ago and then I realized that I did not add in how to put a comment on a GPO.  This is a feature that many Group Policy Administrators may not be aware of. This past summer I attended a presentation at TechEd on Group Policy.  One organization in the crowd had over 5,000 Group Policies.  In an environment like that, the comment section can be priceless.  I always like to write in the comment section why I created the policy so I know its purpose next week after I've completed 50 other tasks and can't remember what I did 5 minutes ago. In the Group Policy module for PowerShell V3, th

Return duplicate values from a collection with PowerShell

If you have a collection of objects and you want to remove any duplicate items, it is fairly simple. # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   # Remove the duplicate values. $Set1 | Select-Object -Unique 1 2 3 4 5 6 7 What if you want only the duplicate values and nothing else? # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   #Create a second collection with duplicate values removed. $Set2 = $Set1 | Select-Object -Unique   # Return only the duplicate values. ( Compare-Object -ReferenceObject $Set2 -DifferenceObject $Set1 ) . InputObject | Select-Object – Unique 1 2 This works with objects as well as numbers.  The first command creates a collection with 2 duplicates of both 1 and 2.   The second command creates another collection with the duplicates filtered out.  The Compare-Object cmdlet will first find items that are diffe

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.