Can PowerShell 1.0 create hard and soft links analogous to the Unix variety?

If this isn't built in, can someone point me to a site that has a ps1 script that mimics this?

This is a necessary function of any good shell, IMHO. :)

11

Best Answer


Windows 10 (and Powershell 5.0 in general) allows you to create symbolic links via the New-Item cmdlet.

Usage:

New-Item -Path C:\LinkDir -ItemType SymbolicLink -Value F:\RealDir

Or in your profile:

function make-link ($target, $link) {New-Item -Path $link -ItemType SymbolicLink -Value $target}

Turn on Developer Mode to not require admin privileges when making links with New-Item:

enter image description here

You can call the mklink provided by cmd, from PowerShell to make symbolic links:

cmd /c mklink c:\path\to\symlink c:\target\file

You must pass /d to mklink if the target is a directory.

cmd /c mklink /d c:\path\to\symlink c:\target\directory

For hard links, I suggest something like Sysinternals Junction.

Add "pscx" module

No, it isn't built into PowerShell. And the mklink utility cannot be called on its own on Windows Vista/Windows 7 because it is built directly into cmd.exe as an "internal command".

You can use the PowerShell Community Extensions (free). There are several cmdlets for reparse points of various types:

  • New-HardLink,
  • New-SymLink,
  • New-Junction,
  • Remove-ReparsePoint
  • and others.

In Windows 7, the command is

fsutil hardlink create new-file existing-file

PowerShell finds it without the full path (c:\Windows\system32) or extension (.exe).

New-Symlink:

Function New-SymLink ($link, $target){if (test-path -pathtype container $target){$command = "cmd /c mklink /d"}else{$command = "cmd /c mklink"}invoke-expression "$command $link $target"}

Remove-Symlink:

Function Remove-SymLink ($link){if (test-path -pathtype container $link){$command = "cmd /c rmdir"}else{$command = "cmd /c del"}invoke-expression "$command $link"}

Usage:

New-Symlink "c:\foo\bar" "c:\foo\baz"Remove-Symlink "c:\foo\bar"

Try junction.exe

The Junction command line utility from SysInternals makes creating and deleting junctions easy.

Further reading

  • MS Terminology: soft != symbolic
    Microsoft uses "soft link" as another name for "junction".
    However: a "symbolic link" is something else entirely.
    See MSDN: Hard Links and Junctions in Windows.
    (This is in direct contradiction to the general usage of those terms where "soft link" and "symbolic link" ("symlink") DO mean the same thing.)

I combined two answers (@bviktor and @jocassid). It was tested on Windows 10 and Windows Server 2012.

function New-SymLink ($link, $target){if ($PSVersionTable.PSVersion.Major -ge 5){New-Item -Path $link -ItemType SymbolicLink -Value $target}else{$command = "cmd /c mklink /d"invoke-expression "$command ""$link"" ""$target"""}}

You can use this utility:

c:\Windows\system32\fsutil.exe create hardlink

I wrote a PowerShell module that has native wrappers for MKLINK. https://gist.github.com/2891103

Includes functions for:

  • New-Symlink
  • New-HardLink
  • New-Junction

Captures the MKLINK output and throws proper PowerShell errors when necessary.

Actually, the Sysinternals junction command only works with directories (don't ask me why), so it can't hardlink files. I would go with cmd /c mklink for soft links (I can't figure why it's not supported directly by PowerShell), or fsutil for hardlinks.

If you need it to work on Windows XP, I do not know of anything other than Sysinternals junction, so you might be limited to directories.

I found this the simple way without external help. Yes, it uses an archaic DOS command but it works, it's easy, and it's clear.

$target = cmd /c dir /a:l | ? { $_ -match "mySymLink \[.*\]$" } | % `{$_.Split([char[]] @( '[', ']' ), [StringSplitOptions]::RemoveEmptyEntries)[1]}

This uses the DOS dir command to find all entries with the symbolic link attribute, filters on the specific link name followed by target "[]" brackets, and for each - presumably one - extracts just the target string.