Reputation: 1533
I am trying to get just the syntax section that get-help
outputs as a string, for example get-help get-childItem
outputs:
NAME
Get-ChildItem
SYNOPSIS
Gets the items and child items in one or more specified locations.
SYNTAX
Get-ChildItem [[-Filter] <System.String>] [-Attributes {Archive | Compressed | Device | Directory | Encrypted | Hidden | IntegrityStream | Normal | NoScrubData | NotContentIndexed | Offline | ReadOnly | ReparsePoint | SparseFile | System | Temporary}] [-Depth
<System.UInt32>] [-Directory] [-Exclude <System.String[]>] [-File] [-FollowSymlink] [-Force] [-Hidden] [-Include <System.String[]>] -LiteralPath <System.String[]> [-Name] [-ReadOnly] [-Recurse] [-System] [<CommonParameters>]
....
DESCRIPTION
The `Get-ChildItem` cmdlet gets the items in one or more specified locations. If the item is a container, it gets the items inside the container, known as child items. You can use the Recurse parameter to get items in all child containers and use the Depth parameter to
....
RELATED LINKS
Online Version: https://docs.microsoft.com/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-7.1&WT.mc_id=ps-gethelp
....
I am interested in the SYNTAX
section, I would like to take the output and print it with a simple function.
Many times, I don't wish to see all of the help output and want to just specifically see the command syntax, to get an idea for
So I am thinking of writing a simple function called syntax
and just do something like syntax get-childItem
and it should only output:
Get-ChildItem [[-Filter] <System.String>] [-Attributes {Archive | Compressed | Device | Directory | Encrypted | Hidden | IntegrityStream | Normal | NoScrubData | NotContentIndexed | Offline | ReadOnly | ReparsePoint | SparseFile | System | Temporary}]...
Get-ChildItem [[-Path] <System.String[]>] [[-Filter] <System.String>] [-Attributes {Archive | Compressed | Device | Directory | Encrypted | Hidden | IntegrityStream | Normal | NoScrubData | NotContentIndexed | Offline | ReadOnly | ReparsePoint | SparseFile...
Getting this syntax section has proven to be a headache though, get-help get-childitem|% syntax
will print just the syntax notation:
Get-ChildItem [[-Filter] <System.String>] [-Attributes {Archive | Compressed | Device | Directory | Encrypted | Hidden | IntegrityStream | Normal | NoScrubData | NotContentIndexed | Offline....
But one of my own functions will not. get-help compile-autoHotkey|% syntax
prints:
syntaxItem
----------
{@{name=Compile-AutoHotkey; CommonParameters=True; parameter=System.Object[]}}
I wrestled with this issue and it just gets worse:
(get-help compile-autoHotkey|% syntax).tostring()
- Prints an empty lineget-help compile-autoHotkey|% syntax|write-host
prints @{syntaxItem=System.Object[]}
"$(get-help compile-autoHotkey|% syntax)"
prints @{syntaxItem=System.Object[]}
Is there a reliable ways to get this information default commandlets and user defined functions?
PS: I know there are interactive ways to read the help and get syntax notation such as PsReadline, I personally just want the syntax notation
Upvotes: 2
Views: 105
Reputation: 439307
Preface:
Santiago's answer is effective in Windows PowerShell, but no longer in PowerShell (Core) 7+, because it relies on a bug that has since been fixed:
The .Synopsis
property should generally not include syntax diagrams, and instead should only report a command's concise description, as reported in the SYNOPSIS
section of Get-Help
output as well as of the first paragraph following the heading in the online help topics such as Get-ChildItem
The only situation in which it does make sense to have .Synopsis
report the syntax diagrams is if a given command has no help associated with it at all (in which case no synopsis can be provided) - this is how it works in PowerShell (Core) 7+.
.syntax
and .parameter
property values renders as expected for "help-less" commands - see GitHub issue #21125 and the bottom section of this answer.As a robust, cross-edition alternative to using Get-Help
's output, you can use
Get-Command -Syntax <command>
to get (just) the syntax diagrams for a given command, which also happens to bypass the aforementioned bugs.
Get-Help
output - would require compensating for these bugs - see the bottom section for an explanation and implementation.Thus, you could define your syntax
function as follows:
function syntax {
param(
[Parameter(Mandatory, ValueFromPipeline)]
[string] $Command,
# Optional parameter that provides context for discovery of dynamic parameters.
[object[]] $ArgumentList
)
process {
$cmdInfo = Get-Command -Name $Command; if (-not $?) { return }
# Windows PowerShell: Resolve an alias to its target command.
# PowerShell (Core) does that automatically.
if (-not $IsCoreCLR -and ($cmdInfo = $cmdInfo.ResolvedCommand)) {
$Command = $cmdInfo.Name
}
Get-Command -Syntax $Command -ArgumentList $ArgumentList
}
}
Note that the above automatically resolves aliases to their target commands in Windows PowerShell (which PowerShell (Core) 7+ does by default), so that you can call syntax
as follows, for instance, relying on built-in alias dir
getting resolved to Get-ChildItem
:
syntax dir # -> syntax diagrams for Get-ChildItem
Pros:
This works even with PowerShell commands that do not come with help.
Given that the information is directly derived from the actual commands via reflection, it is guaranteed to report the actual syntax, whereas it is technically possible for MAML-based information to diverge from the actual syntax.
Potential con:
Get-Command -Syntax
takes the current provider context into account with respect to dynamic parameters, whereas the information provided by Get-Help
- if MAML-based - may choose to report dynamic parameters across all providers by default, as is the case with (Get-Help Get-ChildItem).syntax
To situationally compensate for that, the function above offers an optional -ArgumentList
parameter to which you can pass an argument that implies a specific provider context, analogous to Get-Command
's own -ArgumentList
parameter, to which said argument is relayed.
While -ArgumentList
only accepts positional arguments, the fact that provider cmdlets bind their first positional argument to the -Path
parameter means that passing a single positional argument is sufficient to imply the provider context; e.g. to use the syntax
function above to reflect dynamic parameters for the Certificate
provider (e.g., -Eku
and -ExpiringDays
, invoke it as follows, which binds the Cert:
drive specification positionally to -ArgumentList
):
syntax Get-ChildItem Cert:
As for what you tried:
get-help get-childitem | % syntax
The above:
In PowerShell (Core) 7+: Malfunctions (doesn't render the syntax diagrams) for commands that lack any help information, which aren't just custom commands, but - depending on how PowerShell (Core) was installed - can include the built-in cmdlets.
In Windows PowerShell: Malfunctions for any command.
What it comes down to is that Get-Help
emits [pscustomobject]
instances, including for the nested .syntax
property, that rely on ETS type names to select suitable output-formatting definitions in order to render the value of the .syntax
property
If the required ETS type name to select the desired formatting isn't reflected in the intrinsic pstypenames
property, the object contained in the .syntax
property uses default formatting, which results in the - unhelpful - representation shown in your question.
For the desired rendering of the .syntax
property value to work consistently, its .pstypenames
property value must (also) include a MamlCommandHelpInfo#syntax
ETS type name, whereas:
in Windows PowerShell it invariably only contains ExtendedCmdletHelpInfo#syntax
(only)
in PowerShell (Core) 7+ it contains ExtendedCmdletHelpInfo#syntax
(only) for commands without help.
While this problem is unlikely to be fixed in Windows PowerShell (which will receive critical fixes only), it may get fixed in PowerShell (Core) 7+ - see GitHub issue #21125, which states that the .parameters
property is affected too.
The cross-edition implementation of a syntax
function based on the .syntax
property would therefore have to look like this:
function syntax {
param(
[Parameter(Mandatory, ValueFromPipeline)]
[string] $Command
)
process {
$syntaxInfo = (Get-Help $Command).syntax
# Ensure presence of the relevant ETS type name.
$syntaxInfo.pstypenames.Insert(0, 'MamlCommandHelpInfo#syntax')
# Now the output should render as expected.
$syntaxInfo
}
}
Sample call:
# Declare a function without help, then ask for its syntax.
function Foo { param([int] $Bar) }; syntax Foo
Output (in both PowerShell editions):
foo [[-Bar] <int>] [<CommonParameters>]
As an aside:
[<CommonParameters>]
in the syntax diagram, given that the function is not an advanced one and therefore doesn't support common parameters.Upvotes: 2
Reputation: 60563
The syntax string from the Get-Help
output is contained in the .Synopsis
property, if you want to make a simple function it's as simple as:
function syntax {
param(
[Parameter(Mandatory)]
[string] $Command
)
(Get-Help $Command).Synopsis
}
syntax Get-Item
Upvotes: 3