Share via


Best Practice to Write PowerShell Scripts

Summary

Writing PowerShell script is easy and Powerful. In this TechNet Wiki article I will show few of the best practise I do at my Client Environment

Before You Begin

  • Document your needs before writing PowerShell scripts.
  • Document your PowerShell version you tested.
  • Document the Operating System you tested.
  • Use standard variable naming conventions.
  • Try to fix typo errors in comments and correct before delivering.
  • Align the codes to make it readable.
  • Reduce using Alias to avoid confusion
  • Reduce using Pipelines to avoid performance issues.
  • Use Comment section in appropriate places.
  • Include the modules and assemblies to be loaded in the script.
  • Use Measure-Command and enhance your code performance
  • Use Date and Time Stamp during the script code modification and document the change.
  • Use comment block and make description clear.
  • Document Script Owner and Contact person name.
  • Catch Exceptions for trouble shooting.

How to use Comment?

The comment block in PowerShell looks like below

<#
 #
#>

Any text between <# and #> will be not executed or simple the key # will comment the line

Simple Comment Block Usage

<#
Script: To do some thing
Developed by : Chen V
Contact: Chendrayan.Exchange@hotmail.com
#>

Using Documented Comment Block

<#
 .SYNOPSIS
  This PowerShell script is to fetch computer information.

 .DESCRIPTION
  Demo to Get OS Name and Serial Number.

 .PARAMETER ComputerName
  ComputerName may be your local host or remote server name or IP address.

 .EXAMPLE
  PS C:\> Get-PCinformation -ComputerName '0.0.0.0'
        Computer Name with Serial Number

 .EXAMPLE
  PS C:\> Get-PCInformation -ComputerName 'Localhost'
        Localhost or remote computer name

    .EXAMPLE
        PS C:\>Get-PCInformation -ComputerName 'Server1'
        Server Name with no FQDN [Fully Qualified Domain Name]

    .EXAMPLE
        PS C:\>Get-PCInformation -Computer 'Server.Domain.COM'
        Server Name with FQDN [Fully Qualified Domain Name]

 .INPUTS
  System.String

 .OUTPUTS
  System.String

 .NOTES
  This is a Demo Script.

 .LINK
  about_functions_advanced

 .LINK
  about_comment_based_help

#>

Function Get-PCInformation{
param(
[parameter(mandatory=$true)]
[String]$ComputerName
)

    $SerialNumber = (Get-WmiObject -Class Win32_BIOS -ComputerName $ComputerName).SerialNumber
    $OSName = (Get-WmiObject -Class Win32_OperatingSystem -ComputerName $ComputerName).Caption
"$ComputerName Serial Number is: " + $SerialNumber
"$ComputerName OS Name is: " + $OSName
}



Get-PCInformation -ComputerName localhost 

help Get-PCInformation -Examples

help Get-PCInformation -Detailed

Aligning Codes

Scenario: Sending email using PowerShell, this command uses multiple parameters like 'From' , 'To' , 'SMTP' 'Subject' 'Body'...

Help Send-MailMessage -Parameter '*'

To use this efficiently in the script I have seen codes using newline character '`' in the end of the line like below

Send-MailMessage -From 'Someone@somedomain.com' `
-to 'Someone@somedomain.com' `
-Subject 'Testing' `
-SmtpServer 'SMTP@somedomain.com' `
-Body 'Testing Please Ignore'

I suggest using best method like shown below. The reason is to avoid copy paste error.

$SendMailValues = @{

SMTP = 'SMTP.SOMEDOMAIN.COM'
From = 'SomeOne@SomeDomain.com'
To = 'SomeOne@SomeDomain.com'
Subject = 'Testing'
}

Send-MailMessage @SendMailValues -Body 'Testing'

Using Try Catch Block

try {
#Trying to query running services
Get-WmiObject -Class Win32_Service -ComputerName 'PingDown' -ErrorAction Stop |
    ?{$_.State -eq 'Running'} 
} catch {
$_.Exception.GetType().FullName
$_.Exception.Message | Out-File -FilePath C:\Temp\Logs.txt -Append
}

Comments for Later Use

Scenario: When you code PowerShell script keep comment block on stand by for future enhancement

<# Commented out for later use.

#>

Preference Variable Status

#Gets PowerShell Version
$PSVersionTable

#To Get Error Action Preference
$ErrorActionPreference

#To Get Warning Preference
$WarningPreference

#To Get Confirm Preference
$ConfirmPreference

#To Get Debug Preference
$DebugPreference

#To Get Progress Preference
$ProgressPreference

#To Get Verbose Preference
$VerbosePreference

#To Get What If Preference
$WhatIfPreference

Do not modify with out any specific requirements.

Short Codes

Scenario while giving demo use PowerShell effectively. Recent time in on one of the demo session I have seen this

Write-Host '*************************************************************'
Write-Host ' My Scripting Demo '
Write-Host '*************************************************************'

Instead try to use the code like below which reduce more time

'*' * 80
"{0,49}" -f "My PowerShell Demo"
'*' * 80

Alternatively you can use variable and reuse it as and when required.

 $line = '*' * 80
 
 $line
 "{0,49}" -f "My PowerShell Demo"
 $line 

 Write-Host "Lesson 1 - How to use Help?"
 $line

 

Multiple Functions With help and comments

Function Clear-UserTemp{
<#
 .SYNOPSIS
  To Clear User Temporary Files

 .DESCRIPTION
  This command will remove User Temporary Files.
 
 .EXAMPLE
  Clear-UserTemp


#>
Remove-Item -Path $ENV:TEMP -Recurse -Confirm:$false
}

Function Exit-Skype{
<#
 .SYNOPSIS
  To quit Skype application

 .DESCRIPTION
  This command will kill skype process
 
 .EXAMPLE
  Exit-Skype

#>
Get-Process -Name '*Skype*' | Stop-Process -Force -Confirm:$false
}

Enjoy PowerShell :)