Coming Soon: GET-IT: Endpoint Management 1-Day Conference on September 28th at 9:30 AM ET Coming Soon: GET-IT: Endpoint Management 1-Day Conference on September 28th at 9:30 AM ET
PowerShell

Working with the PowerShell ISE and Script Snippets

I don’t like typing PowerShell scripts any more than the rest of you, so I rely extensively on snippets to save time. Microsoft includes a fair number of snippets out of the box, where you can easily access them in the PowerShell ISE by pressing Ctrl+J to display a popup list. Scroll to the one you want and press enter. In this article, I’ll teach you how to see and use different snippets that you already have available in PowerShell.

In the PowerShell ISE, you can use the PSISE object model to access the current PowerShell tab. Each tab can have its own set of snippets.

Each PowerShell tab has its own snippets. (Image Credit: Jeff Hicks)
Each PowerShell tab has its own snippets. (Image Credit: Jeff Hicks)

You can type $psise.currentpowershelltab.snippets to see all of them. You’ll see something like this for each snippet:

Viewing snippet information in PowerShell. (Image Credit: Jeff Hicks)
Viewing snippet information in PowerShell. (Image Credit: Jeff Hicks)

If you were curious about what you have available, then you can use a command like this to display relevant information.

Sponsored Content

Say Goodbye to Traditional PC Lifecycle Management

Traditional IT tools, including Microsoft SCCM, Ghost Solution Suite, and KACE, often require considerable custom configurations by T3 technicians (an expensive and often elusive IT resource) to enable management of a hybrid onsite + remote workforce. In many cases, even with the best resources, organizations are finding that these on-premise tools simply cannot support remote endpoints consistently and reliably due to infrastructure limitations.

$psise.CurrentPowerShellTab.Snippets | Sort DisplayTitle | select DisplayTitle,Description | out-gridview -title "My Snippets"
Viewing available snippets in GridView. (Image Credit: Jeff Hicks)
Viewing available snippets in GridView. (Image Credit: Jeff Hicks)

Because I’ve already added my own snippets, my results will vary from yours.

Although it’s fun playing with the PSISE object model, there’s also a cmdlet called Get-ISESnippet. Whereas the PSISE object retrieves snippet information by content, this cmdlet lists the snippet files in the default location.

The Get-ISESnippet cmdlet lists the snippet files in the default location. (Image Credit: Jeff Hicks)
The Get-ISESnippet cmdlet lists the snippet files in the default location. (Image Credit: Jeff Hicks)

Sadly, the Get-ISESnippet cmdlet has no parameters. Because of this, you’ll need to take a few more steps if you’re searching for a specific snippet.

Searching for a snippet with the PowerShell Get-ISESnippet cmdlet. (Image Credit: Jeff Hicks)
Searching for a snippet with the PowerShell Get-ISESnippet cmdlet. (Image Credit: Jeff Hicks)

I decided to create my own version of Get-ISESnippet using my Copy-Command tool, which you can learn more about in my article, Making a PowerShell Command Your Own.

#requires -version 4.0
#requires -module ISE

<#
This is a copy of

CommandType Name           ModuleName
----------- ----           ----------
Function    Get-IseSnippet ISE

Created: 5/15/2015
Author : Jeff

  ****************************************************************
  * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
  * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK.  IF   *
  * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
  * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.             *
  ****************************************************************
#>


Function Get-MySnippet {
<#

.SYNOPSIS

Gets snippets that the user created.


.DESCRIPTION

The Get-MySnippet cmdlet gets the PS1XML files that contain reusable text "snippets" that the user created. It works only in Windows PowerShell ISE.

When you use the New-IseSnippet cmdlet to create a snippet, New-IseSnippet creates a <SnippetTitle>.Snippets.ps1xml file in the $home\Documents\WindowsPowerShell\Snippets directory. Get-MySnippet gets the snippet files in the Snippets directory.

Get-MySnippet does not get built-in snippets or snippets that are imported from modules by using the Import-IseSnippet cmdlet.

This cmdlet is introduced in Windows PowerShell 3.0. This specific command is a modified version of Get-ISESnippet.


.PARAMETER Name
The name of a snippet to get. Wildcards are allowed. The default is all snippets.
.EXAMPLE

PS C:\>Get-MySnippet
This command gets all user-defined snippets in the Snippets directory.

.EXAMPLE
PS C:\> get-mysnippet validate* | out-gridview -PassThru | foreach { psedit $_.fullname}

Get all snippets that start with 'Validate' and send the results to Out-Gridview. Select snippets will be opened in the ISE for editing.
.NOTES

The New-IseSnippet cmdlet stores new user-created snippets in unsigned .ps1xml files. As such, Windows PowerShell cannot add them to a session in which the execution policy is AllSigned or Restricted. In a Restricted or AllSigned session, you can create, get, and import unsigned user-created snippets, but you cannot use them in the session.

To use unsigned user-created snippets that the Get-MySnippet cmdlet returns, change the execution policy, and then restart Windows PowerShell ISE.

For more information about Windows PowerShell execution policies, see about_Execution_Policies.

Learn more about PowerShell:
http://jdhitsolutions.com/blog/essential-powershell-resources/

  ****************************************************************
  * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
  * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK.  IF   *
  * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
  * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.             *
  ****************************************************************

.INPUTS
None

.OUTPUTS

System.IO.FileInfo
custom object

.LINK
Get-IseSnippet
New-IseSnippet

#>
[CmdletBinding()]
Param(
[Parameter(Position=0,HelpMessage="Enter the name of snippet")]
[ValidateNotNullorEmpty()]
[string]$Name = "*",
[switch]$Detailed
)

Begin {

    Write-Verbose "Starting $($MyInvocation.Mycommand)"
    Write-Verbose "Using parameter set $($PSCmdlet.ParameterSetName)"
    Write-Verbose ($PSBoundParameters | Out-String)

    #remove Name from Boundparameters
    if ($PSBoundParameters.Name) {
        $PSBoundParameters.Remove("Name") | Out-Null
    }
    #remove Detailed from Boundparameters
    if ($PSBoundParameters.Detailed) {
        $PSBoundParameters.Remove("Detailed") | Out-Null
    }
    #define a snippet namespace
    $snipns = @{snip="http://schemas.microsoft.com/PowerShell/Snippets"}
} #begin

Process {
    
    $results = (Get-IseSnippet @PSBoundParameters).Where({$_.name -like "$name.snippets.ps1xml"})
    if ($Detailed) {
        #get detailed output
        foreach ($item in $results) {
            $author = (Select-XML -Path $item.fullname -Namespace $snipns -XPath "//snip:Author").Node.InnerText
            $title = (Select-XML -Path $item.fullname -Namespace $snipns -XPath "//snip:Title").Node.InnerText
            $description = (Select-XML -Path $item.fullname -Namespace $snipns -XPath "//snip:Description").Node.InnerText
            #create a custom object
            New-Object -TypeName PSObject -Property @{
                Path = $item.Fullname
                Author = $author
                Title = $title
                Description = $description
                Modified = $item.LastWriteTime
            }
      } #foreach
    } #if detailed
    else {
        #write regular results to the pipeline
        $results
    }

} #process

End {
   
    Write-Verbose "Ending $($MyInvocation.Mycommand)"

} #end

} #end function Get-MySnippet

In my version, I included a parameter to filter by file name including the use of wildcards.

Filtering by name with wildcards. (Image Credit: Jeff Hicks)
Filtering by name with wildcards. (Image Credit: Jeff Hicks)

This output is the same you would get with Get-ISESnippet, but I also added a parameter to create more detailed output. I wanted to see some of the same information available when using the PSISE object.

Because the snippet files are XML, I can use Select-XML with an XPath filter for the different attributes I want. The tricky part in this situation is that the query requires the XML namespace.

$snipns = @{snip="http://schemas.microsoft.com/PowerShell/Snippets"}
$author = (Select-XML -Path $item.fullname -Namespace $snipns -XPath "//snip:Author").Node.InnerText

The XPath query will return node objects. The InnerText property should contain the values I want. I should point out that it is technically possible to have multiple snippets in a single snippet file. My technique will most likely fail in that scenario. If you stick to one snippet per file, then this won’t be an issue. After I get all of the details, I write a custom object to the pipeline for each snippet file.

New-Object -TypeName PSObject -Property @{
     Path = $item.Fullname
     Author = $author
     Title = $title
     Description = $description
     Modified = $item.LastWriteTime
   }
Get-MySnippet results. (Image Credit: Jeff Hicks)
Get-MySnippet results. (Image Credit: Jeff Hicks)

I can use this to find specific snippet files.

Get-MySnippet -Detailed | where {$_.description -match "references"}
Finding specific snippets in Windows PowerShell. (Image Credit: Jeff Hicks)
Finding specific snippets in Windows PowerShell. (Image Credit: Jeff Hicks)

Or I can easily load snippet files for editing.

Get-MySnippet -Detailed | where {$_.description -match "references"} | foreach {psedit $_.path}
Get-MySnippet "Validate*" | foreach {psedit $_.fullname}

I hope my tools help you use snippets more in your own script development. Once you build up a library, you’ll be amazed at how quickly you can churn out a high-quality product.

Related Topics:

BECOME A PETRI MEMBER:

Don't have a login but want to join the conversation? Sign up for a Petri Account

Register
Comments (0)

Leave a Reply

Live Webinar: Active Directory Security: What Needs Immediate Priority!Live on Tuesday, October 12th at 1 PM ET

Attacks on Active Directory are at an all-time high. Companies that are not taking heed are being punished, both monetarily and with loss of production.

In this webinar, you will learn:

  • How to prioritize vulnerability management
  • What attackers are leveraging to breach organizations
  • Where Active Directory security needs immediate attention
  • Overall strategy to secure your environment and keep it secured

Sponsored by: