Skip to content

Instantly share code, notes, and snippets.

@mklement0
Last active April 3, 2019 16:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mklement0/9eaf051fdb2289d3dc066938ffbae632 to your computer and use it in GitHub Desktop.
Save mklement0/9eaf051fdb2289d3dc066938ffbae632 to your computer and use it in GitHub Desktop.
Edition-agnostic PowerShell script/function for locating help-topic source files, optionally by part of their file name.
<#
NOTE:
It is BEST TO DOT-SOURCE (.) THIS SCRIPT, which defines a function of the same
name for later use.
While it is possible to invoke this script directly, its help can then only
be invoked with the -? switch, providing only terse help,
whereas dot-sourcing provides full Get-Help integration.
Similarly, only with dot-sourcing do you get tab completion.
#>
function Get-HelpFile {
<#
.SYNOPSIS
Locates help source files, optionally by part of their file names.
.PARAMETER FileNamePart
Part of the base file name (the filename without the extension) of help files
to locate.
If you specify multiple arguments, they are looked for in sequence.
If no argument is given, all installed help files are output.
.NOTES
This function is helpful for tracking down multiple versions of help topics.
Note:
* Conceptual help topic are usually provided as individual *.help.txt
plain-text files.
* Command-specific help topics are usually bundled into module-specific
*-help.xml files that contain MAML.
While the file names typically contain the module's name as-is, that isn't
necessarily the case; notably, the topics for the built-in commands in
* module Microsoft.PowerShell.Core are in file
System.Management.Automation.dll-Help.xml
* module Microsoft.PowerShell.Management are in file
Microsoft.PowerShell.Commands.Management.dll-Help.xml
.EXAMPLE
Get-HelpFile readline
Locates help files whose base file names contain the substring 'readline'
(case-insensitively), presumed to relate to the PSReadLine module.
#>
[OutputType([System.IO.FileInfo])]
[CmdletBinding(PositionalBinding=$false)]
param(
[Parameter(Position=0)]
[string[]] $FileNamePart
)
if (-not $FileNamePart) { $FileNamePart = '' }
$searchBaseDirs = Split-Path ($env:PSModulePath -split [IO.Path]::PathSeparator)
foreach ($str in $FileNamePart) {
foreach ($searchBaseDir in $searchBaseDirs) {
# Note: PS Core allows combining -Filter with -Include, but WinPS does not.
Get-ChildItem -File -LiteralPath $searchBaseDir -Recurse -Filter *$str* |
Where-Object Name -match '(?:\.help\.txt|-help.xml)$'
}
}
}
# -- Generic code that handles the invocation if this script file is invoked directly.
if ($MyInvocation.InvocationName -eq '.' -or $MyInvocation.Line -eq '') { # Being dot-sourced
if ($MyInvocation.Line -eq '' -and $host.Name -eq 'Visual Studio Code Host') { # Support for debugging in VSCode
# If the current file is directly launched for debugging from the editor,
# use a custom invocation with arguments for debugging.
Write-Warning 'VSCode debugging: Invoking embedded function with custom arguments.'
& ([System.IO.Path]::GetFileNameWithoutExtension($PSCommandPath)) # Add arguments for debugging here.
} else {
# Nothing further to do: the function has been defined in the current scope for *later* use.
# However, we warn if arguments were unexpectedly passed or something is being piped.
if ($Args.Count -or $MyInvocation.ExpectingInput) { Write-Warning "Ignoring arguments and/or pipeline input due to being dot-sourced: $PSCommandPath" }
}
} else { # Script is invoked directly (by name/path directly or via &)
# Call the embedded function of the same name, relaying any arguments passed.
if ($MyInvocation.ExpectingInput) { # pipeline input present
$Input | & ([System.IO.Path]::GetFileNameWithoutExtension($PSCommandPath)) @Args
} else { # only arguments, if any
& ([System.IO.Path]::GetFileNameWithoutExtension($PSCommandPath)) @Args
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment