Powershell: 6.2.0-rc.1 Remove-Item -Recurse broken

Created on 29 Mar 2019  路  23Comments  路  Source: PowerShell/PowerShell

in 6.1.2 this command works : Remove-Item C:Users\david\OneDrive\Documents\ -Recurse

but in 6.2.0-rc.1 I get this error

PS C:Users\david> Remove-Item C:Users\david\OneDrive\Documents\ -Recurse
Remove-Item : Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
At line:1 char:1

  • Remove-Item C:Users\david\OneDrive\Documents\ -Recurse
  • ~~~~~~~~~~~
  • CategoryInfo : NotSpecified: (:) [Remove-Item], FormatException
  • FullyQualifiedErrorId : System.FormatException,Microsoft.PowerShell.Commands.RemoveItemCommand
Issue-Bug Up-for-Grabs WG-Engine-Providers

Most helpful comment

I confirm this issue is still there with PowerShell 7.0:

image

When this fails, the same Remove-Item -Recurse -Force operation works in Windows PowerShell 5.1.

All 23 comments

@Baribeault Can you add the output of

$error[0] | fl -showerror -force *

PS C:Users\david> $error[0] | fl -showerror -force *

PSMessageDetails :
Exception : System.FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
at System.Text.StringBuilder.AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args)
at System.String.FormatHelper(IFormatProvider provider, String format, ParamsArray args)
at System.String.Format(IFormatProvider provider, String format, Object arg0)
at System.Management.Automation.Internal.StringUtil.Format(String formatSpec, Object o)
at Microsoft.PowerShell.Commands.FileSystemProvider.RemoveDirectoryInfoItem(DirectoryInfo directory, Boolean recurse, Boolean force,
Boolean rootOfRemoval)
at Microsoft.PowerShell.Commands.FileSystemProvider.RemoveItem(String path, Boolean recurse)
at System.Management.Automation.SessionStateInternal.RemoveItem(CmdletProvider providerInstance, String path, Boolean recurse,
CmdletProviderContext context)
TargetObject :
CategoryInfo : NotSpecified: (:) [Remove-Item], FormatException
FullyQualifiedErrorId : System.FormatException,Microsoft.PowerShell.Commands.RemoveItemCommand
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at , : line 1
PipelineIterationInfo : {}

Hmm, sounds like someone might have messed with one of the resx strings there.

Does $error[0].Exception.GetBaseException() | fl -f give any additional information?

PS C:Users\david> $error[0].Exception.GetBaseException() | fl -f

Message : Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
Data : {}
InnerException :
TargetSite : System.Text.StringBuilder AppendFormatHelper(System.IFormatProvider, System.String, System.ParamsArray)
StackTrace : at System.Text.StringBuilder.AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args)
at System.String.FormatHelper(IFormatProvider provider, String format, ParamsArray args)
at System.String.Format(IFormatProvider provider, String format, Object arg0)
at System.Management.Automation.Internal.StringUtil.Format(String formatSpec, Object o)
at Microsoft.PowerShell.Commands.FileSystemProvider.RemoveDirectoryInfoItem(DirectoryInfo directory, Boolean recurse, Boolean force, Boolean
rootOfRemoval)
at Microsoft.PowerShell.Commands.FileSystemProvider.RemoveItem(String path, Boolean recurse)
at System.Management.Automation.SessionStateInternal.RemoveItem(CmdletProvider providerInstance, String path, Boolean recurse,
CmdletProviderContext context)
HelpLink :
Source : System.Private.CoreLib
HResult : -2146233033

Looks like it should be from these three here, I'd venture to guess, and the resx strings used therein:

1. at Microsoft.PowerShell.Commands.FileSystemProvider.RemoveDirectoryInfoItem(DirectoryInfo directory, Boolean recurse, Boolean force, Boolean
rootOfRemoval)
2. at Microsoft.PowerShell.Commands.FileSystemProvider.RemoveItem(String path, Boolean recurse)
3. at System.Management.Automation.SessionStateInternal.RemoveItem(CmdletProvider providerInstance, String path, Boolean recurse,
CmdletProviderContext context)

C:Users\david\__OneDrive__\Documents\

We don't work with OneDrive well.

Ubuntu shell works fine in a Windows OneDrive folder
rm -r

I confirm this issue is still there with PowerShell 7.0:

image

When this fails, the same Remove-Item -Recurse -Force operation works in Windows PowerShell 5.1.

Is there a workaround here? This has been acknowledged as a bug for over a year with seemingly no movement.

I guess it is not complex fix. I guess we need detect _surrogate_ reparse points. If I remember correctly we already did this for read operations. Also I saw such code in .Net Core for Delete().

This is still happening on July 28, 2020 using PowerShell Core 7.0.3, so whatever is the problem with regular PowerShell (5.x?) has carried over intact (unfortunately) to it's sire, PS 7.x.

I think I must be missing something. Is it really the case that the LTS release of PowerShell Core doesn't contain the working functionality to delete files?
I'm getting "Index (zero based) must be greater than or equal to zero and less than the size of the argument list." even if I pipe the input from a Get-ChildItem foreach loop rather than use -Recurse. Is that a problem only I'm experiencing or is that related to this issue?

As of August 18, 2020, using PowerShell 7.0.3 on Windows 10 Pro Version 2004 (OS Build 19041.450), the following works correctly for me:
Get-ChildItem -Path .\node_modules -Recurse | Remove-Item -Recurse

It's only broken in the OneDrive folder where files are not actual files but reparse points.

@fmorriso, does that command work for you when .node_modules contains folders? I was able to delete individual files from my OneDrive using Remove-Item, but not folders. At least not when the folders are non-empty. But if I delete everything that Get-ChildItem -Recurse lists in reverse order (so files in the folder are deleted before attempting to delete the parent folder) then it works. So my command looks like this:

Get-ChildItem -Path .\node_modules -Recurse | Sort-Object { (--$script:i) } | Remove-Item

I copied an angular project from my c:\projects\angular\ folder to c:\users\username\OneDrive\projects\angular\ and then tried my script and it worked just fine (directory node_modules and all files/subdirectories beneath it were deleted, which was over 883 items).

That's interesting. If you tried to just Remove-Item -Recurse on a folder would that give the error from this bug? I noticed that I was able to delete folders in my personal OneDrive without problems, but in my OneDrive for business folder it gave this error. I'm guessing it's because my OneDrive for Business is having the local "My Documents" and other folders routed to it (even though the folders I'm testing with aren't in there).

I performed the following starting at c:\users\userName\OneDrive\projects\angular\dummyProject\ with no issues (the top-level directory and all subdirectories/files were removed):
Remove-Item -Path .\node_modules -Recurse

Here to confirm the same issue with PowerShell 7.0.3.
image

For context, I am in the middle of a large OneDrive sync and I'm trying to clean up some dead folders. But those dead folders are within other folders that are still being synced.
image

If, instead I try to delete a folder from somewhere that has been "synced", I don't get this problem.
image

It looks like folders in transit to OneDrive cloud are somewhat invisible to OneDrive PowerShell Core during this process.

Hopefully that's a useful repro case:

  • Generate gigabytes of OneDrive changes
  • Attempt to delete folders deep in the structure of the changes that are syncing

Based on previous comments, I wonder if the issue can be avoided by pausing OneDrive synchronization prior to invoking Remove-Item -Recurse.

Hey @fmorriso , this was a good idea, but I just tested this and no luck. Still the same results.
image

I've found this works as a workaround. essentially you have to empty the folders and then remove the folders when empty.

"foldername" | %{
  Get-ChildItem -Recurse $_ -force -file | %{ remove-item $_ -force -Verbose}
 # This gets paths in reverse order so you can remove from the parent down
  (Get-Childitem $_ -Recurse -force).Fullname |sort-object {$_.length} -Descending | remove-item -force -Verbose; 
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

alx9r picture alx9r  路  3Comments

SteveL-MSFT picture SteveL-MSFT  路  3Comments

JohnLBevan picture JohnLBevan  路  3Comments

aragula12 picture aragula12  路  3Comments

Michal-Ziemba picture Michal-Ziemba  路  3Comments