Transform repetitive script blocks into invocable snippets with SnippetPx

The more you write code, the more you notice patterns in the code you write.  This goes for PowerShell, C#, Ruby, and any other programming or scripting language under the sun.  Patterns are opportunities.  Opportunities to generalize them and define them as design patterns.  Opportunities to isolate blocks of reusable code in such a way that they can be reused so that you can follow the DRY principle in your work.  This article is about the latter of those two.

In recent months I have been working on trying to reduce duplication in my own work by keeping my modules and functions as DRY as possible.  One challenge with keeping code DRY in PowerShell is in deciding which is the most appropriate method to do so.  There are many opportunities to keep your code DRY in PowerShell.  You can create:

  • cmdlets
  • advanced functions
  • basic functions
  • unnamed functions (aka script blocks)
  • script files
  • type extensions for the Extended Type System (ETS)
  • classes with properties and methods, either in a .NET assembly that is imported into PowerShell, or if you’re using PowerShell 5.0 or later, in PowerShell itself
    Despite each of these extension points being available to PowerShell, they don’t always fit the scenarios you need them to, perhaps because they are not appropriate for the intended purpose, because they have some limitation that you can’t work around, or perhaps for some other reason.  For example, I find myself writing all of these, and there are certain pieces of code that I want to set up for easy sharing in many of these types of extensions without being an extension point itself.  When you have logic that you might use anywhere that you could write PowerShell, how do you set that up in such a way that you can consume it in all of those locations easily regardless of the machine you are running on, without taking a dependency on physical file paths?  That last point is important, because standalone ps1 files may be one possible answer to this need, except invoking them requires knowing where they are, and when you invoke them you must decide whether to dot source them or call them with the call operator, which in turn means you must know the implications of such a decision.  Plus, when their use spans all of PowerShell (any script, any module, any function), where do you put them without having to burden the consumer with extra setup work?  And how can you create more of these while making them discoverable, and able to be added to or removed from a system with ease?
    Snippets are a great answer to these questions.  Snippet is a programming term that has been around for many years, and it generally refers to a small region of re-usable code.  They are also a lot more than a fancied-up bit of copy/paste functionality.  They have parameters, or fields, that control how they run.  They can surround text you have selected, or simply insert into the current cursor location.  Most importantly however, for me at least, is that snippets can be invocable, and that, my friends, is key because when you’re trying to maintain a DRY code base, you don’t want to inject boilerplate code blocks in many locations…you want to invoke them.

With snippets being a great solution to this problem, I decided to try to build a snippet-based solution that would allow for discoverable, invocable snippets.  I wanted this solution to be able to find snippets regardless of what computer you were running on, as long as you followed a few simple rules.  I wanted this solution to keep snippet definitions as simple as the creation of a ps1 file.  And I wanted this solution to allow for snippets to be invoked in the current scope by default, and in a child scope as an option.

Enter SnippetPx.  SnippetPx is a module that provides two very simple commands, plus a handful of snippets.  The two commands are Get-Snippet, which retrieves the snippets that are discoverable on the local computer, and Invoke-Snippet, which allows a snippet to be invoked by name, with or without parameters, in the current scope or in a child scope.  With this module, any ps1 file that is stored in a “snippets” folder inside of the current user’s Documents\WindowsPowerShell folder, the system %ProgramFiles%\WindowsPowerShell folder, or as a subfolder under the root of any module that is discoverable via PSModulePath will be discoverable as a snippet.  You can see some examples by looking in the “snippets” folder in the SnippetPx module itself, or by looking in another module that includes some snippets such as the TypePx module.  Also, any snippet that is discoverable by this module is invocable by the Invoke-Snippet cmdlet.

Since creating this module, it has quickly become a core module that my other modules take a dependency on in order to keep my code DRY.  That effort has already paid off for myself because it has allowed me to update a block of code that is defined in a snippet and only have to make that change once, while all other locations where that snippet is invoked simply run with the new code change.  I encourage you to give it a try and see if it helps you remove what might otherwise be repetitive code that is more difficult to maintain than it should be.

If you would like to give SnippetPx a try, you can download Snippet from GitHub (yes, it is open source, along with the binary module where Invoke-Snippet and Get-Snippet are implemented) or from the PowerShell Resource Gallery (aka the PowerShellGet public repository).  Feedback is more than welcome through any means by which you want to communicate with me: the Issues page for this project on GitHub, social media channels, comments on this blog, etc.  In the meantime, I will continue to identify opportunities to create more snippets that will be useful to others and push them out either as updates to SnippetPx or in the modules where those snippets are used.

One more thing: if you do decide that you want to create some snippets of your own, there are some useful details in the Notes section of the help documentation for the Get-Snippet and Invoke-Snippet cmdlets.  I strongly recommend giving that a read before you dive into creating invocable snippets, as it provides some additional detail on how snippets are discovered as well as recommendations on the naming of your snippet ps1 files.

Thanks for listening!

Kirk out.

Advertisements

PowerGUI® Pro and PowerGUI® 2.3 are now available!

Today I am happy to announce that PowerGUI Pro  and PowerGUI 2.3 are now available.  This is a really exciting release for all PowerGUI users because there are a lot of cool new features in this release.

For PowerGUI Pro customers, we’ve spent quite a bit of time on MobileShell and made the following enhancements:

  • More mobile device support!
    MobileShell now supports iPhone 3G, 3GS, and 4G, iPad, BlackBerry OS 5.0 and 6.0, Android OS 2.1 and 2.2, and even Windows Phone 7 OS devices!
  • Improved user experience for MobileShell on smartphones!
    Since smartphones have limited real estate for apps, we have redesigned MobileShell to better fit your smartphone device.  Now when you log in you will see your favourite scripts first, front and center, and optionally you can go to another tab if you want to do some ad hoc scripting.  If you are using an iPhone and prefer the old UI, you can specifically use that UI but the new UI is highly recommended for smartphone devices.  Larger devices such as desktop browsers and the iPad still use the old UI since they have more real estate to work with.
  • Improved favourite script management for MobileShell admins!
    Now admins can preconfigure the default favourites that are assigned to users when they first log on to MobileShell.  This makes it easier for you to set up the default commands you want available for your team once and then when they log in for the first time they will get assigned those commands automatically.
  • Role-based assignment of MobileShell commands!
    Admins can now associate modules with Active Directory users and groups so that when a user logs on to MobileShell, all public commands in any module associated with their user account or with a group they are a member of are automatically made available to them as favourites.  This allows you to manage your MobileShell commands in modules using the PowerGUI Script Editor, and whenever you publish a new version your MobileShell users will automatically have the commands from that version available on their handheld device when they log on!

We didn’t forget the freeware community either!  This release also includes the following features for both PowerGUI Pro and PowerGUI (freeware):

  • Virtualization support in PowerGUI!
    With version 2.3, the VMware PowerPack is now available as a core PowerPack included in the PowerGUI Admin Console.  This PowerPack is a fantastic way to manage your virtualization infrastructure.  If you want an example of how this might make a difference for you, have a quick look at this blog post.
  • HTML Reporting support in PowerGUI!
    We have had an Advanced Reporting PowerPack available for download from PowerGUI.org for a while now.  That PowerPack has recently been renamed the HTML Reporting PowerPack, and it now comes with PowerGUI.  This PowerPack allows you to generate HTML reports with features such as indenting, grouping, collapsible sections, and support for list or tabular format for any data you have in front of you in the PowerGUI Admin Console grid.  Just click on the “Create report…” action, configure the report you want to generate, and it will handle the rest for you!
  • Enter-PSSession and Exit-PSSession support!
    You asked, we answered.  Now you can use Enter-PSSession and Exit-PSSession from within the PowerGUI Script Editor to manage remote machines as if you were working on them locally.
  • Greatly improved snippet support!
    This one is a personal favourite of mine.  Snippets are a great way to create a lot of useful PowerShell functionality really quickly.  You just insert the snippet you want, fill in the input fields, and you’re done!  We have had this for a while, and now we have added more features to this support including:

    a) Support for user defined snippets!  If you have snippets you want to use in PowerGUI, you no longer have to have admin access to put them in the snippets subdirectory under the PowerGUI installation folder.  Instead, you can put them into your Documents\WindowsPowerShell\snippets folder and they will automatically be picked up by the PowerGUI Script Editor.  Even better still, if you have a snippet that comes with PowerGUI that you want to override, you simply use the same relative path in the snippets folder in your profile and your snippet will be used in place of the one that comes with PowerGUI!

    b) Support for snippets in modules!  If you import a module, and if that module has a snippets subfolder, then PowerGUI will recognize those snippets and they will be available in the Script Editor automatically.  This allows module authors to include snippets as part of their offering so that users can learn how to use the module commands much more easily!  If you author a module and share it with others, I strongly encourage that you add snippets to that module.  Your module users will thank you for it!

    c) Support for using snippets from any path on your system!  PowerGUI now uses a PGSnippetPath environment variable to decide where to look for snippets, allowing you to reference snippets from any path you include as part of that environment variable!

    Can you tell I love the snippet features? Smile

Of course we also included some bug fixes as usual.  One worth highlighting is that the PowerGUI Script Editor can now be used to debug files that are in a path containing paired square brackets.  We have had several customers let us know that they use these types of paths and that our new debugger wouldn’t stop on breakpoints for them, and this issue is now fixed.

This is a totally awesome release, and I’m really happy that I can finally share it with you!  If you are already a PowerGUI Pro or PowerGUI user, you’ll probably notice the auto-update notify you of the new release when you start it up very soon.  If you don’t want to wait though, you can always force PowerGUI to check for updates using the “Check for Updates” menu item in the help menu, or you can update it manually by downloading it from Quest SupportLink if you use PowerGUI Pro or from the PowerGUI.org download page if you use the freeware version.

I will be recording screencasts for some of these specific features very soon so that you can see how they work first hand, but don’t hesitate to try them out in the meantime and ask questions if you have any.  Also please share any feedback you have for this release, I’d love to hear what you think of it and what you would like to see in future releases!

As always, thanks for your continued support, PowerGUI would not be what it is if we didn’t have such a great community!

Happy scripting!

Kirk out.

How to create PowerGUI® Script Editor Add-ons the easy way

In case you haven’t heard, there is a contest coming up that gives you the opportunity to win some money while having fun with PowerShell and PowerGUI.  In order to win something in the contest you have to enter, and in order to enter you have to create either a PowerPack for the PowerGUI Admin Console or an Add-on for the PowerGUI Script Editor.  I have spent a lot of time creating Script Editor Add-ons over the past few months, and when you work on things like Add-ons it can be very helpful to have the right tools at your side.

One of my favorite tools that I like to use for any repetitive PowerShell scripting is PowerShell snippets.  A PowerShell snippet is an xml document (.snippet file) that defines a short piece of PowerShell script with a few fields that can be customized when the snippet is inserted into a script.  Think of a snippet as a little user interface for injecting small pieces of PowerShell script into larger scripts that you are work on.  Snippets are incredibly useful and easy to create and customize, allowing you to arm yourself with tons of useful pieces of PowerShell script and save yourself a lot of typing.

While working on the Add-ons I have been publishing I decided I should build up a collection of snippets so that I could focus my efforts on the core logic inside the Add-on that makes it do wonderful things like sign scripts, create modules, and build other Add-ons, and less on the trivial details like adding and removing menus, menu items, toolbars, toolbar buttons and dockable windows.  This effort has resulted in a collection of 31 snippets that make creating a PowerGUI Script Editor Add-on much easier and today I have published that collection so that anyone can use them when creating their own Add-ons!

If you want to see an example of how easy it is to insert one of these snippets, here is a screenshot showing the snippet menu that appears after I press Ctrl+I (or Edit | Insert Snippet), along with some of the nested folders and their contents showing some of the snippets that are available:

image

If you want to build Add-ons, these snippets make it much easier to get started.  All you need to do is the following:

1. Download the Authoring Toolkit Add-on version 1.0.2 or later.  In version 1.0.2 I updated the Add-ons that are generated such that they use a $pgse variable for the root of the Add-on SDK.  Most of the snippets are dependent on this variable, so you should either download this version of the Add-on or make sure you are using a $pgse variable as the root of the Add-on SDK in Add-ons you have already started building.

2. Download the Script Editor Add-on snippets.  The download page describes how to install the snippets.  Note that since they must be copied into a Program Files folder, you must have the proper permissions to put them there.

3. Create a new Add-on or open an Add-on you are already working on and start using the Edit | Insert Snippet menu item to build more extensions to the PowerGUI Script Editor UI.

Between the Authoring Toolkit, the tutorial, the SDK documentation, and now these snippets, you should now have plenty of tools available to make it easier for you to create snippets for the contest that starts on October 15th.  I’m looking forward to seeing your entries!

Kirk out.

P.S. As I was publishing this I thought of a bunch more snippets that could be useful, but this is a good first set to get you started. If you like snippets and there are other snippets you would like to see, related to Add-ons or anything else you do with PowerShell, let me know so that I can know where you would like to see more effort in the future.  Thanks!