Given code such as this MRE:
function Get-One {1}
Update-TypeData -TypeName 'Demo' -MemberType 'ScriptProperty' -MemberName 'Test1' -Value {Get-Date}
Update-TypeData -TypeName 'Demo' -MemberType 'ScriptProperty' -MemberName 'Test2' -Value {Get-One}
$example = [PSCustomObject]@{PSTypeName = 'Demo'}
$example
If I invoke it as pwsh -File '.\Demo.ps1' then all works as you'd expect / I get this output:
Test1 Test2
----- -----
2021-04-17 21:35:55 1
However, if I invoke the same command as pwsh -Command '.\Demo.ps1' I get this (i.e. Test2 is blank); whilst I'd expect to get the same as the above:
Test1 Test2
----- -----
2021-04-17 21:35:55
i.e. When I invoke via the -Command parameter, the ScriptProperty can't access cmdlets/functions defined within the script itself; though can access standard ones (e.g. Get-Date).
I'd assume this was a bug; only the same behaviour's seem in both PWSH and PowerShell; which makes that a little less likely.
Is this a bug; or am I missing something in my understanding.
The difference in behavior is explained by the fact that
-Fileimplicitly dot-sources the target script file, which means that it runs in the global scope.Typically, this detail is of little consequence (except if you also pass
-NoExitto request staying in the session after the script terminates).Here, it makes the crucial difference:
With
-File,Get-Oneends up defined in the global scope, which is the prerequisite for theScriptProperty-defining{ Get-One }script block being able to see it.By contrast, running the script file with
-Commanddoes not dot-source it, making theGet-Onecommand effectively invisible to the{ Get-One }script block - and errors occurring inside suchScriptProperty-defining script blocks are quietly ignored.There are two solutions:
Either: Explicitly define your
Get-Onefunction as global:Or: When using
-Command, explicitly dot-source the script: