As a user, I want to be able to override the location where module analysis cache, startup profile data, telemetry.uuid, etc. are created by PowerShell, so that a more appropriate path can be configured when needed. The location PowerShell selects now causes a problem in Azure Functions: https://github.com/Azure/azure-functions-powershell-worker/issues/365.
Platform.CacheDirectory
is an internal variable initialized here (Windows):
https://github.com/PowerShell/PowerShell/blob/a34d0f3e808659b0c07b8fdac83aaae1dae43c21/src/System.Management.Automation/CoreCLR/CorePsPlatform.cs#L149
The problem is that the Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
call returns an empty string in certain environments (such as Azure App Service sandbox). As a result, PowerShell creates (of fails to create) files at an unexpected location (see https://github.com/Azure/azure-functions-powershell-worker/issues/365 for more details).
This problem can be avoided if PowerShell either automatically selected a different location, or allowed us override the default location.
Implementation ideas:
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
, look for an environment variable with a certain name (PSCacheDirectory
? PSOverrideCacheDirectory
? we need to find a good name). If the variable is present, use it. Otherwise, use the default location.Platform.CacheDirectory
is a static variable, and it is initialized and used early. Also, there could be scenarios that require using pwsh.exe anyway.@AnatoliB PowerShell already will use a path defined in env var PSModuleAnalysisCachePath
if it exists, otherwise it uses the default path
@SteveL-MSFT the only place I can find that documentation is here: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_windows_powershell_5.1?view=powershell-5.1
I think we might want to put that information in a more accessible place; that's certainly not where I'd be looking for information on PowerShell v6 and up.
@vexx32 it should probably be documented here: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_environment_variables?view=powershell-7#environment-variables-that-store-preferences. I'll submit a PR.
@SteveL-MSFT I see, thank you. From looking at the code, though, my impression is that it applies literally to the module analysis cache only. There are other files (e.g. telemetry.uuid
, StartupProfileData*
) still created under Platform.CacheDirectory. Can/should we move them, too?
@AnatoliB yes, that env var is literally just the for the module analysis cache. We should probably have a setting in powershell.config.json to set that path if defined. In the case that it's not defined in powershell.config.json and that API call returns an empty string, perhaps we should use the temp path?
@SteveL-MSFT Yes, an optional setting in powershell.config.json and the fallback to temp works for me.
@vexx32 doc PR here: https://github.com/MicrosoftDocs/PowerShell-Docs/pull/5479
Try setting the $ENV:TMP environment variable:
PS[1] (11) > $env:tmp = "c:\temp" PS[1] (12) > [io.path]::GetTempFileName()
c:\temp\tmpB23F.tmp
PS[1] (13) >
Should we move PSModuleAnalysisCachePath to config file too for consistency?
Most helpful comment
@vexx32 doc PR here: https://github.com/MicrosoftDocs/PowerShell-Docs/pull/5479