Skip to content

New-Item -Type SymbolicLink doesn't define symlinks with relative directory targets as directory symlinks #9127

Closed

Description

PR #8783 addressed #3500, which brought the ability to define symlinks whose targets are defined as relative paths.

On Unix-like platforms, symlinks aren't typed; the symlink behaves as if it were the same type (file or directory) of whatever type its target is.

On Windows, by contrast, you must explicitly match the target type at symlink creation time for symlinks to directories to act like directories.
Since New-Item currently does not allow you to specify a symlink type - enum value SymbolicLink is currently the only option - it must itself infer the appropriate type based on the specified target.

As an aside: Since this inference requires that the target already exist, creating symlinks to non-existing targets - which is a legitimate use case - presents a conceptual problem that must be solved separately - see #9067

Currently, the inference doesn't work if the target is specified as a relative path to an existing target directory.

Steps to reproduce (on Windows)

Note: If you don't have developer mode enabled, run the tests as admin (elevated).

Describe "New-Item: symlink with relative path test" {
  BeforeAll {
    Push-Location TestDrive:/
    # Create a directory...
    $null = New-Item -Type Directory someDir
    # ... and a symlink to that directory, as a sibling, using a *relative* path.
    New-Item -Type SymbolicLink someDirLinkRelative -Target someDir
    # ... and a symlink to that directory, as a sibling, using a *relative* path.
    New-Item -Type SymbolicLink someDirLinkAbsolute -Target (Convert-Path someDir)
    # Echo the symlink target information.
    Get-Item someDirLinkRelative, someDirLinkAbsolute | Select LinkType, Target | Out-String | write-verbose -vb
  }
  AfterAll {
    Pop-Location
  }
  
  It "Symlink with absolute path to existing directory behaves like a directory." {
    (Get-Item someDirLinkAbsolute) | Should -BeOfType System.IO.DirectoryInfo
  }

  It "Symlink with relative path to existing directory behaves like a directory." {
    (Get-Item someDirLinkRelative) | Should -BeOfType System.IO.DirectoryInfo
  }
  
}

Expected behavior

Both tests should succeed.

Actual behavior

The test with the relative target path fails.
That is, a file symlink rather than a directory symlink was mistakenly created.

Environment data

PowerShell Core v6.2.0-rc.1 on Microsoft Windows 10 Pro (64-bit; Version 1803, OS Build: 17134.590)

Activity

  1. added
    Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a
    on Mar 12, 2019
  2. added
    Issue-Enhancementthe issue is more of a feature request than a bug
    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassif
    and removed
    Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a
    on Mar 13, 2019
  3. webtroter commented on Feb 27, 2023

    @webtroter

    Hello,

    I'm having this issue on pwsh 7.3.2

    Should I open another issue?

    PS D:\03_Films\JellyServer\Films> Get-Content .\symlink.test.ps1
    Describe "New-Item: symlink with relative path test" {
      BeforeAll {
        Push-Location TestDrive:/
        # Create a directory...
        $null = New-Item -Type Directory someDir
        # ... and a symlink to that directory, as a sibling, using a *relative* path.
        New-Item -Type SymbolicLink someDirLinkRelative -Target someDir
        # ... and a symlink to that directory, as a sibling, using a *relative* path.
        New-Item -Type SymbolicLink someDirLinkAbsolute -Target (Convert-Path someDir)
        # Echo the symlink target information.
        Get-Item someDirLinkRelative, someDirLinkAbsolute | Select LinkType, Target | Out-String | write-verbose -vb
      }
      AfterAll {
        Pop-Location
      }
    
      It "Symlink with absolute path to existing directory behaves like a directory." {
        (Get-Item someDirLinkAbsolute) | Should -BeOfType System.IO.DirectoryInfo
      }
    
      It "Symlink with relative path to existing directory behaves like a directory." {
        (Get-Item someDirLinkRelative) | Should -BeOfType System.IO.DirectoryInfo
      }
    
    }
    PS D:\03_Films\JellyServer\Films> Invoke-Pester .\symlink.test.ps1
    
    Starting discovery in 1 files.
    Discovery finished in 8ms.
    VERBOSE:
    LinkType     Target
    --------     ------
    SymbolicLink someDir
    SymbolicLink C:\Users\webtroter\AppData\Local\Temp\06f02b3c-3c06-4dcb-b85f-259ad73a7d7a\someDir
    
    
    [-] New-Item: symlink with relative path test.Symlink with relative path to existing directory behaves like a directory. 4ms (3ms|1ms)
     Expected the value to have type [System.IO.DirectoryInfo] or any of its subtypes, but got C:\Users\webtroter\AppData\Local\Temp\06f02b3c-3c06-4dcb-b85f-259ad73a7d7a\someDirLinkRelative with type [System.IO.FileInfo].
     at (Get-Item someDirLinkRelative) | Should -BeOfType System.IO.DirectoryInfo, D:\03_Films\JellyServer\Films\symlink.test.ps1:22
     at <ScriptBlock>, D:\03_Films\JellyServer\Films\symlink.test.ps1:22
    Tests completed in 261ms
    Tests Passed: 1, Failed: 1, Skipped: 0 NotRun: 0
    PS D:\03_Films\JellyServer\Films> $PSVersionTable
    
    Name                           Value
    ----                           -----
    PSVersion                      7.3.2
    PSEdition                      Core
    GitCommitId                    7.3.2
    OS                             Microsoft Windows 10.0.19044
    Platform                       Win32NT
    PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
    PSRemotingProtocolVersion      2.3
    SerializationVersion           1.1.0.1
    WSManStackVersion              3.0
    

    EDIT : I found many opened issues relating to this. I guess my question about opening a new issue is answered. I will reply in the opened issues.

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

    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassifIssue-Enhancementthe issue is more of a feature request than a bugResolution-FixedThe issue is fixed.WG-Cmdletsgeneral cmdlet issues

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions