A Cross-Platform Technique for Obtaining Username with PowerShell Core

Problem

While developing a PowerShell Core script I required a means of obtaining the username of the account under which it was run. Since the script was intended to be used on both Windows and GNU/Linux I sought a technique that would work on both platforms.

NB: At the time of writing the script I was using PowerShell 6.1.0 on Windows 10 and Ubuntu Server 16.04 LTS.

Investigation

My initial thought was to use an environment variable within PowerShell’s Env: drive but I soon discovered that the variable names differed between Windows ($env:USERNAME) and Ubuntu ($env:USER). Upon examining the PowerShell Core source code it became evident that PowerShell itself places relatively few items into the Env: drive and that its mostly comprised of platform specific variables, hence the inconsistency in naming between Windows and Ubuntu (behind the scenes, PowerShell does this by calling the .Net method Environment.GetEnvironmentVariables).

I briefly considered writing a function to extract the username from the appropriate environment variable based on whether the platform was Windows or GNU/Linux but this became less attractive when I realised that if the script was run as a cron job on Ubuntu it did not have access to $env:USER (this is a result of cron’s design), so such a function would have to take that into consideration.

Workaround - whoami

In recent years Windows has shipped with a whoami binary, whereas in older versions it was typically available as part of the operating system’s resource kit. On GNU/Linux systems it is part of the GNU coreutils.

Whilst this delivered the desired result (at least on Windows 10 and Ubuntu) I disliked the dependency on the presence of a third party binary, hence I considered this to be a workaround rather than a solution.

Solution

I proceeded to open an issue on the PowerShell Core Github repository where I was advised to use [Environment]::UserName. This proved to work well and was the solution I opted to use.

Further Research

I was curious as to how PowerShell core obtained username for use in transcript file prologues, EG:

**********************
PowerShell transcript start
Start time: 20180919020002
Username: SVR01\backupuser

Upon inspecting the PowerShell Core Github repository I found that it also used the UserName property of the .Net Environment class. Start-Transcript (PowerShell/src/Microsoft.PowerShell.ConsoleHost/host/msh/StartTranscriptCmdlet.cs) calls StartTranscribing (PowerShell/src/System.Management.Automation/namespaces/EnvironmentProvider.cs), which in turn calls LogTranscriptHeader which populates the username with Environment.UserDomainName + "\\" + Environment.UserName unless PowerShell remoting is involved in which case the username is obtained from a Powershell automatic variable $PSSenderInfo.UserInfo.Identity.Name.

Comments

Leaving comments has been disabled for this post.

Copyright © 2018 - 2022 thecliguy.co.uk
For details, see Licences and Copyright