I've attempted using the $function:foo value and get-item function:foo. All attempts succeed in modifying the temporary function object, but the additional property is missing when reassigned to the stored function (either through $function:foo = ... or set-item function:foo ...).
Here are the results of my attempts (all fail):
Setup
$=>function foo { "foo" }
$=>$f = $function:foo
$=>$f = $f | add-member noteproperty bar BARvalue -pass
$=>$f | gm b*
TypeName: System.Management.Automation.ScriptBlock
Name MemberType Definition
---- ---------- ----------
bar NoteProperty System.String bar=BARvalue
#1
$=>set-item function:f $f -force $=>$function:foo | gm b* >
#2
$=>$function:f = $f $=>$function:foo | gm b* >
#3
$=>$f = get-item function:foo
$=>$f | gm
TypeName: System.Management.Automation.FunctionInfo
Name MemberType Definition
---- ---------- ----------
Equals Method System.Boolean Equals(Object obj)
GetHashCode Method System.Int32 GetHashCode()
GetType Method System.Type GetType()
ToString Method System.String ToString()
PSDrive NoteProperty System.Management.Automation.PSDriveInfo PSDrive=Function
PSIsContainer NoteProperty System.Boolean PSIsContainer=False
PSPath NoteProperty System.String PSPath=Microsoft.PowerShell.Core\Function::foo
PSProvider NoteProperty System.Management.Automation.ProviderInfo PSProvider=Microsoft....
CmdletBinding Property System.Boolean CmdletBinding {get;}
CommandType Property System.Management.Automation.CommandTypes CommandType {get;}
DefaultParameterSet Property System.String DefaultParameterSet {get;}
Definition Property System.String Definition {get;}
Description Property System.String Description {get;set;}
Module Property System.Management.Automation.PSModuleInfo Module {get;}
ModuleName Property System.String ModuleName {get;}
Name Property System.String Name {get;}
Options Property System.Management.Automation.ScopedItemOptions Options {get;set;}
Parameters Property System.Collections.Generic.Dictionary`2[[System.String, mscorli...
ParameterSets Property System.Collections.ObjectModel.ReadOnlyCollection`1[[System.Man...
ScriptBlock Property System.Management.Automation.ScriptBlock ScriptBlock {get;}
Visibility Property System.Management.Automation.SessionStateEntryVisibility Visibi...
$=>$f = $f | add-member noteproperty bar barValue -pass
$=>$f | gm b*
TypeName: System.Management.Automation.FunctionInfo
Name MemberType Definition
---- ---------- ----------
bar NoteProperty System.String bar=barValue
$=>set-item function:foo $f
$=>$function:foo | gm b*
>
Not sure what I'm doing wrong. It seems like the properties are being stripped out when reassigned. Is that correct? the defined behavior? I haven't seen any documentation saying that FunctionInfo objects or ScriptBlocks are treated unusually. Is this some esoteric corner of the language?