8
votes

If you implement a custom PowerShell Host with System.Management.Automation (SMA), all of the automatic variables are avaialable, except it seems that $PROFILE is empty. How would one go about recreating it?

Is it always in UserProfile + \Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1? Or do I need to be worried about it being in other places?

To clarify, I only care about CurrentUserCurrentHost profile.

Details

Given this PowerShell script:

Write-Output "_Profiles_" 
Write-Output "CurrentUserCurrentHost = '$($Profile.CurrentUserCurrentHost)'"
Write-Output "CurrentUserAllHosts = '$($Profile.CurrentUserAllHosts)'"
Write-Output "AllUsersCurrentHost = '$($Profile.AllUsersCurrentHost)'"
Write-Output "AllUsersAllHosts = '$($Profile.AllUsersAllHosts)'"

Running it against system PowerShell has the following output:

_Profiles_
CurrentUserCurrentHost = 'C:\Users\rob\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1'
CurrentUserAllHosts = 'C:\User\rob\Documents\WindowsPowerShell\profile.ps1'
AllUsersCurrentHost = 'C:\Windows\System32\WindowsPowerShell\v1.0\Microsoft.PowerShell_profile.ps1'
AllUsersAllHosts = 'C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1'

Running it with a Custom C# PowerShell Host (a System.Management.Automation.Host.PSHost implementation) shows:

_Profiles_
CurrentUserCurrentHost = ''
CurrentUserAllHosts = ''
AllUsersCurrentHost = ''
AllUsersAllHosts = ''

Background

https://github.com/chocolatey/choco/issues/667

This has been tested in PowerShell v3 / System.Managment.Automation (SMA) v3 but it could easily be proven out in other PowerShell versions.

1
It can be in other places. Running from ISE gives "C:\Users\David\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1"David Gardiner
I saw that ISE is different, but I don't really worry about ISE's profile. IMHO the important one is the main PowerShell profile setting.ferventcoder
What about launching the real PowerShell console and asking that to dump out the value? powershell.exe -command "& {``$profile}"David Gardiner
Not a bad idea. Starting up a PowerShell takes a hit though.ferventcoder

1 Answers

1
votes

As a possible fix, this is what I've come up with. However it does mean that $profile is always expected to be in the Documents folder.

var documentsFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments, Environment.SpecialFolderOption.DoNotVerify);
var currentUserCurrentHostProfile = _fileSystem.combine_paths(documentsFolder, "WindowsPowerShell\\Microsoft.PowerShell_profile.ps1");

var profileFix = @"
if ((Test-Path(""{0}"")) -and ($profile -eq $null -or $profile -eq '')) {{
  $global:profile = ""{1}""
}}
".format_with(documentsFolder, currentUserCurrentHostProfile);

pipeline.Commands.Add(new Command(profileFix, isScript: true, useLocalScope: false));

This is done this way due to special accounts like LocalSystem that would not have a profile folder.

Note: .format_with is a string formatter, so the {{ and }} you see will be converted to { and } when it finishes the string formatting.