-
Notifications
You must be signed in to change notification settings - Fork 290
/
Copy pathFunction-Structure.md
291 lines (235 loc) · 7.88 KB
/
Function-Structure.md
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
282
283
284
285
286
287
288
289
290
291
### Functions
Avoid using the `return` keyword in your functions. Just place the object variable on its own.
When declaring simple functions leave a space between the function name and the parameters.
```PowerShell
function MyFunction ($param1, $param2) {
...
}
```
### Advanced Functions
For Advanced Functions and scripts use the format of **\<verb\>-\<noun\>** for
naming. For a list of approved verbs the cmdlet `Get-Verb` will list
them. On the noun side it can be composed of more than one joined word
using Pascal Case and only singular nouns.
In Advanced Functions do not use the keyword `return` to return an object.
In Advanced Functions you return objects inside the `Process {}` block
and not in `Begin {}` or `End {}` since it defeats the advantage of the pipeline.
```PowerShell
# Bad
function Get-USCitizenCapability {
[CmdletBinding()]
[OutputType([psobject])]
param (
[Parameter(Mandatory = $true,
ValueFromPipelineByPropertyName = $true,
Position = 0)]
[int16]
$Age
)
process {
$Capabilities = @{
MilitaryService = $false
DrinkAlcohol = $false
Vote = $false
}
if ($Age -ge 18) {
$Capabilities['MilitaryService'] = $true
$Capabilities['Vote'] = $true
}
$Obj = New-Object -Property $Capabilities -TypeName psobject
}
end { return $Obj }
}
# Good
function Get-USCitizenCapability {
[CmdletBinding()]
[OutputType([psobject])]
param (
[Parameter(Mandatory = $true,
ValueFromPipelineByPropertyName = $true,
Position = 0)]
[int16]
$Age
)
process {
$Capabilities = @{
MilitaryService = $false
DrinkAlcohol = $false
Vote = $false
}
if ($Age -ge 18) {
$Capabilities['MilitaryService'] = $true
$Capabilities['Vote'] = $true
}
New-Object -Property $Capabilities -TypeName psobject
}
}
```
#### Always use CmdletBinding attribute.
#### Always have at least a `process {}` code block if any parameters takes values from the pipeline.
#### Specify an OutputType attribute if the advanced function returns an object or collection of objects.
If the function returns different object types depending on the parameter set provide one per parameter set.
```PowerShell
[OutputType([<TypeLiteral>], ParameterSetName = "<Name>")]
[OutputType("<TypeNameString>", ParameterSetName = "<Name>")]
```
#### When a ParameterSetName is used in any of the parameters, always provide a DefaultParameterSetName in the CmdletBinding attribute.
```PowerShell
function Get-User {
[CmdletBinding(DefaultParameterSetName = "ID")]
[OutputType("System.Int32", ParameterSetName = "ID")]
[OutputType([String], ParameterSetName = "Name")]
param (
[parameter(Mandatory = $true, ParameterSetName = "ID")]
[Int[]]
$UserID,
[parameter(Mandatory = $true, ParameterSetName = "Name")]
[String[]]
$UserName
)
<# function body #>
}
```
#### When using advanced functions or scripts with CmdletBinding attribute avoid validating parameters in the body of the script when possible and use parameter validation attributes instead.
* **AllowNull** Validation Attribute
The AllowNull attribute allows the value of a mandatory parameter to be null ($null).
```PowerShell
param (
[Parameter(Mandatory = $true)]
[AllowNull()]
[String]
$ComputerName
)
```
* **AllowEmptyString** Validation Attribute
The AllowEmptyString attribute allows the value of a mandatory parameter to be an empty string ("").
```PowerShell
param (
[Parameter(Mandatory = $true)]
[AllowEmptyString()]
[String]
$ComputerName
)
```
* **AllowEmptyCollection** Validation Attribute
The AllowEmptyCollection attribute allows the value of a mandatory parameter to be an empty collection (@()).
```PowerShell
param (
[Parameter(Mandatory = $true)]
[AllowEmptyCollection()]
[String[]]
$ComputerName
)
```
* **ValidateCount** Validation Attribute
The ValidateCount attribute specifies the minimum and maximum number
of parameter values that a parameter accepts. PowerShell
generates an error if the number of parameter values in the command that
calls the function is outside that range.
```PowerShell
param (
[Parameter(Mandatory = $true)]
[ValidateCount(1,5)]
[String[]]
$ComputerName
)
```
* **ValidateLength** Validation Attribute
The ValidateLength attribute specifies the minimum and maximum number
of characters in a parameter or variable value. PowerShell generates an
error if the length of a value specified for a parameter or a variable
is outside of the range.
```PowerShell
param (
[Parameter(Mandatory = $true)]
[ValidateLength(1,10)]
[String[]]
$ComputerName
)
```
* **ValidatePattern** Validation Attribute
The ValidatePattern attribute specifies a regular expression that
is compared to the parameter or variable value. PowerShell generates
an error if the value does not match the regular expression
pattern.
```PowerShell
param (
[Parameter(Mandatory = $true)]
[ValidatePattern("[0-9][0-9][0-9][0-9]")]
[String[]]
$ComputerName
)
```
* **ValidateRange** Validation Attribute
The ValidateRange attribute specifies a numeric range for each
parameter or variable value. PowerShell generates an error
if any value is outside that range.
```PowerShell
param (
[Parameter(Mandatory = $true)]
[ValidateRange(0,10)]
[Int]
$Attempts
)
```
* **ValidateScript** Validation Attribute
The ValidateScript attribute specifies a script that is used
to validate a parameter or variable value. PowerShell
pipes the value to the script, and generates an error if the
script returns "false" or if the script throws an exception.
When you use the ValidateScript attribute, the value
that is being validated is mapped to the $_ variable. You can
use the $_ variable to refer to the value in the script.
```PowerShell
param (
[Parameter()]
[ValidateScript({$_ -ge (get-date)})]
[DateTime]
$EventDate
)
```
* **ValidateSet** Attribute
The ValidateSet attribute specifies a set of valid values for a
parameter or variable. PowerShell generates an error if a
parameter or variable value does not match a value in the set. In
the following example, the value of the Detail parameter can only
be "Low," "Average," or "High."
```PowerShell
param (
[Parameter(Mandatory = $true)]
[ValidateSet("Low", "Average", "High")]
[String[]]
$Detail
)
```
* **ValidateNotNull** Validation Attribute
The ValidateNotNull attribute specifies that the parameter
value cannot be null ($null). PowerShell generates an
error if the parameter value is null.
The ValidateNotNull attribute is designed to be used when the
type of the parameter value is not specified or when the specified
type will accept a value of null. (If you specify a type that will
not accept a null value, such as a string, the null value will be
rejected without the ValidateNotNull attribute, because it does not
match the specified type.)
```PowerShell
param (
[Parameter(Mandatory = $true)]
[ValidateNotNull()]
$ID
)
```
* **ValidateNotNullOrEmpty** Validation Attribute
The ValidateNotNullOrEmpty attribute specifies that the parameter
value cannot be null ($null) and cannot be an empty string ("").
PowerShell generates an error if the parameter is used in
a function call, but its value is null, an empty string, or an empty
array.
```PowerShell
param (
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[String[]]
$UserName
)
```