Skip to content

New-Item -ItemType SymbolicLink folder cannot be opened #2915

Closed

Description

@yanxyz

Use the lastest PowerShell to create a symbolic link folder:

New-Item -ItemType Directory .\a
New-Item .\a\t.txt -Value "hello"
New-Item -ItemType SymbolicLink -Name .\d  -Value .\a
# The Mode property is empty in the result of above cmdlet
Get-ItemPropertyValue .\d -Name Mode
# Get-ItemPropertyValue : Exception getting "Mode": "句柄无效。"
# My OS language is Chinese, "句柄无效" means "invalid handler"

The big problem is that the symbolic link d created above can't be opened. When using the system default PowerShell(PowerShell 5.1, My OS is Windows 10 x64) to create a symbolic link folder, it works well. Another question, now use the lastest PowerShell to remove the symbolic link that is created by the system default PowerShell

> Remove-Item .\d -Recurse
# Remove-Item : F:\test\test-powershell\Symlink\d is an NTFS junction point. Use the Force parameter to delete or modify this object.

It says "d is an NTFS junction point", well, d is a symbolic link,isn't it?

> $PSVersionTable
Name                           Value
----                           -----
SerializationVersion           1.1.0.1
BuildVersion                   3.0.0.0
WSManStackVersion              3.0
GitCommitId                    v6.0.0-alpha.14
PSEdition                      Core
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
CLRVersion
PSRemotingProtocolVersion      2.3
PSVersion                      6.0.0-alpha

Activity

  1. mwrock commented on Jan 15, 2017

    @mwrock
    Contributor

    I'm seeing this as well:

    New-Item -Path src -ItemType SymbolicLink -value C:\dev\habitat\components\hab
    

    then:

    [HAB-STUDIO] C:\hab\studios> cd src
    cd : Cannot find path 'src' because it does not exist.
    At line:1 char:1
    + cd src
    + ~~~~~~
        + CategoryInfo          : ObjectNotFound: (src:String) [Set-Location], ItemNotFoundE
       xception
        + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationComm
       and
    

    However it works fine on shipping powershell 5.1 on windows 10.

  2. mklement0 commented on Apr 6, 2017

    @mklement0
    Contributor

    The problem still exists as of alpha17.

    What appears to be happening is that in Core the link is mistakenly created as a file symlink rather than a directory symlink.

    You can verify this with cmd /c dir /al d, which in PS Core yields something like (note the <SYMLINK>, which should be <SYMLINKD>):

    04/06/2017  04:12 PM    <SYMLINK>      d [C:\Users\jdoe\Desktop\pg\a]
    

    whereas in Windows PS it correctly yields something like:

    04/06/2017  04:12 PM    <SYMLINKD>      d [C:\Users\jdoe\Desktop\pg\a]
    

    I agree that the error message mentioning a junction point rather than a symbolic link is misleading, but it sounds like this problem may go away on its own once -Force is no longer needed.

  3. jeffbi commented on Apr 7, 2017

    @jeffbi

    Actually, the -Force issue is not related to this. I was just writing up my own version of this issue when I saw this conversation.

    In Windows PS 5.1, New-Item -ItemType SymbolicLink would create a directory symbolic link (<SYMLINKD>) when the target was a directory, a file symbolic link (<SYMLINK>) when the target was a file, and throw an ObjectNotFound error if the target did not exist.

    It appears that at some point the cmdlet was changed to bring it more in line with the Windows mklink and Unix ln commands, allowing a symbolic link to be created that linked to a non-existent item. In making that change, the ability to create directory symbolic links to existing directories was (presumably) inadvertently lost.

    Since I'm working in this area anyway, and because this is impacting my ability to write tests for #1930, I'm happy to take this on.

    I think, though, that there should be some conversation around whether (and how) a user should be able to deliberately create a "file" symbolic link to a directory with New-Item. mklink allows it, and in Unix they're all file links anyway.

  4. mklement0 commented on Apr 7, 2017

    @mklement0
    Contributor

    jeffbi:

    The -Force issue is entirely incidental to the issue at hand - it was an aside by Ivan Yan (@yanxyz) that perhaps should have been filed as a separate issue to begin with: it relates to removing a directory symlink, whereas the issue at hand is the inability to even create such a symlink. (And, as I said, if -Force will no longer be required to remove a directory symlink, no one will get to see that confusing error message anyway.)

    It appears that at some point the cmdlet was changed to bring it more in line with the Windows mklink and Unix ln commands, allowing a symbolic link to be created that linked to a non-existent item. In making that change, the ability to create directory symbolic links to existing directories was (presumably) inadvertently lost.

    That sounds like a promising lead: see this commit (Andy Jordan (@andschwa)).

    there should be some conversation around whether (and how) a user should be able to deliberately create a "file" symbolic link to a directory with New-Item

    Excellent point: If you're creating a symlink to a non-existing item, in the absence of knowing that not-yet-extant item's type, on Windows you must specify whether it is a file or directory - and there's currently no way to specify that.

  5. jeffbi commented on Apr 7, 2017

    @jeffbi

    Michael Klement (@mklement0) Apologies, I misread your comment.

    As for creating a symlink on Windows, I think you really need to be able to specify file or directory whether the target item exists or not. Windows is perfectly happy to allow you to create both a file and a directory symlink to either a file, a directory, or a yet-to-be-created object.

    03/24/2017  04:06 PM                 0 test.txt
    04/06/2017  10:38 PM    <DIR>          sub
    04/06/2017  10:38 PM    <SYMLINK>      sym-to-nix [nix]
    04/06/2017  10:38 PM    <SYMLINK>      sym-to-sub [sub]
    04/06/2017  10:39 PM    <SYMLINK>      sym-to-text [text.txt]
    04/06/2017  10:38 PM    <SYMLINKD>     symd-to-nix [nix]
    04/06/2017  10:38 PM    <SYMLINKD>     symd-to-sub [sub]
    04/06/2017  10:39 PM    <SYMLINKD>     symd-to-text [text.txt]
    
  6. iSazonov commented on Apr 7, 2017

    @iSazonov
    Collaborator

    jeffbi Do you work on fix for the Issue?

  7. jeffbi commented on Apr 7, 2017

    @jeffbi

    Ilya (@iSazonov) Since it's getting in my way, I'm about to start.

    My intention at the moment is to have the cmdlet create file symlinks to targets that do not exist, and either file or directory symlinks to appropriate existing targets. I still believe we need the ability to have the user specify what kind of link is actually desired. This is only for Windows, as Unix uses file links even to directories.

  8. joeyaiello commented on Apr 10, 2017

    @joeyaiello
    Contributor

    Ugh, so we can either:

    • add more enums to -Type (i.e. DirectorySymbolicLink and FileSymbolicLink), but that means we have to leave SymbolicLink and have it try to "do the right thing" (file link for files and non-existent targets, and directory link for directories)
    • add a parameter like -SymbolicLinkType, but now you're stuck in the dynamic parameter catch-22

    I understand why someone would might want to create a directory symbolic link to a non-existent target, but could someone explain why I might want to create a file-based symbolic link to a directory?

  9. jeffbi commented on Apr 10, 2017

    @jeffbi

    Joey Aiello (@joeyaiello) Honestly, I don't know why someone would want to create a file-type symbolic link to a directory. Windows allows the mklink command to do so---in fact it is the default behavior unless the /D option is explicitly given---so presumably someone thought at one time that it would be useful.

    Unix doesn't have the notion of a separate directory-type symbolic link, so new enums for DirectorySymbolicLink and FileSymbolicLink would be meaningless for Linux and OS X. The Linux implementation of ln has a -d switch for creating directory hard links, but that's pretty much never actually allowed, even for the superuser. Combining the -d switch with the -s switch (even on an NTFS volume) simply ignores the -d and creates a "normal" sym link. The OS X version of ln does not even offer the option.

  10. joeyaiello commented on Apr 10, 2017

    @joeyaiello
    Contributor

    Well, it looks like your PR (#3509) is doing the right thing for now, If people desperately need directory symlinks to non-existent targets, we'll figure it out then.

  11. jeffbi commented on Apr 11, 2017

    @jeffbi

    Sorry, I'm getting ahead of myself a bit. If you want to put this off until more discussion happens, I'm fine with that. I suggested the discussion, you'd think I'd be patient enough to let it happen.

    In the Pester tests for #1930 (PR #3441), I'd rather not have to shell out the mklink and ln commands for testing with links, so I'll hold off on completing that PR until a decision is made on this one.

  12. iSazonov commented on Apr 11, 2017

    @iSazonov
    Collaborator

    jeffbi I see that you have already done a full analysis 👍 and we can continue to work on your PR.
    It would be great to do a "full specification" or "full description" of the behaivor and place it in description of the PR.
    I also want to add that we would be good to do warnings in unusual cases (non-exist targets, file to directory links).

  13. jeffbi commented on Apr 11, 2017

    @jeffbi

    Ilya (@iSazonov) I've updated the PR's description with additional details about how links are created.

    As for warnings about "unusual cases", what's unusual to you and I may not be unusual for others. I can imagine scenarios for creating sym links to yet-be-created items. And keep in mind that file-type sym links to directories is the default behavior of mklink when not explicitly given the /D switch.

  14. iSazonov commented on Apr 12, 2017

    @iSazonov
    Collaborator

    jeffbi Thanks for clarify! I thought more about typos in the console when the user can quietly get a dead link 😕

  15. daxian-dbw commented on Apr 14, 2017

    @daxian-dbw
    Member

    jeffbi Is Remove-Item on a symbolic directory also resolved via #3509? If not, is it tracked by another issue?

  16. jeffbi commented on Apr 14, 2017

    @jeffbi

    No, the Remove-item issue is not resolved by #3509. I have a separate set of fixes for #621. What #3509 gives me is, like #3441, the ability to use the fixed New-Item in tests for symlinks.

  17. daxian-dbw commented on Apr 14, 2017

    @daxian-dbw
    Member

    jeffbi Got it. Thank you for fixing this issue!

  18. iSazonov commented on Apr 15, 2017

    @iSazonov
    Collaborator

    👍

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

Metadata

Metadata

Assignees

Labels

Issue-BugIssue has been identified as a bug in the productResolution-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