Get arguments passed to powershell.exe

Viewed 770

Is there a way to determine, in a Profile script, what arguments were passed to the powershell executable?

Use-case

I'd like to check whether the WorkingDirectory parameter was set, before overriding it with my own cd in my user profile.

Attempts

I've made a few helpless attempts to get variable values from within the profile script, with no luck. None of them seem to give me any information about whether pwsh.exe was invoked with a -wd parameter or not:

echo $PSBoundParameters
echo $ArgumentList
echo (Get-Variable MyInvocation -Scope 0).Value;
2 Answers

To inspect PowerShell's own invocation command line, you can use:

  • [Environment]::CommandLine (single string)

  • or [Environment]::GetCommandLineArgs() (array of arguments, including the executable as the first argument).

These techniques also work on Unix-like platforms.

Caveat: As of PowerShell Core 7 (.NET Core 3.1), it is pwsh.dll, not pwsh[.exe] that is reported as the executable.


To check in your $PROFILE file if a working directory was specified on startup could look like this, though do note that the solution is not foolproof:

$workingDirSpecified =
  ($PSVersionTable.PSEdition -ne 'Desktop' -and
   [Environment]::GetCommandLineArgs() -match '^-(WorkingDirectory|wd|wo|wor|work|worki|workin|working|workingd|workingdi|workingdir|workingdire|workingdirec|workingdirect|workingdirecto|workingdirector)') -or
  [Environment]::CommandLine -match
    '\b(Set-Location|sl|cd|chdir|Push-Location|pushd|pul)\b'
  • In PowerShell Core, a working directory may have been specified with the -WorkingDirectory / -wd parameter (which isn't supported in Windows PowerShell); e.g.,
    pwsh -WorkingDirectory /

    • Note: Given that it is sufficient to specify only a prefix of a parameter's name, as long as that prefix uniquely identifies the parameter, it is necessary to also test for wo, wor, work, ...
  • In both PowerShell Core and Windows PowerShell, the working directory may have been set with a cmdlet call (possibly via a built-in alias) as part of a -c / -Command argument (e.g.,
    pwsh -NoExit -c "Set-Location /")

    • Note: In this scenario, unlike with -WorkingDirectory, the working directory has not yet been changed at the time the $PROFILE file is loaded.

It is possible, but unlikely for the above to yield false positives; to use a contrived example:
pwsh -NoExit -c "'Set-Location inside a string literal'"

How about (powershell.exe or pwsh.exe?):

get-ciminstance win32_process | where name -match 'powershell.exe|pwsh.exe' | 
  select name,commandline
Related