Help not working in my PowerShell Function

Hello,
I have a simple PowerShell Function, that I am importing as a module, which does not display the help. The Module imports correctly (I can run the function no problem) but when i type help [name of function] I get just the default help and not anything that I have typed.
Here is the code for the function:-
<#
.SYNOPSIS
Retrieves registry keys beneath HKCU\software as a gridview.

.DESCRIPTION
Retrieves registry keys beneath HKCU\software as a gridview for use as the parameter 
in set-HKCURegKeySoftwareBak

.PARAMETER
There is no parameter for this function.

.EXAMPLE
Set-Location

#>
Function Find-HKCURegistrykey{
Set-Location HKCU:\software
dir | Out-GridView
}
Any suggestions to get the help working would be appreciated.

You want to place the comment within the Function like this.

Function Find-HKCURegistrykey{
<#
.SYNOPSIS
Retrieves registry keys beneath HKCU\software as a gridview.

.DESCRIPTION
Retrieves registry keys beneath HKCU\software as a gridview for use as the parameter
in set-HKCURegKeySoftwareBak

.PARAMETER
There is no parameter for this function.

.EXAMPLE
Set-Location
#>

Set-Location HKCU:\software
dir | Out-GridView
}

I’ve had this problem in the past as well. I found one site that recommended having four empty lines between the comment block help and the actual code. Once I adopted that I had no further problems.

It’s interesting that you say it works with four empty lines between the help and the code as that goes directly against Microsoft’s documentation:
about_comment_based_help

I just tried editing a .psm1 I have and moved the comment based help up and out of the function definition and included 4 blank lines between the help and the function and i do not get help.
code snipped:

.EXAMPLE
PS C:\> Protect-String "Secret message" -Encryption AES
Enter Master Password: ********
A7B3uXRDkDZkejQVQhwqn2I4KJjsxfqCbc1a+9Jgg620=

This command will encrypt the provided string with AES 256-bit encryption. If no Master Password is found in the current session (set with Set-MasterPassword) then it will prompt for one  to be set.
#>




Function Protect-String {
    [cmdletbinding()]
    Param (

Then asking for help:

get-help protect-string

NAME
    Protect-String

SYNTAX
    Protect-String [-InputString] <string> [[-Encryption] {DPAPI | AES}]  [<CommonParameters>]


ALIASES
    None


REMARKS
    None

If i remove the four blank lines, remove and re-import, i still don’t have help info.

This is all with a monolithic psm1 file where all function definitions are contained within.
If I change the test and leave functions as individual .ps1 files and the .psm1 file just loops through them and dot sources them I get different behavior.
With the help info at the top of the .ps1 file before the function definition I get help when i run Get-Help against the function. If I include four blank lines between the comment based help and the function definition I do not get help. If I include only one blank line (per Microsoft’s documentation) I do get help.

even if i skip all of the psm1 stuff and use Import-Module against a single .ps1 file containing my function definition I still get help returned when the comment based help is present before the function definition as long as there are not more than one blank line between.

I forgot something to include. Here is an example from one of my scripts.

<#
.SYNOPSIS
Retrieves 'enabled' Servers from Active Directory, queries each server's DNS record and retrieves additional information. 

.DESCRIPTION
Retrieves all computer objects with an operating system including the word 'server' in it where the server status is 'enabled'.

Retrieves the following properties for each server; ComputerName, LastLogonDate, Enabled, Model, IPv4Address, IPv6Address, DNSIPv4Address, OperatingSystem, DNLocation, and DistinguishedName.

Checks DNS for the presence of A and/or AAAA records for the server.

Builds an excel formated document with three sheets. 'Win AD Servers' lists the servers with their results. The 'Operating Systems' sheet displays a graph of operating systems. The Counts By Site displays a list of sites with the operating systems and counts for that site.

.EXAMPLE
.\Get-AllADServers2.ps1

Gets all of the Computer Objects from Active Directory with a OperatingSystem property that has 'Server' in it with a status of enabled and the specified properties.

Queries each server for Model info, IP address info, PowerShell version and checks for DNS A and AAAA records for the server.

Data is saved to the current working directory in an Excel workbook called 'AllServersInAD.xlsx'
DNS errors are logged in 'AllServersDNSErrors.txt' - servers that have no DNS entries

.NOTES
This script and 'Get-Details.ps1' must be together in the 'current working directory' to work. The current working directory is where all files will get created.

Active Directory tracks the last login date for computer objects. The last login date can be as much as two weeks in the past. That means any lastlogindate later than 14 days ago would mean the server is missing, either the network has been down for an extended period or the server is simply offline.

Since computer objects must change their machine password with AD once every 90 days, it is safe to consider a server with a lastlogindate greater than 90 days in the past as one that is no longer a viable computer. It won't be able to login again - without manual intervention.

That makes the last login date piece of information invaluble for locating servers that should be disabled and/or removed from AD.

A DNS query is made to ensure client computers can lookup the server.

Import-Excel is a required module as it is used to create the Excel Workbook which includes a graph that a simple export-csv can't create.
#>




[CmdletBinding()]
param ()

Note: All of the help text goes inside the <# and #>, the four empty lines and the use of [CmdletBinding()] and param () are also required for the help to show up.

Is this a .ps1 file you’re showing as an example from @KevinGagel ?
The help info shows an example of calling it via .\Get-AllADServers2.ps1 which makes me think this is a script file, not a function definition.
I’ll again defer to the Microsoft documentation on comment based help. In a script file the comment based help can go at the beginning of the file (and likely should). I don’t think the amount of spaces between the comment block and the next line of code matters in this instance.
I have multiple script files with comment based help and it doesn’t seem to matter if there’s zero or a dozen blank lines between the comment block and the code.

The original problem @RedKites posted about is specifically a function, not a script file.

1 Like

Yes, it is a ps1 file. The setup is the same for both.

Interesting - I learned something new today. I didn’t know you could do comment based help in a ps1 file. I’m almost always writing functions in a module, so never had a reason to try.

This might help: