1

In a PowerShell console, the $PROFILE variable is a [string]. Why is it not a [string] in VS Code?

PS C:\> $PROFILE
C:\Users\pwatson2\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
PS C:\> $PROFILE.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

PS C:\> $PSVersionTable.PSVersion.ToString()
7.1.5

In the VS Code terminal it is a [PSCustomObject].

[DBG]: PS C:\> $PROFILE

AllUsersAllHosts                          AllUsersCurrentHost                                        CurrentUserAllHosts
----------------                          -------------------                                        -------------------
C:\Program Files\PowerShell\7\profile.ps1 C:\Program Files\PowerShell\7\Microsoft.VSCode_profile.ps1 C:\Users\pwatson2\Docu…
[DBG]: PS C:\> $PROFILE.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    PSCustomObject                           System.Object

[DBG]: PS C:\> $PSVersionTable.PSVersion.ToString()
7.1.5

UPDATE:

<dropped for clarity>

UPDATE 2:

Here is the output in the TERMINAL window when VSCode PowerShell extension starts. The profile scripts are shown below. When the CurrentUserAllHosts script is run, $PROFILE is NULL. None of these scripts set the value of $PROFILE.

There are two (2) problems.

When one of the non-user profile scripts is invoked (probably AllUsersAllHosts), it appears that the path to the script does not use appropriately placed QUOTATION MARK characters.

When the CurrentUserAllHosts script is run, $PROFILE is NULL.

=====> PowerShell Preview Integrated Console v2021.10.3 <=====

C:\Program: The term 'C:\Program' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Running profile C:\Users\lit\Documents\PowerShell\profile.ps1
PROFILE is NULL
PS C:\Users\lit>

When the TERMINAL command prompt becomes available, the PROFILE variable now contains the following.

PS C:\Users\lit> $PROFILE | Format-List -Property *

AllUsersAllHosts       : C:\Program Files\PowerShell\7\profile.ps1
AllUsersCurrentHost    : C:\Program Files\PowerShell\7\Microsoft.VSCode_profile.ps1
CurrentUserAllHosts    : C:\Users\lit\Documents\PowerShell\profile.ps1
CurrentUserCurrentHost : C:\Users\lit\Documents\PowerShell\Microsoft.VSCode_profile.ps1

These are the profile scripts. Note that both of the Microsoft.VSCode_profile.ps1 files do not exist.

PS C:\> Get-Content -Path 'C:\Program Files\PowerShell\7\profile.ps1'
$s = $($MyInvocation.MyCommand.Source)
Write-Host "Running profile $s"
if ($null -eq $PROFILE) {
    Write-Host "PROFILE is NULL"
} else {
    Write-Host "PROFILE is of type $($PROFILE.GetType())"

    $scope = $PROFILE |
        Get-Member -Type NoteProperty |
        Where-Object { $_.Definition.EndsWith($s) } |
        ForEach-Object { $_.Name }
    Write-Host "$($PSVersionTable.PSVersion.ToString()) $scope @ $($MyInvocation.MyCommand.Source)"
}
PS C:\> Get-Content -Path 'C:\Program Files\PowerShell\7\Microsoft.VSCode_profile.ps1'
Get-Content: Cannot find path 'C:\Program Files\PowerShell\7\Microsoft.VSCode_profile.ps1' because it does not exist.
PS C:\> Get-Content -Path 'C:\Users\lit\Documents\PowerShell\profile.ps1'
$s = $($MyInvocation.MyCommand.Source)
Write-Host "Running profile $s"
if ($null -eq $PROFILE) {
    Write-Host "PROFILE is NULL"
} else {
    Write-Host "PROFILE is of type $($PROFILE.GetType())"

    $scope = $PROFILE |
        Get-Member -Type NoteProperty |
        Where-Object { $_.Definition.EndsWith($s) } |
        ForEach-Object { $_.Name }
    Write-Host "$($PSVersionTable.PSVersion.ToString()) $scope @ $($MyInvocation.MyCommand.Source)"
}
PS C:\> Get-Content -Path 'C:\Users\lit\Documents\PowerShell\Microsoft.VSCode_profile.ps1'
Get-Content: Cannot find path 'C:\Users\lit\Documents\PowerShell\Microsoft.VSCode_profile.ps1' because it does not exist.
PS C:\>
lit
  • 14,456
  • 10
  • 65
  • 119
  • That is odd. Same results for me if I use the "GetType()" command, however when I use the method suggested on the MSDN docs in my PS console: "$PROFILE | Get-Member -Type NoteProperty", it shows that $PROFILE is an object with multiple string properties. – diopside Nov 01 '21 at 18:02
  • scratch that. It seems Get-Member always returns a PSCustomObject. https://thomasrayner.ca/the-difference-between-get-member-and-gettype-in-powershell/ Still doesn't explain the VSCode incongruency though – diopside Nov 01 '21 at 18:10
  • I don't see this problem. Perhaps something earlier in your session or in your `$PROFILE` file accidentally caused the `$PROFILE` variable to get overwritten? Here's how you can provoke the symptom: `$PROFILE = $PROFILE | Select-Object * -ExcludeProperty Length` – mklement0 Nov 01 '21 at 19:09
  • 2
    @diopside, `$PROFILE | Get-Member` (no arguments) shows the type name at the top, followed by the type's member. Normally, `$PROFILE` contains a _string_ that is _also decorated with NoteProperty members_, which is unusual (they are what shows with your `$PROFILE | Get-Member -Type NoteProperty` command). See [this answer](https://stackoverflow.com/a/55561454/45375) for details. – mklement0 Nov 01 '21 at 20:35
  • @mklement0, I see the NoteProperty members on the string. That makes me wonder how it can be called a [string] type when it has additional members that are not part of a [string]. I think you helped me with these some time ago. Now, it appears that when a `Microsoft.VSCode_profile.ps1 script is run, $PROFILE is null. Am I looking at this incorrectly? – lit Nov 01 '21 at 20:40
  • 2
    another day, another powershell peculiarity! thanks for that clarification – diopside Nov 01 '21 at 20:41
  • @lit, It is unusual and not recommended to decorate a `[string]` instance with NoteProperty members, but it is technically _possible_ (via an invisible `[psobject]` wrapper), and such a decorated string is stored in the automatic `$PROFILE` variable (it is an awkward solution that may be a historical wart). Normally, these NoteProperty members do not get in the way and the variable still behaves like a regular string. User code should never _set_ `$PROFILE`, so if that happens you should locate where that happens and remove it. – mklement0 Nov 01 '21 at 20:48
  • @mklement0, it appears that when Microsoft.VSCode_profile.ps1 is invoked, that $PROFILE is null. Is the best place for an issue like that on Github? – lit Nov 01 '21 at 21:25
  • @lit, I'd first check the content of that file and, if it exists, try without it (e.g. by temporarily renaming it). – mklement0 Nov 01 '21 at 22:15
  • @mklement0, which file? `profile.ps1` and `Microsoft.VSCode_profile.ps1` are being invoked when the PowerShell extension starts. – lit Nov 01 '21 at 22:22
  • @lit, yes, loading profiles is an all-or-nothing proposition: unless suppressed, such as with `-noprofile` in CLI calls, _all_ profiles are loaded. So I would temporarily rename them _all_ to see if the problem persists, and then re-enable them one by one in order to identify the culprit. Or are you saying that that if _none_ of the files listed in `$PROFILE | Select *host*` exist, the `$PROFILE` variable still ends up misdefined? – mklement0 Nov 01 '21 at 22:28
  • 1
    This is issue https://github.com/PowerShell/vscode-powershell/issues/3650#issuecomment-954557385 – lit Nov 03 '21 at 21:00
  • 1
    I’m voting to close this question because issue is acknowledged on Github for PowerShell VSCode extension. – lit Nov 03 '21 at 21:01
  • I'm glad you found the problem, @lit. I didn't see the symptom, because it apparently only affects a _preview_ version of the PowerShell extension, and the problem will likely be fixed in the next _stable_ version. I now see that your sample output _implies_ the fact that you were using a preview version, but in general I suggest making that fact explicit in questions. – mklement0 Nov 07 '21 at 18:58
  • 1
    @mklement0, yes, the preview version has already been patched and delivered. Seems to be working well. I have forgotten why I had to move to the preview version. I needed something that the GA version did not do correctly. The output of the extension startup, `=====> PowerShell Preview Integrated Console v2021.10.3 <=====` explicitly states that it is the preview version. Yes, that was in the UPDATE: section. https://github.com/PowerShell/vscode-powershell/issues/3662 – lit Nov 07 '21 at 21:35
  • Thanks, @lit. I did _eventually_ notice the `Preview` in `=====> PowerShell Preview Integrated Console v2021.10.3 <=====`, but my previous comment was suggesting that it's better to also call out the fact that a preview version is used _explicitly_. – mklement0 Nov 07 '21 at 21:40

1 Answers1

0

Just replace...

"$s = $($MyInvocation.MyCommand.Source)"

with... "$s = $PROFILE"

Heyvoon
  • 71
  • 2
  • 11