Debugging in the PowerShellEditorServices for Visual Studio Code

You’ve probably heard about Microsoft’s Visual Studio Code editor.  It was announced at the 2014 online Connect event.  It is a free, light-weight, cross-platform code editor supporting Windows, Linux and MacOS. 

I’ve been a big fan and user of the built-in PowerShell ISE for years.  It is still the best “debugger” out there.  However the ISE editor limitations, lack of customization, lack of source control integration and general atrophy (ISE hasn’t been significantly updated since it shipped with V2) was really starting to get to me.

As a user of Visual Studio, I really appreciate its extensibility support and more importantly the active ecosystem built around that extensibility.  I use VS extensions, often referred to as VSIXs, to improve the editor’s capabilities.  I use the Microsoft Productivity Power Tools, Web Essentials and C# Essentials.  A number of these tools, like the Productivity Power Tools, add editor enhancements that would work in any language.  If only PowerShell ISE had this sort of an extension ecosystem. 

Unfortunately, the reality is that a editor such as ISE, dedicated to a “single” language, is very unlikely to ever gain such momentum as VS has with its extensions.  And it doesn’t help that the ISE extension API is sorely lacking.  You do however see such extensibility and momentum around light-weight code editors such as Sublime and Atom. 

So I was really excited by the prospect of Visual Studio Code when it was announced.  I figured VSCode had the following advantages over PowerShell ISE:

  • VSCode is being actively developed and enhanced.
  • It is already a more powerful text editor with features like multicursor support.
  • Version control support via Git is built-in.
  • You can use it on Linux.  Yeah, I’m still hoping we will see PowerShell running on Linux at some point.

The downside to VSCode’s PowerShell support at that time were poor syntax highlighting and Intellisense but more importantly no debug suppport and no REPL.  I tried to help improve the syntax highlighting by sending some regex changes to the VSCode team.  That helped a little but unknownst to me at the time, the whole VSCode PowerShell support landscape was about to change.

At the 2015 online Connect event, Microsoft made two huge announcements about VSCode.  First, Microsoft open sourced VSCode on GitHub.  Second, Microsoft finally announced a supported extensibility API for VSCode.  As a PowerShell MVP, I was made aware of an effort to build a PowerShell Editor Services extension for VSCode.  I immediately signed up to help as the extension would be made open source on GitHub as well.

This extension addresses many issues with PowerShell support in VSCode.  First, it adopts a syntax colorization grammar format called TextMate that other light-weight editors use.  Second, it provides a mechanism to hook into the editor to provide all sorts of features such as Intellisense, Symbol searching & highlighting, alias expansion, etc.  Third, there is a debugging API to provide debug support for a language. 

David Wilson and others on the PowerShell team did a ton of work to get the very capable PowerShellEditorServices extension off the ground.  Since then, some MVPs including myself, Doug Finke and Adam Driscoll have been submitting PRs to improve the extension.

I have submitted a number of PRs in the last couple of months.  The first was to support Symbol search in PowerShell e.g. type Ctrl+P, then “@:” to see all the symbols in your open script files.  Note that as you move the selection amongst the different symbols in the list, the associated script is highlighted in the editor e.g.:


The rest of my PRs have been to enhance the debugger’s Variables display to provide more and better representations of PowerShell and .NET types.  For instance, PSCustomObjects now display their properties in the Variables window.  Collections display their contents and .NET objects wrapped in a PSObject are unwrapped to show the underlying object’s properties.  Here is what the Variables window looks like now when debugging a PowerShell script in VSCode:


The Variables window for this extension shows four top level containers.  The Script and Global containers are fairly obvious in terms of what they contain.  The Local container contains the local variables for the currently selected stack frame i.e. the selected line in the “Call Stack” section. 

The Auto container attempts to show you the variables you are likely to be interested in for any particular stack frame.  The idea is shamelessly borrowed from Visual Studio’s excellent debugger.  The heuristics for determining what gets displayed in the Auto window will likely change as we get more experience using this debugger.  If you have suggestions, please leave them at

As you explore the variables in any of the four containers, you will note that collections show not only their type but the number of elements in the collection.  For example, see the variable $Process in the image above under the Auto container.  It displays as $Process: [Process[1]] and when you open that node you see each element displayed (only one in this case).

Also note that the debugger in VSCode has sections (windows) to show breakpoints and variables you are “watching”.  There is even a “REPL” window that is active while debugging. 

I’m very excited by how much richer this extension makes both the PowerShell editing and debug experience in VSCode.  I’m currently in “dog-fooding” mode with VSCode as my primary editor for PowerShell.  I’m sure we will find many things that need to be improved as we use the extension and VSCode together.  But the really cool thing is that since the extension is open source, we don’t have to wait for someone on the PowerShell team to fix a bug or implement a new feature.  We can do that ourselves! 

I expect big uptake for PowerShellEditorServices extension for VSCode in 2016.  Heck, the extension was made public on the VSCode Marketplace only a little over a month ago and it’s already approaching 9000 downloads.  That’s pretty impressive!

I’ll sign off with one last tip.  If you are a Pluralsight subscriber, you should check out John Papa’s course on Visual Studio Code.  It is excellent!  If you are not a subscriber, you can sign up for a free trial and get 10 free days (or up to 200 minutes) to start watching this course.  BTW there are also some pretty awesome PowerShell courses on Pluralsight from notable PowerShell luminaires such as Don Jones, Jeff Hicks, Jim Christopher, Adam Bertram, Thomas Lee and many others.

Posted in PowerShell, PowerShellEditorServices, VSCode | Tagged , , | 1 Comment

PowerShell Snippets for Visual Studio Code

If you are a fan of using Visual Studio Code as a lightweight text editor and are also a PowerShell scripter, you have probably found VS Code’s PowerShell support somewhat lacking.  For instance, while it can syntax colorize PowerShell script such as showing $foo in the color for variables, it doesn’t know that ${global:foo} is also a variable.  I have submitted an issue on this along with an improved powershellDef.js file.  You should be able to pull that down from here.  Then copy that into your C:\Program Files (x86)\Microsoft VS Code\resources\app\plugins\vs.language.powershell\out directory.

Another issue is that there are no snippets for PowerShell.  Well, now there is.  Grab this powershell.json snippets file from here and put it in your ~\AppData\Roaming\Code\User\Snippets directory.  This snippets file provides the following snippets:

  • Class
  • Condition double quoted string statement
  • Condition expression statement
  • Condition single quoted string statement
  • Condition statement
  • Do…until loop
  • Do…while loop
  • Else statement
  • ElseIf statement
  • Enum
  • For loop
  • Foreach statement
  • Function
  • Function advanced
  • Help
  • If statement
  • Method
  • Property
  • Property hidden
  • Reverse for loop
  • Switch statement
  • Try catch
  • Try catch finally
  • Try finallly
  • While loop

Once you installed the snippets file, you can create a PowerShell script file – save it as a .PS1 file and Code will recognize it as a PowerShell script.  If it is not saved, press Ctrl+Shift+P to bring up the command palette, select “Change Language Mode” then select PowerShell.  Now type “tr” and you should see a completion list like this appear:


Note that the first entry in the completion list above, with the icon “abc”, is there because the word “try” was used elsewhere in my script file.  This is very basic form of Intellisense providing auto-completion of words that it has encountered in the file. You will want to press the down arrow to select the other entries.  Notice that snippets have an icon that looks like an empty box with dotted lines on the bottom.  And snippets typically display a description as well e.g. “Try catch”.  Press either {Tab} or {Enter} to use the snippet.

Enjoy and let me know if you find any issues.  Note that snippets in Visual Studio Code act a bit weird when auto-completion takes place.  It will no longer allow you to tab through the various placeholders in a snippet.  I’ve submitted that as an issue to the VS Code team.  Hopefully they can fix it (or educate me on how it supposed to work).

Posted in PowerShell, VSCode | 13 Comments

An Explanation of the .NET add_EventName / remove_EventName Methods for PowerShell Scripters

If you have ever attempted to write a little WinForms or WPF UI using PowerShell you have no doubt run across a method like add_Click() e.g.

Add-Type -AssemblyName System.Windows.Forms 
$form = New-Object Windows.Forms.Form 
$button = New-Object Windows.Forms.Button 
$button.Text = "Close" 

This might be a bit confusing if you are looking at C# examples or even the MSDN topic on a Windows Form Button.  It says the event name is simply “Click”.  What is going on here?

When C# and .NET were first introduced they were inspired by Java but they also added some features Java didn’t have.  Two of these features were language level support for properties and events.  Two concepts borrowed from Delphi which isn’t too surprising given that the chief architect of C#, Anders Heljsberg, came from Borland where he was the chief architect of Delphi.  Anders’ contributions date back to the introduction of Turbo Pascal which I thoroughly enjoyed during my college days.

The basic gist of properties is that they are used as if you are reading and writing a field of an object except that the author of the type can inject code during the read/write process.  So in C#, when creating a class you can create a property like this:

public class MyClass 
    private string _name;
    public string Name 
        get { return _name; }
            if (_name != value) 
                _name = value;

As an author of a type in .NET this is great because I can check to see if the value is different and only if it is different, perform some application specific logic.  For instance, WPF apps often need to let UI elements know when the value of the property has changed.  WPF’s data binding relies on this behavior and when it has been notified of a change to a property, it can get the new value for the property and update the UI automatically. Properties in .NET give us the necessary hooks to do this.

Note that in the code above, _name is a field. If I had made that field public, then a user of the type would have direct access to the field.  They could get or set the _name field and the class would have no way to know the field has been accessed or modified because there is no way to inject code during the read or write of a field.

Keep in mind that getting and setting a property in C#, VB and PowerShell is a language convenience commonly referred to as “syntactical sugar“.  When the C# source above is compiled, the generated assembly (dll or exe) shows this representation in common intermediate language (CIL):


Sidebar: Common Intermediate Language
What C# and VB compile down to is known as Common Intermediate Language.  This is typically what a .NET executable or DLL contains.  It is an architecture neutral representation of compiled source code that is not directly executable.  It has to be “just in time” compiled using a jitter (just-in-time compiler) or “ahead-of-time” compiled using a tool such as ngen.exe or the new .NET native compiler.

In either case, the JIT or AOT compiler needs to know the CPU architecture of the target device so it can generate the appropriate machine code.  This is typically either x86 (32 or 64 bit) or ARM.  .NET assemblies running on a Raspbery Pi2 with Windows 10 IoT or a Windows Phone require ARM compiled machine code

I’m using a tool called ILDASM that comes with the Windows SDK above to show the CIL contents of the .NET assembly generated from the C# MyClass source code shown above.  Notice that there is a “Name” property.  Here’s what ILDASM shows if you double-click on Name:

.property instance string Name()
  .get instance string MyClass::get_Name()
  .set instance void MyClass::set_Name(string)
} // end of property MyClass::Name

The Name property is simply a pointer to the compiler generated methods get_Name() and set_Name(string).  This is where the actual implementations of the property getter and setter reside.

The way you access a property in Java is to call a method; either a get<Property> or set<Property> method.  This is a common convention that is used because Java does not have first class support for properties.   Fortunately, accessing a property in C# looks just like you are reading or writing a field:

var obj = new MyClass();
obj.Name = "John";

Keep in mind that the C# source “obj.Name” is converted into a call to obj.get_Name() and obj.Name = “John” is converted to a call to obj.set_Name(“John”) at the CIL level.  At first glance this seems like it would be a minimal convenience but it turns out to be huge for C# and .NET’s usability IMO.

PowerShell also supports the property access syntactical sugar at the language level as well:

$obj = New-Object MyClass
$obj.Name = 'John'

Unfortunately, PowerShell does not support .NET event subscription syntactical sugar like C# and VB do.  That said, you’ll see that there is an easy workaround.  You could also argue that for most scripting scenarios you don’t use .NET events.  However, as soon as you want to build a UI, either with Windows Forms or WPF you’ll be using events, perhaps a lot.

Lets take a look at a class definition with events:

using System;
using System.ComponentModel;

public class MyClass : INotifyPropertyChanged
    private string _name;
    public string Name 
        get { return _name; }
            if (_name != value) 
                _name = value;

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
            new PropertyChangedEventArgs(propertyName));

This adds an event definition – PropertyChanged.  Let’s take a look at the CIL that got generated when I compiled this C# source code:


Notice again that there is an event called “PropertyChanged” but if we look at its CIL definition we will see it is very similar to the one for the Name property:

.event [System]System.ComponentModel.PropertyChangedEventHandler PropertyChanged
  .addon instance void MyClass::add_PropertyChanged(class [System]System.ComponentModel.PropertyChangedEventHandler)
  .removeon instance void MyClass::remove_PropertyChanged(class [System]System.ComponentModel.PropertyChangedEventHandler)
} // end of event MyClass::PropertyChanged

It just references the add_PropertyChanged and remove_PropertyChanged methods.  The actual implementation of event subscription and unsubscription are done in these two methods.

In C# you can subscribe to the PropertyChanged event with the += and -= syntactical sugar e.g.:

var obj = new MyClass();
obj.PropertyChanged += 
    (sender, args) => Console.WriteLine(args.PropertyName);

The same syntax += in PowerShell does not work for event subscription.  Fortunately the syntactical sugar is not required, we can just call the add_PropertyChanged() method directly.  The same goes for remove_PropertyChanged(), instead of C#’s -= syntax, if we need to unsubscribe from the event.

Add-Type -Path .\MyClass.dll
$obj = New-Object MyClass
$obj.add_PropertyChanged({Write-Host "$($_.PropertyName)"})
$obj.Name = 'Paul'

It works. It perhaps isn’t as elegant but more importantly I think the issue is lack of documentation and examples that use an event’s add/remove methods.  This is because the vast majority of .NET samples on the internet are in C# which are going to use the += and -= syntax..  It leaves the average PowerShell scripter scratching their head about why the C# += syntax doesn’t work.  And wondering what is up with this weird add_Click() method in the PowerShell script examples that show how to use Windows Forms.

Hopefully, if you’ve made it this far, you’ll have a good handle on these compiler generated methods for subscribing and unsubscribing to events.

Posted in .NET, PowerShell | 4 Comments

PSCX 3.2.1 Pushed to the PowerShellGallery

When you get your shiny new Windows 10 system up and running and want to get PSCX 3.2.1 installed, just drop to the console and execute:

Install-Module Pscx -Scope CurrentUser

If you are running from an elevated prompt, you can skip providing the “-Scope CurrentUser” and Pscx will be installed for all users.  However if you aren’t running in an elevated session, the “CurrentUser” scope is the only scope PowerShell can install into with standard user privileges.

There have been a few bug fixes to Pscx to make it work better on PowerShell 5.0.  The Get-Parameter command has been updated to not generate errors when trying to determine dynamic parameters for the available providers.  There’s also a new parameter, SkipProviderParameters, that will speed up discovery of parameters at the expense of not listing any provider specific parameters.  Expand-Archive has been updated to output DirectoryInfo and FileInfo objects of created directories and files if the PassThru parameter is specified.

Keep in that there are some commands that overlap with PowerShell 5.0.  Those are:

  • Format-Hex
  • Get-Clipboard
  • Set-Clipboard
  • Expand-Archive

To ensure you get the Pscx version of these commands, use Pscx\<command_name>.  To use the PowerShell versions, you use the appropriate module prefix: Microsoft.PowerShel.Utility, Microsoft.PowerShell.Management and Microsoft.PowerShell.Archive.

Posted in PSCX | Leave a comment

PSScriptAnalyzer–FxCop for PowerShell script

As a C and now C# developer I’ve always liked getting help with my code in the form of either Lint for C or code analysis a.k.a. FxCop for C#.  These tools are great at pointing out real and potential issues that are usually worth addressing.  As the old manufacturing saying goes, the earlier you catch a problem, the cheaper it is to fix.  This is also true for software including shell scripts.  Bugs can range from benign to frustrating to downright  catastrophically damaging.  I had a co-worker many years ago write a Korn shell script with a line like this:

rm –rf $folder

At one point, he made a change to the script that resulted in $folder having only “/” assigned to it.  That wasn’t the intention.  Needless to say, he and our system adminstrator, weren’t too happy the next day.

I’m very excited about PSScriptAnalyzer and its potential to help folks improve their scripts by having the collective wisdom of the PowerShell team and greater community embodied in rules that can detect potential problems before they become real problems.  Problems that can potentially take hours to track down. 

The following is the about topic for PSScriptAnalyzer that I wrote.  Hopefully it gives you a good understanding of how to use PSScriptAnalyzer.  It also demonstrates that the PSScriptAnalyzer team is taking community contributions via pull requests on GitHub specifically at

As you try the script analyzer on your scripts, keep in mind that it is the early days for this tool.  You’ll likely find issues that indicate a bug in the tool rather than your script.  Please submit these as issues on the PSScriptAnalyzer GitHub site.  And if you’re “that” type, fix the issue yourself and submit a PR.  As we all make the tool better, every user benefits.

The team holds a community meeting once every three weeks or so – at least for these early stages of the development of PSScriptAnalyzer.  These meetings are open to the community.  You can catch up on past meetings via the meeting notes on the project’s wiki.

BTW if you write PowerShell modules for the public, please consider writing an about topic for your module.  Module level about topics should be the primary/intro help topic folks can rely upon to find out information about a module. While folks can probably piece together the necessary information from the help topics of individual module commands, why make them do that when an about topic is so easy to write?

        PSScriptAnalyzer is a static code checker for PowerShell script.

        PSScriptAnalyzer checks the quality of Windows PowerShell script by evaluating
        that script against a set of rules.  The script can be in the form of a
        stand-alone script (.ps1 files), a module (.psm1, .psd1 and .ps1 files) or
        a DSC Resource (.psm1, .psd1 and .ps1 files).
        The rules are based on PowerShell best practices identified by the 
        PowerShell Team and the community. These rules can help you create more 
        readable, maintainable and reliable scripts. PSScriptAnalyzer generates 
        DiagnosticResults (errors and warnings) to inform you about potential script 
        issues, including the reason why there might be an issue, and provide you  
        with guidance on how to fix the issue.

        PSScriptAnalyzer is shipped with a collection of built-in rules that check 
        various aspects of PowerShell code such as presence of uninitialized 
        variables, usage of the PSCredential Type, usage of Invoke-Expression, etc.
        The following additional functionality is also supported:
        * Including and/or excluding specific rules globally
        * Suppression of rules within script
        * Creation of custom rules
        * Creation of loggers

        There are two commands provided by the PSScriptAnalyzer module, those are:
        Get-ScriptAnalyzerRule [-CustomizedRulePath <string[]>] [-Name <string[]>] 
                               [-Severity <string[]>] 

        Invoke-ScriptAnalyzer  [-Path] <string> [-CustomizedRulePath <string[]>] 
                               [-ExcludeRule <string[]>] [-IncludeRule<string[]>] 
                               [-Severity <string[]>] [-Recurse] [-SuppressedOnly] 

        To run the script analyzer against a single script file execute:
        PS C:\> Invoke-ScriptAnalyzer -Path myscript.ps1
        This will analyze your script against every built-in rule.  As you may find
        if your script is sufficiently large, that could result in a lot of warnings
        and/or errors. See the next section on recommendations for running against
        an existing script, module or DSC resource.
        To run the script analyzer against a whole directory, specify the folder
        containing the script, module and DSC files you want analyzed.  Specify
        the Recurse parameter if you also want sub-directories searched for files 
        to analyze.
        PS C:\> Invoke-ScriptAnalyzer -Path . -Recurse
        To see all the built-in rules execute:
        PS C:\> Get-ScriptAnalyzerRule

        If you have the luxury of starting a new script, module or DSC resource, it
        is in your best interest to run the script analyzer with all the rules 
        enabled.  Be sure to evaluate your script often to address rule violations as 
        soon as they occur.  
        Over time, you may find rules that you don't find value in or have a need to 
        explicitly violate.  Suppress those rules as necessary but try to avoid 
        "knee jerk" suppression of rules.  Analyze the diagnostic output and the part
        of your script that violates the rule to be sure you understand the reason for 
        the warning and that it is indeed OK to suppress the rule.  For information on 
        how to suppress rules see the RULE SUPPRESSION section below.

        If you have existing scripts, they are not likely following all of these best 
        practices, practices that have just found their way into books, web sites, 
        blog posts and now the PSScriptAnalyer in the past few years.
        For these existing scripts, if you just run the script analyzer without
        limiting the set of rules executed, you may get deluged with diagnostics
        output in the form of information, warning and error messages.  You should 
        try running the script analyzer with all the rules enabled (the default) and
        see if the output is "manageable".  If it isn't, then you will want to "ease 
        into" things by starting with the most serious violations first - errors.
        You may be temtped to use the Invoke-ScriptAnalyzer command's Severity 
        parameter with the argument Error to do this - don't.  This will run every 
        built-in rule and then filter the results during output.  The more rules the 
        script analyzer runs, the longer it will take to analyze a file.  You can 
        easily get Invoke-ScriptAnalyzer to run just the rules that are of severity 
        Error like so:
        PS C:\> $errorRules = Get-ScriptAnalyzer -Severity Error
        PS C:\> Invoke-ScriptAnalyzer -Path . -IncludeRule $errorRules
        The output should be much shorter (hopefully) and more importantly, these rules
        typically indicate serious issues in your script that should be addressed.
        Once you have addressed the errors in the script, you are ready to tackle
        warnings.  This is likely what generated the most output when you ran the 
        first time with all the rules enabled.  Now not all of the warnings generated 
        by the script analyzer are of equal importance.  For the existing script 
        scenario, try running error and warning rules included but with a few rules 
        PS C:\> $rules = Get-ScriptAnalyzerRule -Severity Error,Warning
        PS C:\> Invoke-ScriptAnalyzer -Path . -IncludeRule $rules -ExcludeRule `
                    PSAvoidUsingCmdletAliases, PSAvoidUsingPositionalParameters

        The PSAvoidUsingCmdletAliases and PSAvoidUsingPositionalParameters warnings 
        are likely to generate prodigious amounts of output.  While these rules have 
        their reason for being many existing scripts violate these rules over and 
        over again.  It would be a shame if you let a flood of warnings from these two 
        rules, keep you from addressing more potentially serious warnings.
        There may be other rules that generate a lot of output that you don't care 
        about - at least not yet.  As you examine the remaining diagnostics output, 
        it is often helpful to group output by rule.  You may decide that the one or 
        two rules generating 80% of the output are rules you don't care about.  You 
        can get this view of your output easily:
        PS C:\> $rules = Get-ScriptAnalyzerRule -Severity Error,Warning
        PS C:\> $res = Invoke-ScriptAnalyzer -Path . -IncludeRule $rules -ExcludeRule `
                          PSAvoidUsingPositionalParameters, PSAvoidUsingCmdletAliases
        PS C:\> $res | Group RuleName | Sort Count -Desc | Format-Table Count, Name
        This renders output like the following:
        Count Name
        ----- ----
           23 PSAvoidUsingInvokeExpression
            8 PSUseDeclaredVarsMoreThanAssigments
            8 PSProvideDefaultParameterValue
            6 PSAvoidUninitializedVariable
            3 PSPossibleIncorrectComparisonWithNull
            1 PSAvoidUsingComputerNameHardcoded
        You may decide to exclude the PSAvoidUsingInvokeExpression rule for the moment
        and focus on the rest, especially the PSUseDeclaredVarsMoreThanAssigments, 
        PSAvoidUninitializedVariable and PSPossibleIncorrectComparisonWithNull rules.
        As you fix rules, go back and enable more rules as you have time to address 
        the associated issues.  In some cases, you may want to suppress a rule at
        the function, script or class scope instead of globally excluding the rule.  
        See the RULE SUPPRESSION section below.
        While getting a completely clean run through every rule is a noble goal, it 
        may not always be feasible. You have to weigh the gain of passing the rule 
        and eliminating a "potential" issue with changing script and possibly 
        introducing a new problem.  In the end, for existing scripts, it is usually 
        best to have evaluated the rule violations that you deem the most valuable to 


        Rule suppression allows you to turn off rule verification on a function, 
        scripts or class definition.  This allows you to exclude only specified 
        scripts or functions from verification of a rule instead of globally 
        excluding the rule.  

        There are several ways to suppress rules.  You can suppress a rule globally 
        by using the ExcludeRule parameter when invoking the script analyzer e.g.:
        PS C:\> Invoke-ScriptAnalyzer -Path . -ExcludeRule `
                    PSProvideDefaultParameterValue, PSAvoidUsingWMICmdlet
        Note that the ExcludeRule parameter takes an array of strings i.e. rule names.
        Sometimes you will want to suppress a rule for part of your script but not for
        the entire script.  PSScriptAnalyzer allows you to suppress rules at the 
        script, function and class scope.  You can use the .NET Framework 
        System.Diagnoctics.CodeAnalysis.SuppressMesssageAttribute in your script 
        like so:
        function Commit-Change() {
                                                               "", Scope="Function", 

        PSScriptAnalyzer has been designed to allow you to create your own rules via
        a custom .NET assembly or PowerShell module.  PSScriptAnalyzer also allows 
        you to plug in a custom logger (implemented as a .NET assembly).

        PSScriptAnalyzer is open source on GitHub:
        As you run the script analyzer and find what you believe to be are bugs,
        please submit them to:
        Better yet, fix the bug and submit a pull request.
Posted in PowerShell 5.0, PSScriptAnalyzer | Leave a comment

DNVM Execution Results in Get-Help Error in PowerShell

If you are running dnvm with no parameters on PowerShell with PSCX, you’re likely to see this error:

4> dnvm
You must specify a command!
   ___  _  ___   ____  ___
  / _ \/ |/ / | / /  |/  /
 / // /    /| |/ / /|_/ /
/____/_/|_/ |___/_/  /_/
.NET Version Manager v1.0.0-beta4-10356
By Microsoft Open Technologies, Inc.

usage: dnvm  []

Get-Help : Get-Help could not find dnvm-alias in a help file in this session. To
download updated help topics type: "Update-Help". To get help online, search for the
help topic in the TechNet library at
At C:\Program Files\Microsoft DNX\Dnvm\dnvm.ps1:755 char:17
+                 $h = Get-Help $_.Name
+                 ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (:) [Get-Help], HelpNotFoundException
    + FullyQualifiedErrorId : HelpNotFound,Microsoft.PowerShell.Commands.GetHelpCommand

    alias     C:\Program Files\Microsoft DNX\Dnvm\dnvm.ps1 : You cannot call a method on a
At line:1 char:1
+ dnvm
+ ~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,dnvm.ps1

There is apparently a bug in the PSCX proxy command for Get-Help, which adds support for looking up help for .NET types and members on MSDN.  For now, you can disable the Get-Help proxy by either editing your existing Pscx.UserPreferences.ps1 file.

If you are not use the Pscx.UserPreferences.ps1 file, you will need to copy one to your profile dir.  Your profile dir can be found like so:

PS C:\> (Split-Path $profile –Parent)

The Pscx.UserPreferences.ps1 file can be located in your Pscx install dir which can be found with this command:

PS C:\> (Get-Module Pscx).ModuleBase

With this info, copy the Pscx.UserPreferences.ps1 file into your profile dir.

Now edit the Pscx.UserPreferences.ps1 file in your profile dir and change this line:

GetHelp           = $true


GetHelp           = $false

Save the file and the next time you load PSCX, use this command line or replace the existing import of PSCX in your profile script with this one:

PS C:\> Import-Module Pscx -Arg "$(Split-Path $profile -Par)\Pscx.UserPreferences.ps1"

Sorry for this inconvenience.  I will be looking into a fix for PSCX vnext which might just be to disable the Get-Help proxy by default.

Posted in .NETCore, PSCX | Leave a comment

Windows PowerShell V5 Goodies in the April WMF5 Preview

It looks like we will get not just the package management features PackageManagement  and PowerShellGet, but the whole of PowerShell V5 downlevel to Windows 7.  This is great news!

The big features in V5 are package management, improved DSC and support for classes but there are quite a number of small goodies that folks will find useful.

First up are the package management features.  If you used a previous preview or read about earlier previews of PowerShell V5, you’ve probably heard about OneGet.  News alert: the OneGet module had to be renamed, due to trademark conflicts, to PackageManagement.  What is it with all this renaming?  First Metro, then OneDrive, now OneGet and possibly even Skype.  I guess I know why my company uses boring model numbers for products.  Smile

Keep in mind that OneGet, er PackageManagement is *not* a package manager itself but a manager of package managers.  One of those is PowerShellGet which comes “in the box”.

The PackageManagement module allows you to register various package sources.  By default you get the PSGallery which uses the PSModule provider used by PowerShellGet.  With this one feature you will be able to install popular PowerShell modules as simply as this:

PS C:\> Install-Module Pscx -Scope CurrentUser

You can install a module for all users (-Scope AllUsers) but you need to be running in an admin console to do so.  This feature alone is huge because it opens up easy access to very useful modules like Pscx, PSReadline, Pester, ISESteroids, xWebAdministration, etc to average users who might not know where to find these modules.  After all, we have multiple repos for these: CodePlex, GitHub, PoshCode, etc.  Additionally you can easily update modules to their latest versions using Update-Module.

When you start searching for or installing packages the first time, the PackageManagement module will need to bootstrap certain providers/sources like Chocolatey, which also requires it to download the NuGet provider (Chocolatey uses NuGet packages).

The Install-Package command allows you to install software from various repos. By default PowerShell comes with a Chocolatey provider which will allow you to install from Chocolatey but be careful, the same package may be found in multiple places.  For instance PSCX is on both the PSGallery and Chocolatey.

PS C:\> Find-Package Pscx | Format-Table -AutoSize

Name Version Source
---- ------- ------
pscx 3.2.0   chocolatey

The Install-Module command, as configured, will install only from the PSGallery.  However if you use Install-Package you can use the –Source parameter to specify the particular package source you want to install from.  Note that the version of Pscx from Chocolatey is actually the MSI installer for Pscx.

Chocolatey is a very handy source of developer tools.  You can easily find and install various tools using Install-Package e.g.:

PS C:\> Install-Package dotPeek –Source chocolatey
PS C:\> Install-Package fiddler4 -Source chocolatey

If you are thinking this looks like apt-get or yum on Linux, you’re right. Windows is overdue for a simple package management capability like this.

I’ve covered the classes feature in a previous blog post.  However there is a new related feature that will make using .NET types much easier and that is the new “using namespace” feature.  Ever get tired of typing full type names over and over?  Now you don’t need to:

using namespace System.Collections.Generic
$list = New-Object 'List[int]'
$cust = New-Object 'Dictionary[string, hashtable]'

I’ve been waiting a long time for that feature!!

There are also number of handy new commands:

  • Compress/Expand-Archive – finally!
  • Get/Protect/Unprotect-CmsMessage – protects secrets using PKI.  See my blog post on these commands.
  • Get-ItemProperyValue
  • New-Guid
  • New-TemporaryFile
  • Get-Clipboard – this can even paste file lists
  • Set-Clipboard
  • Format-Hex (the one in PSCX is better IMO)
  • Out-File, Add-Content and Set-Content have a new parameter -NoNewline
  • Get-ChildItem now has a -Depth parameter you use with -Recurse
  • Convert-String – for changing text from one form to another
  • ConvertFrom-String – to extract information from text into objects
  • New-Item -ItemType now takes SymbolicLink, HardLink and Junction as additional arguments
  • Test-ModuleManifest
  • Debug-Job, Debug-Process, Debug-Runspace
  • Disable-RunspaceDebug, Enable-RunspaceDebug, Get-RunspaceDebug, Wait-Debugger
  • Enter-PSHostProcess, Exit-PSHostProcess, Get-PSHostProcessInfo

For the Get-Clipboard FileList support, check this out.  I copied two files from different directories into the clipboard from Windows Explorer.  I was able to “get” those file items using Get-Clipboard:

PS C:\> Microsoft.PowerShell.Management\Get-Clipboard -Format FileDropList

    Directory: C:\Program Files (x86)\Windows Kits\10\Platforms\UAP\10.0.10030.0

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
darhsl       12/31/1600   5:00 PM                Platform.xml

    Directory: C:\Program Files (x86)\Windows Kits\10\Source\ucrt\conio

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
darhsl       12/31/1600   5:00 PM                pipe.cpp

Note that I prefixed Get-Clipboard with Microsoft.PowerShell.Management\Get-Clipboard to ensure I am using the new Get-Clipboard command and not the one in Pscx.

There are also a lot of enhancements to debugging.  You can break into the PowerShell debugger on any running script in the console by pressing Ctrl+Break (in ISE it is Ctrl+B).  You can remote edit a script using PSEdit from within a remote, interactive session (started with Enter-PSSession).  You can attach to any PowerShell engine process for debugging using Enter-PSHostProcess – this includes processes running on a remote machine!  Once you’re attached to the process, you can list all available runspaces using Get-Runspace, then start debugging the runspace you’re interested in using Debug-Runspace.

Get-Command will now also show the “Source” of a command instead of the ModuleName.  The pain in V4 and below is that when you use Get-Command on an exe or external script the default display did not show the path.  You had to pipe through Format-List Path to see the path to the command.  Not the case in V5, check it out:

PS C:\> Get-Command dnvm | Format-Table -AutoSize

CommandType    Name     Version Source
-----------    ----     ------- ------
ExternalScript dnvm.ps1         C:\Program Files\Microsoft DNX\Dnvm\dnvm.ps1

PowerShell V4 was interesting because of the DSC feature but as a dev I wasn’t able to use DSC that much so V4 was a bit of a let down for me.  However V5 is packed with lots of goodies for developers!!  You can grab the April WMF5 Preview from the link on this PowerShell team blog post.  Or if you are using Windows 10 build 10074 or higher, you already have it.

Posted in PowerShell 5.0 | Leave a comment