Add New-TemporaryDirectory cmdlet (Fixes #25754) - #27086
#27086Add New-TemporaryDirectory cmdlet (Fixes #25754)#27086Thatgfsj wants to merge 27 commits intoPowerShell:masterPowerShell/PowerShell:masterfrom Thatgfsj:feature/issue-25754-v2Thatgfsj/PowerShell:feature/issue-25754-v2Copy head branch name to clipboard
Conversation
- Initialize tempDirPath to null for definite assignment - Move variable declarations to method level (matching New-TemporaryFile pattern) - Add null/empty check before creating DirectoryInfo (matching New-TemporaryFile pattern)
|
Friendly ping @SteveL-MSFT @daxian-dbw — this adds a cmdlet (mirrors the existing pattern). The latest commit fixes a CodeFactor code-quality flag by matching the reference implementation's null-initialization and null-check pattern. CI re-running, ready for review. |
StyleCop SA1117 requires parameters to be all on one line or each on its own line. The [Cmdlet] attribute had mixed formatting with two positional parameters on the first line and named parameters on separate lines.
Put all parameters on the first line except HelpUri, matching the existing reference implementation in the same directory.
StyleCop SA1117 requires parameters to be either all on the same line or each on its own line. The reference file's mixed format is grandfathered but new files must comply.
|
@Thatgfsj Kindly please fill out the summary, context and checklist as part of the PR Template as we cannot/should not merge without these being filled out correctly. |
|
Gentle ping for review. This PR has been open for 6 weeks. Anything needed from my side? |
|
@Thatgfsj - Thank you for updating the PR Context, Summary and Checklist. |
There was a problem hiding this comment.
Pull request overview
This PR adds a new New-TemporaryDirectory cmdlet to Microsoft.PowerShell.Utility to mirror the existing New-TemporaryFile cmdlet by creating a temporary directory under the system temp path and returning a DirectoryInfo.
Changes:
- Export
New-TemporaryDirectoryfromMicrosoft.PowerShell.Utilityon both Windows and Unix module manifests. - Add
NewTemporaryDirectoryCommandcmdlet implementation returningSystem.IO.DirectoryInfo.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/Modules/Windows/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 | Exports the new New-TemporaryDirectory cmdlet on Windows. |
| src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 | Exports the new New-TemporaryDirectory cmdlet on Unix. |
| src/Microsoft.PowerShell.Commands.Utility/commands/utility/NewTemporaryDirectoryCommand.cs | Implements the New-TemporaryDirectory cmdlet logic. |
| /// <summary> | ||
| /// The implementation of the "New-TemporaryDirectory" cmdlet. | ||
| /// </summary> | ||
| [Cmdlet(VerbsCommon.New, "TemporaryDirectory", SupportsShouldProcess = true, ConfirmImpact = ConfirmImpact.Low, HelpUri = "https://go.microsoft.com/fwlink/?LinkId=xxxxx")] |
| tempDirPath = Path.Combine(tempPath, Path.GetRandomFileName()); | ||
| Directory.CreateDirectory(tempDirPath); |
| protected override void EndProcessing() | ||
| { | ||
| string tempDirPath = null; | ||
| string tempPath = Path.GetTempPath(); | ||
| if (ShouldProcess(tempPath)) | ||
| { |
|
@SteveL-MSFT we missed this PR in the Cmdlets WG are we wanting to take this one or the other one? |
|
CodeFactor green ✅ on |
|
|
||
| Context "OutputType" { | ||
| It "has an OutputType of System.IO.DirectoryInfo" { | ||
| (Get-Command New-TemporaryDirectory).OutputType | Should -BeExactly "System.IO.DirectoryInfo" |
There was a problem hiding this comment.
The OutputType property returns a collection of PSTypeName objects rather than a plain string, so -BeExactly against a string is fragile and can fail even when the cmdlet is correctly annotated. Asserting against .OutputType.Name with -Contain is more robust. This mirrors the form used on the parallel PR #27549 (and what Copilot recommended there).
| (Get-Command New-TemporaryDirectory).OutputType | Should -BeExactly "System.IO.DirectoryInfo" | |
| (Get-Command New-TemporaryDirectory).OutputType.Name | Should -Contain "System.IO.DirectoryInfo" |
|
@jshigetomi Can we have |
@Thatgfsj This might be a hallucination, NewTemporaryFileCommand uses base class Cmdlet |
|
@jshigetomi You're absolutely right — my mistake. To summarize the current state of this PR: Features:
Tests:
Other:
|
…mprove validation - Remove HelpUri (was shared with New-TemporaryFile, needs its own fwlink) - Add ValidatePattern on Prefix to reject path-illegal characters - Fix ShouldProcess targetDescription to be more descriptive - Restore do/while collision guard in CreateWithoutPrefix (race condition fix) - Use Directory.CreateDirectory() return value instead of redundant new DirectoryInfo()
|
Pushed
CodeFactor green ✅. |
|
Here's a summary of where this PR stands: What was wrong initially:
What was done to fix it:
Current status:
Still need to fix the OutputType test assertion and double-check the base class. Should be close to done after that. |
|
@jshigetomi Thanks for the review. Fixed the OutputType test assertion to use |
|
@Thatgfsj Could you add the help uri back in? @sdwheeler will make it go live once this is merged in and released. |
|
Okay, I'll finish it later. |
…comma - Windows manifest: add missing comma after Get-SecureRandom - Both manifests: New-TemporaryDirectory now correctly before New-TemporaryFile - DefaultCommands.Tests.ps1: swap entries to correct alphabetical order
|
@jshigetomi Done! Added the |
|
@jshigetomi this pr seems weird, don't know why. Can you please ask @Thatgfsj to handle If you also see the #27549 actually uses the shared @Thatgfsj Can you please make this little better using the above and looking at the #27549 ? But wait for the confirmation for @jshigetomi and @sdwheeler . Thanks! |
|
Okay, I will respond in two days. |
…reuse PathUtils.GetTemporaryDirectory()
|
@jshigetomi @Thatgfsj Thanks for the review! Updated based on the feedback:
The descriptive text ('Temp directory under ...' etc.) is gone, and the CreateTemporaryDirectory shared helper in PathUtils.cs introduced by this PR is now actually used by the cmdlet — so the split has clear benefit. Pushed as d21d9bb on feature/issue-25754-v2. Ready for another look. |
|
@Thatgfsj Could you please make the following updates before we proceed with this PR?
|
|
Ok,let me take a look |
… platform-aware validation - Fix SA1204: move static CreateErrorRecord before instance members - Remove hardcoded [ValidatePattern] regex, use Path.GetInvalidFileNameChars() for platform-aware validation - Consolidate CreateWithPrefix / CreateWithoutPrefix into a single code path - Use Directory.CreateTempSubdirectory() for both prefix and no-prefix cases, guaranteeing atomic creation without race conditions - Add test for invalid prefix characters
|
@jshigetomi Addressed all four points in
|
|
@Thatgfsj The current CI failures are compile-time failures, so the Pester/xUnit tests have not run yet.
- /// Uses <see cref="Directory.CreateTempSubdirectory()"/> for atomic creation,
+ /// Uses <see cref="Directory.CreateTempSubdirectory(string)"/> for atomic creation,This same diagnostic is causing the Windows, Linux, macOS, xUnit, and CodeQL jobs to fail at Also, the latest implementation no longer calls |
PR Summary
Adds a
New-TemporaryDirectorycmdlet that creates a temporary directory in the system's temp folder and returns aDirectoryInfoobject pointing to it. This mirrors the existingNew-TemporaryFilecmdlet pattern.PR Context
Fixes #25754. PowerShell currently has
New-TemporaryFilebut no equivalent for directories. Users often need a throwaway directory for intermediate file processing, build artifacts, or isolated test environments. This cmdlet fills that gap by providing a simple, consistent, andShouldProcess-aware way to create temporary directories.PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright header