PowerShell有一个非常好的内置帮助系统,我经常使用它,并且能够使用Get-Help *
查看所有帮助选项并查询Cmdlet,或者可以使用Get-Help about_*
查找主题,然后说出Get-Help about_compar*
来打开比较运算符主题,一切都很好。
但是,我试图找到如何在各种字符串运算符(例如.replace,.compare,.split和.substring)上获得帮助的方法。有谁知道如何在PowerShell控制台上提出这些主题(可能它们可能隐藏在某些about_ *主题内,但是对我来说不明显或不清楚)?
此外,字符串运算符具有-replace,-compare,-split变体等,尽管与.replace等几乎相同,但一个版本使用正则表达式,而另一个版本则不使用正则表达式。有谁知道是否有帮助主题(再次可以从控制台获得!)来澄清所有这些?如果PowerShell的帮助系统缺少对它的内置帮助系统中所有这些内容的澄清,则它们会感到非常缺乏,因为它们是该语言的一个非常常用的部分(因此,希望所有这些内容都被包含在我的about_ *主题中) '尚未找到)。
答案 0 :(得分:1)
如前所述,.net类型的 方法 (例如System.String.Split()
)不是 PowerShell 的一部分,但是使用PowerShell构建的.NET框架,因此您必须在https://docs.microsoft.com 处咨询官方文档,例如本示例中String.Split()
的示例链接句子。
但是,诸如-split
之类的 操作员是 PowerShell语言功能,它们既可以发现他们的文档,又可以集中精力进行操作,具体信息目前很麻烦。
about_*
帮助主题中包含语言特性(例如,运算符)的文档,该主题可以用Get-Help -Category HelpFile
进行定位,您可以将其与传递运算符的(加引号的)名称结合使用为了搜索这些主题的内容:
Get-Help -Category HelpFile -Name '-replace'
至少缩小了搜索范围,但仍包含所有提及 -replace
的帮助主题;结果将包含 about_Operators帮助主题,该主题是概述页面,该页面链接到侧重于运算符(例如算术运算符)的特定类别的更多特定页面,比较运算符...,但也直接描述了一些通用运算符 。当前没有直接的方法可以获取给定操作员的重点信息,但是应该有:见this GitHub suggestion。
下面是两个 helper函数,它们试图克服当前的局限性(从v7.0开始)Show-OperatorHelp
和Show-TypeHelp
。
注意:
这两个功能(必不可少)都不会在控制台中显示文档(终端),而是在默认的网络浏览器中打开在线文档。
在Show-TypeHelp
中,支持仅限于.NET附带的(公共)类型,因此,文档页面位于https://docs.microsoft.com。
Show-OperatorHelp
会在可能的情况下打开仅描述感兴趣的运算符的特定部分;某些运算符(例如算术运算符+
,-
)没有单独的部分,但是在这些情况下,总体主题通常很短,因此很容易找到感兴趣的部分。 / p>
它们带有基于注释的帮助,因此您可以使用-?
和Get-Help
来了解有关它们的更多信息。
例如,您可以将它们放置在$PROFILE
文件中,或者-给定它们的长度-您可能要根据它们创建外部脚本(* .ps1)您放置在$env:Path
中列出的目录中。为此,只需去除function <name> {
行和最后一个}
并将它们保存到*.ps1
文件中。
Show-OperatorHelp
:
# Opens the home (overview) page for all PowerShell operators
Show-OperatorHelp
# Lists all operators in the console,
# along with their friendly names and categories.
Show-OperatorHelp -List
# Opens the help topic (section) for the -replace operator.
# Equivalent of
Show-OperatorHelp -Name '-replace'
# because you omit the initial '-'; if you do specify it, quote the entire argument.
Show-OperatorHelp replace
# Opens the help topic (section) for @(...), the array-subexpression operator.
# Note the need for quoting.
Show-OperatorHelp '@()'
Show-TypeHelp
:
# Opens the documentation for the System.String.Split() method.
# You can specify a type name ('string' in this example) as follows:
# * Use a full type name, with the initial 'System.' component optionally omitted (e.g. 'Text.Encoding' for 'System.Text.Encoding'
# * Use a type accelerator such as 'xml' for 'System.Xml.XmlDocument'
# Tab-completion: You can type (part of) a the name of a type
# (last component of the full name) and cycle through loaded types by that name.
# E.g., typing `arrayli` tab-completes to 'System.Collections.ArrayList'.
# Alternatively, *pipe* an instance of a string to the function (see next example).
Show-TypeHelp string split # Short for: Show-TypeHelp -Type string -Member split
# Opens the documentation for the [Microsoft.PowerShell.Commands.MatchInfo]
# type, instances of which Select-String outputs.
'foo' | Select-String o | Show-TypeHelp
注意:我建议从以下MIT许可的Gist中获取源代码,因为只有它们会得到维护:
Show-OperatorHelp
源代码:注意:忽略语法突出显示的损坏。
function Show-OperatorHelp {
<#
.SYNOPSIS
Shows documentation for PowerShell's operators.
.DESCRIPTION
Navigates to operator-specific or -related online help topics in your default
web browser.
Invoke argument-less to see the operators overview help topic.
-Precedence shows the topic about operator precedence.
-QuotingRules shows the topic about string literals and quoting.
-Name <name> targets a specific operator.
.PARAMETER Name
The name of an operator.
Note that most names must be passed *in quotes* for syntactic reasons;
e.g., '-match' instead of -match
However, you may omit the initial '-', in which case you needn't quote.
Use -List to see all names.
.PARAMETER Precedence
Opens the help topic that describes operator precedence.
.PARAMETER List
Parameter description
.PARAMETER QuotingRules
Opens the help topic that describes the quoting rules and syntax for
string literals.
.PARAMETER CopyUrl
Instead of opening the topic page in a browser, copies the page's URL to
the clipboard.
.PARAMETER Version
Specify a specific PowerShell version number (e.g., 7 or 5.1) for which to
display the requested help topic.
By default, the executing engine's version number is used.
.EXAMPLE
Show-OperatorHelp
Opens the home (overview) page for all PowerShell operators.
.EXAMPLE
Show-OperatorHelp replace
Opens the help topic (section) for the -replace operator.
Equivalent of: Show-OperatorHelp -Name '-replace'
.EXAMPLE
Show-OperatorHelp -List
Lists all operators, along with their friendly names and categories.
.EXAMPLE
Show-OperatorHelp -Precedence
Shows the help topic about operator precedence.
#>
[CmdletBinding(DefaultParameterSetName = 'HomePage', SupportsShouldProcess, PositionalBinding = $false)]
param (
[Parameter(ParameterSetName = 'Name', Mandatory, Position = 0)]
[string] $Name
,
[Parameter(ParameterSetName = 'Precedence')]
[switch] $Precedence
,
[Parameter(ParameterSetName = 'List')]
[Alias('ListAvailable')]
[switch] $List
,
[Parameter(ParameterSetName = 'QuotingRules')]
[Alias('StringLiterals')]
[switch] $QuotingRules
,
[Parameter(ParameterSetName = 'Name')]
[Parameter(ParameterSetName = 'Precedence')]
[Parameter(ParameterSetName = 'QuotingRules')]
[Parameter(ParameterSetName = 'HomePage')]
[Alias('cp')]
[switch] $CopyUrl
,
[Parameter(ParameterSetName = 'Name')]
[Parameter(ParameterSetName = 'Precedence')]
[Parameter(ParameterSetName = 'QuotingRules')]
[Parameter(ParameterSetName = 'HomePage')]
[string] $Version # PowerShell version
)
# Default to the executing PowerShell engine's version.
# Note: If no "?view=powershell-<ver>" query string is present,
# the currently highest stable version overall is targeted.
if ($Version) {
$verObj = $Version -as [version]
if (-not $verObj) { $verObj = "$Version.0" -as [version] }
if (-not $verObj) { Throw "Unrecognized PowerShell version number: $Version" }
}
else {
$verObj = $PSVersionTable.PSVersion
}
$Version = ('{0}.{1}' -f $verObj.Major, $verObj.Minor) -replace '\.0$'
$opTable = @{
# about_Arithmetic_Operators
'-' = [pscustomobject] @{ Name = '-'; FriendlyName = 'subtraction / sign inversion'; Topic = 'about_Arithmetic_Operators'; Category = 'Arithmetic' }
'*' = [pscustomobject] @{ Name = '*'; FriendlyName = 'multiplication / string replication'; Topic = 'about_Arithmetic_Operators'; Category = 'Arithmetic' }
'/' = [pscustomobject] @{ Name = '/'; FriendlyName = 'division'; Topic = 'about_Arithmetic_Operators'; Category = 'Arithmetic' }
'%' = [pscustomobject] @{ Name = '%'; FriendlyName = 'modulus'; Topic = 'about_Arithmetic_Operators'; Category = 'Arithmetic' }
'+' = [pscustomobject] @{ Name = '+'; FriendlyName = 'addition / string conatenation'; Topic = 'about_Arithmetic_Operators'; Category = 'Arithmetic' }
'-band' = [pscustomobject] @{ Name = '-band'; FriendlyName = 'bitwise AND'; Topic = 'about_Arithmetic_Operators'; Category = 'Bitwise' }
'-bor' = [pscustomobject] @{ Name = '-bor'; FriendlyName = 'bitwise OR'; Topic = 'about_Arithmetic_Operators'; Category = 'Bitwise' }
'-bxor' = [pscustomobject] @{ Name = '-bxor'; FriendlyName = 'bitwise XOR'; Topic = 'about_Arithmetic_Operators'; Category = 'Bitwise' }
'-bNot' = [pscustomobject] @{ Name = '-bNot'; FriendlyName = 'bitwise complement'; Topic = 'about_Arithmetic_Operators'; Category = 'Bitwise' }
# about_Assignment_Operators
'=' = [pscustomobject] @{ Name = '='; FriendlyName = 'assignment'; Topic = 'about_Assignment_Operators'; Category = 'Assignment' }
'+=' = [pscustomobject] @{ Name = '+='; FriendlyName = 'compound assignment'; Topic = 'about_Assignment_Operators'; Category = 'Assignment' }
'-=' = [pscustomobject] @{ Name = '-='; FriendlyName = 'compound assignment'; Topic = 'about_Assignment_Operators'; Category = 'Assignment' }
'*=' = [pscustomobject] @{ Name = '*='; FriendlyName = 'compound assignment'; Topic = 'about_Assignment_Operators'; Category = 'Assignment' }
'/=' = [pscustomobject] @{ Name = '/='; FriendlyName = 'compound assignment'; Topic = 'about_Assignment_Operators'; Category = 'Assignment' }
'%=' = [pscustomobject] @{ Name = '%='; FriendlyName = 'compound assignment'; Topic = 'about_Assignment_Operators'; Category = 'Assignment' }
'++' = [pscustomobject] @{ Name = '++'; FriendlyName = 'increment'; Topic = 'about_Assignment_Operators'; Category = 'Assignment' }
'--' = [pscustomobject] @{ Name = '--'; FriendlyName = 'decrement'; Topic = 'about_Assignment_Operators'; Category = 'Assignment' }
# about_Comparison_Operators
'-eq' = [pscustomobject] @{ Name = '-eq'; FriendlyName = 'equality'; Topic = 'about_Comparison_Operators'; Anchor = '-eq'; Category = 'Equality' }
'-ne' = [pscustomobject] @{ Name = '-ne'; FriendlyName = 'inequality'; Topic = 'about_Comparison_Operators'; Anchor = '-ne'; Category = 'Equality' }
'-gt' = [pscustomobject] @{ Name = '-gt'; FriendlyName = 'greater-than'; Topic = 'about_Comparison_Operators'; Anchor = '-gt'; Category = 'Equality' }
'-ge' = [pscustomobject] @{ Name = '-ge'; FriendlyName = 'greater-than-or-equal'; Topic = 'about_Comparison_Operators'; Anchor = '-gt'; Category = 'Equality' }
'-lt' = [pscustomobject] @{ Name = '-lt'; FriendlyName = 'less-than'; Topic = 'about_Comparison_Operators'; Anchor = '-lt'; Category = 'Equality' }
'-le' = [pscustomobject] @{ Name = '-le'; FriendlyName = 'less-than-or-equal'; Topic = 'about_Comparison_Operators'; Anchor = '-le'; Category = 'Equality' }
'-like' = [pscustomobject] @{ Name = '-like'; FriendlyName = 'wildcard matching'; Topic = 'about_Comparison_Operators'; Anchor = '-like'; Category = 'Matching' }
'-notlike' = [pscustomobject] @{ Name = '-notlike'; FriendlyName = 'negated wildcard matching'; Topic = 'about_Comparison_Operators'; Anchor = '-notlike'; Category = 'Matching' }
'-match' = [pscustomobject] @{ Name = '-match'; FriendlyName = 'regular-expression matching'; Topic = 'about_Comparison_Operators'; Anchor = '-match'; Category = 'Matching' }
'-notmatch' = [pscustomobject] @{ Name = '-notmatch'; FriendlyName = 'negated regular-expression matching'; Topic = 'about_Comparison_Operators'; Anchor = '-notmatch'; Category = 'Matching' }
'-replace' = [pscustomobject] @{ Name = '-replace'; FriendlyName = 'regular-expression-based string replacement'; Topic = 'about_Comparison_Operators'; Anchor = 'replacement-operator'; Category = 'String' }
'-in' = [pscustomobject] @{ Name = '-in'; FriendlyName = 'LHS contained in RHS'; Topic = 'about_Comparison_Operators'; Anchor = '-in'; Category = 'Containment' }
'-notIn' = [pscustomobject] @{ Name = '-notIn'; FriendlyName = 'LHS not contained in collection'; Topic = 'about_Comparison_Operators'; Anchor = '-notin'; Category = 'Containment' }
'-contains' = [pscustomobject] @{ Name = '-contains'; FriendlyName = 'collection contains RHS'; Topic = 'about_Comparison_Operators'; Anchor = '-contains'; Category = 'Containment' }
'-notContains' = [pscustomobject] @{ Name = '-notContains'; FriendlyName = 'collection doesn''t contain RHS'; Topic = 'about_Comparison_Operators'; Anchor = '-notcontains'; Category = 'Containment' }
# about_Join
'-join' = [pscustomobject] @{ Name = '-join'; FriendlyName = 'string joining'; Topic = 'about_Join'; Category = 'String' }
# about_Split
'-split' = [pscustomobject] @{ Name = '-split'; FriendlyName = 'string splitting'; Topic = 'about_Split'; Category = 'String' }
# about_Logical_Operators
'-not' = [pscustomobject] @{ Name = '-not'; FriendlyName = 'logical NOT'; Topic = 'about_Logical_Operators'; Category = 'Logical' }
'!' = [pscustomobject] @{ Name = '!'; FriendlyName = 'logical NOT'; Topic = 'about_Logical_Operators'; Category = 'Logical' }
'-and' = [pscustomobject] @{ Name = '-and'; FriendlyName = 'logical AND'; Topic = 'about_Logical_Operators'; Category = 'Logical' }
'-or' = [pscustomobject] @{ Name = '-or'; FriendlyName = 'logical OR'; Topic = 'about_Logical_Operators'; Category = 'Logical' }
'-xor' = [pscustomobject] @{ Name = '-xor'; FriendlyName = 'logical XOR'; Topic = 'about_Logical_Operators'; Category = 'Logical' }
# about_Operators
'$()' = [pscustomobject] @{ Name = '$()'; FriendlyName = 'subexpression'; Topic = 'about_Operators'; Anchor = 'subexpression-operator--'; Category = 'Evaluation' }
'@()' = [pscustomobject] @{ Name = '@()'; FriendlyName = 'array-subexpression'; Topic = 'about_Operators'; Anchor = 'array-subexpression-operator--'; Category = 'Evaluation' }
'()' = [pscustomobject] @{ Name = '()'; FriendlyName = 'grouping'; Topic = 'about_Operators'; Anchor = 'grouping-operator--'; Category = 'Evaluation' }
'. ' = [pscustomobject] @{ Name = '.'; FriendlyName = '(dot-)source'; Topic = 'about_Operators'; Anchor = 'dot-sourcing-operator-'; Category = 'Execution' } # Sadly, we have to use '. ' to distinguish it from the member-access operator
'&' = [pscustomobject] @{ Name = '&'; FriendlyName = 'call (execute)'; Topic = 'about_Operators'; Anchor = 'call-operator-'; Category = 'Execution' }
' &' = [pscustomobject] @{ Name = '&'; FriendlyName = 'background'; Topic = 'about_Operators'; Anchor = 'background-operator-'; Category = 'Execution' } # Sadly, we have to use ' &' to distinguish it from the call operator
'&&' = [pscustomobject] @{ Name = '&&'; FriendlyName = 'pipeline-chain AND'; Topic = 'about_Pipeline_Chain_Operators'; Category = 'Pipeline' }
'||' = [pscustomobject] @{ Name = '||'; FriendlyName = 'pipeline-chain OR'; Topic = 'about_Pipeline_Chain_Operators'; Category = 'Pipeline' }
'|' = [pscustomobject] @{ Name = '|'; FriendlyName = 'pipeline'; Topic = 'about_Operators'; Anchor = 'pipeline-operator-'; Category = 'Pipeline' }
'.' = [pscustomobject] @{ Name = '.'; FriendlyName = 'member access'; Topic = 'about_Operators'; Anchor = 'member-access-operator-'; Category = 'Object' }
'::' = [pscustomobject] @{ Name = '::'; FriendlyName = 'static member access'; Topic = 'about_Operators'; Anchor = 'static-member-operator-'; Category = 'Object' }
'[0]' = [pscustomobject] @{ Name = '[0]'; FriendlyName = 'index'; Topic = 'about_Operators'; Anchor = 'index-operator--'; Category = 'Object' }
'[int]' = [pscustomobject] @{ Name = '[int]'; FriendlyName = 'cast / type constraint'; Topic = 'about_Operators'; Anchor = 'cast-operator--'; Category = 'Type' }
',' = [pscustomobject] @{ Name = ','; FriendlyName = 'array constructor'; Topic = 'about_Operators'; Anchor = 'comma-operator-'; Category = 'Array' }
'..' = [pscustomobject] @{ Name = '..'; FriendlyName = 'range (numbers/characters) '; Topic = 'about_Operators'; Anchor = 'range-operator-'; Category = 'Array' }
'-f' = [pscustomobject] @{ Name = '-f'; FriendlyName = 'format (strings)'; Topic = 'about_Operators'; Anchor = 'format-operator--f'; Category = 'String' }
'?:' = [pscustomobject] @{ Name = '?:'; FriendlyName = 'ternary conditional'; Topic = 'about_Operators'; Anchor = 'ternary-operator--if-true--if-false'; Category = 'Conditional' }
'??' = [pscustomobject] @{ Name = '??'; FriendlyName = 'null-coalescing'; Topic = 'about_Operators'; Anchor = ''; Category = 'Conditional' } # ?? Not yet covered in the v7 topic as of 12 Dec 2019
# about_Redirection
'>' = [pscustomobject] @{ Name = '>'; FriendlyName = 'redirection'; Topic = 'about_Redirection'; Category = 'Stream' }
'>>' = [pscustomobject] @{ Name = '>>'; FriendlyName = 'appending redirection'; Topic = 'about_Redirection'; Category = 'Stream' }
# about_Type_Operators
'-is' = [pscustomobject] @{ Name = '-is'; FriendlyName = 'type(-inheritance) / interface test'; Topic = 'about_Type_Operators'; Category = 'Type' }
'-isnot' = [pscustomobject] @{ Name = '-isnot'; FriendlyName = 'negated type(-inheritance) / interface test'; Topic = 'about_Type_Operators'; Category = 'Type' }
'-as' = [pscustomobject] @{ Name = '-as'; FriendlyName = 'conditional type conversion'; Topic = 'about_Type_Operators'; Category = 'Type' }
# --- Not covered by an operator help topic, but could be considered one.
# about_Splatting
'@' = [pscustomobject] @{ Name = '@'; FriendlyName = 'splatting (arguments)'; Topic = 'about_Splatting'; Category = 'Splatting' }
}
# As a courtesy, interpret variations of quotes / quoting styles passed as -Name as if -Quoting had been passed instead.
$parameterSetNameInEffect = $PSCmdlet.ParameterSetName
if ($Name -replace '\s' -match '^(?:''''?|""?|@''(''@)?|@"("@)?)$') {
$parameterSetNameInEffect = 'QuotingRules'
}
$url = ''
switch ($parameterSetNameInEffect) {
'Name' {
$warning = ''
# See if the name matches an entry as-is.
$entry = $opTable[$Name]
# If '.' was passed, warn about member-access / dot-sourcing ambiguity.
if ($Name -eq '.') {
$warning = "Defaulting to member-access operator; for the dot-sourcing operator, pass '. '"
}
elseif ($Name -eq '&') {
$warning = "Defaulting to call operator; for the background operator, pass ' &'"
}
elseif ($Name.Trim() -eq '@') {
$warning = "Defaulting to splatting operator; for the array-subexpression operator, pass '@()'; for here-strings, pass '@`"`"@' or -QuotingRules"
}
elseif (-not $entry) {
# Remove any spaces, to support name variations such as '( )', '[ ]'
$normalizedName = $Name -replace ' '
}
if (-not $entry) {
# If not, try prepending "-", to allow users to specify 'replace' instead of '-replace', for instance.
$entry = $opTable["-$normalizedName"]
}
if (-not $entry) {
# Variations of redirection operators.
if ($entry -match '^[\d*]?>>?(&\d?)') {
$entry = $opTable['>']
}
}
if (-not $entry) {
# Map case variants to their unqualified form; e.g. '-ireplace' -> '-replace'
$baseName = $normalizedName -replace '^(?=-?)[ci](?=[a-z])'
if ($baseName -ne $normalizedName) {
if ($baseName -notlike '-*') { $baseName = '-' + $baseName }
$entry = $opTable[$baseName]
}
}
if (-not $entry -and $normalizedName -like '`[*`]') {
# varations of referring to the index / cast / type-constraint operator
$bracketName = $normalizedName
if ($bracketName -eq '[]') {
$bracketName = '[0]' # default to indexer, but warn
$warning = "Defaulting to index operator; for the cast / type-constraint operators, pass '[int]'"
}
elseif ($bracketName -match '^\[(\d+|[''"].*[''"])\]$') {
$bracketName = '[0]' # indexer - numeric or string
}
else {
$bracketName = '[int]' # cast
}
$entry = $opTable[$bracketName]
}
if (-not $entry) {
Throw "Not a recognized operator: $Name"
}
elseif ($warning) {
Write-Warning $warning
}
$url = "https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/" + $entry.Topic
if ($entry.Anchor) {
$url += '#' + $entry.Anchor
}
break
}
'Precedence' {
$url = 'https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Operator_Precedence'
break
}
'QuotingRules' {
$url = 'https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Quoting_Rules'
break
}
'HomePage' {
$url = 'https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Operators'
break
}
'List' {
# List the operators table below.
}
Default { Throw "What are you doing here?" }
}
if ($url -and $Version) {
$versionQueryString = '?view=powershell-' + $Version
if ($url.Contains('#')) {
$url = $url -replace '(#.+)$', ($versionQueryString + '$1')
}
else {
$url += $versionQueryString
}
}
# -WhatIf support.
if (-not $PSCmdlet.ShouldProcess((("`n" + $url + "`n"), "List all operators")[$parameterSetNameInEffect -eq 'List'])) { return }
if ($parameterSetNameInEffect -eq 'List') {
$opTable.Values | Select-Object Name, FriendlyName, Category | Sort-Object Category, Name
}
else {
if ($CopyUrl) {
Write-Verbose "Copying URL to clipboard: $url"
Set-Clipboard $url
}
else {
Write-Verbose "Navigating to: $url"
Start-Process $url
}
}
}
Show-TypeHelp
源代码:注意:忽略语法突出显示的损坏。
function Show-TypeHelp {
<#
.SYNOPSIS
Shows documentation for built-in .NET types.
.DESCRIPTION
Navigates to the specified .NET type's docs.microsoft.com documentation page
in your default web browser, assuming the type comes with .NET.
Use -WhatIf to preview the URL that would be opened.
There are two basic invocation patterns:
* Provide the full name of a type a type accelerator or a [type] instance
via the -Type parameter.
* Tab-completion works with the (prefixes of) a type's simple name (without
namespace component); e.g., Get-TypeHelp List<tab> cycles through all
loaded types whose name is or starts with 'List'.
* Pipe instance(s) of the type of interest.
.PARAMETER Type
Can be the name of a type (e.g. "string"), or a type literal (e.g. [string]).
If given a name, the name must be one of the following:
* The type's full name; e.g., 'System.Xml.XmlDocument'.
* The full name with the 'System.' prefix omitted; e.g., 'Xml.XmlDocument'
* The name of a PowerShell type accelerator; e.g., 'xml'
.PARAMETER Member
The optional name of a property or method to get specific information on.
If the target type has no such member, a warning is issued, and you're taken
to the type's home page.
.PARAMETER InputObject
Object(s), typically provided via the pipeline, whose type's documentation
page should be opened.
.PARAMETER Platform
The target .NET platform / standard, which must include a specific major.minor
version number; e.g., 'dotnetcore-3.1'.
Currently (v7.0), the latest 'netframework-*' version is targeted by default, i.e.,
the Windows-only .NET Framework (FullCLR).
Use tab completion to cycle through the available platforms, but note that
you must complete the specific version number yourself.
.EXAMPLE
Get-TypeHelp xml
Opens the documentation page for type [xml], i.e., for System.Xml.XmlDocument
.EXAMPLE
Get-TypeHelp string split
Opens the documentation page for the System.String type's Split() method.
.EXAMPLE
Get-Item / | Get-TypeHelp
Opens the documentation page for type System.IO.DirectoryInfo, an instance
of which is output by the Get-Item command.
.EXAMPLE
Get-TypeHelp regex -Platform netcore-3.1
Opens the documenation page for type System.Text.RegularExpressions.Regex
for the .NET Core 3.1 platform.
#>
[CmdletBinding(DefaultParameterSetName = 'ByType', SupportsShouldProcess = $true)]
[OutputType()] # No output.
param(
[Parameter(ParameterSetName = 'ByType', Mandatory, Position = 0)]
[ArgumentCompleter( {
param($cmd, $param, $wordToComplete)
# Remove enclosing / opening quote(s), if present.
$wordToComplete = $wordToComplete -replace '^[''"]|[''"]$'
if ($tp = $wordToComplete -as [Type]) {
# Already a full type name or the name of a type accelerator such as [xml]
$tp.FullName
}
else {
# Get the full names of all public types (including nested ones), but exclude dynamic assemblies.
# (Dynamic assemblies can't be expected to have documentation pages anyway; also, not excluding them would break the .GetExportedTypes() call.)
$allLoadedTypes = [System.AppDomain]::CurrentDomain.GetAssemblies().Where( { -not $_.IsDynamic }).GetExportedTypes().FullName
# Prefix-name-only-match against all loaded full type names from non-dynamic assemblies at
# and enclose in embedded '...' if the type name contains a ` char. (generics), then sort.
$(foreach ($match in $allLoadedTypes -match "[+.]$wordToComplete[^.]*$") {
($match, "'$match'")[$match -match '`']
}) | Sort-Object
}
})]
[Type] $Type
,
[Parameter(ParameterSetName = 'ByType', Position = 1)]
[string] $Member
,
[Parameter(ParameterSetName = 'ByInstance', ValueFromPipeline, Mandatory)]
[ValidateNotNullOrEmpty()]
$InputObject
,
[ArgumentCompleter( {
'netcore-', 'netframework-', 'xamarinmac-', 'dotnet-plat-ext-', 'netstandard-', 'dotnet-uwp-', 'xamarinandroid-', 'xamarinios-10.8', 'xamarinmac-' -like "$wordToComplete*"
})]
[string] $Platform
,
[Alias('cp')]
[switch] $CopyUrl
)
begin {
$types = [System.Collections.Generic.List[Type]]::new()
$instances = [System.Collections.Generic.List[object]]::new()
if ($Platform -and $Platform -notmatch '^[a-z][a-z-]+-\d+\.\d+$') {
Throw "The -Platform value must be in the form '<platform-id>-<major>.<minor>'; e.g., 'netcore-3.1'; use tab completion to cycle through the supported platforms and add a version number."
}
}
process {
switch ($PSCmdlet.ParameterSetName) {
'ByType' { $types.Add($Type) }
'ByInstance' { $instances.Add($InputObject) }
Default { Throw 'What are you doing here?' }
}
}
end {
# If instances were given, determine their types now.
if ($PSCmdlet.ParameterSetName -eq 'ByInstance') {
$types = $instances.ToArray().ForEach('GetType') | Select-Object -Unique
}
$urls = foreach ($tp in $types) {
# Make sure that the member exists, otherwise a 404 happens.
if ($Member -and $tp.GetMembers().Name -notcontains $Member) {
Write-Warning "Ignoring member name '$Member', because type '$tp' has no such member."
$Member = ''
}
# Transform the full type name to the format used in the URLs.
# '`1' -> '-1'
# System.Environment+SpecialFolder -> 'System.Environment.SpecialFolder'
$typeNameForUrl = $tp.FullName -replace '`', '-' -replace '\+', '.'
"https://docs.microsoft.com/$PSCulture/dotnet/api/$typeNameForUrl" + ('', ".$Member")[$Member -ne ''] + ('', "?view=$Platform")[[bool] $Platform]
}
if ($PSCmdlet.ShouldProcess("`n" + ($urls -join "`n") + "`n")) {
if ($CopyUrl) {
Write-Verbose "Copying URL(s) to clipboard: $urls"
Set-Clipboard $urls
}
else {
Write-Verbose "Navigating to: $urls"
Start-Process $urls
}
}
}
}