Getting Started with the PowerShell 5.0 Information Stream

One of the great additions to PowerShell 5.0 is the new information stream. You can use this stream as a logging mechanism in your scripts and functions, which is something I want to demonstrate today.


There are three elements that you’ll need to understand to make this all work: a preference variable, a cmdlet, and an output variable.
The new cmdlet is called Write-Information, which by itself doesn’t appear to do anything.

Write-Information (Image Credit: Jeff Hicks)
Write-Information (Image Credit: Jeff Hicks)

That’s because there’s a new preference variable in PowerShell 5.0, much like ErrorActionPreference and VerbosePreference, called InformationPreference. It uses the same values as the other preference variables. The default is SilentlyContinue.
Default value for InformationPreference (Image Credit: Jeff Hicks)
Default value for InformationPreference (Image Credit: Jeff Hicks)

This means that the information stream is turned off. To turn it on, set the InformationPreference value to Continue.
Testing the new InformationPreference value (Image Credit: Jeff Hicks)
Testing the new InformationPreference value (Image Credit: Jeff Hicks)

Now, that hardly looks exciting, and there’s not much to do with it. That’s because we need the third element, an output variable. PowerShell 5.0 includes a new common parameter, like outputvariable and ErrorVariable, called InformationVariable. This parameter has an alias of iv. Let’s repeat the process.
Using the InformationVariable parameter (Image Credit: Jeff Hicks)
Using the InformationVariable parameter (Image Credit: Jeff Hicks)

This still doesn’t look like much, but we’ll get there. Before we get too far, there’s another new parameter called InformationAction, which has an alias of infra. Like the common ErrorAction parameter, you should set the value on a per command basis and not set the global preference variable. Let me set the global preference back and use the proper technique.
The proper way to use the information stream (Image Credit: Jeff Hicks)
The proper way to use the information stream (Image Credit: Jeff Hicks)

Now, what is $a?
The new InformationRecord object (Image Credit: Jeff Hicks)
The new InformationRecord object (Image Credit: Jeff Hicks)

By default, all you see is the message data.
An actual InformationRecord object (Image Credit: Jeff Hicks)
An actual InformationRecord object (Image Credit: Jeff Hicks)

The time stamp, user, and computer information was all autogenerated. For my purposes, I am not concerned about the process or thread ID information. Notice that Tags property? You can tag different pieces of information. Here’s how you might take advantage of this feature.

I have a very simple function.

Function Test-Me {
[cmdletbinding()]
Param()
Write-Verbose "InformationPreference = $InformationPreference"
Write-Information -MessageData "Starting $($MyInvocation.MyCommand) " -Tags Process
Write-Information -MessageData "PSVersion = $($PSVersionTable.PSVersion)" -Tags Meta
Write-Information -MessageData "OS = $((Get-CimInstance Win32_operatingsystem).Caption)" -Tags Meta
Write-Verbose "Getting top 5 processes"
Get-process | sort WS -Descending | select -first 5 -outvariable s
Write-Information -MessageData ($s[0] | out-string) -Tags Data
Write-Information -MessageData "Ending $($MyInvocation.MyCommand) " -Tags Process
}

Let’s run it.

Testing the function without information (Image Credit: Jeff Hicks)
Testing the function without information (Image Credit: Jeff Hicks)

I included verbose output to show the InformationPreference value. Because it is SilentlyContinue, none of the Write-Information commands do anything. Next, let’s run it and specify an InformationVariable.
Using InformationVariable (Image Credit: Jeff Hicks)
Using InformationVariable (Image Credit: Jeff Hicks)

The output is the same and none of the Write-Information messages appear on the screen. But look what we have now:
Viewing the information variable (Image Credit: Jeff Hicks)
Viewing the information variable (Image Credit: Jeff Hicks)

This is a collection of rich objects.
Viewing an information variable object properties (Image Credit: Jeff Hicks)
Viewing an information variable object properties (Image Credit: Jeff Hicks)

I can find data by tag if I want.
Finding information by tag (Image Credit: Jeff Hicks)
Finding information by tag (Image Credit: Jeff Hicks)

Or view in a timeline fashion.
An information timeline (Image Credit: Jeff Hicks)
An information timeline (Image Credit: Jeff Hicks)

You can do whatever you want with this data. You could write parts of it to a text file or you could export it to an XML file. It all depends on what you intend to do with the information.
The important step is to use the InformationVariable parameter so the stream has some place to store data. If you want to see the messages, then tell PowerShell to show them.
Viewing information messages inline (Image Credit: Jeff Hicks)
Viewing information messages inline (Image Credit: Jeff Hicks)


In my function, this probably isn’t very practical, but you should get the idea. The tricky part is knowing what is output and what is an information message. I’ll show you a solution to that challenge in another article.