Steven Murawski

SysAdmin, DevOps, PowerShell, and Other Stuff

Adding Custom Properties to Functions

A question was asked on StackOverflow regarding how to add properties to a function, and then be able to retain that custom property when recalling that function from the function Provider.   I’m not going to copy my answer here, but I do want to throw out a possible work around for this issue. 

(It has been bugging me and I can’t really concentrate on my other tasks, so I need to get this out of the way.)

One suggestion I had was to create a type extension that had the property he was adding, but he was more interested in tagging specific functions, not all of them.

So, I’ve written a couple of little ScriptProperties to save and restore NoteProperties which have been added to FunctionInfo objects.  I’ve added these to a PS1XML.

   1: <?xml version="1.0" encoding="utf-8" ?> 
   2: <Types> 
   3:     <Type> 
   4:         <Name>System.Management.Automation.FunctionInfo</Name> 
   5:         <Members> 
   6:             <ScriptMethod> 
   7:                 <Name>SaveMetadata</Name> 
   8:                 <Script> 
   9: $DefaultProperties = 'PSPath', 'PSDrive', 'PSProvider', 'PSIsContainer'
  10: $SaveDirectory = Split-Path $profile
  11: $File = Join-Path $SaveDirectory "$($this.Name).xml"
  12: $this.PSObject.Properties | Where-Object {$DefaultProperties -notcontains $_.Name -and $_.MemberType -like 'NoteProperty'} | Export-Clixml -Path $file
  13:                 </Script> 
  14:             </ScriptMethod>
  15:             <ScriptMethod> 
  16:                 <Name>LoadMetadata</Name> 
  17:                 <Script> 
  18: $SaveDirectory = split-path $profile
  19: $PathToCustomProp = Join-Path $SaveDirectory "$($this.name).xml"
  20: if (Test-Path $PathToCustomProp)
  21: {
  22:     foreach ($Property in Import-Clixml -Path $PathToCustomProp)
  23:     {
  24:         Add-Member -InputObject $this -MemberType NoteProperty -Name $Property.Name -Value $Property.Value
  25:     }
  26: }
  27:                 </Script> 
  28:             </ScriptMethod> 
  29:         </Members> 
  30:     </Type> 
  31: </Types> 

After saving this file as a PS1XML file, you can call Update-TypeData –Prepend path\to\thefile.ps1xml, and every FunctionInfo object will have two script properties – SaveMetadata and LoadMetadata.  As I’ve configured it, the data will be saved to the user’s profile directory and under a filename that matches the function name.  So, you can add NoteProperties to your heart’s desire and save and recall them as needed. 

I don’t have a direct application for this, and it can probably be cleaned up or done more efficiently, but I had to work through the problem.  I’d love to hear your feedback!