Crear enlaces duros y blandos con PowerShell

226

¿Puede PowerShell 1.0 crear enlaces duros y blandos análogos a la variedad Unix?

Si esto no está integrado, ¿alguien puede señalarme un sitio que tenga un script ps1 que imite esto?

Esta es una función necesaria de cualquier buen shell, en mi humilde opinión. :)

Mike T
fuente
66
Los usuarios de Windows 10 ven stackoverflow.com/a/34905638/195755 . Windows 10 está integrado. Copiar / Pegar: New-Item -Type y presione tabulador para recorrer las opciones Hardlink, SymbolicLinky Junctionaparece para mí. Sistema operativo Works Win 10, Server 2016+ o anterior con Powershell 5.0+ instalado a través de Windows Management Framework 5.0+.
yzorg
2
No puedo encontrar documentación decente de MSDN / TechNet para New-Item -Type HardLinkni New-Item -Type SymbolicLink. Los documentos de elementos nuevos se vinculan help about_Providers, sugiere que lea la ayuda para cada proveedor (que no está vinculado). Pero si lo buscas en Google, hay muchos rumores en la comunidad de PowerShell New-Item -Type HardLink. Parece que el equipo de ingeniería de PowerShell ha creado puntos de extensión de proveedores que confunden al equipo de documentación.
yzorg

Respuestas:

253

Puede llamar al mklinkproporcionado por cmd, desde PowerShell para hacer enlaces simbólicos:

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

Debe pasar /da mklinksi el destino es un directorio.

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

Para enlaces duros, sugiero algo como Sysinternals Junction .

Jason R. Coombs
fuente
29
Si tiene un perfil de PowerShell, también puede realizar una función rápidafunction mklink { cmd /c mklink $args }
Joe Young, el
14
y si desea hacer un enlace de directorio, el comando será algo así como {cmd / c mklink / D "toDir" fromDir}
DavidDraughn
99
Agregar el parámetro / H a mklink creará un enlace rígido sin la necesidad de un programa de terceros como Sysinternals Junction.
Fopedush
3
Creo que jocassid tiene la mejor respuesta. En mi humilde opinión, debemos tratar de enseñar cómo utilizar PowerShell, no utilizar exploits y hacks a través de cmd.exe.
Cameron Oakenleaf el
2
@SergeVoloshenko Seguro que sí . Es cierto que el uso New-Item detecta si el objetivo es un directorio , pero New-Item fallará si el objetivo no existe, mientras que mklink creará el enlace simbólico independientemente .
Jason R. Coombs
266

Windows 10 (y Powershell 5.0 en general) le permite crear enlaces simbólicos a través del cmdlet New-Item .

Uso:

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

O en tu perfil:

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

Active el modo de desarrollador para no requerir privilegios de administrador al hacer enlaces con New-Item:

ingrese la descripción de la imagen aquí

jocassid
fuente
2
Este enlace ahora está roto debido a la reorganización de la documentación de MS. Encontré un enlace de trabajo actual en technet.microsoft.com/en-us/library/hh849795.aspx
Aaron Thomas
3
New-Item -Path C: \ LinkDir -ItemType SymbolicLink -Value F: \ RealDir
Daniel Fisher lennybacon
77
desde Windows v1703, mklink permite crear enlaces simbólicos sin elevación de cuenta, si el modo Desarrollador está habilitado en Configuración, Nuevo elemento no. Ojalá en la próxima actualización.
papo
Fascinante. Entonces, esto es bastante distinto de un .lnkacceso directo de Explorer . En el explorador, un acceso directo y un enlace simbólico del mismo nombre se muestran uno al lado del otro como si nada estuviera mal. Sus comportamientos son sutilmente diferentes; siguiendo el enlace simbólico se muestra la ruta absoluta en la barra del Explorador. Seguir el acceso directo lo trata como si el directorio padre del enlace simbólico fuera el padre verdadero.
BaseZen
1
Con la respuesta aceptada , pude usar rutas relativas, que no era el caso con el New-Itemcomando.
Dave F
41

Agregar módulo "pscx"

No, no está integrado en PowerShell. Y la mklinkutilidad no se puede invocar sola en Windows Vista / Windows 7 porque está integrada directamente cmd.execomo un "comando interno" .

Puede usar las Extensiones de comunidad de PowerShell (gratis). Existen varios cmdlets para puntos de análisis de varios tipos:

  • New-HardLink,
  • New-SymLink,
  • New-Junction,
  • Remove-ReparsePoint
  • y otros.
Keith Hill
fuente
1
Buen intento. Sin embargo, si desea ejecutar el servidor XP o W2K3 en x32 o x64, New-Symlink no funciona. En XP, le dirá cortésmente que debe ejecutar Vista para este comando. En el servidor W2K3, se rompe completamente.
Mike T
Eso es porque XP no admite enlaces simbólicos. Esa es una característica nueva de Vista. Creo que el servidor W2K3 tampoco admite enlaces simbólicos. Tienes que subir al servidor W2K8 para obtener soporte para enlaces simbólicos. Investigaré por qué new-symlink está bombardeando en W2k3, debería aparecer un mensaje de error similar a XP.
Keith Hill
Intenté new-junction y eso funcionará para mí. Lástima que la funcionalidad del enlace no se degrada a las uniones en XP y W2K3
Mike T
sobre el uso adicional de new-junction ... obtengo una unión al nuevo punto de análisis. Sin embargo, los errores ls (o get-childitem) indican que ... "El nombre de archivo, el nombre del directorio o la sintaxis de la etiqueta de volumen es incorrecta" Si intento ingresar un subdirectorio desde allí.
Mike T
2
Los usuarios de Windows 10 ven la respuesta stackoverflow.com/a/34905638/195755 . Windows 10 está integrado. Copiar / Pegar: New-Item -Type y presione tabulador para recorrer las opciones. Hardlink, SymbolicLinky Junctionaparece para mí. Funciona con Win 10, Server 2016+ o un sistema operativo anterior con Powershell 5.0 instalado a través de Windows Management Framework 5.0+.
yzorg
23

En Windows 7, el comando es

fsutil hardlink create new-file existing-file

PowerShell lo encuentra sin la ruta completa (c: \ Windows \ system32) o la extensión (.exe).

quigi
fuente
1
fsutil hardlinkrequiere new-filey existing-fileestar en el mismo disco. Si eso te importa, usa cmd's mklink /cen su lugar.
trapeado el
99
Los enlaces duros @mopsled, por definición, deben estar en el mismo volumen que el objetivo, esto no es una limitación específica para fsutil(o Windows para el caso)
Dev
¿hay un equivalente para enlaces simbólicos y enlaces "blandos"?
jshall
Trabajó también en un sistema Windows10.
FooF
15

Nuevo enlace simbólico:

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"
}

Eliminar enlace simbólico:

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

    invoke-expression "$command $link"
}

Uso:

New-Symlink "c:\foo\bar" "c:\foo\baz"
Remove-Symlink "c:\foo\bar"
bviktor
fuente
2
Los usuarios de Windows 10 ven stackoverflow.com/a/34905638/195755 . Windows 10 está integrado. Copiar / Pegar: New-Item -Type y presione tabulador para recorrer las opciones. Hardlink, SymbolicLinky Junctionaparece para mí. Funciona con Win 10, Server 2016+ o un sistema operativo anterior con Powershell 5.0 instalado a través de Windows Management Framework 5.0+.
yzorg
O si el nombre del archivo los contiene.
Chris Charabaruk
10

Prueba junction.exe

La utilidad de línea de comando Junction de SysInternals facilita la creación y eliminación de uniones.

Otras lecturas

  • Terminología de MS: soft! = Simbólico
    Microsoft usa "soft link" como otro nombre para "junction" .
    Sin embargo: un "enlace simbólico" es algo completamente distinto.
    Consulte MSDN: enlaces duros y uniones en Windows.
    (Esto está en contradicción directa con el uso general de los términos donde "enlace suave" y "enlace simbólico" ( "enlace simbólico" ) SIGNIFICA lo mismo ).
notandy
fuente
El uso correcto de esta utilidad me permite unir otro directorio y recorrer sus subdirectorios con éxito. Todo en XP y W2K3. Simplemente agregue el exe a un directorio en su RUTA y llámelo como de costumbre.
Mike T
No creo que pueda usar junction.exe para crear enlaces simbólicos.
Jason R. Coombs
3
Es mejor usar el mklinkque se envía con Windows. Si tiene una versión de Windows con la que se envía.
Borrado el
5

Puedes usar esta utilidad:

c:\Windows\system32\fsutil.exe create hardlink
Cheeso
fuente
1
Sin embargo, requerirá privilegios elevados. Crear enlaces duros generalmente no lo hace.
Joey
3

Escribí un módulo de PowerShell que tiene envoltorios nativos para MKLINK. https://gist.github.com/2891103

Incluye funciones para:

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

Captura la salida de MKLINK y arroja los errores de PowerShell adecuados cuando es necesario.

joshuapoehls
fuente
3

Combiné dos respuestas (@bviktor y @jocassid). Fue probado en Windows 10 y 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"""
    }
}
mhenry1384
fuente
1

En realidad, el comando Sysinternals junction solo funciona con directorios (no me pregunte por qué), por lo que no puede vincular archivos. Optaría cmd /c mklinkpor enlaces blandos (no puedo entender por qué no es compatible directamente con PowerShell) o fsutilpor enlaces duros.

Si necesita que funcione en Windows XP, no conozco nada más que Sysinternals junction, por lo que puede estar limitado a directorios.

luego
fuente
-1

Encontré esto de la manera simple sin ayuda externa. Sí, utiliza un comando arcaico de DOS, pero funciona, es fácil y está claro.

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

Utiliza el comando dir DOS para encontrar todas las entradas con el atributo de enlace simbólico, filtra el nombre del enlace específico seguido de los corchetes "[]" de destino y para cada uno, presumiblemente uno, extrae solo la cadena de destino.

Steven
fuente
55
¿Es esta una respuesta para una pregunta diferente?
Allanrbo