Powershell: Make the location where caching files are stored customizable

Created on 24 Feb 2020  路  9Comments  路  Source: PowerShell/PowerShell

Summary of the new feature/enhancement

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.

Proposed technical implementation details

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:

  • Instead of just invoking 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.
  • Alternatively, give just _PS SDK users_ an API to set this location. This would be enough to mitigate the issue with Azure Functions. Implementing this would be somewhat challenging though, since Platform.CacheDirectory is a static variable, and it is initialized and used early. Also, there could be scenarios that require using pwsh.exe anyway.
Issue-Enhancement WG-Engine

Most helpful comment

All 9 comments

@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.

@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.

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?

Was this page helpful?
0 / 5 - 0 ratings