Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
# Conflicts:
#	Best-Practices/Introduction.md
#	Best-Practices/Output-and-Formatting.md
#	README.md
#	Style-Guide/Readability.md
#	TableOfContents.md
  • Loading branch information
Adam Gabryś committed Jul 19, 2017
2 parents df08531 + 863e1f9 commit 2c521c6
Show file tree
Hide file tree
Showing 21 changed files with 145 additions and 135 deletions.
File renamed without changes.
140 changes: 70 additions & 70 deletions Best Practices/Error Handling.md → Best-Practices/Error-Handling.md
Original file line number Diff line number Diff line change
@@ -1,70 +1,70 @@
# ERR-01 Use -ErrorAction Stop when calling cmdlets

When trapping an error, try to use -ErrorAction Stop on cmdlets to generate terminating, trappable exceptions.

# ERR-02 Use $ErrorActionPreference='Stop' or 'Continue' when calling non-cmdlets

When executing something other than a cmdlet, set $ErrorActionPreference='Stop' before executing, and re-set to Continue afterwards. If you're concerned about using -ErrorAction because it will bail on the entire pipeline, then you've probably over-constructed the pipeline. Consider using a more scripting-construct-style approach, because those approaches are inherently better for automated error handling.

Ideally, whatever command or code you think might bomb should be dealing with one thing: querying one computer, deleting one file, updating one user. That way, if an error occurs, you can handle it and then get on with the next thing.

# ERR-03 Avoid using flags to handle errors

Try to avoid setting flags:

```PowerShell
try {
$continue = $true
Do-Something -ErrorAction Stop
} catch {
$continue = $false
}
if ($continue) {
Do-This
Set-That
Get-Those
}
```

Instead, put the entire "transaction" into the Try block:

```PowerShell
try {
Do-Something -ErrorAction Stop
Do-This
Set-That
Get-Those
} catch {
Handle-Error
}
```

It's a lot easier to follow the logic.

# ERR-04 Avoid using $?

When you need to examine the error that occurred, try to avoid using $?. It actually doesn't mean an error did or did not occur; it's reporting whether or not the last-run command considered itself to have completed successfully. You get no details on what happened.


# ERR-05 Avoid testing for a null variable as an error condition

Also try to avoid testing for a null variable as an error condition:

```
$user = Get-ADUser -Identity DonJ
if ($user) {
$user | Do-Something
} else {
Write-Warning "Could not get user $user"
}
```

There are times and technologies where that's the only approach that will work, especially if the command you're running won't produce a terminating, trappable exception. But it's a logically contorted approach, and it can make debugging trickier.

# ERR-06 Copy $Error[0] to your own variable

Within a `catch` block, `$_` will contain the last error that occurred, as will `$Error[0]`. Use either - but immediately copy them into your own variable, as executing additional commands can cause `$_` to get "hijacked" or `$Error[0]` to contain a different error.

It isn't necessary to clear `$Error` in most cases. `$Error[0]` will be the last error, and PowerShell will maintain the rest of the `$Error` collection automatically.
# ERR-01 Use -ErrorAction Stop when calling cmdlets

When trapping an error, try to use -ErrorAction Stop on cmdlets to generate terminating, trappable exceptions.

# ERR-02 Use $ErrorActionPreference='Stop' or 'Continue' when calling non-cmdlets

When executing something other than a cmdlet, set $ErrorActionPreference='Stop' before executing, and re-set to Continue afterwards. If you're concerned about using -ErrorAction because it will bail on the entire pipeline, then you've probably over-constructed the pipeline. Consider using a more scripting-construct-style approach, because those approaches are inherently better for automated error handling.

Ideally, whatever command or code you think might bomb should be dealing with one thing: querying one computer, deleting one file, updating one user. That way, if an error occurs, you can handle it and then get on with the next thing.

# ERR-03 Avoid using flags to handle errors

Try to avoid setting flags:

```PowerShell
try {
$continue = $true
Do-Something -ErrorAction Stop
} catch {
$continue = $false
}
if ($continue) {
Do-This
Set-That
Get-Those
}
```

Instead, put the entire "transaction" into the Try block:

```PowerShell
try {
Do-Something -ErrorAction Stop
Do-This
Set-That
Get-Those
} catch {
Handle-Error
}
```

It's a lot easier to follow the logic.

# ERR-04 Avoid using $?

When you need to examine the error that occurred, try to avoid using $?. It actually doesn't mean an error did or did not occur; it's reporting whether or not the last-run command considered itself to have completed successfully. You get no details on what happened.


# ERR-05 Avoid testing for a null variable as an error condition

Also try to avoid testing for a null variable as an error condition:

```
$user = Get-ADUser -Identity DonJ
if ($user) {
$user | Do-Something
} else {
Write-Warning "Could not get user $user"
}
```

There are times and technologies where that's the only approach that will work, especially if the command you're running won't produce a terminating, trappable exception. But it's a logically contorted approach, and it can make debugging trickier.

# ERR-06 Copy $Error[0] to your own variable

Within a `catch` block, `$_` will contain the last error that occurred, as will `$Error[0]`. Use either - but immediately copy them into your own variable, as executing additional commands can cause `$_` to get "hijacked" or `$Error[0]` to contain a different error.

It isn't necessary to clear `$Error` in most cases. `$Error[0]` will be the last error, and PowerShell will maintain the rest of the `$Error` collection automatically.
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ If you scan through code projects on [PoshCode](https://github.com/PoshCode) or

Over the years several attempts have been made to arrive at a consensus, most notably the "Great Debate" series of blog posts on [PowerShell.org](https://powershell.org/?s=great+debate) following the 2013 Scripting Games, which outlined some of the more controversial issues and asked for community discussions.

This project has been created, in part, as a public place to continue those debates as well as to document the consensus of the community when we _do_ arrive at a consensus.
This project has been created, in part, as a public place to continue those debates as well as to document the consensus of the community when we _do_ arrive at a consensus.

Remember that best practices are not hard-and-fast rules. We don't even consider them as solid as the style guide rules. They are the things you should _usually_ do as a starting point, and should deviate from when it's appropriate.

One final note about these Best Practices: the perspective of these guidelines has so-far been strongly influenced by system administrator practitioners, less-so by language geeks and developers. We're trying to balance that and provide perspective, but when it comes to best practices, we definitely allow the experience of administrators to drive what the PowerShell community considers best and worst practices -- so if you are working from a different perspective, you'll have to take all of this with a grain of salt.

## Table of Contents

- [Naming Conventions](Naming%20Conventions.md)
- [Building Reusable Tools](Building%20Reusable%20Tools.md)
- [Output and Formatting](Output%20and%20Formatting.md)
- [Error Handling](Error%20Handling.md)
- [Naming Conventions](Naming-Conventions.md)
- [Building Reusable Tools](Building-Reusable-Tools.md)
- [Output and Formatting](Output-and-Formatting.md)
- [Error Handling](Error-Handling.md)
- [Performance](Performance.md)
- [Security](Security.md)
- [Language, Interop and .Net](Language,%20Interop%20and%20.Net.md)
- [Metadata, Versioning, and Packaging](Metadata,%20Versioning,%20and%20Packaging.md)
- [Language, Interop and .Net](Language,-Interop-and-.Net.md)
- [Metadata, Versioning, and Packaging](Metadata,-Versioning,-and-Packaging.md)
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ TODO: This whole document is STILL ROUGH DRAFT

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.

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).
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).

Generally, you should consider the other Write-* commands first when trying to give information to the user.

Expand All @@ -28,11 +28,11 @@ You should use the debug output stream for output that is useful for script debu
## Use CmdletBinding if you are using output streams

As we've already written elsewhere, you should probably [always use CmdletBinding](../Style%20Guide/Code%20Layout%20and%20Formatting.md#always-start-with-cmdletbinding).
As we've already written elsewhere, you should probably [always use CmdletBinding](../Style-Guide/Code-Layout-and-Formatting.md#always-start-with-cmdletbinding).

However, it's particularly important when you're using Write-Verbose and Write-Debug, as the Verbose and Debug output streams are off by default, and the `[CmdletBinding()]` attribute enables the common `-Verbose` and `-Debug` switches which turn those streams on.
However, it's particularly important when you're using Write-Verbose and Write-Debug, as the Verbose and Debug output streams are off by default, and the `[CmdletBinding()]` attribute enables the common `-Verbose` and `-Debug` switches which turn those streams on.

It also enables the switches for the Warning and Error streams, as well as ways of collecting those streams into variables. You should read the [always use CmdletBinding](../Style%20Guide/Code%20Layout%20and%20Formatting.md#always-start-with-cmdletbinding) topic for more information.
It also enables the switches for the Warning and Error streams, as well as ways of collecting those streams into variables. You should read the [always use CmdletBinding](../Style-Guide/Code-Layout-and-Formatting.md#always-start-with-cmdletbinding) topic for more information.

## Use Format Files for your custom objects

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
30 changes: 15 additions & 15 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ The *PowerShell Best Practices* are always evolving, and continue to be edited a

To repeat from the ReadMe, the guidelines are divided into these sections:

* [Style Guide (Introduction)](Style%20Guide/Introduction.md)
* [Code Layout and Formatting](Style%20Guide/Code%20Layout%20and%20Formatting.md)
* [Function Structure](Style%20Guide/Function%20Structure.md)
* [Documentation and Comments](Style%20Guide/Documentation%20and%20Comments.md)
* [Readability](Style%20Guide/Readability.md)
* [Naming Conventions](Style%20Guide/Naming%20Conventions.md)
* [Best Practices (Introduction)](Best%20Practices/Introduction.md)
* [Naming Conventions](Best%20Practices/Naming%20Conventions.md)
* [Building Reusable Tools](Best%20Practices/Building%20Reusable%20Tools.md)
* [Output and Formatting](Best%20Practices/Output%20and%20Formatting.md)
* [Error Handling](Best%20Practices/Error%20Handling.md)
* [Performance](Best%20Practices/Performance.md)
* [Security](Best%20Practices/Security.md)
* [Language, Interop and .Net](Best%20Practices/Language%2C%20Interop%20and%20.Net.md)
* [Metadata, Versioning, and Packaging](Best%20Practices/Metadata%2C%20Versioning%2C%20and%20Packaging.md)
* [Style Guide (Introduction)](Style-Guide/Introduction.md)
* [Code Layout and Formatting](Style-Guide/Code-Layout-and-Formatting.md)
* [Function Structure](Style-Guide/Function-Structure.md)
* [Documentation and Comments](Style-Guide/Documentation-and-Comments.md)
* [Readability](Style-Guide/Readability.md)
* [Naming Conventions](Style-Guide/Naming-Conventions.md)
* [Best Practices (Introduction)](Best-Practices/Introduction.md)
* [Naming Conventions](Best-Practices/Naming-Conventions.md)
* [Building Reusable Tools](Best-Practices/Building-Reusable-Tools.md)
* [Output and Formatting](Best-Practices/Output-and-Formatting.md)
* [Error Handling](Best-Practices/Error-Handling.md)
* [Performance](Best-Practices/Performance.md)
* [Security](Best-Practices/Security.md)
* [Language, Interop and .Net](Best-Practices/Language%2C-Interop-and-.Net.md)
* [Metadata, Versioning, and Packaging](Best-Practices/Metadata%2C-Versioning%2C-and-Packaging.md)

Markdown documents on GitHub support linking within a document, but only to headers, so when editing, in addition to keeping practices and guidelines in the documents where they make sense, please use headlines for each guideline, and lower level headlines for rationale, examples, counter examples, and exceptions.

Expand Down
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This work is licensed under a [Creative Commons Attribution-ShareAlike 4.0 Inter

**Share** — copy and redistribute the material in any medium or format

**Adapt** — remix, transform, and build upon the material
**Adapt** — remix, transform, and build upon the material

The authors encourage you to redistribute this content as widely as possible, but require that you give credit to the primary authors below, and that you notify us on github of any improvements you make.

Expand All @@ -30,21 +30,21 @@ Having said that, remember: the points in the Best Practices documents and the S

The guidelines are divided into these sections:

* [Style Guide (Introduction)](Style%20Guide/Introduction.md)
* [Code Layout and Formatting](Style%20Guide/Code%20Layout%20and%20Formatting.md)
* [Function Structure](Style%20Guide/Function%20Structure.md)
* [Documentation and Comments](Style%20Guide/Documentation%20and%20Comments.md)
* [Readability](Style%20Guide/Readability.md)
* [Naming Conventions](Style%20Guide/Naming%20Conventions.md)
* [Best Practices (Introduction)](Best%20Practices/Introduction.md)
* [Naming Conventions](Best%20Practices/Naming%20Conventions.md)
* [Building Reusable Tools](Best%20Practices/Building%20Reusable%20Tools.md)
* [Output and Formatting](Best%20Practices/Output%20and%20Formatting.md)
* [Error Handling](Best%20Practices/Error%20Handling.md)
* [Performance](Best%20Practices/Performance.md)
* [Security](Best%20Practices/Security.md)
* [Language, Interop and .Net](Best%20Practices/Language%2C%20Interop%20and%20.Net.md)
* [Metadata, Versioning, and Packaging](Best%20Practices/Metadata%2C%20Versioning%2C%20and%20Packaging.md)
* [Style Guide (Introduction)](Style-Guide/Introduction.md)
* [Code Layout and Formatting](Style-Guide/Code-Layout-and-Formatting.md)
* [Function Structure](Style-Guide/Function-Structure.md)
* [Documentation and Comments](Style-Guide/Documentation-and-Comments.md)
* [Readability](Style-Guide/Readability.md)
* [Naming Conventions](Style-Guide/Naming-Conventions.md)
* [Best Practices (Introduction)](Best-Practices/Introduction.md)
* [Naming Conventions](Best-Practices/Naming-Conventions.md)
* [Building Reusable Tools](Best-Practices/Building-Reusable-Tools.md)
* [Output and Formatting](Best-Practices/Output-and-Formatting.md)
* [Error Handling](Best-Practices/Error-Handling.md)
* [Performance](Best-Practices/Performance.md)
* [Security](Best-Practices/Security.md)
* [Language, Interop and .Net](Best-Practices/Language%2C-Interop-and-.Net.md)
* [Metadata, Versioning, and Packaging](Best-Practices/Metadata%2C-Versioning%2C-and-Packaging.md)

### Current State:

Expand All @@ -66,7 +66,7 @@ _The Community Book of PowerShell Practices_ was originally compiled and edited

Portions copyright (c) Don Jones, Matt Penny, 2014-2015

_The PowerShell Style Guide_ was originally created by Carlos Perez, for his students, and all the good parts were written by him.
_The PowerShell Style Guide_ was originally created by Carlos Perez, for his students, and all the good parts were written by him.

Portions copyright (c) Carlos Perez, 2015

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
10 changes: 5 additions & 5 deletions Style Guide/Introduction.md → Style-Guide/Introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

## Introduction

In the Python community, developers have a great programming style reference provided as part of the language enhancement process specifications ([PEP-8](https://www.python.org/dev/peps/pep-0008/)), but in the PowerShell world there has been no official documentation of community preferences.
In the Python community, developers have a great programming style reference provided as part of the language enhancement process specifications ([PEP-8](https://www.python.org/dev/peps/pep-0008/)), but in the PowerShell world there has been no official documentation of community preferences.

This document is an attempt to come to an agreement on a style-guide because we know that the more people follow the same set of code-style habits, the more readable the community's code will be. In other words, although the recommendations of this guide are _just recomendations_, if you follow them, you will write PowerShell code that is more easily read, understood, and maintained.

## Table of Contents

- [Code Layout and Formatting](Code%20Layout%20and%20Formatting.md)
- [Function Structure](Function%20Structure.md)
- [Documentation and Comments](Documentation%20and%20Comments.md)
- [Code Layout and Formatting](Code-Layout-and-Formatting.md)
- [Function Structure](Function-Structure.md)
- [Documentation and Comments](Documentation-and-Comments.md)
- [Readability](Readability.md)
- [Naming Conventions](Naming%20Conventions.md)
- [Naming Conventions](Naming-Conventions.md)

File renamed without changes.
2 changes: 1 addition & 1 deletion Style Guide/Readability.md → Style-Guide/Readability.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
TODO: This section should probably be merged to [Code Layout and Formatting](Code%20Layout%20and%20Formatting.md), and based on the [#15](https://github.com/PoshCode/PowerShellPracticeAndStyle/issues/15), we should remove or rewrite the backticks section.
TODO: This section should probably be merged to [Code Layout and Formatting](Code-Layout-and-Formatting.md), and based on the [#15](https://github.com/PoshCode/PowerShellPracticeAndStyle/issues/15), we should remove or rewrite the backticks section.

# READ-01 Indent your code

Expand Down
File renamed without changes.
Loading

0 comments on commit 2c521c6

Please sign in to comment.