Last Update: Sep 04, 2024 | Published: Jan 12, 2016
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.
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.
This means that the information stream is turned off. To turn it on, set the InformationPreference value to Continue.
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.
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.
Now, what is $a?
By default, all you see is the message data.
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.
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.
The output is the same and none of the Write-Information messages appear on the screen. But look what we have now:
This is a collection of rich objects.
I can find data by tag if I want.
Or view in a timeline fashion.
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.
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.