DCSIMG
Improving the output of Update-Help - Shay Levy

Shay Levy

If you repeat it, PowerShell it!

News


btn_donate_LG

View Shay Levy's profile on LinkedIn Follow Shay Levy at Twitter Shay Levy's Facebook profile Subscribe to my FriendFeed


site statistics




Improving the output of Update-Help

Source: PowerShellMagazine.com

 

If you’ve updated PowerShell to version 3.0 you probably noticed that help is no longer shipped in the box. PowerShell 3.0 includes a new feature, the Updatable Help system, which allows you to ensure that help on the local computer stays up to date.

PowerShell is now a part of the operating system and operating systems gets to be updated only during service packs or specific patches. The Updatable Help system and its cmdlets (*-Help) make it easy to download and install help files, or updating exiting help files, as soon as newer help files become available.

To download and install help files for the first time, use the Update-Help cmdlet. When executed, Update-Help goes through a series of steps to get the latest help versions of the modules installed on your system:

  1. It determines which modules support updatable help by checking the HelpInfoUri key in the module manifest file.  The HelpInfoUri contains the Internet location where each module stores its updatable help files.
  2. Compares each module local help files with the newest help files that are available for each module.
  3. Downloads the new files (packaged in a cab file).
  4. Unwraps the help file package, verifies that the files are valid, and then installs the help files in the language-specific subdirectory of the module directory.

Note: There are a few things to take into account when using Update-Help. First, you must run PowerShell as an administrator as help files are written to the installation folder of PowerShell and that happens to be under theSystem32 folder. PowerShell allows you to update help files once every 24 hours. To override this behavior you must specify the -Force switch.

By default, the Update-Help cmdlet doesn’t generate any output. When executed, it displays a progress bar that prints information about the current module update phase.

updateHelp

If you want to see what’s going on under the hood, include the -Verbose switch:

updateHelp1

One of the things that really annoys me is the output of the -Verbose switch, the way it is written makes it very hard to read and determine which files and modules has been updated. In this post I want to introduce you to a new feature in PowerShell 3.0 that can help you change the way the verbose information is displayed in the console.

In the previous version of PowerShell it was very hard to capture the output of the Verbose stream, or any other PowerShell-related stream. Luckily, this has changed in PowerShell 3.0 and now it is a very easy thing to do. We can now redirect and merge any of the pipeline output streams (see list below) to text files. You can read more about this in about_Redirection help topic.

By default, the Update-Help command doesn’t write anything to the pipeline so we can safely merge the verbose stream to the standard output stream and parse it without having to worry about information from both sources gets mixed together.

Each redirection operator uses a character to represent each output type:

  • * – All output
  • 1 – Success output
  • 2 – Errors
  • 3 – Warning messages
  • 4 – Verbose output
  • 5 – Debug messages

The Verbose stream constant is 4, and Success output is 1, so we use the redirection operator (e.g ‘>’) to funnel the output:

PS> $uh = Update-Help -Verbose -Force 4>&1

Let’s examine the first element; we can see that the connection is redirecting to another URI.

PS> $uh[0]
VERBOSE: Your connection has been redirected to the following URI:
VERBOSE: http://download.microsoft.com/download/3/4/C/34C6B4B6-63FC-46BE-9073-FC75EAD5A136/

The second element in the output of Update-Help contains the information we are after. We can see that theMicrosoft.PowerShell.Management was updated, and we
also get information about the path of the help file, its culture, and the version information.

PS> $uh[1]
VERBOSE: Microsoft.PowerShell.Management: Updated
VERBOSE:
C:\Windows\System32\WindowsPowerShell\v1.0\en-US\Microsoft.PowerShell.Commands.Management.dll-hel
p.xml. Culture en-US
VERBOSE: Version 3.1.0.0

Let’s see what Get-Member has to say about it:

PS> $uh[1] | Get-Member

   TypeName: System.Management.Automation.VerboseRecord

Name                  MemberType   Definition
----                  ----------   ----------
Equals                Method       bool Equals(System.Object obj)
GetHashCode           Method       int GetHashCode()
GetType               Method       type GetType()
ToString              Method       string ToString()
WriteVerboseStream    NoteProperty System.Boolean WriteVerboseStream=True
InvocationInfo        Property     System.Management.Automation.InvocationInfo InvocationInfo {get;}
Message               Property     string Message {get;set;}
PipelineIterationInfo Property     System.Collections.ObjectModel.ReadOnlyCollection[int] PipelineIterationInfo {get;}

We get a System.Management.Automation.VerboseRecord object which describes a verbose message sent to the verbose stream, and information about the command that sent the message (InvocationInfo). The Message property contains the actual message we see in the console. If you need to identify verbose messages written to the success stream, you can safely rely on this type and filter objects accordingly.

PS> $uh[1].Message
Microsoft.PowerShell.Management: Updated C:\Windows\System32\WindowsPowerShell\v1.0\en-US\Microsoft.PowerShell.Commands
.Management.dll-help.xml. Culture en-US Version 3.1.0.0

We can split the message (by default the Split method breaks the string on the space character) and get access to the array elements we get back:

PS> $uh[1].Message.split()
Microsoft.PowerShell.Management:
Updated
C:\Windows\System32\WindowsPowerShell\v1.0\en-US\Microsoft.PowerShell.Commands.Management.dll-help.xml.
Culture
en-US
Version
3.1.0.0

Based on the output of the Split operation, we want to extract the relevant pieces of information, create a new custom object and write it back to the pipeline, one object at a time.
The information we want is:

  1. The module name–it’s the first item (index 0). The value is followed by a colon, we’ll remove it later on.
  2. The file path that’s being updated (third line, index 2).
  3. The culture of the help file (fifth line, index 4).
  4. The version of the new help file (last line, we can refer to it as index -1, which in PowerShell gives back the last array element).

We can now construct a new custom object. We’ll start by creating a custom object for the first array element:

$message = $uh[1].Message.split()[0,2,4,-1]

[PSCustomObject]@{
	Module = $message[0] -replace ':$'
	FileName = (Split-Path $message[1] -Leaf).Trim('.')
	Culture = $message[2]
	Version  = $message[-1]
}

Module                        FileName                      Culture                       Version
------                        --------                      -------                       -------
Microsoft.PowerShell.Manag... Microsoft.PowerShell.Comma... en-US                         3.1.0.0

As soon as each object (verbose message) is processed, the object goes out to the console. As you can see, the output of the Module and FileName properties is truncated. We could use the -AutoSize of the Format-Table cmdlet to adjust the columns size, but doing so will block output of objects to the console until all objects were processed.

When processing the verbose stream we also want to avoid processing unnecessary messages, we want to skip any messages that contains URI redirections, so we process only messages that contains the word “Updated”. We pipe the custom objects to the Tee-Object cmdlet, to send output to the console as soon as it flows in, and also save the output to a variable that we can format the way we want it to.

Here’s the full snippet. Output shown on screen is also saved in the UpdatedHelp variable. When the script finished executing we can investigate and format it as we like.

Update-Help -Force -Verbose 4>&1 |
Where-Object {$_.Message -like '*: Updated*'} |
ForEach-Object {

    $message = $_.Message.Split()[0,2,4,-1]

    [PSCustomObject]@{
        Module = $message[0] -replace ':$'
        FileName = (Split-Path $message[1] -Leaf).Trim('.')
        Culture = $message[2]
        Version  = $message[-1]
    }

} | Tee-Object -Variable UpdatedHelp

$UpdatedHelp | Format-Table -AutoSize

 

updateHelp2

Comments

グッチコピー said:

この人が脱退してから、AKBの話題が減った気がする。

# December 23, 2012 8:07 AM

ブランド時計 said:

品質がよい、価格が低い、実物写真!当社の商品は絶対の自信が御座います。100%品質保証 !満足保障100%!

# December 23, 2012 2:49 PM

Powershell: Improving the output of Update-Help « MS Tech BLOG said:

Pingback from  Powershell: Improving the output of Update-Help « MS Tech BLOG

# January 10, 2013 2:43 PM

Top 5 New Lync 2013 PowerShell Features | Inside Lync said:

Pingback from  Top 5 New Lync 2013 PowerShell Features | Inside Lync

# February 23, 2013 10:20 PM

GraliaExhaura said:

You created some decent points there. I looked on the web for the concern and discovered most individuals will go along with along with your web page.

[URL=http://www.mkbagforcheap.com]michael kors bags[/URL]

# May 4, 2013 6:09 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: