You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Best-Practices/Building-Reusable-Tools.md
+6-13Lines changed: 6 additions & 13 deletions
Original file line number
Diff line number
Diff line change
@@ -2,20 +2,18 @@
2
2
3
3
For this discussion, it's important to have some agreed-upon terminology. While the terminology here isn't used universally, the community generally agrees that several types of "script" exist:
4
4
5
-
1. Some scripts contain tools, when are meant to be reusable. These are typically functions or advanced functions, and they are typically contained in a script module or in a function library of some kind. These tools are designed for a high level of re-use.
6
-
2. Some scripts are controllers, meaning they are intended to utilize one or more tools (functions, commands, etc) to automate a specific business process. A script is not intended to be reusable; it is intended to make use of reuse by leveraging functions and other commands
5
+
1. Some scripts contain tools, which are meant to be reusable. These are typically functions or advanced functions, and they are typically contained in a script module or in a function library of some kind. These tools are designed for a high level of reuse.
6
+
2. Some scripts are controllers, meaning they are intended to utilize one or more tools (functions, commands, etc) to automate a specific business process. A controller script is not intended to be reusable; it is intended to make use of reuse by leveraging functions and other commands.
7
7
8
8
For example, you might write a "New-CorpUser" script, which provisions new users. In it, you might call numerous commands and functions to create a user account, mailbox-enable them, provision a home folder, and so on. Those discrete tasks might also be used in other processes, so you build them as functions. The script is only intended to automate that one process, and so it doesn't need to exhibit reusability concepts. It's a standalone thing.
9
9
10
-
Controllers, on the other hand, often produce output directly to the screen (when designed for interactive use), or may log to a file (when designed to run unattended).
11
-
10
+
Controllers often produce output directly to the screen (when designed for interactive use), or may log to a file (when designed to run unattended).
12
11
13
12
# TOOL-02 Make your code modular
14
13
15
14
Generally, people tend to feel that most working code - that is, your code which does things - should be modularized into functions and ideally stored in script modules.
16
15
17
-
That makes those functions more easily re-used. Those functions should exhibit a high level of reusability, such as accepting input only via parameters and producing output only as objects to the pipeline
18
-
16
+
That makes those functions more easily reused. Those functions should exhibit a high level of reusability, such as accepting input only via parameters and producing output only as objects to the pipeline.
19
17
20
18
# TOOL-03 Make tools as re-usable as possible
21
19
@@ -29,9 +27,9 @@ You can get a list of the verbs by typing 'get-verb' at the command line.
29
27
30
28
# TOOL-05 Use PowerShell standard parameter naming
31
29
32
-
Tools should be consistent with PowerShell native cmdlets in regards parameter naming.
30
+
Tools should be consistent with PowerShell native cmdlets in regard to parameter naming.
33
31
34
-
For example, use $ComputerName and $ServerInstance rather than something like $Param_Computer or $InstanceName
32
+
For example, use $ComputerName and $ServerInstance rather than something like $Param_Computer or $InstanceName.
35
33
36
34
# TOOL-06 Tools should output raw data
37
35
@@ -45,7 +43,6 @@ For example, a function named Get-DiskInfo would return disk sizing information
45
43
46
44
An intermediate step is useful for tools that are packaged in script modules: views. By building a manifest for the module, you can have the module also include a custom .format.ps1xml view definition file. The view can specify manipulated data values, such as the default view used by PowerShell to display the output of Get-Process. The view does not manipulate the underlying data, leaving the raw data available for any purpose.
47
45
48
-
49
46
# WAST-01 Don't re-invent the wheel
50
47
51
48
There are a number of approaches in PowerShell that will "get the job done." In some cases, other community members may have already written the code to achieve your objectives. If that code meets your needs, then you might save yourself some time by leveraging it, instead of writing it yourself.
@@ -77,15 +74,12 @@ It has been argued by some that, "I didn't know such-and-such existed, so I wrot
77
74
78
75
On the flip side, it's important to note that writing your own code from the ground up can be useful if you are trying to learn a particular concept, or if you have specific needs that are not offered by another existing solution.
79
76
80
-
81
77
# WAST-02 Report bugs to Microsoft
82
78
83
79
An exception: if you know that a built-in technique doesn't work properly (e.g., it is buggy or doesn't accomplish the exact task), then obviously it's fine to re-invent the wheel. However, in cases where you're doing so to avoid a bug or design flaw, then you should - as an upstanding member of the community - report the bug on [github.com/powershell](https://github.com/PowerShell/PowerShell/issues) also.
84
80
85
-
86
81
TODO: The "PURE" section is dubious at best. We need to discuss it.
87
82
88
-
89
83
# PURE-01 Use native PowerShell where possible
90
84
91
85
This means not using COM, .NET Framework classes, and so on when there is a native Windows PowerShell command or technique that gets the job done.
@@ -103,4 +97,3 @@ Document the reason for using tools other than PowerShell in your comments.
103
97
That said, you truly become a better PowerShell person if you take the time to wrap a less-preferred way in an advanced function or cmdlet. Then you get the best of both worlds: the ability to reach outside the shell itself for functionality, while keeping the advantages of native commands.
104
98
105
99
Ignorance, however, is no excuse. If you've written some big wrapper function around Ping.exe simply because you were unaware of Test-Connection, then you've wasted a lot of time, and that is not commendable. Before you move on to a less-preferred approach, make sure the shell doesn't already have a way to do what you're after.
Copy file name to clipboardExpand all lines: Best-Practices/Output-and-Formatting.md
+3-3Lines changed: 3 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ TODO: This whole document is STILL ROUGH DRAFT
6
6
7
7
Previous to PowerShell 5, Write-Host has no functionality at all in non-interactive scripts. It cannot be captured or redirected, and therefore should only be used in functions which are "Show"ing or "Format"ing output, or to display something as part of an interactive prompt to the user.
8
8
9
-
That is: you should not use Write-Host to create script output unless your script (or function, or whatever) uses the Show verb (as in, Show-Performance) or the Format verb (as in, Format-Hex), or has a `-Formatted` switch parameter. You may also use it to build a interactions with the user in other cases (e.g. to write extra information to the screen before prompting the user for a choice or input).
9
+
That is: you should not use Write-Host to create script output unless your script (or function, or whatever) uses the Show verb (as in, Show-Performance) or the Format verb (as in, Format-Hex), or has a `-Formatted` switch parameter. You may also use it to build interactions with the user in other cases (e.g., to write extra information to the screen before prompting the user for a choice or input).
10
10
11
11
Generally, you should consider the other Write-* commands first when trying to give information to the user.
12
12
@@ -22,7 +22,7 @@ You should use verbose output for information that contains details about the va
22
22
23
23
## Use Write-Debug to give information to someone maintaining your script
24
24
25
-
You should use the debug output stream for output that is useful for script debugging (ie: "Now entering main loop" or "Result was null, skipping to end of loop"), or to display the value of a variable before a conditional statement, so the maintainer can break into the debugger if necessary.
25
+
You should use the debug output stream for output that is useful for script debugging (e.g., "Now entering main loop" or "Result was null, skipping to end of loop"), or to display the value of a variable before a conditional statement, so the maintainer can break into the debugger if necessary.
26
26
27
27
> TIP: When debugging you should be aware that you can set `$DebugPreference = "Continue"` to see this information on screen without entering a breakpoint prompt.
28
28
@@ -48,7 +48,7 @@ When you combine the output of multiple types objects, they should generally be
48
48
49
49
### Two important exceptions to the single-type rule
50
50
51
-
**For internal functions** it's ok to return multiple different types because they won't be "output" to the user/host, and can offer significant savings (e.g. one database call with three table joins, instead of three database calls with two or three joins each). You can then call these functions and assign the output to multiple variables, like so:
51
+
**For internal functions** it's ok to return multiple different types because they won't be "output" to the user/host, and can offer significant savings (e.g., one database call with three table joins, instead of three database calls with two or three joins each). You can then call these functions and assign the output to multiple variables, like so:
As described elsewhere in this guide, many folks in the community would dislike this approach for aesthetic reasons. However, this approach has the advantage of utilizing PowerShell's pipeline to "stream" the content in file.txt. Provided that the fictional "Do-Something" command isn't blocking the pipeline (a la Sort-Object), the shell can send lines of content (String objects, technically) through the pipeline in a continuous stream, rather than having to buffer them all into memory.
43
+
As described elsewhere in this guide, many folks in the community would dislike this approach for aesthetic reasons. However, this approach has the advantage of utilizing PowerShell's pipeline to "stream" the content in file.txt. Provided that the fictional "Do-Something" command isn't blocking the pipeline (à la Sort-Object), the shell can send lines of content (String objects, technically) through the pipeline in a continuous stream, rather than having to buffer them all into memory.
44
44
45
45
Some would argue that this second approach is always a poor one, and that if performance is an issue then you should devolve from a PowerShell-native approach into a lower-level .NET Framework approach:
46
46
@@ -73,9 +73,8 @@ The moral here is that both aesthetic and performance are important consideratio
73
73
74
74
This is just a rough guideline, but as a general rule:
75
75
76
-
1. Language features are faster than features of the .net framework
77
-
2. Compiled methods on objects and .net classes are still faster than script
76
+
1. Language features are faster than features of the .NET Framework
77
+
2. Compiled methods on objects and .NET classes are still faster than script
78
78
3. Simple PowerShell script is still faster than calling functions or cmdlets
79
79
80
80
It's counter-intuitive that script is faster than calling cmdlets that are compiled, but it's frequently true, unless there is a lot of work being done by each cmdlet. The overhead of calling cmdlets and passing data around is significant. Of course, this is just a guideline, and you should always **measure**.
Copy file name to clipboardExpand all lines: Best-Practices/Security.md
+6-7Lines changed: 6 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -16,11 +16,11 @@ param (
16
16
)
17
17
```
18
18
19
-
If you absolutely must pass a password in a plain string to a .Net API call or a third party library it is better to decrypt the credential as it is being passed instead of saving it in a variable.
19
+
If you absolutely must pass a password in a plain string to a .NET API call or a third party library, it is better to decrypt the credential as it is being passed instead of saving it in a variable.
0 commit comments