You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Provide a platform-agnostic way to determine the temp. directory, e.g., via an automatic variable. #4216
lukeb1961: That indeed yields the platform-specific temporary directory, but it has an unwanted side effect: New-TemporaryFile invariably creates the file whose [System.IO.FileInfo] representation it outputs.
In other words: every time you execute (New-TemporaryFile).DirectoryName, you leave an unused temporary file behind.
Additionally, it's a computationally expensive approach.
Liturgist: $Env:TMP is not an option, because it is ill-advised to either (a) have PowerShell automatically defineenvironment variables or (b) pretend that non-existent environment variables exist.
An automatic PowerShell variable such as $TMP is an option, however, although the thing to keep in mind is that retroactively introducing automatic variables is technically a breaking change.
If we went the variable route, it would have to be something like $interop:TEMP to avoid name collision. A variable is probably easier to use in scripts than an API although we can certainly support both.
In #3571 I suggested other variables in addition to TEMP
On a related note, I think a separate namespace for all preference variables would be beneficial as well, such as $pspref:
The caveat is that even though collisions are far less likely than with unqualified variable names, someone could have done something like the following:
Since the term path is ambiguous (even though it is used in the .NET API to refer to a directory path in this case), my preference would be Get-TemporaryDirectory, and I certainly wouldn't mind having such a cmdlet.
That said, a cmdlet is a bit heavy-handed for something that returns a single piece of information with no variations in functionality.
Consider the existing Get-Host / $Host duo: Do you ever find yourself using Get-Host instead of $Host?
Thank you for curating the issues, Michael Klement.
It seems that the tradition of a tmp/temp directory is that every program can us it in whatever way it wants. That works until name collision or there are multiple instances of the same program. In the first case, the applications must choose different names. In the second, the application may identify its files by including unique information such as its PID in the filename.
(a) I fully agree that with guaranteed uniqueness, the application should not care about where a temporary file or directory is located or the name.
A constraint should be that it is possible to locate post-mortem the temporary files and directories to enable anomaly remediation (finding and fixing bugs). Does this suggest that automatic temp cleanup should be a preference setting?
The suggestion of -NamePrefix was based on an application being able to identify its own temprrary files in a single pool. Although guaranteed uniqueness obviates this as a requirement, the developer may find comfort in recognizing foo_xxxx.tmp, bar_xxxx.tmp, bosh_xxxx.tmp, and others when mutiple temporary files are in use.
I agree that if we have New-TemporaryFile that we should have New-TemporaryDirectory.
Reacted by Michael Klement, Rain Sallow (/u/ta11ow) and Marc
Certainly TEMP: doesn't solve the unique temp folder that New-TemporaryDirectory would solve and the two are orthogonal. Uniqueness is certainly useful particularly if you have multiple processes or even runspaces, but that deviates from what this original issue intended.
Steve Lee (@SteveL-MSFT) - Ok. I do not see a Temp: drive from Get-PSDrive in 6.2.1. Am I looking in the wrong place, or when might the Temp: drive become available? #3442 appears to show Waiting - DotNetCore.
Will the Temp: drive be global for the system in the same way a /tmp on *NIX systems is currently?
Will there be a New-TemporaryDirectory to be orthogonal with New-TemporaryFile?
Liturgist It was an experimental feature. Now it is in 7.0. You can download daily build and find it there. It is "global" in PowerShell session.
No immediate plans exist to implement New-TemporaryDirectory - you can discuss in #3442.
TEMP: is a PowerShell-only drive (you can list them with Get-PSDrive) and such drives aren't visible to the outside world, including .NET
You must translate PS-drive-based paths to their underlying "native" filesystem paths, which is what Convert-Path is for.
Note that there's another pitfall associated with passing filesystem paths to .NET methods (though not to external programs): .NET typically sees a different working directory than PowerShell, so that passing relative paths typically doesn't work as intended - it is best to pass full paths always, which Convert-Path can also help with.
In short: it's good to form a habit of passing filesystem paths to .NET methods via Convert-Path -LiteralPath.
If you stay in the realm of PowerShell, you won't face that problem; for instance, you could use Expand-Archive.
Activity
lukeb1961 commentedon Jul 11, 2017
what about something like: (New-TemporaryFile).DirectoryName
mklement0 commentedon Jul 11, 2017
lukeb1961: That indeed yields the platform-specific temporary directory, but it has an unwanted side effect:
New-TemporaryFileinvariably creates the file whose[System.IO.FileInfo]representation it outputs.In other words: every time you execute
(New-TemporaryFile).DirectoryName, you leave an unused temporary file behind.Additionally, it's a computationally expensive approach.
iSazonov commentedon Jul 11, 2017
We've had discussed this in a nutshell. Thank you for opening the Issue.
Internally we already have "TemporaryDirectory", just "GetTemporaryDirectory()" and "CreateTemporaryDirectory()". We could make it public.
Liturgist commentedon Jul 14, 2017
How about going with $Env:TMP on all platforms? That is not quite like Windows, Mac, or Linux. No turf war.
mklement0 commentedon Jul 14, 2017
Liturgist:
$Env:TMPis not an option, because it is ill-advised to either (a) have PowerShell automatically define environment variables or (b) pretend that non-existent environment variables exist.An automatic PowerShell variable such as
$TMPis an option, however, although the thing to keep in mind is that retroactively introducing automatic variables is technically a breaking change.SteveL-MSFT commentedon Jul 14, 2017
If we went the variable route, it would have to be something like $interop:TEMP to avoid name collision. A variable is probably easier to use in scripts than an API although we can certainly support both.
In #3571 I suggested other variables in addition to TEMP
mklement0 commentedon Jul 14, 2017
Steve Lee (@SteveL-MSFT):
Good point; an
$interop:namespace is indeed a way to avoid collisions.If we take a step back: If we want PowerShell to become the lingua franca of the shell world, do we really want to frame things as "interop"?
How about trusting PowerShell's automatic variables to Do the Right Thing(TM) generically, which would call for a namespace such as
$ps:?SteveL-MSFT commentedon Jul 14, 2017
Michael Klement (@mklement0) the
$ps:prefix/namespace has been proposed before. It would be nice if we had used that from the beginning :)Personally, I prefer
$ps:for exactly your reasoning. Perhaps this can be a discussion point at the next Community Call.cc @PowerShell/powershell-committee
mklement0 commentedon Jul 15, 2017
I'm glad to hear it, Steve Lee (@SteveL-MSFT).
On a related note, I think a separate namespace for all preference variables would be beneficial as well, such as
$pspref:The caveat is that even though collisions are far less likely than with unqualified variable names, someone could have done something like the following:
iSazonov commentedon Jul 15, 2017
Why we cannot use
[system.io.path]::GetTempPath()?https://github.com/dotnet/coreclr/blob/6ba74dc2a7194f8d6c86c3aeab572a074ef645c8/src/mscorlib/shared/System/IO/Path.Unix.cs#L153
https://github.com/dotnet/coreclr/blob/6ba74dc2a7194f8d6c86c3aeab572a074ef645c8/src/mscorlib/shared/System/IO/Path.Windows.cs#L94
mklement0 commentedon Jul 15, 2017
Ilya (@iSazonov):
That works, but it is both hard to remember and cumbersome to type.
Good to know as a workaround, though.
iSazonov commentedon Jul 16, 2017
If we have
New-TemporaryFileusers expectGet-TemporaryPathofGet-TemporaryDirectory.mklement0 commentedon Jul 16, 2017
Ilya (@iSazonov):
Since the term path is ambiguous (even though it is used in the .NET API to refer to a directory path in this case), my preference would be
Get-TemporaryDirectory, and I certainly wouldn't mind having such a cmdlet.That said, a cmdlet is a bit heavy-handed for something that returns a single piece of information with no variations in functionality.
Consider the existing
Get-Host/$Hostduo: Do you ever find yourself usingGet-Hostinstead of$Host?49 remaining items
Liturgist commentedon Jan 19, 2019
Thank you for curating the issues, Michael Klement.
It seems that the tradition of a tmp/temp directory is that every program can us it in whatever way it wants. That works until name collision or there are multiple instances of the same program. In the first case, the applications must choose different names. In the second, the application may identify its files by including unique information such as its PID in the filename.
(a) I fully agree that with guaranteed uniqueness, the application should not care about where a temporary file or directory is located or the name.
A constraint should be that it is possible to locate post-mortem the temporary files and directories to enable anomaly remediation (finding and fixing bugs). Does this suggest that automatic temp cleanup should be a preference setting?
The suggestion of -NamePrefix was based on an application being able to identify its own temprrary files in a single pool. Although guaranteed uniqueness obviates this as a requirement, the developer may find comfort in recognizing foo_xxxx.tmp, bar_xxxx.tmp, bosh_xxxx.tmp, and others when mutiple temporary files are in use.
I agree that if we have New-TemporaryFile that we should have New-TemporaryDirectory.
SteveL-MSFT commentedon Jan 19, 2019
Certainly
TEMP:doesn't solve the unique temp folder thatNew-TemporaryDirectorywould solve and the two are orthogonal. Uniqueness is certainly useful particularly if you have multiple processes or even runspaces, but that deviates from what this original issue intended.Liturgist commentedon Jun 13, 2019
What was the result of this discussion?
SteveL-MSFT commentedon Jun 14, 2019
New-TemporaryDirectoryis #3442A
Temp:drive resolves this issue.Liturgist commentedon Jun 15, 2019
Steve Lee (@SteveL-MSFT) - Ok. I do not see a
Temp:drive fromGet-PSDrivein 6.2.1. Am I looking in the wrong place, or when might theTemp:drive become available? #3442 appears to showWaiting - DotNetCore.Will the
Temp:drive be global for the system in the same way a/tmpon *NIX systems is currently?Will there be a
New-TemporaryDirectoryto be orthogonal withNew-TemporaryFile?iSazonov commentedon Jun 15, 2019
Liturgist It was an experimental feature. Now it is in 7.0. You can download daily build and find it there. It is "global" in PowerShell session.
No immediate plans exist to implement
New-TemporaryDirectory- you can discuss in #3442.SteveL-MSFT commentedon Jun 20, 2019
Liturgist if you want to try it on 6.2.1, just do this:
Enable-ExperimentalFeature PSTempDriveThen restart pwsh.
LYP951018 commentedon Aug 1, 2019
I'm trying
TEMP:\but I found that I could not useTEMP:\directly in C# methods or external tools, e.g.or
unzip foo -d TEMP:\fooI must use
Get-Item TEMP:\or something to achieve this...mklement0 commentedon Aug 1, 2019
Yupei Liu (@LYP951018):
TEMP:is a PowerShell-only drive (you can list them withGet-PSDrive) and such drives aren't visible to the outside world, including .NETYou must translate PS-drive-based paths to their underlying "native" filesystem paths, which is what
Convert-Pathis for.Note that there's another pitfall associated with passing filesystem paths to .NET methods (though not to external programs): .NET typically sees a different working directory than PowerShell, so that passing relative paths typically doesn't work as intended - it is best to pass full paths always, which
Convert-Pathcan also help with.In short: it's good to form a habit of passing filesystem paths to .NET methods via
Convert-Path -LiteralPath.If you stay in the realm of PowerShell, you won't face that problem; for instance, you could use
Expand-Archive.anonhostpi commentedon Nov 24, 2025
New-TemporaryDirectoryis being reconsidered: #25754 (comment)In that older issue, they chose to use dotnet APIs which was not adequate for CLM shells.