Skip to main content

Get Help Creating PowerShell Help Files

Updated: May 25, 2015 – The code now includes the filters for PowerShell V5 Common Parameters.

One of the tasks of creating a polished and professional looking PowerShell cmdlet or script is to include a help file.  In my humble opinion, the cmdlet Get-Help is the most powerful cmdlet in all of PowerShell.  I’ve been saying that since I discovered it in PowerShell V2 and I still say that in all of my PowerShell and Windows classes.  The reason that it is so powerful is because of the excellent design of the help system and our ability to use it with everything that we create. 
So why are so many PowerShell code writers not willing to write a help file for all of their hard work?  When I talk about this in class, it is like I am speaking about a taboo subject.  Most people hate to write “documentation”.  This is part of creating that professional product.  In my PowerShell classes, where we actually do learn to write help files, there are two issues that prevent many from successfully creating a help file the first time around.
Issue #1 – Incorrect spelling of keywords.  It happens.  I do it myself.  I misspelled parameter as parmeter in the description of each switch parameter in this cmdlets help file.  The keyword PARAMETER was not misspelled once because I used this code to help generate the actual help file for this code.
Issue #2 – “Do I have to include each parameter in my help file?”  Yes you do.  Again, think professionalism here.  In my PowerShell classes, I try to allow for about 4 hours at the end of class on Friday for each student to try and complete a simple automation task that they bring in from work.  This not only makes a great finale to the class, but also reinforces what we learned during the week. I do not do their project for them, but I coach them.  Sometimes they have a lot of parameters and then they have to write the help file.  Well, this code will help speed things along.
Lets execute this code against a PowerShell cmdlet Get-Date.  We are not going to write the help file for Get-Date. That is already done.  Get-Date has a lot of parameters to it and I just want to demonstrate how easy this process is.  First we will run the code and then paste the output right onto the screen so we can see it.

PS C:\> New-HelpFile -Source Get-Date
 
Help file has been copied to the clipboard.
 
PS C:\> <#
.SYNOPSIS
 
.DESCRIPTION
 
.PARAMETER Date
 
.PARAMETER Year
 
.PARAMETER Month
 
.PARAMETER Day
 
.PARAMETER Hour
 
.PARAMETER Minute
 
.PARAMETER Second
 
.PARAMETER Millisecond
 
.PARAMETER DisplayHint
 
.PARAMETER UFormat
 
.PARAMETER Format
 
.Example
 
.Example
 
.NOTES
 
#>
 
If we ran this against our function or script, all that we would have to do is paste this comment block into the correct location in our code to be recognized as a help file.  Then just fill in the descriptions for each keyword and you are done.  To discover the correct location of where to paste this code just take a look at the help file About_Comment_Based_Help for the correct location.  Refer to the sections:
SYNTAX FOR COMMENT-BASED HELP IN FUNCTIONS
SYNTAX FOR COMMENT-BASED HELP IN SCRIPTS
I’ve included this code in one of my PowerShell modules that I not only use for myself, but I also provide the module to my students in my PowerShell class after they had a taste of creating a help file from scratch.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

Function New-HelpFile

{

[CmdletBinding()]

Param (

    [parameter(Mandatory=$true)]

    [String]
    $Source,
 
    [Int]
    $Examples= 2,
 
    [Switch]$Inputs,
    [Switch]$Outputs,
    [Switch]$Link,
    [Switch]$Component,
    [Switch]$Role,
    [Switch]$Functionality,
    [Switch]$ForwardHelpTargetName,
    [Switch]$ForwardHelpCategory,
    [Switch]$RemoteHelpRunspace,
    [Switch]$ExternalHelp
 
)
 
    # Get the list of parameters for the cmdlet.
    [System.Collections.Arraylist]$Params = (Get-Command $Source).
        Parameters.Keys
 
  
  
    # Remove the common parameters for the list if they are present.
    Try
    {
        $Params.Remove("Verbose")
        $Params.Remove("Debug")
        $Params.Remove("ErrorAction")
        $Params.Remove("WarningAction")
        $Params.Remove("ErrorVariable")
        $Params.Remove("WarningVariable")
        $Params.Remove("OutVariable")
        $Params.Remove("OutBuffer")
        $Params.Remove("PipelineVariable")
        $Params.Remove("InformationAction")
        $Params.Remove("InformationVariable")
    }
    Catch {}
 
    # Write the Help File.
    $Out = $Null # Makes sure the variable is clear.
  
    $Out += "<#`n"
    $Out += ".SYNOPSIS`n`n"
    $Out += ".DESCRIPTION`n`n"
  
    # Add the Parameters
    ForEach($P in $Params)
    {
        $Out+= ".PARAMETER $P`n`n"
    }
 
    # Add the Examples
    For ($X = 1; $X -le $Examples; $X++)
    {
       $Out+= ".Example`n`n"
    }
    If ($Inputs) {$Out += ".INPUTS`n`n"}
    If ($Outputs) {$Out += ".OUTPUTS`n`n"}
  
    # I almost always add NOTES so I just have it in be default.
    $Out += ".NOTES`n`n"
 
    If ($Link) {$Out += ".LINK`n`n"}
    If ($Component) {$Out += ".COMPONENT`n`n"}
    If ($Role) {$Out += ".ROLE`n`n"}
    If ($Functionality) {$Out += ".FUNCTIONALITY`n`n"}
    If ($ForwardHelpTargetName) {$Out += ".FORWARDHELPTARGETNAME`n`n"}
    If ($ForwardHelpCategory) {$Out += ".FORWARDHELPCATEGORY `n`n"}
    If ($RemoteHelpRunspace) {$Out += ".REMOTEHELPRUNSPACE `n`n"}
    If ($ExternalHelp) {$Out += ".EXTERNALHELP  `n`n"}
 
    $Out += "#>"
 
    # Sends the output to the clipboard.
    $Out | Clip
 
    # Let the user know that the process is complete.
    Write-Host "Help file has been copied to the clipboard."
 
<#
.SYNOPSIS
Helps you create a help file for your scripts and functions.
 
.DESCRIPTION
Reads the source code of a script or a function in memory and creates the basic
framework for a help file for both your functions in memory, and your saved
scripts.
 
For scripts, this code will only read the parameters for the script.  It will
not read parameters of functions inside of the script.
 
For functions, this code will only read the parameters of the root function, not
the parameters of sub functions.
 
The keywords that are automatically included in the output is:
- SYNOPSIS
- DESCRPTION
- PARAMETER (One for each listed parameter in the root PARAM block)
- EXAMPLE (2 by default)
- NOTES
 
Once this cmdlet is done, it will copy the text for the help file to the
clipboard.  You must paste it into your code in the correct location.  Refer
to the help file About_Comment_Based_Help for the correct location.  Refer to
the sections:
SYNTAX FOR COMMENT-BASED HELP IN FUNCTIONS
SYNTAX FOR COMMENT-BASED HELP IN SCRIPTS
 
 
.PARAMETER Source
The name of the source code or function in memory to create the help file for.
 
.PARAMETER Examples
The number of example sections that you would like to automatically generate.
The default number is 2.
 
.PARAMETER Inputs
Switch parameter to add the "INPUTS" keyword.
 
.PARAMETER Outputs
Switch parameter to add the "OUTPUTS" keyword.
 
.PARAMETER Link
Switch parameter to add the "LINK" keyword.
 
.PARAMETER Component
Switch parameter to add the "COMPONENT" keyword.
 
.PARAMETER Role
Switch parameter to add the "ROLE" keyword.
 
.PARAMETER Functionality
Switch parameter to add the "FUNCTIONALITY" keyword.
 
.PARAMETER ForwardHelpTargetName
Switch parameter to add the "FORWARDHELPTARGETNAME" keyword.
 
.PARAMETER ForwardHelpCategory
Switch parameter to add the "FORWARDHELPCATEGORY" keyword.
 
.PARAMETER RemoteHelpRunspace
Switch parameter to add the "REMOTEHELPRUNSPACE" keyword.
 
.PARAMETER ExternalHelp
Switch parameter to add the "EXTERNALHELP" keyword.
 
 
.Example
New-HelpFile -Cmdlet New-LabVM -Examples 3
 
Creates a new helpfile based on a function/cmdlet in memory called New-LabVM.
This will copy to the clipboard the text to create a help file with 3 example
keywords instead of the default 2.  You must insert the help file in the
correct location for the help file to work.
 
.Example
New-HelpFile -Cmdlet "E:\temp\Test1.ps1" -Link -Role
 
Creates a new help file based on a saved script called Test1.ps1.
This will copy to the clipboard the text to create a help file with both the
LINK and ROLE keywords.  You must insert the help file in the
correct location for the help file to work.
 
.NOTES
===============================================================================
== Cmdlet: New-HelpFile                                                      ==
== Author: Jason A. Yoder                                                    ==
== Company: MCTExpert of Arizona                                             ==
== Date: February 18, 2015                                                   ==
== Last Update: May 25, 2015                                                 ==
== Copyright: All rights reserved.                                           ==
== Version: 1.0.0.1                                                          ==
== Legal: The user assumes all responsibility and liability for the usage of ==
== this PowerShell code.  MCTExpert of Arizona, Its officers, shareholders,  ==
== owners, and their relatives are not liable for any damages.  As with all  ==
== code, review it and understand it prior to usage.  It is recommended that ==
== this code be fully tested and validated in a test environment prior to    ==
== usage in a production environment.                                        ==
==                                                                           ==
== Does this code make changes: NO                                           ==
==                                                                           ==
== Update May 25, 2015: Filtering added for PowerShell V5                    ==
== Common Parameters InformationAction and InformationVariable.              ==
===============================================================================
 
.LINK
About_Comment_Based_Help
#>
} # End: Function New-HelpFile
 
 
 

Comments

Popular posts from this blog

Adding a Comment to a GPO with PowerShell

As I'm writing this article, I'm also writing a customization for a PowerShell course I'm teaching next week in Phoenix.  This customization deals with Group Policy and PowerShell.  For those of you who attend my classes may already know this, but I sit their and try to ask the questions to myself that others may ask as I present the material.  I finished up my customization a few hours ago and then I realized that I did not add in how to put a comment on a GPO.  This is a feature that many Group Policy Administrators may not be aware of. This past summer I attended a presentation at TechEd on Group Policy.  One organization in the crowd had over 5,000 Group Policies.  In an environment like that, the comment section can be priceless.  I always like to write in the comment section why I created the policy so I know its purpose next week after I've completed 50 other tasks and can't remember what I did 5 minutes ago. In the Group Policy module for PowerShell V3, th

Return duplicate values from a collection with PowerShell

If you have a collection of objects and you want to remove any duplicate items, it is fairly simple. # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   # Remove the duplicate values. $Set1 | Select-Object -Unique 1 2 3 4 5 6 7 What if you want only the duplicate values and nothing else? # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   #Create a second collection with duplicate values removed. $Set2 = $Set1 | Select-Object -Unique   # Return only the duplicate values. ( Compare-Object -ReferenceObject $Set2 -DifferenceObject $Set1 ) . InputObject | Select-Object – Unique 1 2 This works with objects as well as numbers.  The first command creates a collection with 2 duplicates of both 1 and 2.   The second command creates another collection with the duplicates filtered out.  The Compare-Object cmdlet will first find items that are diffe

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.