Skip to content

Creating symbolic links or junctions with New-Item doesn't work if target contains '[' or ']' #6232

Closed

Description

@lkydev

Steps to reproduce

  1. Type on an NTFS/ReFS file system:
New-Item -Path '[target]' -ItemType Directory
  1. Try creating a junction (or symbolic link, substitute with 'SymbolicLink' in the -ItemType parameter)
New-Item -Path '[source]' -Value '[target]' -ItemType Junction

Expected behavior

The junction should be created even if the target path contains square bracket characters

Actual behavior

An error message is resulted:

new-item : Cannot find path '[target]' because it does not exist.
At line:1 char:1
+ New-Item -Path '[source]' -Value '[target]' -Itemtype Junction
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (:) [New-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.NewItem Command

Note: the command can be made to work with double escapes, but it seems hacky.

new-item -path '[source]' -value "```[target```]" -Itemtype Junction

Environment data

Name                           Value
----                           -----
PSVersion                      6.0.1
PSEdition                      Core
GitCommitId                    v6.0.1
OS                             Microsoft Windows 6.1.7601 S
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
    WG-Engine-Providersbuilt-in PowerShell providers such as FileSystem, Certificates, Registry, etc.
    on Feb 24, 2018
  2. iSazonov commented on Feb 24, 2018

    @iSazonov
    Collaborator

    It is expected behavior because we support wildcards in paths.

    Perhaps we could add -LiteralPath in New-Item

  3. lkydev commented on Feb 25, 2018

    @lkydev
    Author
    1. I had the problem with the '-Value' parameter, not '-Path' or even '-LiteralPath'.

    2. So perhaps we need '-LiteralValue', not '-LiteralPath'.

  4. kwkam commented on Feb 26, 2018

    @kwkam
    Contributor

    -Name is -LiteralPath
    This should work:

    New-Item -Name '[target]' -ItemType Directory`
    New-Item -Name '[source]' -Value '[target]' -ItemType Junction
  5. mklement0 commented on Feb 26, 2018

    @mklement0
    Contributor

    Ilya (@iSazonov):

    To be clear: wildcard support should not apply when creating new items.

    NewItem's -Path parameter:

    • is, on the one hand, commendably already treated as a literal - the new item is created with the specified name as-is.

      • Similarly, -Name is treated literally, but invariably creates the new item in the current location.
    • on the other hand, the parameter name clashes with the use of -Path in cmdlets such as Get-ChildItem, where it implies wildcard support, in contrast with the -LiteralPath parameter;
      New-Item doesn't even have a -LiteralPath parameter (arguably, though, it should be added as an alias of -Path).

    Similarly, the -Value parameter - whose alias name is -Target - should always treat a value passed to it as a literal, but currently doesn't - and that is the bug.

    kwkam: -Name is not an alias of -LiteralPath, not least because New-Item doesn't even have a -LiteralPath parameter (see above). Aside from that, the inappropriate treatment of a value passed to -Value / -Target as a wildcard expression is the same.

  6. added
    Issue-BugIssue has been identified as a bug in the product
    and removed
    Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a
    on Feb 26, 2018
  7. kwkam commented on Feb 26, 2018

    @kwkam
    Contributor

    Okay I forgot I was using a patched(#5896) build.

    Michael Klement (@mklement0) For consistency with other cmdlet's -Path parameter, and for the convenient with tab completion, I think -Path should stay as is. As for the -Path and -Name, what if we want to do, for example, New-Item -Path '`[path`]/item_[0-9]' -Name '[sub]/dir' -ItemType Directory? -Name can act as -LiteralPath in my opinion.

  8. mklement0 commented on Feb 26, 2018

    @mklement0
    Contributor

    kwkam:

    I think -Path should stay as is

    I wasn't suggesting that New-Item's -Path be changed, I was suggesting that -LiteralPath be added as an alias for it.

    The reason for suggesting that is that -Path already acts the way -LiteralPath usually does.

    Conceptually speaking, -Name is a path component, and, more precisely, the leaf component - it should never accept a path.

    Unfortunately, it currently does accept a path, namely a relative one: either relative to the path specified in -Path, or, in the latter's absence, relative to the current directory.

    Aside from that, -Name doesn't - and shouldn't - accept wildcard patterns either.

    For consistency, given that -Path and -Name don't accept wildcard patterns, neither should -Value (a.k.a. -Target).

  9. Moonsilence commented on Jan 2, 2019

    @Moonsilence

    Similarly, the -Value parameter - whose alias name is -Target - should always treat a value passed to it as a literal, but currently doesn't - and that is the bug.

    Hey! Googling an Error lead me here. Trying to create a Symlink to a path that contains square brackets using

    New-Item -Path C:\my\path\cover.jpg -ItemType SymbolicLink -Value C:\my\path[1995]\cover.jpg

    "not found"

    Has this bug been fixed yet?

  10. vexx32 commented on Jan 2, 2019

    @vexx32
    Collaborator

    I see a lot of PRs with kwkam's work but I'm not sure that specific issue has been completely fixed yet.

  11. anthonypants commented on Apr 14, 2019

    @anthonypants

    This is definitely still happening in 6.2.0.

  12. JessiAuro commented on Aug 6, 2019

    @JessiAuro

    Running 6.2.2 on Linux and found this issue after hours of scratching my head. In my use case in particular it's important the original file names are preserved.

    I tried escaping wildcard characters in the value I pass to -Value/-Target, but that just results in ItemNotFoundException. Re-reading the above, I've found that double-escaping the path first does solve the problem, but that's obviously not something that should be expected of anyone.

    What's confusing me the most is from what I read I still don't quite understand why -Value isn't presumable literal. The discussion on the above PR seems much more concerned about -Path and doesn't seem to at all address that -Value should always be literal regardless of how -Path is handled.

  13. KaXaSA commented on Sep 21, 2020

    @KaXaSA
  14. 13 remaining items

  15. mklement0 commented on Jun 5, 2023

    @mklement0
    Contributor

    Sam (@sam-6174), yes, that's a viable workaround (previously mentioned); note that none of the double quotes are needed in your sample call. Also, since your example creates a hard link (/h) let me show symlink examples (cmd /c mklink /? shows help):

    # Symlink to a FILE
    cmd /c mklink    $link_file_path $src_file_path
    # Symlink to a DIRECTORY
    cmd /c mklink /D $link_file_path $src_file_path
  16. soredake commented on Dec 5, 2023

    @soredake

    Still relevant.

  17. sam-6174 commented on Dec 6, 2023

    @sam-6174

    Sam (@sam-6174), yes, that's a viable workaround (previously mentioned); note that none of the double quotes are needed in your sample call. Also, since your example creates a hard link (/h) let me show symlink examples (cmd /c mklink /? shows help):

    # Symlink to a FILE
    cmd /c mklink    $link_file_path $src_file_path
    # Symlink to a DIRECTORY
    cmd /c mklink /D $link_file_path $src_file_path

    As it turns out, there's actually not enough quotes in the original code, i.e. this...

    cmd "/c" mklink "/h" "$link_file_path" "$src_file_path"

    ... needs to be updated to this...

    cmd "/c" mklink "/h" ('"' + $link_file_path + '"') ('"' + $src_file_path + '"')

    Without these quotes, the original code will fail if $link_file_path contains an ampersand, i.e. &

  18. added
    KeepOpenThe bot will ignore these and not auto-close
    Up-for-GrabsUp-for-grabs issues are not high priorities, and may be opportunities for external contributors
    on Dec 20, 2023
  19. SteveL-MSFT commented on Dec 20, 2023

    @SteveL-MSFT
    Member

    In #13136 the PS-Committee made the decision that -Target should always be treated as literal

  20. GameMicrowave commented on Jan 5, 2025

    @GameMicrowave
    Contributor

    Yes, I met the error today, the -target should treat the path as literal always😡

  21. microsoft-github-policy-service commented on May 12, 2025

    @microsoft-github-policy-service
    Contributor

    📣 Hey @lkydev, how did we do? We would love to hear your feedback with the link below! 🗣️

    🔗 https://aka.ms/PSRepoFeedback

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 providerIn-PRIndicates that a PR is out for the issueIssue-BugIssue has been identified as a bug in the productUp-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