Latest posts by Michael Pietroforte (see all)
- Author and member of the year 2019 – Why DevOps still doesn't rule the IT world - Wed, Jan 1 2020
- Results of the 4sysops member and author competition in 2018 - Tue, Jan 8 2019
- Why Microsoft is using Windows customers as guinea pigs - Reply to Tim Warner - Tue, Dec 18 2018
In a way, the PowerShell profile is the renaissance of autoexec.bat. Of course, PowerShell profiles are a bit more powerful. You can use a PowerShell profile to configure your aliases, load modules, define functions, or change the font size of your console.
PowerShell host ^
Before I can explain the purpose of the different PowerShell profiles, I have to clarify two concepts: “user” and “host.” Depending on the context, “host” can mean many different things in IT. If you use it together with “user,” you can easily associate it with “computer,” as in user and computer Group Policy settings.
“User” indeed refers to the logged-on user in the context of PowerShell profiles; however, “host” has nothing to do with a computer here. Essentially, a PowerShell host is an interface to the PowerShell engine. Sometimes, you will also hear the term “shell” instead of “host.” You can see the engine as the core of PowerShell where the language with its capabilities sits. For instance, a Windows 8.1 installation comes with two PowerShell engines: the PowerShell 2.0 engine and the PowerShell 4.0 engine. Various host applications exist to work with PowerShell engines.
On a Windows 8.1 computer, two PowerShell hosts are pre-installed: powershell.exe and powershell_ISE.exe. The powershell.exe host starts the PowerShell console, and the PowerShell Integrated Scripting Environment (ISE) runs when you launch powershell_ISE.exe. Both host applications can communicate with the two engines mentioned above. Third-party host applications, such as PowerGUI and PowerShellPlus, also exist as interfaces to Microsoft’s PowerShell engines.
The $Host.Name variable allows you to display the official name of the PowerShell host. We will need these names later when we configure the PowerShell profile. Microsoft’s name for the PowerShell console is “ConsoleHost,” PowerShell ISE goes by the name “Windows PowerShell ISE Host,” PowerGUI is called “PowerGUIScriptEditorHost,” and PowerShellPlus is “PowerShellPlus Host.”
Host name of PowerShellPlus
PowerShell profile variables ^
Each host application allows you to use one or multiple PowerShell profiles, and some hosts have their own profiles. The reason is that not all settings work for every host. For instance, a PowerShell module that allows you to set the font size might not work on every host. Unfortunately, not all hosts play by the same rules when it comes to profiles, as we will see below.
The $Profile variable controls the use of PowerShell profiles. This variable has four properties. Each property refers to a different profile file, as follows:
This means that you can use four different profiles for every host. The variables that contain “AllHosts” refer to profiles that every host will run when you launch its application. Variables with “CurrentHost” refer to profiles that only a particular host will recognize. Thus, the values of CurrentHost variables depend on the host, and the AllHosts variables are host independent.
For instance, this means that the CurrentHost variables of the PowerShell console and PowerShell ISE have different values.
$PsHome refers to C:\Windows\System32\WindowsPowerShell\v1.0, and $Home is the location of the user’s profile (C:\users\username\).
However, PowerShell console and PowerShell ISE have the same AllHosts variables.
|$Profile.AllUsersAllHosts||Console and ISE||$PsHome\Profile.ps1|
|$Profile.CurrentUserAllHosts||Console and ISE||$Home\Documents\WindowsPowerShell\Profile.ps1|
The CurrentUser variables refer to profile files that are stored in your user profile. Hence, settings in these profiles always only affect your own PowerShell environments. By contrast, AllUser variables stand for profiles that are located in a system folder. All settings that you store in these profiles affect every user that logs on to this machine.
PowerShellPlus and PowerShellGUI use the profiles of the PowerShell console. This means that all code that you put in the PowerShell console profiles will be executed by those two hosts. These hosts don’t have their own CurrentHost variables; that is, they don’t use specific profile files. However, it is still possible to use different profile settings for those host applications, as we will see below.
For the sake of completeness, the PowerShell GUI doesn’t know any of the variables mentioned above. It simply loads all PowerShell console profiles. PowerShellPlus knows all variables except $Profile.AllUsersCurrentHost. So, you have another example of how hosts can differ.
PowerShell profile order ^
If you work with multiple profiles, it is theoretically possible for conflicts to exist because each host will execute all four profiles if they are available.For example, if you set a variable with different values in different profiles, the end result could be unexpected.
However, because every host will execute the profiles in the order in which their variables are listed above, the outcome is predictable. The last profile wins. In general, the more specific the realm of a profile is, the higher its rank is. Hence, the profile for the current user and the current host is the profile that always has the last word.
Which profile should you use? ^
So far, everything was quite simple, right? Now comes the difficult part. Which profile should you use, and should you really work with multiple profiles? Who has the choice has the agony! The decision certainly depends on your work environment, but, in the vast majority of cases, I think one profile is enough. Keeping all your PowerShell settings in just one file will minimize the risk of something going wrong, and you always have to edit just one file.
This doesn’t mean that you can’t work with different hosts. I recommend simply using a dedicated section in your profile for each host. For instance, with a simple if-statement in an AllHosts profile, you can ensure that PowerShell ISE configurations are not executed if you launch another host.
if ($Host.Name -eq 'Windows PowerShell ISE Host')
<PowerShell ISE statements>
Most of your settings will work in all hosts anyway, so your host-specific sections will be small.
The question remains of which of the two AllHosts profiles you should use. If you often log on with different user names on the same machine, the AllUser profile will be your choice. But I think most admins always log on with the same account; in that case, I recommend the CurrentUser profile. That way, other users on the same machine don’t have to live with your settings, and, if you work with roaming user profiles, you can always bring your settings with you, no matter on which machine you log on. Thus, in most cases, $Home\Documents\WindowsPowerShell\Profile.ps1 is your choice. In my view, AllUser profiles should only be used in cases where multiple admins want to work with the same pre-defined functions.
Create a profile ^
On a freshly installed Windows machine, none these profile files exist. You can simply create the files and the corresponding folders mentioned above in File Explorer and edit them with the editor of your choice. Of course, you can also do this with PowerShell. If we assume that you follow my advice, you can just paste the little script below to your host application to create your profile.
$myProfile = $Profile.CurrentUserAllHosts
if (-not (test-path $myProfile))
new-item -path $myProfile -type file -force
The script first checks if the profile already exists (test-path); if not, it creates the file (new-item). The force parameter ensures that the corresponding folders will be created as well. In any case, the profile will then be opened in PowerShell ISE.
Note that on a PowerShell console you have to press ENTER twice after you pasted the script.
Also note that the script doesn’t work in PowerShellGUI because this host application doesn’t know this profile variable. So, if you just execute it on a PowerShell console, you are fine. Perhaps you’ll configure a variable or alias in your profile that allows you to quickly edit your profile in the future. If you do, don’t use $Profile; this variable is already set and has the same value as $Profile.CurrentUserCurrentHost.
Which profile do you use? What kind of customizations did you include in your profile?