Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I recreate PowerShell $profile variable? It's empty in a custom Host

Tags:

c#

powershell

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.

like image 590
ferventcoder Avatar asked Mar 26 '16 18:03

ferventcoder


People also ask

How do you initialize a variable in PowerShell?

To create a new variable, use an assignment statement to assign a value to the variable. You don't have to declare the variable before using it. The default value of all variables is $null . To get a list of all the variables in your PowerShell session, type Get-Variable .

How do I refresh a PowerShell profile?

If you want to globally refresh your profile from a script, you will have to run that script "dot-sourced". When you run your script, all the profile script runs in a "script" scope and will not modify your "global" scope.


1 Answers

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.

like image 177
ferventcoder Avatar answered Oct 20 '22 18:10

ferventcoder