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
-File
implicitly 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
-NoExit
to request staying in the session after the script terminates).Here, it makes the crucial difference:
With
-File
,Get-One
ends 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
-Command
does not dot-source it, making theGet-One
command 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-One
function as global:Or: When using
-Command
, explicitly dot-source the script: