Skip to content

Move-Item: Move directory to another drive fails #15072

Closed

Description

@hazychill

Steps to reproduce

Move-Item -LiteralPath 'D:\work\testdir' -Destination 'I:\work\testdir'

D: and I: are just two different simple volume on two different HDD, not DFS or something.

Expected behavior

Directory testdir is moved from D: to I: without error, which is the case with PowerShell-7.2.0-preview.3.

PS D:\tools\PowerShell-7.2.0-preview.3-win-x64> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.2.0-preview.3
PSEdition                      Core
GitCommitId                    7.2.0-preview.3
OS                             Microsoft Windows 10.0.19042
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

PS D:\tools\PowerShell-7.2.0-preview.3-win-x64> Get-ChildItem -LiteralPath 'D:\work'

    Directory: D:\work

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          2021/03/20    21:47                testdir

PS D:\tools\PowerShell-7.2.0-preview.3-win-x64> Get-ChildItem -LiteralPath 'I:\work'
PS D:\tools\PowerShell-7.2.0-preview.3-win-x64> Move-Item -LiteralPath 'D:\work\testdir' -Destination 'I:\work\testdir'
PS D:\tools\PowerShell-7.2.0-preview.3-win-x64> Get-ChildItem -LiteralPath 'D:\work'
PS D:\tools\PowerShell-7.2.0-preview.3-win-x64> Get-ChildItem -LiteralPath 'I:\work'

    Directory: I:\work

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          2021/03/20    21:59                testdir

PS D:\tools\PowerShell-7.2.0-preview.3-win-x64>

Actual behavior

In PowerShell-7.2.0-preview.4, Move-Item returns error.

PS D:\tools\PowerShell-7.2.0-preview.4-win-x64> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.2.0-preview.4
PSEdition                      Core
GitCommitId                    7.2.0-preview.4
OS                             Microsoft Windows 10.0.19042
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

PS D:\tools\PowerShell-7.2.0-preview.4-win-x64> Get-ChildItem -LiteralPath 'D:\work'

    Directory: D:\work

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          2021/03/20    21:59                testdir

PS D:\tools\PowerShell-7.2.0-preview.4-win-x64> Get-ChildItem -LiteralPath 'I:\work'
PS D:\tools\PowerShell-7.2.0-preview.4-win-x64> Move-Item -LiteralPath 'D:\work\testdir' -Destination 'I:\work\testdir'
Move-Item: Source and destination path must have identical roots. Move will not work across volumes.
PS D:\tools\PowerShell-7.2.0-preview.4-win-x64> Get-ChildItem -LiteralPath 'D:\work'

    Directory: D:\work

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          2021/03/20    21:59                testdir

PS D:\tools\PowerShell-7.2.0-preview.4-win-x64> Get-ChildItem -LiteralPath 'I:\work'
PS D:\tools\PowerShell-7.2.0-preview.4-win-x64>

Error details

PS D:\tools\PowerShell-7.2.0-preview.4-win-x64> Get-Error

Exception             :
    Type       : System.IO.IOException
    TargetSite :
        Name          : MoveTo
        DeclaringType : System.IO.DirectoryInfo
        MemberType    : Method
        Module        : System.IO.FileSystem.dll
    StackTrace :
   at System.IO.DirectoryInfo.MoveTo(String destDirName)
   at Microsoft.PowerShell.Commands.FileSystemProvider.MoveDirectoryInfoUnchecked(DirectoryInfo directory, String destinationPath, Boolean force)
   at Microsoft.PowerShell.Commands.FileSystemProvider.MoveDirectoryInfoItem(DirectoryInfo directory, String destination, Boolean force)
    Message    : Source and destination path must have identical roots. Move will not work across volumes.
    Source     : System.IO.FileSystem
    HResult    : -2146232800
TargetObject          : D:\work\testdir
CategoryInfo          : WriteError: (D:\work\testdir:DirectoryInfo) [Move-Item], IOException
FullyQualifiedErrorId : MoveDirectoryItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand
InvocationInfo        :
    MyCommand        : Move-Item
    ScriptLineNumber : 1
    OffsetInLine     : 1
    HistoryId        : 4
    Line             : Move-Item -LiteralPath 'D:\work\testdir' -Destination 'I:\work\testdir'
    PositionMessage  : At line:1 char:1
                       + Move-Item -LiteralPath 'D:\work\testdir' -Destination 'I:\work\testdi …
                       + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    InvocationName   : Move-Item
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo :

In my quick analysis, #14913 may affect this issue. DirectoryInfo.MoveTo returns IOException with HResult = -2146232800(0x80131620), not -2147024891(0x80070005), which fallback condition for CopyAndDelete expects.

Environment data

PS D:\tools\PowerShell-7.2.0-preview.4-win-x64> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.2.0-preview.4
PSEdition                      Core
GitCommitId                    7.2.0-preview.4
OS                             Microsoft Windows 10.0.19042
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Activity

  1. added
    Needs-TriageThe issue is new and needs to be triaged by a work group.
    on Mar 20, 2021
  2. iSazonov commented on Mar 20, 2021

    @iSazonov
    Collaborator

    I can confirm. It's a shame that this happened!
    As I commented in #14913 we shouldn't depend on driver error codes.
    And moreover a best way is to follow .Net and use one code path for all platforms if possible. See #14913 (comment)

  3. added
    WG-Engine-Providersbuilt-in PowerShell providers such as FileSystem, Certificates, Registry, etc.
    on Mar 20, 2021
  4. 237dmitry commented on Mar 20, 2021

    @237dmitry

    Is this even possible? Move a directory from one partition to another without copying/deleting it.

  5. jborean93 commented on Mar 20, 2021

    @jborean93
    Collaborator

    Is this even possible? Move a directory from one partition to another without copying/deleting it.

    No but the code is meant to have a fallback to do the copy and delete if the move fails due to it being in different volumes.

  6. SteveL-MSFT commented on Mar 21, 2021

    @SteveL-MSFT
    Member

    Relying on any IOException to try CopyAndDelete() is a big behavioral change and may introduce other subtle side effects. Looking at my original PR, it seems that the mistake was removing the existing code to check the root drive on Windows. The safest fix is to add that check back restoring the previous behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs-TriageThe issue is new and needs to be triaged by a work group.WG-Engine-Providersbuilt-in PowerShell providers such as FileSystem, Certificates, Registry, etc.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions