Last active
April 28, 2021 23:06
-
-
Save mklement0/46fea9e6e5ef1a3ceaf681c976cb68e3 to your computer and use it in GitHub Desktop.
PowerShell function that wraps Select-String to make it search the formatted representations of its input objects.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
Prerequisites: PowerShell v3+ | |
License: MIT | |
Author: Michael Klement <[email protected]> | |
DOWNLOAD and DEFINITION OF THE FUNCTION: | |
irm https://gist.github.com/mklement0/46fea9e6e5ef1a3ceaf681c976cb68e3/raw/Select-StringFormatted.ps1 | iex | |
The above directly defines the function below in your session and offers guidance for making it available in future | |
sessions too. | |
DOWNLOAD ONLY: | |
irm https://gist.github.com/mklement0/46fea9e6e5ef1a3ceaf681c976cb68e3/raw > Select-StringFormatted.ps1 | |
The above downloads to the specified file, which you then need to dot-source to make the function available | |
in the current session: | |
. ./Select-StringFormatted.ps1 | |
To learn what the function does: | |
* see the next comment block | |
* or, once downloaded and defined, invoke the function with -? or pass its name to Get-Help. | |
To define an ALIAS for the function, (also) add something like the following to your $PROFILE: | |
Set-Alias scs Select-StringFormatted | |
#> | |
function Select-StringFormatted { | |
<# | |
.SYNOPSIS | |
Select-String wrapper command that for non-string input | |
searches the *formatted* object representations rather than the often | |
useless .ToString() representations. | |
All Select-String parameters as of PowerShell 7.0 are supported - see the latter's help. | |
If you try to use a parameter that was only introduced in 7.0 in an earlier version, it is | |
ignored, and a warning is emitted. | |
.EXAMPLE | |
Get-Process | Select-StringFormatted pwsh | |
Output lines that contain "pwsh" in Get-Process' formatted output. | |
.LINK | |
Select-String | |
#> | |
[CmdletBinding(DefaultParameterSetName = 'File', HelpUri = 'https://go.microsoft.com/fwlink/?LinkID=2097119')] | |
param( | |
[ValidateSet('Ordinal', 'Invariant', 'Current', '', 'af', 'af-NA', 'af-ZA', 'agq', 'agq-CM', 'ak', 'ak-GH', 'am', 'am-ET', 'ar', 'ar-001', 'ar-AE', 'ar-BH', 'ar-DJ', 'ar-DZ', 'ar-EG', 'ar-EH', 'ar-ER', 'ar-IL', 'ar-IQ', 'ar-JO', 'ar-KM', 'ar-KW', 'ar-LB', 'ar-LY', 'ar-MA', 'ar-MR', 'ar-OM', 'ar-PS', 'ar-QA', 'ar-SA', 'ar-SD', 'ar-SO', 'ar-SS', 'ar-SY', 'ar-TD', 'ar-TN', 'ar-YE', 'arn', 'arn-CL', 'as', 'as-IN', 'asa', 'asa-TZ', 'ast', 'ast-ES', 'az', 'az-Cyrl', 'az-Cyrl-AZ', 'az-Latn', 'az-Latn-AZ', 'ba', 'ba-RU', 'bas', 'bas-CM', 'be', 'be-BY', 'bem', 'bem-ZM', 'bez', 'bez-TZ', 'bg', 'bg-BG', 'bm', 'bm-ML', 'bn', 'bn-BD', 'bn-IN', 'bo', 'bo-CN', 'bo-IN', 'br', 'br-FR', 'brx', 'brx-IN', 'bs', 'bs-Cyrl', 'bs-Cyrl-BA', 'bs-Latn', 'bs-Latn-BA', 'byn', 'byn-ER', 'ca', 'ca-AD', 'ca-ES', 'ca-FR', 'ca-IT', 'ccp', 'ccp-BD', 'ccp-IN', 'ce', 'ce-RU', 'ceb', 'ceb-PH', 'cgg', 'cgg-UG', 'chr', 'chr-US', 'ckb', 'ckb-IQ', 'ckb-IR', 'co', 'co-FR', 'cs', 'cs-CZ', 'cv', 'cv-RU', 'cy', 'cy-GB', 'da', 'da-DK', 'da-GL', 'dav', 'dav-KE', 'de', 'de-AT', 'de-BE', 'de-CH', 'de-DE', 'de-IT', 'de-LI', 'de-LU', 'dje', 'dje-NE', 'dsb', 'dsb-DE', 'dua', 'dua-CM', 'dv', 'dv-MV', 'dyo', 'dyo-SN', 'dz', 'dz-BT', 'ebu', 'ebu-KE', 'ee', 'ee-GH', 'ee-TG', 'el', 'el-CY', 'el-GR', 'en', 'en-001', 'en-150', 'en-AD', 'en-AE', 'en-AG', 'en-AI', 'en-AL', 'en-AR', 'en-AS', 'en-AT', 'en-AU', 'en-BA', 'en-BB', 'en-BD', 'en-BE', 'en-BG', 'en-BI', 'en-BM', 'en-BR', 'en-BS', 'en-BW', 'en-BZ', 'en-CA', 'en-CC', 'en-CH', 'en-CK', 'en-CL', 'en-CM', 'en-CN', 'en-CO', 'en-CX', 'en-CY', 'en-CZ', 'en-DE', 'en-DG', 'en-DK', 'en-DM', 'en-EE', 'en-ER', 'en-ES', 'en-FI', 'en-FJ', 'en-FK', 'en-FM', 'en-FR', 'en-GB', 'en-GD', 'en-GG', 'en-GH', 'en-GI', 'en-GM', 'en-GR', 'en-GU', 'en-GY', 'en-HK', 'en-HR', 'en-HU', 'en-ID', 'en-IE', 'en-IL', 'en-IM', 'en-IN', 'en-IO', 'en-IS', 'en-IT', 'en-JE', 'en-JM', 'en-JP', 'en-KE', 'en-KI', 'en-KN', 'en-KR', 'en-KY', 'en-LC', 'en-LR', 'en-LS', 'en-LT', 'en-LU', 'en-LV', 'en-ME', 'en-MG', 'en-MH', 'en-MM', 'en-MO', 'en-MP', 'en-MS', 'en-MT', 'en-MU', 'en-MV', 'en-MW', 'en-MX', 'en-MY', 'en-NA', 'en-NF', 'en-NG', 'en-NL', 'en-NO', 'en-NR', 'en-NU', 'en-NZ', 'en-PG', 'en-PH', 'en-PK', 'en-PL', 'en-PN', 'en-PR', 'en-PT', 'en-PW', 'en-RO', 'en-RS', 'en-RU', 'en-RW', 'en-SA', 'en-SB', 'en-SC', 'en-SD', 'en-SE', 'en-SG', 'en-SH', 'en-SI', 'en-SK', 'en-SL', 'en-SS', 'en-SX', 'en-SZ', 'en-TC', 'en-TH', 'en-TK', 'en-TO', 'en-TR', 'en-TT', 'en-TV', 'en-TW', 'en-TZ', 'en-UA', 'en-UG', 'en-UM', 'en-US', 'en-US-POSIX', 'en-VC', 'en-VG', 'en-VI', 'en-VU', 'en-WS', 'en-ZA', 'en-ZM', 'en-ZW', 'eo', 'eo-001', 'es', 'es-419', 'es-AG', 'es-AI', 'es-AR', 'es-AW', 'es-BB', 'es-BL', 'es-BM', 'es-BO', 'es-BQ', 'es-BR', 'es-BS', 'es-BZ', 'es-CA', 'es-CL', 'es-CO', 'es-CR', 'es-CU', 'es-CW', 'es-DM', 'es-DO', 'es-EA', 'es-EC', 'es-ES', 'es-FK', 'es-GD', 'es-GF', 'es-GL', 'es-GP', 'es-GQ', 'es-GT', 'es-GY', 'es-HN', 'es-HT', 'es-IC', 'es-KN', 'es-KY', 'es-LC', 'es-MF', 'es-MQ', 'es-MS', 'es-MX', 'es-NI', 'es-PA', 'es-PE', 'es-PH', 'es-PM', 'es-PR', 'es-PY', 'es-SR', 'es-SV', 'es-SX', 'es-TC', 'es-TT', 'es-US', 'es-UY', 'es-VC', 'es-VE', 'es-VG', 'es-VI', 'et', 'et-EE', 'eu', 'eu-ES', 'ewo', 'ewo-CM', 'fa', 'fa-AF', 'fa-IR', 'ff', 'ff-Latn', 'ff-Latn-BF', 'ff-Latn-CM', 'ff-Latn-GH', 'ff-Latn-GM', 'ff-Latn-GN', 'ff-Latn-GW', 'ff-Latn-LR', 'ff-Latn-MR', 'ff-Latn-NE', 'ff-Latn-NG', 'ff-Latn-SL', 'ff-Latn-SN', 'fi', 'fi-FI', 'fil', 'fil-PH', 'fo', 'fo-DK', 'fo-FO', 'fr', 'fr-BE', 'fr-BF', 'fr-BI', 'fr-BJ', 'fr-BL', 'fr-CA', 'fr-CD', 'fr-CF', 'fr-CG', 'fr-CH', 'fr-CI', 'fr-CM', 'fr-DJ', 'fr-DZ', 'fr-FR', 'fr-GA', 'fr-GF', 'fr-GN', 'fr-GP', 'fr-GQ', 'fr-HT', 'fr-KM', 'fr-LU', 'fr-MA', 'fr-MC', 'fr-MF', 'fr-MG', 'fr-ML', 'fr-MQ', 'fr-MR', 'fr-MU', 'fr-NC', 'fr-NE', 'fr-PF', 'fr-PM', 'fr-RE', 'fr-RW', 'fr-SC', 'fr-SN', 'fr-SY', 'fr-TD', 'fr-TG', 'fr-TN', 'fr-VU', 'fr-WF', 'fr-YT', 'fur', 'fur-IT', 'fy', 'fy-NL', 'ga', 'ga-IE', 'gaa', 'gaa-GH', 'gd', 'gd-GB', 'gez', 'gez-ER', 'gez-ET', 'gl', 'gl-ES', 'gn', 'gn-PY', 'gsw', 'gsw-CH', 'gsw-FR', 'gsw-LI', 'gu', 'gu-IN', 'guz', 'guz-KE', 'gv', 'gv-IM', 'ha', 'ha-GH', 'ha-NE', 'ha-NG', 'haw', 'haw-US', 'he', 'he-IL', 'hi', 'hi-IN', 'hi-Latn', 'hr', 'hr-BA', 'hr-HR', 'hsb', 'hsb-DE', 'hu', 'hu-HU', 'hy', 'hy-AM', 'ia', 'ia-001', 'id', 'id-ID', 'ig', 'ig-NG', 'ii', 'ii-CN', 'io', 'io-001', 'is', 'is-IS', 'it', 'it-CH', 'it-IT', 'it-SM', 'it-VA', 'iu', 'iu-CA', 'ja', 'ja-JP', 'jbo', 'jbo-001', 'jgo', 'jgo-CM', 'jmc', 'jmc-TZ', 'jv', 'jv-ID', 'ka', 'ka-GE', 'kab', 'kab-DZ', 'kaj', 'kaj-NG', 'kam', 'kam-KE', 'kcg', 'kcg-NG', 'kde', 'kde-TZ', 'kea', 'kea-CV', 'khq', 'khq-ML', 'ki', 'ki-KE', 'kk', 'kk-KZ', 'kkj', 'kkj-CM', 'kl', 'kl-GL', 'kln', 'kln-KE', 'km', 'km-KH', 'kn', 'kn-IN', 'ko', 'ko-KP', 'ko-KR', 'kok', 'kok-IN', 'kpe', 'kpe-GN', 'kpe-LR', 'ks', 'ks-Arab', 'ks-Arab-IN', 'ks-Aran', 'ks-Aran-IN', 'ks-Deva', 'ks-IN', 'ksb', 'ksb-TZ', 'ksf', 'ksf-CM', 'ksh', 'ksh-DE', 'ku', 'ku-TR', 'kw', 'kw-GB', 'ky', 'ky-KG', 'lag', 'lag-TZ', 'lb', 'lb-LU', 'lg', 'lg-UG', 'lkt', 'lkt-US', 'ln', 'ln-AO', 'ln-CD', 'ln-CF', 'ln-CG', 'lo', 'lo-LA', 'lrc', 'lrc-IQ', 'lrc-IR', 'lt', 'lt-LT', 'lu', 'lu-CD', 'luo', 'luo-KE', 'luy', 'luy-KE', 'lv', 'lv-LV', 'mas', 'mas-KE', 'mas-TZ', 'mer', 'mer-KE', 'mfe', 'mfe-MU', 'mg', 'mg-MG', 'mgh', 'mgh-MZ', 'mgo', 'mgo-CM', 'mi', 'mi-NZ', 'mk', 'mk-MK', 'ml', 'ml-IN', 'mn', 'mn-MN', 'mni', 'mni-Beng', 'mni-Beng-IN', 'mni-Mtei', 'mni-Mtei-IN', 'moh', 'moh-CA', 'mr', 'mr-IN', 'ms', 'ms-Arab', 'ms-Arab-BN', 'ms-Arab-MY', 'ms-BN', 'ms-MY', 'ms-SG', 'mt', 'mt-MT', 'mua', 'mua-CM', 'my', 'my-MM', 'myv', 'myv-RU', 'mzn', 'mzn-IR', 'naq', 'naq-NA', 'nb', 'nb-NO', 'nb-SJ', 'nd', 'nd-ZW', 'nds', 'nds-DE', 'nds-NL', 'ne', 'ne-IN', 'ne-NP', 'nl', 'nl-AW', 'nl-BE', 'nl-BQ', 'nl-CW', 'nl-NL', 'nl-SR', 'nl-SX', 'nmg', 'nmg-CM', 'nn', 'nn-NO', 'nnh', 'nnh-CM', 'nqo', 'nqo-GN', 'nr', 'nr-ZA', 'nso', 'nso-ZA', 'nus', 'nus-SS', 'ny', 'ny-MW', 'nyn', 'nyn-UG', 'oc', 'oc-FR', 'om', 'om-ET', 'om-KE', 'or', 'or-IN', 'os', 'os-GE', 'os-RU', 'pa', 'pa-Arab', 'pa-Arab-PK', 'pa-Aran', 'pa-Aran-PK', 'pa-Guru', 'pa-Guru-IN', 'pl', 'pl-PL', 'ps', 'ps-AF', 'ps-PK', 'pt', 'pt-AO', 'pt-BR', 'pt-CH', 'pt-CV', 'pt-FR', 'pt-GQ', 'pt-GW', 'pt-LU', 'pt-MO', 'pt-MZ', 'pt-PT', 'pt-ST', 'pt-TL', 'qu', 'qu-BO', 'qu-EC', 'qu-PE', 'rm', 'rm-CH', 'rn', 'rn-BI', 'ro', 'ro-MD', 'ro-RO', 'rof', 'rof-TZ', 'ru', 'ru-BY', 'ru-KG', 'ru-KZ', 'ru-MD', 'ru-RU', 'ru-UA', 'rw', 'rw-RW', 'rwk', 'rwk-TZ', 'sa', 'sa-IN', 'sah', 'sah-RU', 'saq', 'saq-KE', 'sat', 'sat-Deva', 'sat-Deva-IN', 'sat-Olck', 'sat-Olck-IN', 'sbp', 'sbp-TZ', 'sc', 'sc-IT', 'scn', 'scn-IT', 'sd', 'sd-Deva', 'sd-PK', 'se', 'se-FI', 'se-NO', 'se-SE', 'seh', 'seh-MZ', 'ses', 'ses-ML', 'sg', 'sg-CF', 'shi', 'shi-Latn', 'shi-Latn-MA', 'shi-Tfng', 'shi-Tfng-MA', 'si', 'si-LK', 'sk', 'sk-SK', 'sl', 'sl-SI', 'smn', 'smn-FI', 'sn', 'sn-ZW', 'so', 'so-DJ', 'so-ET', 'so-KE', 'so-SO', 'sq', 'sq-AL', 'sq-MK', 'sq-XK', 'sr', 'sr-Cyrl', 'sr-Cyrl-BA', 'sr-Cyrl-ME', 'sr-Cyrl-RS', 'sr-Cyrl-XK', 'sr-Latn', 'sr-Latn-BA', 'sr-Latn-ME', 'sr-Latn-RS', 'sr-Latn-XK', 'ss', 'ss-SZ', 'ss-ZA', 'st', 'st-LS', 'st-ZA', 'sv', 'sv-AX', 'sv-FI', 'sv-SE', 'sw', 'sw-CD', 'sw-KE', 'sw-TZ', 'sw-UG', 'syr', 'syr-IQ', 'syr-SY', 'ta', 'ta-IN', 'ta-LK', 'ta-MY', 'ta-SG', 'te', 'te-IN', 'teo', 'teo-KE', 'teo-UG', 'tg', 'tg-TJ', 'th', 'th-TH', 'ti', 'ti-ER', 'ti-ET', 'tig', 'tig-ER', 'tk', 'tk-TM', 'tn', 'tn-BW', 'tn-ZA', 'to', 'to-TO', 'tr', 'tr-CY', 'tr-TR', 'trv', 'trv-TW', 'ts', 'ts-ZA', 'tt', 'tt-RU', 'twq', 'twq-NE', 'tzm', 'tzm-MA', 'ug', 'ug-CN', 'uk', 'uk-UA', 'ur', 'ur-Arab', 'ur-Arab-IN', 'ur-Arab-PK', 'ur-Aran', 'ur-Aran-IN', 'ur-Aran-PK', 'ur-IN', 'ur-PK', 'uz', 'uz-Arab', 'uz-Arab-AF', 'uz-Cyrl', 'uz-Cyrl-UZ', 'uz-Latn', 'uz-Latn-UZ', 'vai', 'vai-Latn', 'vai-Latn-LR', 'vai-Vaii', 'vai-Vaii-LR', 've', 've-ZA', 'vi', 'vi-VN', 'vun', 'vun-TZ', 'wa', 'wa-BE', 'wae', 'wae-CH', 'wal', 'wal-ET', 'wo', 'wo-SN', 'wuu', 'xh', 'xh-ZA', 'xog', 'xog-UG', 'yav', 'yav-CM', 'yi', 'yi-001', 'yo', 'yo-BJ', 'yo-NG', 'yue', 'yue-Hans', 'yue-Hans-CN', 'yue-Hant', 'yue-Hant-HK', 'zgh', 'zgh-MA', 'zh', 'zh-Hans', 'zh-Hans-CN', 'zh-Hans-HK', 'zh-Hans-MO', 'zh-Hans-SG', 'zh-Hant', 'zh-Hant-CN', 'zh-Hant-HK', 'zh-Hant-MO', 'zh-Hant-TW', 'zu', 'zu-ZA')] | |
[ValidateNotNull()] | |
[string] | |
${Culture}, | |
[Parameter(ParameterSetName = 'ObjectRaw', Mandatory, ValueFromPipeline)] | |
[Parameter(ParameterSetName = 'Object', Mandatory, ValueFromPipeline)] | |
[AllowEmptyString()] | |
[AllowNull()] | |
[psobject] | |
${InputObject}, | |
[Parameter(Mandatory, Position = 0)] | |
[string[]] | |
${Pattern}, | |
[Parameter(ParameterSetName = 'FileRaw', Mandatory, Position = 1, ValueFromPipelineByPropertyName)] | |
[Parameter(ParameterSetName = 'File', Mandatory, Position = 1, ValueFromPipelineByPropertyName)] | |
[string[]] | |
${Path}, | |
[Parameter(ParameterSetName = 'LiteralFileRaw', Mandatory, ValueFromPipelineByPropertyName)] | |
[Parameter(ParameterSetName = 'LiteralFile', Mandatory, ValueFromPipelineByPropertyName)] | |
[Alias('PSPath', 'LP')] | |
[string[]] | |
${LiteralPath}, | |
[Parameter(ParameterSetName = 'LiteralFileRaw', Mandatory)] | |
[Parameter(ParameterSetName = 'FileRaw', Mandatory)] | |
[Parameter(ParameterSetName = 'ObjectRaw', Mandatory)] | |
[switch] | |
${Raw}, | |
[switch] | |
${SimpleMatch}, | |
[switch] | |
${CaseSensitive}, | |
[Parameter(ParameterSetName = 'File')] | |
[Parameter(ParameterSetName = 'Object')] | |
[Parameter(ParameterSetName = 'LiteralFile')] | |
[switch] | |
${Quiet}, | |
[switch] | |
${List}, | |
[switch] | |
${NoEmphasis}, | |
[ValidateNotNullOrEmpty()] | |
[string[]] | |
${Include}, | |
[ValidateNotNullOrEmpty()] | |
[string[]] | |
${Exclude}, | |
[switch] | |
${NotMatch}, | |
[switch] | |
${AllMatches}, | |
[ValidateNotNullOrEmpty()] | |
[System.Text.Encoding] | |
${Encoding}, | |
[ValidateRange(0, 2147483647)] | |
[ValidateNotNullOrEmpty()] | |
[ValidateCount(1, 2)] | |
[int[]] | |
${Context}) | |
begin { | |
Set-StrictMode -Version 1 | |
# Ignore parameters that are only supported in v7+ | |
if ($PSVersionTable.PSVersion.Major -lt 7) { | |
('Culture', 'Raw', 'NoEmphasis').ForEach( { | |
if ($PSBoundParameters.ContainsKey($_)) { | |
$null = $PSBoundParameters.Remove($_) | |
Write-Warning "Ignoring parameter $_, because it is only supported in PowerShell 7.0 or above." | |
} | |
}) | |
} | |
# Set up the steppable pipeline. | |
try { | |
# If -Path or -LiteralPath are specified - i.e if Select-String itself should read *files*, we | |
# always perform a normal Select-String invocation. | |
$passThruOnly = $PSBoundParameters.ContainsKey('Path') -or $PSBoundParameters.ContainsKey('LiteralPath') | |
$commandToWrapPassThru = { Select-String @PSBoundParameters } | |
$steppablePipelinePassThru = $commandToWrapPassThru.GetSteppablePipeline($myInvocation.CommandOrigin) | |
$steppablePipelinePassThru.Begin($PSCmdlet) | |
$commandToWrapFormattted = $null | |
if (-not $passThruOnly) { | |
$commandToWrapFormattted = { Out-String -Stream | Select-String @PSBoundParameters } | |
$steppablePipelineFormatted = $commandToWrapFormattted.GetSteppablePipeline($myInvocation.CommandOrigin) | |
$steppablePipelineFormatted.Begin($PSCmdlet) | |
} | |
} | |
catch { | |
$PSCmdlet.ThrowTerminatingError($_) | |
} | |
} | |
process { | |
if ($passThruOnly -or $_ -is [System.IO.FileSystemInfo]) { | |
$steppablePipelinePassThru.Process($_) | |
} else { | |
$steppablePipelineFormatted.Process($_) | |
} | |
} | |
end { | |
$steppablePipelinePassThru.End() | |
if ($steppablePipelineFormatted) { $steppablePipelineFormatted.End() } | |
} | |
} | |
# -------------------------------- | |
# GENERIC INSTALLATION HELPER CODE | |
# -------------------------------- | |
# Provides guidance for making the function persistently available when | |
# this script is either directly invoked from the originating Gist or | |
# dot-sourced after download. | |
# IMPORTANT: | |
# * DO NOT USE `exit` in the code below, because it would exit | |
# the calling shell when Invoke-Expression is used to directly | |
# execute this script's content from GitHub. | |
# * Because the typical invocation is DOT-SOURCED (via Invoke-Expression), | |
# do not define variables or alter the session state via Set-StrictMode, ... | |
# *except in child scopes*, via & { ... } | |
if ($MyInvocation.Line -eq '') { | |
# Most likely, this code is being executed via Invoke-Expression directly | |
# from gist.github.com | |
# To simulate for testing with a local script, use the following: | |
# Note: Be sure to use a path and to use "/" as the separator. | |
# iex (Get-Content -Raw ./script.ps1) | |
# Derive the function name from the invocation command, via the enclosing | |
# script name presumed to be contained in the URL. | |
# NOTE: Unfortunately, when invoked via Invoke-Expression, $MyInvocation.MyCommand.ScriptBlock | |
# with the actual script content is NOT available, so we cannot extract | |
# the function name this way. | |
& { | |
param($invocationCmdLine) | |
# Try to extract the function name from the URL. | |
$funcName = $invocationCmdLine -replace '^.+/(.+?)(?:\.ps1).*$', '$1' | |
if ($funcName -eq $invocationCmdLine) { | |
# Function name could not be extracted, just provide a generic message. | |
# Note: Hypothetically, we could try to extract the Gist ID from the URL | |
# and use the REST API to determine the first filename. | |
Write-Verbose -Verbose "Function is now defined in this session." | |
} | |
else { | |
# Indicate that the function is now defined and also show how to | |
# add it to the $PROFILE or convert it to a script file. | |
Write-Verbose -Verbose @" | |
Function `"$funcName`" is now defined in this session. | |
* If you want to add this function to your `$PROFILE, run the following: | |
"``nfunction $funcName {``n`${function:$funcName}``n}" | Add-Content `$PROFILE | |
* If you want to convert this function into a script file that you can invoke | |
directly, run: | |
"`${function:$funcName}" | Set-Content $funcName.ps1 -Encoding $('utf8' + ('', 'bom')[[bool] (Get-Variable -ErrorAction Ignore IsCoreCLR -ValueOnly)]) | |
"@ | |
} | |
} $MyInvocation.MyCommand.Definition # Pass the original invocation command line to the script block. | |
} | |
else { | |
# Invocation presumably as a local file after manual download, | |
# either dot-sourced (as it should be) or mistakenly directly. | |
& { | |
param($originalInvocation) | |
# Parse this file to reliably extract the name of the embedded function, | |
# irrespective of the name of the script file. | |
$ast = $originalInvocation.MyCommand.ScriptBlock.Ast | |
$funcName = $ast.Find( { $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $false).Name | |
if ($originalInvocation.InvocationName -eq '.') { | |
# Being dot-sourced as a file. | |
# Provide a hint that the function is now loaded and provide | |
# guidance for how to add it to the $PROFILE. | |
Write-Verbose -Verbose @" | |
Function `"$funcName`" is now defined in this session. | |
If you want to add this function to your `$PROFILE, run the following: | |
"``nfunction $funcName {``n`${function:$funcName}``n}" | Add-Content `$PROFILE | |
"@ | |
} | |
else { | |
# Mistakenly directly invoked. | |
# Issue a warning that the function definition didn't effect and | |
# provide guidance for reinvocation and adding to the $PROFILE. | |
Write-Warning @" | |
This script contains a definition for function "$funcName", but this definition | |
only takes effect if you dot-source this script. | |
To define this function for the current session, run: | |
. "$($originalInvocation.MyCommand.Path)" | |
"@ | |
} | |
} $MyInvocation # Pass the original invocation info to the helper script block. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment