Skip to content

New-Item -ItemType SymbolicLink - can't create functioning relative links  #12784

Closed

Description

Steps to reproduce

Follow example 7 here: [ https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/new-item?view=powershell-7

1. Create a folder eg. named "power"
2. In this (power) folder create an empty folder named "Notice"
3. In this (power) folder create a file named "Notice.txt"
4. As admin run this script: 
New-Item -ItemType SymbolicLink -Path .\link -Target .\Notice

Expected behavior

Functioning link to Notice named "link"

Actual behavior

link not working

#Note
Working perfectly with absolute path and in cmd
cmd >mklink /d "./link2" "./Notice"

Environment data

PS C:\retus\test2Die\power problems> $psversiontable

Name Value


PSVersion 7.1.0-preview.3
PSEdition Core
GitCommitId 7.1.0-preview.3
OS Microsoft Windows 10.0.18362
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
    Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a
    on May 25, 2020
  2. KalleOlaviNiemitalo commented on May 25, 2020

    @KalleOlaviNiemitalo

    I think it's the same bug as in #12785, i.e. caused by #8783, but more serious here because Windows supports relative symbolic links, unlike relative junctions.

    As a workaround, start PowerShell in the desired directory, instead of using Set-Location within PowerShell. New-Item -ItemType SymbolicLink will then correctly create a relative symbolic link. This works with both directory symbolic links and file symbolic links.

  3. iSazonov commented on May 26, 2020

    @iSazonov
    Collaborator

    I'd expect two different PRs.

    1. Bug - We should resolve and check absolute path here
      exists = GetFileSystemInfo(strTargetPath, out isDirectory) != null;
    2. Enhancement - Since it is possible to create symbolic links to non-existing targets and default always is file symlink we should add new type SymbolicLinkDirectory to force creating link to directory.
  4. added
    WG-Engine-Providersbuilt-in PowerShell providers such as FileSystem, Certificates, Registry, etc.
    Issue-BugIssue has been identified as a bug in the product
    Issue-Enhancementthe issue is more of a feature request than a bug
    Up-for-GrabsUp-for-grabs issues are not high priorities, and may be opportunities for external contributors
    and removed
    Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a
    on May 26, 2020
  5. KalleOlaviNiemitalo commented on May 26, 2020

    @KalleOlaviNiemitalo

    This seems a duplicate of #9127.

  6. vexx32 commented on May 26, 2020

    @vexx32
    Collaborator

    Seems like it has the same cause, but a slightly different symptom, aye.

  7. KalleOlaviNiemitalo commented on Jun 26, 2020

    @KalleOlaviNiemitalo

    Should retest this with v7.1.0-preview.4.

  8. iSazonov commented on Jun 26, 2020

    @iSazonov
    Collaborator

    The example works for me.

  9. anthonyvdotbe commented on Mar 7, 2021

    @anthonyvdotbe

    This issue occurs for me (though not always, and I don't understand yet when it does/doesn't) with v7.1.2 on Windows 10.0.19042.0.

    Edit: I can consistently reproduce this by launching a Windows Sandbox, installing PowerShell 7.1.2 in it, and running the following 2 commands:

    New-Item -ItemType Directory -Path target
    New-Item -ItemType SymbolicLink -Path link -Value target
    
  10. darthwalsh commented on Jul 6, 2023

    @darthwalsh

    The actual behavior was changed, to now produce an error on relative paths: #18251 #19409

  11. darthwalsh commented on Jan 9, 2024

    @darthwalsh

    For comparison. this is working on macOS:

    $ touch Notice
    $ New-Item -ItemType SymbolicLink -Path .\link -Target .\Notice
    
        Directory: /var/folders/v7/p7wfv43s725dwxcp5fn3vyz80000gp/T/DEL-20240109-12-54-05.87
    
    UnixMode         User Group         LastWriteTime         Size Name
    --------         ---- -----         -------------         ---- ----
    lrwxr-xr-x    walshca staff        1/9/2024 12:54            8 link -> ./Notice
    
    $ ls -l
    total 0
    -rw-r--r--@ 1 walshca  staff  0 Jan  9 12:54 Notice
    lrwxr-xr-x@ 1 walshca  staff  8 Jan  9 12:54 link -> ./Notice
    $ $PSVersionTable
    
    Name                           Value
    ----                           -----
    PSVersion                      7.4.0
    PSEdition                      Core
    GitCommitId                    7.4.0
    OS                             Darwin 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:54:51 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6030
    Platform                       Unix
    PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
    PSRemotingProtocolVersion      2.3
    SerializationVersion           1.1.0.1
    WSManStackVersion              3.0
    

    If it also works on Windows then the issue should be closed

  12. darthwalsh commented on Jul 9, 2024

    @darthwalsh

    Theodor Heiselberg (@sukkergris) can you check if this still reproduces for you on latest pwsh? Tried on Windows and i'm seeing functional relative links

    $ touch Notice
    $ New-Item -ItemType SymbolicLink -Path .\link -Target .\Notice
    
        Directory: C:\Users\cwalsh\AppData\Local\Temp\DEL-20240709-08-18-13.58
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    la---            7/9/2024  8:18 AM              0 link -> .\Notice
    
    $ cat link
    $ "ABC" > Notice
    $ cat link
    ABC
    $ gci
    
        Directory: C:\Users\cwalsh\AppData\Local\Temp\DEL-20240709-08-18-13.58
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    la---            7/9/2024  8:18 AM              0 link -> .\Notice
    -a---            7/9/2024  8:18 AM              5 Notice
    
    $ $psversiontable
    
    Name                           Value
    ----                           -----
    PSVersion                      7.4.2
    PSEdition                      Core
    GitCommitId                    7.4.2
    OS                             Microsoft Windows 10.0.19045
    Platform                       Win32NT
    PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
    PSRemotingProtocolVersion      2.3
    SerializationVersion           1.1.0.1
    WSManStackVersion              3.0
    
    $ cmd
    Microsoft Windows [Version 10.0.19045.4529]
    (c) Microsoft Corporation. All rights reserved.
    
    C:\Users\cwalsh\AppData\Local\Temp\DEL-20240709-08-18-13.58>more link
    ABC
    
  13. KalleOlaviNiemitalo commented on Jul 9, 2024

    @KalleOlaviNiemitalo

    It's still not working quite right:

    PowerShell 7.4.3
    Loading personal and system profiles took 519ms.
    PS C:\temp> New-Item -ItemType Directory subdir
    
        Directory: C:\temp
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    d----            9.7.2024    19.28                subdir
    
    PS C:\temp> Set-Location subdir
    PS C:\temp\subdir> New-Item -ItemType Directory target
    
        Directory: C:\temp\subdir
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    d----            9.7.2024    19.29                target
    
    PS C:\temp\subdir> New-Item -ItemType SymbolicLink -Path link -Target target
    
        Directory: C:\temp\subdir
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    la---            9.7.2024    19.29              0 link -> target
    
    PS C:\temp\subdir> Set-Location link
    Set-Location: Cannot find path 'link' because it does not exist.
    

    Above, the New-Item cmdlet should have created a directory symbolic link, because -Target target refers to an existing directory. It incorrectly created a file symbolic link instead.

    However, if I then start another PowerShell process in the directory and retry the operation with that, it works fine:

    PS C:\temp\subdir> pwsh
    PowerShell 7.4.3
    Loading personal and system profiles took 506ms.
    PS C:\temp\subdir> Remove-Item link
    PS C:\temp\subdir> New-Item -ItemType SymbolicLink -Path link -Target target
    
        Directory: C:\temp\subdir
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    l----            9.7.2024    19.30                link -> target
    
    PS C:\temp\subdir> Set-Location link
    PS C:\temp\subdir\link>
    

    It seems that, when New-Item is checking whether the -Target is a file or a directory, in order to decide whether it should create a file symbolic link or a directory symbolic link, it resolves the target path against the directory in which PowerShell was started, rather than the directory in which the link is being created.

  14. Universal-Invariant commented on Apr 7, 2025

    @Universal-Invariant

    New-Item -Path "Z:\SP" -ItemType SymbolicLink -Value "\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2\windows\system32\config"

    fails with

    New-Item : Cannot find path '\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2\windows\system32\config' because it does
    not exist.

    New-Item -Path "Z:" -Name "SP" -ItemType SymbolicLink -Value FileSystem::$snapshotPath
    also fails.

    but

    mklink /d Z:\SP "\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2\windows\system32\config"

    works

    One can get at this by creating a shadow volume:

    $Path = "C:\windows\system32\config"
    $directoryRoot = [System.IO.Directory]::GetDirectoryRoot($Path).ToString()
    
    $shadow = (Get-WmiObject -List Win32_ShadowCopy).Create($directoryRoot, "ClientAccessible")
    $shadowCopy = Get-WmiObject Win32_ShadowCopy | ? { $_.ID -eq $shadow.ShadowID }
    $snapshotPath = $shadowCopy.DeviceObject + "\" + $Path.Replace($directoryRoot, "") + "\"
    
        cmd.exe /c "mklink /d  Z:\SP "$snapshotPath""
    

    (I've played around with various "solutions" but nothing works while mklink works fine)

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

    Area-FileSystem-Providerspecific to the FileSystem providerIssue-BugIssue has been identified as a bug in the productIssue-Enhancementthe issue is more of a feature request than a bugResolution-No ActivityIssue has had no activity for 6 months or moreUp-for-GrabsUp-for-grabs issues are not high priorities, and may be opportunities for external contributorsWG-Cmdletsgeneral cmdlet issues

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions