A better approach to formatting in PowerShell

Even without a traditional user interface, it is important to separate the presentation layer from the data processing layer.

For all of its strengths, Windows PowerShell is not without its fair share of weaknesses.  One of the weaknesses in PowerShell that has been with the scripting language since version 1.0 is how it handles formatting.  When it comes to formatting data, you have two options: use one of the core Format-* cmdlets (Format-Table, Format-List, Format-Wide, or Format-Custom), or create a format ps1xml file that defines one or more formats for a specific type in an XML document.  The former only works for the script consumer, because the core Format-* cmdlets actually convert rich object data into format data, not bearing any resemblance to the original objects with properties and methods that you started with.  The latter works for the script author as well as the script consumer, however it is significantly more complicated to implement, and it has its share of limitations as well (for example, once a default format is defined for a type, a script author will not be able to have the results of their script rendered in another format by default without taking some extra steps that shouldn’t be necessary).  The end result of these limitations and complications is a formatting system that is not fully leveraged in the majority of PowerShell scripts that are shared among the community.

I recently found myself looking at this problem and asking myself one more time if I could do better (it is a problem that I had looked at in the past).  The variety of formats that are available is encouraging, and you can generate some pretty useful report-like output when you take the time to leverage the formatting system.  But something would have to be done to fix the user experience.  The end goal I was envisioning was quite clear: a distinct separation of the presentation layer from the data processing layer such that formatting information would never get in the way of data processing.

Fortunately, PowerShell is quite well set up for this type of change.  Every command that you run has its results sent through the Out-Default cmdlet.  Out-Default internally knows what to do with whatever you throw at it, whether that be object data or format data (which really is object data as well, but I’m making a distinction here).  When you return an object from a command to the console, if that object is not format data, Out-Default internally will look at the object type, identify the default format for that type, convert the object into format data and then output that format data to the console.  If Out-Default does receive format data instead because the object was already converted into format data, it simply renders that format data in the console.  Given that is the case, it should be possible to modify the core Format-* cmdlets so that they attach format data to the objects that they format instead of converting object data into format data, and it should also be possible to modify the core Out-Default cmdlet so that it detects format data when it is attached to an object and renders that format data directly to the console instead of looking at the object type to decide what format to use.  That, my friends, is exactly what I did.

FormatPx is a module made up of a nested binary module that defines five proxy cmdlets (Format-Table, Format-List, Format-Wide, Format-Custom, and Out-Default) plus one new cmdlet (Format-Default) and a script module that automatically applies the Force parameter whenever Format-Table, Format-List, or Format-Wide are used.  It changes how the core Format-* cmdlets work as described above, and it also makes it easier to get format information from types that include a custom format as their default.  Here’s a short screencast showing FormatPx in action:

(Note, do not adjust your computer, there is no audio in this screencast.)

Better PowerShell formatting with FormatPx

That’s a decent overview of what you get with the FormatPx module – a separation of the formatting layer from the data processing layer, giving you much more control over the presentation of your script results without ps1xml file complexity while still allowing script consumers to view the results in whatever format they like.  What do you think?

Kirk out.

Advertisements

Making history more fun with PowerShell

History is boring.

While I don’t believe that is true (I actually find history quite fascinating), it is certainly how I would have responded if asked about history while taking it in high school.  I’m not the only one who felt this way back then either.  When I asked my wife for her opinion about it, she told me that it was in her history class where she learned to write upside down with her non-dominant hand.

My problem with history is the presentation of it.  It can be fun and include a lot of contextual detail that is presented with zeal and that connects with the audience; or, like my high school history class, it can be presented as a timeline with boring details attached to it.

PowerShell automatically tracks the commands that you invoke in a history table that you can view at any time with the Get-History cmdlet.  If you invoke Get-History (or its alias, h) after you’ve been using PowerShell for a bit, you should see results similar to the following:

native powershell history

That’s not entirely useless, because it shows commands that we ran earlier, but as far as presentation goes it’s pretty boring, right?  Now, this is only the default format for history in PowerShell, and as with most data in PowerShell this screenshot doesn’t paint the full picture.  Each entry also includes other fields that are not shown in the default format, as can be seen here:

native powershell history expanded

The problem is, that’s all you get: a timeline with boring details attached to it.  The ExecutionStatus property tells me whether a command completed or failed, but the usefulness of that information is very limited because a value of Failed only means the command failed with a terminating error; if a command failed with a non-terminating error, then ExecutionStatus will simply indicate that the command completed, which is not very useful knowledge to have.  Start and end execution times are useful, but that means I need to do math to determine how long various commands took, or re-run the commands inside of Measure-Command.  There’s no zeal behind the presentation of this information.

Fortunately, PowerShell is extensible, so I decided I should be able to do better.  Here’s my view of what PowerShell history should be, as provided by HistoryPx:

powershell extended history from HistoryPx

HistoryPx is an open-source PowerShell module that transparently integrates into the PowerShell environment where it is loaded.  You simply load the module by importing it with Import-Module into an environment running PowerShell 3.0 or later, and once it is loaded it will start tracking extended history information for every command you run.  Extended history information includes the command duration, whether or not the command was successful, any output returned by the command, and any errors that were added to the $error log by the command.  When you invoke Get-History, the new default format for extended history information presents most of these details, or you can pipe the results to Format-List * to get all properties where you can see the core history properties as well as the extended information added by HistoryPx.

In addition to providing extended history information in PowerShell, the HistoryPx module includes one other feature that is quite useful.  It defines a double-underscore ($__) variable in the global scope that will always contain the output of the last command that was executed.  When the last command doesn’t have any output, $__ will be assigned a value of $null.  This comes in handy when you invoke a command that takes time to complete but forget to capture the results in a variable.

If you want to give this module a try, head on over to the HistoryPx page on GitHub where you can learn how to install or update it in your environment and read additional details provided in the readme file on GitHub.  If you are concerned about memory usage with this module, your questions are addressed in the readme as well.  This is only the first release of this module, and I am already starting to track features that I want to add to another release.  If you do give it a try, please let me know what you think, either in the comments on this blog post or in GitHub, and please log any issues you find on GitHub as well.

Thanks!

Kirk out.

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.

PowerShell debugging, amplified

This article is about the PowerShell module that I am most proud of and that I have personally found more useful than any other module I have created.  I hope that you enjoy it as much as I do.

Every programming language must be designed with debugging in mind, and PowerShell is no exception.  No matter who you are, no matter how well you know the language, you will inevitably come across something that isn’t working like it should.  What you do in these situations depends on your comfort level with programming and debugging.  For some, this means adding lines to the code that produce extra output so that they can get a handle on what is going on.  For others, this means rolling up the sleeves and stepping through the code in a debugger.  And there are others still who aren’t comfortable enough with programming or debugging, so they turn to others for assistance.  Regardless of which of these approaches you would take, I believe I have a module that can help.

DebugPx is a free, open source PowerShell module that was designed to make it easier to troubleshoot problems in PowerShell code.  It comes with two core commands: breakpoint and ifdebug.  It also includes a few helpful utility commands to control how the breakpoint command works.  The core commands are described as follows:

breakpoint The breakpoint command is used to trigger a breakpoint at the current location.  By default, the breakpoint command causes Windows PowerShell to immediately enter the debugger whenever it is invoked in an interactive session.  If it is invoked with its optional ConditionScript parameter, it will only trigger the breakpoint if the script block expression that was provided for the ConditionScript parameter evaluates to true.  It also accepts an optional string Message parameter, and it will write the message provided to this parameter to the current host whenever the breakpoint is triggered.
ifdebug

The ifdebug command is used to identify a block of PowerShell script that you only want to run in one of two scenarios: when you invoke a command with -Debug, or when the $DebugPreference variable is set to anything either than SilentlyContinue or Ignore.

Both of these commands are very powerful and they can make troubleshooting problems in PowerShell scripts a lot easier.  Let me provide some background details so that you understand the problems that these commands solve, problems that still exist in PowerShell 5.0 today.

PowerShell version 1.0 did not come with breakpoint support.  It had a debugger, and that debugger is still useful today, even though a new debugger has been in PowerShell since version 2.0.  It had a -Debug common parameter that was available on every cmdlet and, since version 2.0 of PowerShell, on every advanced function as well.  It had a $DebugPreference built-in variable.  It also had a Write-Debug cmdlet that allowed you to have some level of debugger control over your scripts.  The behaviour of the Debug common parameter, $DebugPreference and how those affect Write-Debug behaviour is quite interesting, and once you understand how those work together, you may see why their implementation leaves some opportunities on the table.

When you invoke a cmdlet or an advanced function with the -Debug common parameter, PowerShell internally sets the $DebugPreference variable value to Inquire within the scope of that command.  As far as PowerShell preference variables go, a value of Inquire means that PowerShell will prompt the user to ask if they want to continue the execution of the associated command, stop the associated command immediately, or enter a the debugger at that point, allowing the user to invoke PowerShell commands to troubleshoot the system.  This behaviour seems like it was designed to fill the void when PowerShell did not have breakpoints, because it allowed scripters to enter the debugger as long as they threw a few Write-Debug commands into their scripts.

The problem with this approach is that it tries to do too many things and mixes up several distinct needs in the process.  The ability to write debug information to the debug stream during script execution, and the ability to enter the debugger on a breakpoint at a specific location in a script are two distinct needs that are mashed together when they shouldn’t be.  Another limitation with this approach is that scripters can’t simply change the way a script is invoked in order to gather additional debug information from an environment where they aren’t able to debug with breakpoints as easily, because using -Debug meant prompting the user every time Write-Debug would be called, and often you’re trying to help a user who is having a problem in this scenario, not confuse them by asking them to continue a bunch of Write-Debug calls while telling you what is happening.  Yet another limitation with this approach is that there is no easy way to include PowerShell commands inside of an advanced function or script that will only execute when you are debugging, allowing a command or script author to include support for generating debug output but only when that command or script is invoked with -Debug.

When breakpoints were later added along with a new debugger in PowerShell 2.0, PowerShell script authors were suddenly able to set breakpoints in their scripts, either visually using PowerShell ISE or for conditional breakpoints, command breakpoints, or variable breakpoints using the Set-PSBreakpoint cmdlet.  This functionality solved the need for breakpoints, and it started the separation of the need to enter the debugger from the need to be able to write debug output; however, the -Debug common parameter behaviour didn’t change, so there still wasn’t a good vehicle for writing information to the debug stream without any requirement for user interaction during the process.  Also, while this breakpoint functionality was useful, it came with its own share of limitations.  If you were working in an environment other than PowerShell ISE that didn’t have visual support for setting PowerShell breakpoints (such as notepad++, sublime text, or some other awesome editor), you simply had no choice but to work with the Set-PSBreakpoint cmdlet, which isn’t a very friendly way to set breakpoints in PowerShell, putting it mildly.  Also, if you were debugging PowerShell code across multiple sessions, you would have to reset your breakpoints every time, either manually or using a profile or some other script, none of which is very practical.

DebugPx was designed to solve almost all of these problems with the breakpoint and ifdebug commands.  With the DebugPx module installed and discoverable via the PSModulePath environment variable, you can trigger a breakpoint at a specific location by simply invoking the breakpoint command (or the bp alias, for short).  These breakpoints are identifiable in any editor because you can see the commands in the files where they are used.  They work in unsaved files.  They even work in an interactive PowerShell prompt, or inside of a block that you run in PowerShell using copy/paste, or inside of a block that you select in ISE and run by using the Run Selection (F8) feature.  They are properly ignored if they are inside of a function that uses the System.Diagnostics.DebuggerHidden attribute.  They are conditional if you invoke them with a condition script block (which would map to the first, ConditionalScript parameter), or unconditional otherwise.  They can be globally enabled or disabled using the Enable-BreakpointCommand or Disable-BreakpointCommand commands.  They will only cause PowerShell to enter the debugger if they are encountered in an interactive session.  And if you want a message to be displayed when the breakpoint activates (for example, as a reminder why you wanted to break when that obscure scenario that you previously couldn’t catch occurs), you can pass a message to the -Message parameter and the breakpoint will output the message to the host when the breakpoint is triggered.

If you are debugging in other scenarios, where you may not be able to use the breakpoint command to enter a debugger because you are not in an interactive session (such as in background jobs, scheduled tasks, Azure Automation or Service Management Automation scripts, or perhaps in a remote customer’s environment), you can include rich debug information inside of an ifdebug command script block, and anything that is output from inside of that script block will automatically be written to the debug stream without prompting the end user.  This includes object data, text strings, or anything else you want to write to the debug stream in order to figure out what is going on when that script runs.  If the command containing ifdebug is not invoked with -Debug, PowerShell will simply skip directly over that script block, avoiding running debug logic when it is not needed, which is better for performance.

Both the breakpoint command and ifdebug can be used in the middle of a pipeline as well.  This is important because it allows for writing debug information to the debug stream or triggering a breakpoint in the middle of a pipeline during the processing of that pipeline.  If you use the breakpoint command in a pipeline and you either have the breakpoint command disabled or you are in a script block with the DebuggerHidden attribute set, or if you use the ifdebug command in a pipeline and you didn’t run the script with -Debug, both the breakpoint and the ifdebug commands will simply pass the pipeline object down to the next stage in the pipeline for additional processing.

At this point, you’re probably getting a feeling for the kind for the power that these commands provide.  Let me show you a few simple examples that demonstrate how you might use them in practice.  You can try these examples at the command prompt in the PowerShell host of your choice, or in a script file, or in functions you write, or script module files, or workflows, etc.

Enter the debugger in the middle of a series of commands

$services = Get-Service wuauserv,bits
breakpoint
Restart-Service -InputObject $services -WhatIf

Enter the debugger conditionally in the middle of a pipeline (using the bp alias)

gsv audiosrv,bits,wuauserv | bp {$_.Name -eq ‘bits’} | spsv -WhatIf

Display a message as you enter the debugger reminding you why you are doing so

Get-Process -Name Idle,PowerShell,Explorer |
   
breakpoint {$_.Id -eq 0} -Message ‘Process ID is zero???’ |
   
Format-Table

Disable the breakpoint command so that you can run without debugging

Disable-BreakpointCommand
gsv audiosrv,bits,wuauserv | breakpoint {$_.Name -eq ‘bits’} | spsv -WhatIf
‘See, the breakpoint command did not cause PowerShell to enter the debugger!’

Re-enable the breakpoint command so that it functions normally again

Enable-BreakpointCommand

Skip over breakpoints in a script block by using the DebuggerHidden attribute

& {
    [System.Diagnostics.DebuggerHidden()]
    param()
    breakpoint
    ‘The breakpoint command is effectively disabled in the current scope.’
}
‘But it still works in scopes that do not use the DebuggerHidden attribute.’
breakpoint

Create a function that generates some useful debug information

function Test-IfDebug {
    [CmdletBinding()]
    param()
    ifdebug {
        # This may be useful when debugging, but I wouldn’t want to gather
        # this information in everyday use. It is an exaggerated example of
        # what you might want to collect when debugging something.

        ‘*************** Current Operating System ***************’
        Get-WmiObject -Class Win32_OperatingSystem | Format-List *
        ‘*************** Running Services ***************’
        Get-Service | Format-List *
        ‘*************** Running Processes ***************’
        Get-Process | Format-List *
    }
    Get-Service w*
}

Invoke that function without debugging

Test-IfDebug

Invoke that function with debug output turned on

Test-IfDebug -Debug

Compare the performance of the two

Measure-Command {Test-IfDebug}
Measure-Command {Test-IfDebug –Debug}

I think those examples provide a good demonstration of how these commands work.  As I hinted at earlier in this article, I am super-excited about this module and I’m thrilled that I can share it with you now.  If you want to give it a try, install the latest version in your environment by following the instructions on the DebugPx project page on GitHub.  I have a few more features planned for this debugging toolkit, and I would be very happy to entertain your ideas as well, so please let me know what you think!  Have fun debugging!

Kirk out.

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.

PowerGUI® Online

With the PowerGUI Challenge contest only a few weeks away, you may be wondering where you can go to learn more about PowerGUI in preparation for the contest.  Or maybe you’re looking for inspiration for the kinds of things you can do by using PowerShell with PowerGUI so that you can plan an entry for the contest.  To help provide some assistance with this, a few minutes ago I just published the first release of the new PowerGUI Online Add-on.  This Add-on adds a new PowerGUI Online menu to your Script Editor that provides you with fast access to dozens of useful resources for PowerGUI.  It includes links to many online resources, including:

  • Contest resources
  • Discussion forums
  • Learning center
  • PowerPack categories
  • Script Editor Add-ons
  • PowerGUI Team members on Twitter
  • Developer resources (PowerGUI VSX)
  • The PowerGUI channel on YouTube
  • Request a script
  • and more!

There are a lot of online resources available to help you get the most out of PowerShell and PowerGUI, and this Add-on pulls them all together into one organized menu.

One thing I really like about this Add-on is that when you click on any of the items in this menu, if you are running the PowerGUI Script Editor in STA mode (which is the default) the associated web page will be loaded right in the Script Editor!  Here’s a screenshot showing the Add-on in action with the embedded web browser appearing as another tab in the Script Editor:

PowerGUIOnline.Menu

If you are not running in STA mode (which means you are running in MTA mode), then the web pages associated with the PowerGUI Online menu items will load in your default web browser when clicked on.

This is the first release of this Add-on, so please let us know what you think.  It’s really easy.  Just click on the Feedback menu item in the new PowerGUI Online menu and leave us a note on our forums.

Kirk out.

P.S. Keep watching this blog for more useful content related to the PowerGUI Challenge contest that is coming soon.

PowerShell modules made easy with PowerGUI®

Today I have the pleasure of sharing another PowerGUI Script Editor Add-on with you that I recently finished and that I personally find extremely useful.  This Add-on is all about defining PowerShell modules.  It’s called the Module Management Add-on, and it adds the following commands to the PowerGUI Script Editor menu and toolbars:

  • New Module – facilitates the creation of brand new modules from scratch by creating the module folder as well as the script module (psm1) file and the module manifest (psd1) file that defines the module, pre-populating as many relevant details in the manifest as possible such as the module name, description and GUID, the copyright date, your name, your company name, etc. in the appropriate places.
  • New Module Manifest – facilitates the creation of manifest files for existing modules, pre-populating as many relevant details in the manifest as possible such as the module name, description and GUID, the copyright date, your name, your company name, and the complete listing of all files included in the module.
  • Convert to Module – facilitates creating a new module from an entire script file or from the selected portion of a script file (this also generates the manifest and it is a really easy way to convert from PowerShell 1.0-style ps1 files that act as a function library but cannot be unloaded to PowerShell 2.0 modules that can be loaded and unloaded as needed).

Here’s a screenshot showing what the File menu looks like after you have installed this Add-on:

Module Management Add-on Menu Additions

Also, this Add-on adds some of the more frequently used commands to the toolbar:

Module Management Add-on Toolbar Buttons

When you want to create a new module, you can either use the menu item or the toolbar button to create the new module, or simply press Ctrl+Shift+M.  This displays the following dialog:

image

The author and company name are pulled directly from your Windows Registry, and the description and version fields are assigned generic default values.  You can change these values however you like for your module, and the Add-on will remember the values (aside from name) for the next time you use this command.  Also, you can use this dialog to create child modules by specifying a name with backslashes in it.  The module that is generated will be placed in the WindowsPowerShell\Modules folder under your user Documents folder, with all files in a folder for the module.  As soon as you enter a name and then click on OK, the module will be created and both the script module (psm1) file and the manifest (psd1) file will open in the Script Editor for editing, allowing you to add them to source control right away if you are using PowerGUI Pro with the source control feature.  As an option, you can use this dialog to create a new module without a manifest by simply clearing all fields except for the Name field.

There may be cases where you already have a module that you have created, and you want to create a manifest for that module.  Or perhaps you have a module you are already working with and you want to create additional manifests for that module (this allows users to work with an entire module or only portions of that module).  In these cases, you can use the menu item to create the new manifest, or you can simply press Ctrl+Shift+N.  This displays the following dialog:

image

Look familiar?  It should.  Creating a module manifest for an existing module is very similar to creating a new module because most of the details you provide in this dialog are stored in the module manifest.  Just like when you create modules, you can modify these details that are provided by default and you can assign a name (with an optional relative path) for the module for which you are creating a manifest.  Once the manifest is created, the Script Editor will open the manifest file automatically.

The other useful feature included in version 1.0 of the Module Management Add-on is the Convert to Module command.  This can be invoked through the File menu or the toolbar button as well.  You can either convert an entire file to a module or, if you have any text selected in the file, only the selected text will be used in the new module.  Note that the original file and its contents are left intact during the conversion process.  To perform the conversion, simply open the file you want to use for the conversion and select the text you want to use as the base for your module or don’t select anything if you want to convert the entire file.  Then click on the Convert to Module command in the File menu or on the toolbar, and you will be presented with the following dialog:

image

Once more, this should look familiar.  All operations for creating modules and manifest accept the same input values because they are all used in each operation.  You simply provide the necessary details, or remove all fields except for the module name if you don’t want to use a manifest, and then click on OK for the module to be created and the appropriate files to be opened in the Script Editor for you.

These are all very useful features to have at hand, whether you are working on new modules in PowerShell 2.0 or creating PowerShell 2.0 modules from function libraries (ps1 files) that you created in PowerShell 1.0.

If this Add-on interests you, simply go to the Module Management Add-on page and follow the installation instructions provided there.

As with many other Add-ons I have created, this is an early version of the Add-on so I would love to get your feedback on it. Do you find it useful as is?  How you would like to see it improved in a future release?  Would you like to see a Module menu and/or toolbar with menu items to add functions and aliases?  What else would you like to see for improved module management?  I have ideas, but I don’t want to influence your feedback too much, so I’ll keep my ideas to myself and let you speak up about what else you would like to see in this Add-on or others.

As always, thanks for reading!

Kirk out.

Share this post: