Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mwallner/767916771203b9388bf17e75e9ddc77e to your computer and use it in GitHub Desktop.
Save mwallner/767916771203b9388bf17e75e9ddc77e to your computer and use it in GitHub Desktop.
Fixup PSModulePath in PowerShell Desktop when called indirectly called from pwsh
#region fix PSModulePath in PowerShell Desktop when indirectly called from pwsh
function Invoke-FixPSModulePathForPowerShellDesktopWhenIndirectlyCalledFromPwsh {
if (($env:PSModulePath -split ';') -contains "${env:ProgramFiles}\PowerShell\Modules") {
# need to rip out the good bits for pwsh -> something -> powershell call chain
# chocolateyInstall\helpers\functions\Get-EnvironmentVariable.ps1
function Get-EnvironmentVariable {
<#
.SYNOPSIS
Gets an Environment Variable.
.DESCRIPTION
This will will get an environment variable based on the variable name
and scope while accounting whether to expand the variable or not
(e.g.: `%TEMP%`-> `C:\User\Username\AppData\Local\Temp`).
.NOTES
This helper reduces the number of lines one would have to write to get
environment variables, mainly when not expanding the variables is a
must.
.PARAMETER Name
The environment variable you want to get the value from.
.PARAMETER Scope
The environment variable target scope. This is `Process`, `User`, or
`Machine`.
.PARAMETER PreserveVariables
A switch parameter stating whether you want to expand the variables or
not. Defaults to false.
.PARAMETER IgnoredArguments
Allows splatting with arguments that do not apply. Do not use directly.
.EXAMPLE
Get-EnvironmentVariable -Name 'TEMP' -Scope User -PreserveVariables
.EXAMPLE
Get-EnvironmentVariable -Name 'PATH' -Scope Machine
.LINK
Get-EnvironmentVariableNames
.LINK
Set-EnvironmentVariable
#>
[CmdletBinding()]
[OutputType([string])]
param(
[Parameter(Mandatory = $true)][string] $Name,
[Parameter(Mandatory = $true)][System.EnvironmentVariableTarget] $Scope,
[Parameter(Mandatory = $false)][switch] $PreserveVariables = $false,
[parameter(ValueFromRemainingArguments = $true)][Object[]] $ignoredArguments
)
# Do not log function call, it may expose variable names
## Called from chocolateysetup.psm1 - wrap any Write-Host in try/catch
[string] $MACHINE_ENVIRONMENT_REGISTRY_KEY_NAME = "SYSTEM\CurrentControlSet\Control\Session Manager\Environment\";
[Microsoft.Win32.RegistryKey] $win32RegistryKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey($MACHINE_ENVIRONMENT_REGISTRY_KEY_NAME)
if ($Scope -eq [System.EnvironmentVariableTarget]::User) {
[string] $USER_ENVIRONMENT_REGISTRY_KEY_NAME = "Environment";
[Microsoft.Win32.RegistryKey] $win32RegistryKey = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey($USER_ENVIRONMENT_REGISTRY_KEY_NAME)
}
elseif ($Scope -eq [System.EnvironmentVariableTarget]::Process) {
return [Environment]::GetEnvironmentVariable($Name, $Scope)
}
[Microsoft.Win32.RegistryValueOptions] $registryValueOptions = [Microsoft.Win32.RegistryValueOptions]::None
if ($PreserveVariables) {
Write-Verbose "Choosing not to expand environment names"
$registryValueOptions = [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames
}
[string] $environmentVariableValue = [string]::Empty
try {
#Write-Verbose "Getting environment variable $Name"
if ($win32RegistryKey -ne $null) {
# Some versions of Windows do not have HKCU:\Environment
$environmentVariableValue = $win32RegistryKey.GetValue($Name, [string]::Empty, $registryValueOptions)
}
}
catch {
Write-Debug "Unable to retrieve the $Name environment variable. Details: $_"
}
finally {
if ($win32RegistryKey -ne $null) {
$win32RegistryKey.Close()
}
}
if ($environmentVariableValue -eq $null -or $environmentVariableValue -eq '') {
$environmentVariableValue = [Environment]::GetEnvironmentVariable($Name, $Scope)
}
return $environmentVariableValue
}
$machineVar = Get-EnvironmentVariable -Name 'PSModulePath' -Scope 'Machine'
$userVar = Get-EnvironmentVariable -Name 'PSModulePath' -Scope 'User'
$env:PSModulePath = "$userVar;$machineVar"
}
}
#endregion fix PSModulePath in PowerShell Desktop when indirectly called from pwsh
if ($PSVersionTable.PSEdition -eq 'Desktop') {
Invoke-FixPSModulePathForPowerShellDesktopWhenIndirectlyCalledFromPwsh
}
@mwallner
Copy link
Author

mwallner commented Jul 4, 2024

... or you hijack CrateProcessW ... PowerShell/PowerShell#20804 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment