A Custom PSVersionTable Solution
In this issue:
- A Few Notes on History Streams
- December 2025 Scripting Challenge
- Copy Confusion
- Attack of the Clones
- Hashtable Updates
- Hashtable or Object?
- New-CustomPSVersionTable
- Adding Custom Formatting
- Summary
A Few Notes on History Streams
> After publishing my recent issue that explored using alternate data streams to store file history, this I realizes there was a challenge with my code using event subscriptions to automate the update process. Updating the alternate data stream counts as a changed event, so it is possible to have an update loop where each update to the history stream causes another update. Fortunately, in the code I was testing I had set a limit. Do not implement any of the code event subscription code. I have a work around in mind that I will publish later if it works. This is why you should always test in non-production environments first.
> I also want to add that there is no support for alternate data streams in tools such. as OneDrive or DropBox. I verified that my backup solution retains the alternate data streams, but they do not replicate across my OneDrive devices.
December 2025 Scripting Challenge
At the end of last year, I left you with another PowerShell scripting challenge. I asked you to write a PowerShell function to create a customized version of $PSVersionTable. The command should create output in the global scope.
It should meet the following requirements:
- Allow the user to define the variable name'
- Allow the user to create a hashtable or a custom object'
- On Windows systems, update the operating system value from WMI'
- Add a computername entry'
- Add the date PowerShell was updated or installed. Hint: Get the command folder last write time.
- Remove the following entries:
WsmanStackVersion,SerializationVersion, andPSRemotingProtocolVersion' - The code must run cross-platform'
Write your code to be as efficient as possible, yet still easy to understand. For bonus points, create a custom formatted view for object output.
Copy Confusion
At first glance, this doesn't seem too difficult. I can start with making a copy of $PSVersionTable. However, this won't work the way you think it will. You may have done something like this in the past:
PS C:\> $a = 1
PS C:\> $b = $a
PS C:\> $b = 5
PS C:\> $b
5
PS C:\> $a
1
So you think this should work:
PS C:\> $j = $h
PS C:\> $j
Name Value
---- -----
location home
version 7.5.4
name jeff
Watch what happens as I modify the copy.
PS C:\> $j.Add('responding',$True)
PS C:\> $j
Name Value
---- -----
responding True
location home
version 7.5.4
name jeff
PS C:\> $h
Name Value
---- -----
responding True
location home
version 7.5.4
name jeff
Attack of the Clones
The original variable is modified as well. create a true copy, you can use the Clone() method.
PS C:\> $h | Get-Member clone
TypeName: System.Collections.Hashtable
Name MemberType Definition
---- ---------- ----------
Clone Method System.Object Clone(), System.Object ICloneable.Clone()
Let me reset my test variables.
PS C:\> $h = @{name='jeff';version=[version]'7.5.4';location='home'}
PS C:\> $j = $h.Clone()
PS C:\> $j
Name Value
---- -----
name jeff
location home
version 7.5.4
Now, if I modify the clone, the original remains unchanged.
PS C:\> $j.add('responding',$True)
PS C:\> $j.responding
True
PS C:\> $h.responding
PS C:\>
In my function, I will create a clone of the original $PSVersionTable to work with.
$clone = $PSVersionTable.clone()
Hashtable Updates
The challenge asked to add information about the computer name.
$clone.Add("Computername",[System.Environment]::MachineName)
I'm using the .NET property so that this will work cross-platform.
Operating System Info
On Windows, getting the operating system information is easy with WMI.
if ($isWindows) {
$clone['OS'] = (Get-CimInstance -ClassName Win32_OperatingSystem -Property Caption).Caption
}
I'm using the -Property parameter to limit the data returned. All I need is the Caption property so why waste resources retrieving all the properties? Every little bit of performance helps.
I wasn't expecting you to get details on non-Windows systems. This would have sufficed.
elseif ($isLinux) {
$clone['OS'] = 'Linux'
}
elseif ($isMacOS) {
$clone['OS'] = 'MacOS'
}