Public/Get-CommandHistory.ps1
function Get-CommandHistory { <# .SYNOPSIS Get a filtered and de-duplicated list of commands from your history. .DESCRIPTION This function filters the output of Get-History to exclude a list of ignored commands and any commands that are less than 4 characters long. It can also be used to find all commands that match a given pattern. It is useful for quickly finding things from your history that you want to document or re-invoke. .PARAMETER All Show all command history without filtering anything out. .PARAMETER Exclude A string or array of strings to exclude. Commands that have these words in them will be excluded from the history output. The default ignored commands are: Get-History, Invoke-CommandHistory, Get-CommandHistory, clear. .PARAMETER Filter A string or regex pattern to find in the command history. Commands that contain this pattern will be returned. The Filter is passed to the -match operator, so it can be a simple string or a more complex regex pattern. .EXAMPLE Get-CommandHistory -Filter 'Disk' This will return all commands from your history that contain the word 'Disk'. .EXAMPLE Get-CommandHistory -Exclude 'Get-Service', 'Get-Process' This will return all commands from your history that do not contain the words 'Get-Service' or 'Get-Process' (while also still filtering out the default ignore list). .EXAMPLE Get-CommandHistory -All This will return all commands from your history without any filtering. .NOTES Author: Sam Erde Version: 2.0.0 Modified: 2025-09-08 #> [CmdletBinding(DefaultParameterSetName = 'BasicFilter')] [Alias('gch')] [OutputType([Microsoft.PowerShell.Commands.HistoryInfo[]])] param ( # Show all command history without filtering anything out. [Parameter(ParameterSetName = 'NoFilter')] [switch] $All, # A string or array of strings to exclude from the command history list. [Parameter()] [ValidateNotNullOrEmpty()] [string[]] $Exclude, # A string or regex Filter to search for matches in the command history. [Parameter()] [ValidateNotNullOrEmpty()] [string[]] $Filter ) begin { # Send non-identifying usage statistics to PostHog. Write-PSPreworkoutTelemetry -EventName $MyInvocation.MyCommand.Name -ParameterNamesOnly $MyInvocation.BoundParameters.Keys # Initialize variables if (-not $All.IsPresent) { # Set the default list of commands to ignore as a regex pattern of strings [string]$DefaultIgnoreCommands = 'Get-History|Invoke-CommandHistory|Get-CommandHistory|clear' # Build initial filter conditions to get completed commands. # TO DO: Create a switch parameter to include incomplete commands. [string[]]$FilterConditions = @('$_.ExecutionStatus -eq "Completed"') # Filter words to exclude if ($Exclude.Length -gt 0) { [string]$IgnorePattern = "$DefaultIgnoreCommands|$($Exclude -join '|')" $FilterConditions += "`$_.CommandLine -notmatch '$IgnorePattern'" } else { $FilterConditions += "`$_.CommandLine -notmatch '$DefaultIgnoreCommands'" } # Filter words to include if ($Filter -and $Filter.Length -gt 0) { # Additional check to ensure we have non-empty filter strings [string[]]$NonEmptyFilters = $Filter | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } if ($NonEmptyFilters.Length -gt 0) { # Create the regex string pattern [string]$MatchPattern = ($NonEmptyFilters -join '|').Trim() $FilterConditions += "`$_.CommandLine -match '$MatchPattern'" } } # Combine all filter conditions with -and [string]$FilterExpression = $FilterConditions -join ' -and ' [scriptblock]$WhereFilter = [scriptblock]::Create($FilterExpression) } else { # If the All switch is present, do not filter anything out. [scriptblock]$WhereFilter = { $true } } } process { Get-History | Where-Object -FilterScript $WhereFilter | Sort-Object -Property CommandLine -Unique | Sort-Object -Property Id } } # end function Get-CommandHistory |