Use Code Snippets to Simplify Writing PowerShell Scripts

Summary: Microsoft Scripting Guy, Ed Wilson, shows how to use code snippets to simplify writing Windows PowerShell scripts.

Weekend Scripter: Code snippets

Microsoft Scripting Guy, Ed Wilson, here. I was recently in a meeting in which Jeffrey Snover (the original architect for Windows PowerShell) was also present. I love hearing Jeffrey Snover talk because he is so enthusiastic, and also a genius. Anyway, during the meeting, he mentioned working with snippets, and he said it is a feature that could easily be added to the Windows PowerShell ISE. I quickly jotted the idea down in my meeting notes, and could not wait until I had the opportunity to try it out.

I decided to use an instance of the System.Windows.Forms.OpenFileDialog class that I had previously used in the Hey, Scripting Guy! Can I Open a File Dialog Box with Windows PowerShell? post. While I was at it, I took the opportunity to update the code to Windows PowerShell 2.0 standards, which includes getting rid of the obsolete LoadWithPartialName static method from the System.Reflection.Assembly .NET Framework class, as well as using a Try / Catch construction to handle my error handling responsibilities.

The complete Get-CodeSnippet function is shown here.

Get-CodeSnippet.ps1

Function Get-CodeSnippet

{

<#

.Synopsis

Either displays contents of a file in Notepad, or adds the content to

current insertion point of script.

.Description

The Get-CodeSnippet function accepts an input folder of code snippets,

and displays a file dialog box that allows you to select a particular

file to either view the contents in Notepad, or add the content to

your script at the current insertion point.

.Example

Get-CodeSnippet -InitialDirectory c:\fso

Opens a File Dialog box situated on the c:\fso directory. Initial view

is .ps1 and .psm1 files, but you can choose to view all files. If you

select a file, its contents will be displayed in Notepad.

.Example

Get-CodeSnippet -InitialDirectory c:\fso -add

Opens a File Dialog box situated on the c:\fso directory. Initial view

is .ps1 and .psm1 files, but you can choose to view all files. If you

select a file, its contents will automatically be added at the current

insertion point of your script.

.Parameter InitialDirectory

The initial directory to be homed for the Open File Dialog box

.Parameter Add

A switched parameter that will cause the function to add the content to

current script at current insertion point.

.Inputs

[string]

.Outputs

[string]

.Notes

NAME: Get-CodeSnippet

AUTHOR: ed wilson, msft

LASTEDIT: 01/26/2011 13:14:07

KEYWORDS: Scripting Techniques, Scripting Templates, Weekend Scripter

HSG: WES-2-5-2011

.Link

Http://www.ScriptingGuys.com

#Requires -Version 2.0

#>

Param(

[Parameter(Mandatory=$true)]

[string]$InitialDirectory,

[switch]$add

)

If($ExecutionContext.Host.name -notmatch “ISE Host$”)

{

$response = Read-Host -Prompt “This script must run in Windows PowerShell ISE. <Y> to exit.”

if($response -match “y”) { Exit }

} #end if

Add-Type -AssemblyName “System.windows.forms”

$OpenFileDialog = new-object System.Windows.Forms.OpenFileDialog

$OpenFileDialog.initialDirectory = $initialDirectory

$OpenFileDialog.filter = “PowerShell Scripts (*.ps1;*.psm1)|*.ps1;*.psm1|All files (*.*)| *.*”

$OpenFileDialog.ShowDialog() | out-null

Try

{

if(!$add)

{ notepad $openfileDialog.filename }

if($add)

{

$content = Get-Content -Path $OpenFileDialog.filename -Encoding ascii -Delimiter `r`n

$psise.CurrentFile.Editor.InsertText($content)

} #end if $add

} #end try

Catch [System.Exception]

{ “No file was selected.” }

} #end function Get-CodeSnippet

The first portion of the Get-CodeSnippet function contains the comment-based Help tags. The addition of this Help allows the function to interact with the Get-Help cmdlet. For more information about working with comment-based Help, see this Hey, Scripting Guy! post: How Do I Add Help Information for Windows PowerShell Parameters?

The Help portion of the function is shown here.

<#

.Synopsis

Either displays contents of a file in Notepad, or adds the content to

current insertion point of script.

.Description

The Get-CodeSnippet function accepts an input folder of code snippets,

and displays a file dialog box that allows you to select a particular

file to either view the contents in Notepad, or add the content to

your script at the current insertion point.

.Example

Get-CodeSnippet -InitialDirectory c:\fso

Opens a File Dialog box situated on the c:\fso directory. Initial view

is .ps1 and .psm1 files, but you can choose to view all files. If you

select a file, its contents will be displayed in Notepad.

.Example

Get-CodeSnippet -InitialDirectory c:\fso -add

Opens a File Dialog box situated on the c:\fso directory. Initial view

is .ps1 and .psm1 files, but you can choose to view all files. If you

select a file, its contents will automatically be added at the current

insertion point of your script.

.Parameter InitialDirectory

The initial directory to be homed for the Open File Dialog box

.Parameter Add

A switched parameter that will cause the function to add the content to

current script at current insertion point.

.Inputs

[string]

.Outputs

[string]

.Notes

NAME: Get-CodeSnippet

AUTHOR: ed wilson, msft

LASTEDIT: 01/26/2011 13:14:07

KEYWORDS: Scripting Techniques, Scripting Templates, Weekend Scripter

HSG: WES-2-5-2011

.Link

Http://www.ScriptingGuys.com

#Requires -Version 2.0

#>

Next, I add two parameters to the function. The first parameter, InitialDirectory, is used to specify the directory to search for code snippets, and it is a mandatory parameter. Therefore, it will cause a dialog box to display if it is missing. An example of such a dialog box is shown in the following image.

Image of dialog box

The Add parameter is a switched parameter; therefore, it only takes effect when it is present. It is used to cause the function to add the selected code snippet to the current insertion point of the script. The parameter section of the script is shown here.

Param(

[Parameter(Mandatory=$true)]

[string]$InitialDirectory,

[switch]$add

)

The script next makes a check to determine if it is running within the Windows PowerShell ISE. If it is, everything is groovy; but if it is not running inside the Windows PowerShell ISE, a message appears that states the script needs to run in the ISE, and the script prompts to exit the host. This portion of the script is shown here.

If($ExecutionContext.Host.name -notmatch “ISE Host$”)

{

$response = Read-Host -Prompt “This script must run in Windows PowerShell ISE. <Y> to exit.”

if($response -match “y”) { Exit }

} #end if

Now, I add the System.Windows.Forms .NET Framework class to the Windows PowerShell ISE environment by using the Add-Type cmdlet. Next, I create an instance of the OpenFileDialog class, and I set the initial directory to that obtained via the input parameters. I use a filter that will display only .ps1 and .psm1 files. This portion of the script is shown here.

Add-Type -AssemblyName “System.windows.forms”

$OpenFileDialog = new-object System.Windows.Forms.OpenFileDialog

$OpenFileDialog.initialDirectory = $initialDirectory

$OpenFileDialog.filter = “PowerShell Scripts (*.ps1;*.psm1)|*.ps1;*.psm1|All files (*.*)| *.*”

$OpenFileDialog.ShowDialog() | out-null

I now use a Try / Catch construction to open the file that is selected in Notepad for viewing. If the Add parameter was used when the function was called, the code from the file is added at the current insertion point. This portion of the script is shown here.

Try

{

if(!$add)

{ notepad $openfileDialog.filename }

if($add)

{

$content = Get-Content -Path $OpenFileDialog.filename -Encoding ascii -Delimiter `r`n

$psise.CurrentFile.Editor.InsertText($content)

} #end if $add

} #end try

Catch [System.Exception]

{ “No file was selected.” }

} #end function Get-CodeSnippet

To use the Get-CodeSnippet function, I can add it to my Windows PowerShell ISE Profile, so that it is available, or I can run it once inside the Windows PowerShell ISE. At that point, it is added to the Function: drive, and I can call it directly from the immediate window.

I now open a new Windows PowerShell ISE sheet, and type the function name in the immediate window, as shown in the following image.

Image of PowerShell ISE sheet

I then select the code that I want to add to my new script from the Open file dialog box that appears, as shown in the following image.

Image of dialog box

When I click the Open button, the code that is contained inside the file is automatically added to my current script as shown in the following image.

Image of script example

Of course, this technique is much more powerful than simply adding a single WMI command. If the code snippet is designed to be easily incorporated into your current script, it can make things easy. I will expand on this topic tomorrow.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy