Summary: Microsoft Scripting Guy, Ed Wilson, shows how to remove all error commands from your Windows PowerShell command history.

Microsoft Scripting Guy, Ed Wilson, is here. One of the great things about being involved with a Windows PowerShell user group is all the great people I meet and all the cool ideas that arise. It seems that every time I attend a Windows PowerShell user group meeting, I come away with at least one idea for a Hey, Scripting Guy! Blog post. (The Charlotte PowerShell User Group meets on the first Thursday of the month at the Microsoft office in Charlotte, North Carolina, in the United States.)

Note You can see if there is a Windows PowerShell user group that meets in your area by going to the PowerShellGroup.org webpage. If you would like to start a Windows PowerShell user group in your area, you may want to take a look at these Hey, Scripting Guy! Blog posts for ideas on how to start.

Image of NYC Windows PowerShell user group logo

 

Double Note   Tonight, February 11, 2013, at 6:00 P.M. in New York City is the NYC Windows PowerShell User Group meeting. They will be sharing their favorite Windows PowerShell tips and tricks, and I will publish them on the Hey, Scripting Guy! Blog. This will be cool. If you are anywhere near the Sixth Avenue Microsoft office, you should check it out. You can register (for free) via the link above.

 

 

Examining the error object

Anyway, Microsoft PowerShell MVP Jim Christopher (the Charlotte Windows PowerShell user group president) created a lab using a way cool SQLite provider he wrote. This turned into a great hands-on lab for working with providers. During the course of the wrap up and summary, I suggested we look though the $error object and commented on the fact that if you pipe the object to Format-List * and use the –FORCE parameter, additional details appear. 

An example of this technique is shown using $error[0], which is always the most recent error generated.

$error[0] | Format-List * -Force

The command and its associated output are shown in the following figure.

Image of command output

So, the InvocationInfo property contains an object. I can access the object directly, as shown here.

$Error[0].InvocationInfo

The command and the output associated with the command are shown here.

Image of command output

Now, if I use the Get-History cmdlet to display my command history, I can immediately see several errors are retained in my history. This makes it a real pain when I am using the Up Arrow key through a series of commands. The Get-History command and the associated output are shown here.

Image of command output

Ok, now I clear the history entries that have errors

To clear all of the error-causing commands from my command history, I first pipe the $error object to the Foreach-Object cmdlet (% is an alias for the Foreach-Object cmdlet). Inside the script block for the Foreach-Object cmdlet, I pipe the history IDs to the Where-Object (? is an alias for the Where-Object) where I look for a history ID that is greater than 0.

Once I find those, I pipe the history IDs once again to a Foreach-Object cmdlet (still using % as an alias). Inside the Foreach-Object cmdlet, I use the Clear-History cmdlet to remove the error-inducing commands from my history stack. The complete command is shown here.

$Error | % { $_.invocationinfo.historyid} | ? {$_ -gt 0} | % {clear-history -id $_}

Now when I check my command history, I see that that most of the offending commands were successfully removed from the history. This is shown in the following image.

Image of command output

But, some of the errors—those related to calling a static method on a non-existent type—did not get deleted. The reason is that those types of errors do not write the proper history index—instead they show up with a -1 for the HistoryID, as shown here.

15:06 C:\> $Error[0].InvocationInfo

MyCommand             :

BoundParameters       : {}

UnboundArguments      : {}

ScriptLineNumber      : 1

OffsetInLine          : 1

HistoryId             : -1

ScriptName            :

Line                  : [int8]::minvalue

PositionMessage       : At line:1 char:1

                        + [int8]::minvalue

                        + ~~~~~~~~~~~~~~~~

PSScriptRoot          :

PSCommandPath         :

InvocationName        :

PipelineLength        : 0

PipelinePosition      : 0

ExpectingInput        : False

CommandOrigin         : Internal

DisplayScriptPosition :

Still, this is pretty useful, and I would not have even come up with the idea if I had not attended the Windows PowerShell user group meeting the other night in Charlotte. In fact, I am thinking about putting this into a function called Remove-BadHistoryEntry and placing it in my profile. In fact, I just wrote the Remove-BadHistoryEntry function and uploaded it to the Scripting Guys Script Repository. Check it out. It is cool.

Join me tomorrow when I will talk about more way cool Windows PowerShell stuff.

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

Ed Wilson, Microsoft Scripting Guy