Powershell: New-TemporaryFile not available when calling powershell.exe from PowerShell 7 through cmd.exe or CreateProcess

Created on 15 Nov 2020  路  7Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

PS C:\test> cmd.exe /c "powershell.exe -command ""New-TemporaryFile"""

Expected behavior

Command to success and return a temporary file path

Actual behavior

Error of "The term 'New-TemporaryFile' is not recognized as the name of a cmdlet, function, script file..."

Environment data

PowerShell 7.1 on Windows 10 x64 version 2004 (for pwsh.exe)
Windows PowerShell 5.1 (for powershell.exe)

Note

When callingPS C:\test> powershell.exe -command "New-TemporaryFile" the command works as expected. It seems that when passing through cmd.exe or ::CreateProcess() the Microsoft.PowerShell.Utility assembly somehow is loaded differently and a few commands, including New-TemporaryFile end up missing.

New-TemporaryFile is available both on PowerShell 7 and on Windows PowerShell 5.1 so this is quite an interesting behavior

Issue-Question WG-Engine

All 7 comments

That _is_ pretty odd! I don't think there's much, if anything, that PS 7 can do to rectify the behaviour you're seeing in Windows PowerShell.

WinPS is not being developed any further, so I don't think it's likely that whatever is causing this in Windows PowerShell will be fixed.

It's a moot point, as @vexx32 states, but the bug is related to New-TemporaryFile being implemented as a _function_ in Windows PowerShell.

In other words: it seems that all commands returned by Get-Command -Module Microsoft.PowerShell.Utility -Type function are affected in Windows PowerShell, and potentially all other commands implemented as _functions_.

In PowerShell Core, all former Microsoft.PowerShell.Utility _functions_ have been re-implemented as _cmdlets_, so the problem by definition doesn't arise there.

That said, in PowerShell Core there still are _functions_ among the in-box modules, as
Get-Command -Type function | where Source -like 'Microsoft.*' indicates.

Calling such a function via the PowerShell _Core_ CLI seems to work fine, fortunately:

pwsh -noprofile -c 'Compress-Archive -?'

I guess it is again PSModulePath issue. If we run _directly_ Windows PowerShell we modify PSModulePath as needed, otherwise we don't.

I got myself confused earlier: I actually only see the problem in 7.1.0-rc.2, and no longer in 7.1.0, in combination with Windows PowerShell v5.1.19041.610.

Also, unless the following test is flawed, the problem does _not_ appear to be related to $env:PSModulePath, because I get equivalent results in both versions:

PSCore> cmd /c powershell.exe -nop -command `$env:PSModulePath -split "';'"

@mklement0 I think you were on the right track before. When I run your PSModulePath query command on 7.1.0 with the cmd.exe proxy I get %ProgramFiles%\PowerShell\Modules and %ProgramFiles%\PowerShell\7\Modules on top of the paths returned _without_ going through the cmd.exe proxy.

Looks like they have precedence over the others, when loading Microsoft.PowerShell.Utility.

When running your variant, with manually setting PSModulePath, I get no errors, New-TemporaryFile is called successfully.

Interesting, @hero101111; your experience is consistent with @iSazonov's explanation, but the strange thing is that the despite the presence of these extra, PS Core-only folders, the command succeeds for me in 7.1.0 - the only notable difference is that my installation is in a custom location inside my $env:USERPROFILE folder.

I just tried installing PowerShell 7.1.0 in $env:USERPROFILE and it still fails to locate New-TemporaryFile. Tried it also on a second Windows 10 version 2004 (Windows PowerShell 5.1.19041) machine as well. Seems like there's a different factor at play here.

Was this page helpful?
0 / 5 - 0 ratings