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
Remove-Item removes the symbolic links and junctions when used with -WhatIf parameter #16664
PS C:\Users\tospaa>$PSVersionTable
Name Value
---------
PSVersion 7.2.1
PSEdition Core
GitCommitId 7.2.1
OS Microsoft Windows 10.0.19043
Platform Win32NT
PSCompatibleVersions {1.0,2.0,3.0,4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Carl Morris (@msftrncs) I now longer have any influence to get items looked at having been removed from the working group.
Sorry to hear that. Interpersonal issues?
I got suspended on here for arguing with someone and categorising their behaviour over a long period as that of a troll. My access to the working group - and that of another member who'd be on the same side of the argument - vanished later without a word. Characterize that as you will.
Carl Morris (@msftrncs) I now longer have any influence to get items looked at having been removed from the working group.
Sorry to hear that. Interpersonal issues?
I got suspended on here for arguing with someone and categorising their behaviour over a long period as that of a troll. My access to the working group - and that of another member who'd be on the same side of the argument - vanished later without a word. Characterize that as you will.
Here's hoping that your explanation here doesn't meet the same fate.
@ImportTaste There seems to a small flurry of issues around the behaviour of Remove-Item, not always honouring -whatif is one, -filter and -recurse interacting in a way that is probably just wrong, but definitely counter-intuitive, and not having the same dynamic parameters as Get-ChildItem (like -file and -directory)
Someone more optimistic than I am might look to all these to be bundled up and addressed together.
The issue seems specific to directory reparse points. For file symlinks, it works as expected.
$null= mkdir dir
$null= ni file.txt
$null= ni -Type SymbolicLink filelink.txt -Target .\file.txt
$null= ni -Type SymbolicLink dirlink -Target .\dir
ls
rm .\filelink.txt -WhatIf
rm .\dirlink -WhatIf
ls
Disclaimer: This comment is mostly written by Codex/ChatGPT. I'm not exactly sure of the code review part, but I really observed the real world behavior.
Confirmed that this is still reproducible in PowerShell 7.6.4.
Environment
PSVersion 7.6.4
PSEdition Core
GitCommitId 7.6.4
OS Windows 11 Pro for Workstations, build 26200, x64
Observed real-world behavior
During debugging with tooling that manages an NTFS junction, I deliberately used -WhatIf to preview the operation, with no intent of modifying the link:
What if: Performing the operation "Remove Directory" on target "<junction>".
The invocation completed without error, but the junction itself was detached despite -WhatIf. The target directory and its contents remained intact.
This is particularly dangerous in recovery and diagnostic tooling, where -WhatIf is relied upon as the dry-run safety boundary before a destructive filesystem operation.
Source-level cause in v7.6.4
The source-level cause previously identified in this thread remains present in v7.6.4:
I would like to work on this one. The cause is the spot MatejKafka pointed to: in RemoveDirectoryInfoItem the branch that detaches symbolic links and junctions runs before the ShouldProcess answer is checked, so -WhatIf and a No to -Confirm still remove the link. I have a small fix that only takes that branch once ShouldProcess approves, plus Pester tests for a directory symbolic link and a junction, and I reproduced the bug and checked the fix on a local macOS build of master. @powershell/powershell could this be assigned to me?
Activity
God-damnit-all commentedon Feb 10, 2022
I can confirm. This just ruined my day.
darthwalsh commentedon Jul 6, 2023
#19714 seems to be the same issue. (probably best to close one as a dupe?)
msftrncs commentedon Jul 10, 2023
James O'Neill (@jhoneill), the conversation appears to have moved to this older thread that didn't turn up when originally researching my issue.
ViperTG commentedon Aug 9, 2023
Can confirm this is still an issue in 7.3.6, just had it delete my links while testing .. very annoying.
msftrncs commentedon Sep 27, 2023
ViperTG, still an issue, until this issue is closed. James O'Neill (@jhoneill) had at least marked #19714 as a bug.
jhoneill commentedon Sep 27, 2023
Carl Morris (@msftrncs) I now longer have any influence to get items looked at having been removed from the working group.
God-damnit-all commentedon Sep 28, 2023
Sorry to hear that. Interpersonal issues?
jhoneill commentedon Sep 28, 2023
I got suspended on here for arguing with someone and categorising their behaviour over a long period as that of a troll. My access to the working group - and that of another member who'd be on the same side of the argument - vanished later without a word. Characterize that as you will.
God-damnit-all commentedon Sep 28, 2023
Here's hoping that your explanation here doesn't meet the same fate.
God-damnit-all commentedon Nov 5, 2023
I feel like I should point out that while not a lot of Windows users are going to run into this, this is potentially ruinous on a Linux system.
jhoneill commentedon Nov 10, 2023
@ImportTaste There seems to a small flurry of issues around the behaviour of
Remove-Item, not always honouring-whatifis one,-filterand-recurseinteracting in a way that is probably just wrong, but definitely counter-intuitive, and not having the same dynamic parameters asGet-ChildItem(like-fileand -directory)Someone more optimistic than I am might look to all these to be bundled up and addressed together.
MatejKafka commentedon May 15, 2024
The issue seems specific to directory reparse points. For file symlinks, it works as expected.
MatejKafka commentedon May 15, 2024
The issue is here:
PowerShell/src/System.Management.Automation/namespaces/FileSystemProvider.cs
Lines 3029 to 3046 in fc68b61
I don't have time to champion a PR, Justin Grote (@JustinGrote) said he might go for it.
Seems it was always somewhat broken, but this issue was exposed in f1769fe
VirgilMing commentedon Jul 30, 2026
Disclaimer: This comment is mostly written by Codex/ChatGPT. I'm not exactly sure of the code review part, but I really observed the real world behavior.
Confirmed that this is still reproducible in PowerShell 7.6.4.
Environment
Observed real-world behavior
During debugging with tooling that manages an NTFS junction, I deliberately used
-WhatIfto preview the operation, with no intent of modifying the link:PowerShell specifically printed:
The invocation completed without error, but the junction itself was detached despite
-WhatIf. The target directory and its contents remained intact.This is particularly dangerous in recovery and diagnostic tooling, where
-WhatIfis relied upon as the dry-run safety boundary before a destructive filesystem operation.Source-level cause in v7.6.4
The source-level cause previously identified in this thread remains present in v7.6.4:
https://github.com/PowerShell/PowerShell/blob/v7.6.4/src/System.Management.Automation/namespaces/FileSystemProvider.cs#L3035-L3080
RemoveDirectoryInfoItem()stores the result ofShouldProcess()incontinueRemoval:However, the reparse-point/name-surrogate branch executes before the later
if (continueRemoval)guard and calls:It then returns. Consequently, when
ShouldProcess()returnsfalsefor-WhatIf, a junction or directory symbolic link is still detached.The reparse-point branch should also be gated by
continueRemoval, or the method should return immediately whencontinueRemovalis false.A regression test should verify that:
Remove-Item -WhatIfon supported platforms;-Recurse -Force -WhatIfcombination.Since #19714 was labeled
Issue-Bugand closed as a duplicate of this issue, could the same bug label also be applied to this primary tracking issue?Om-singhaI commentedon Oct 16, 2026
I would like to work on this one. The cause is the spot MatejKafka pointed to: in
RemoveDirectoryInfoItemthe branch that detaches symbolic links and junctions runs before theShouldProcessanswer is checked, so-WhatIfand a No to-Confirmstill remove the link. I have a small fix that only takes that branch onceShouldProcessapproves, plus Pester tests for a directory symbolic link and a junction, and I reproduced the bug and checked the fix on a local macOS build of master. @powershell/powershell could this be assigned to me?