Savoir si un fichier est un lien symbolique dans PowerShell

j'ai un script PowerShell qui marche dans un arborescence de répertoires, et parfois j'ai des fichiers auxiliaires reliés en dur qui ne devraient pas être traités. Est-il un moyen facile de savoir si un fichier (qui est, System.IO.FileInfo ) est un lien en dur ou pas?

dans la négative, serait-ce plus facile avec des liens symboliques (liens symboliques)?

20
demandé sur Peter Mortensen 2009-05-03 23:27:28

5 réponses

essayez ceci:

function Test-ReparsePoint([string]$path) {
  $file = Get-Item $path -Force -ea SilentlyContinue
  return [bool]($file.Attributes -band [IO.FileAttributes]::ReparsePoint)
}

c'est une implémentation assez minime, mais ça devrait faire l'affaire. Notez que ceci ne distingue pas entre un lien dur et un lien symbolique. En dessous, ils profitent tous les deux de NTFS reparse points , IIRC .

30
répondu Keith Hill 2017-04-06 18:13:48

utilise Where-Object pour rechercher L'attribut Repsepoint file.

Get-ChildItem | Where-Object { $_.Attributes -match "ReparsePoint" }
13
répondu k3yz101 2015-12-30 16:59:04

si vous avez Powershell 5+ l'une des lignes suivantes liste récursivement tous les liens durs de fichiers, les jonctions de répertoires et les liens symboliques et leurs cibles à partir de d:\Temp\ :

dir 'd:\Temp' -recurse -force | ?{$_.LinkType} | select FullName,LinkType,Target

sortie:

FullName                                LinkType     Target
--------                                --------     ------
D:\Temp\MyJunctionDir                   Junction     {D:\exp\junction_target_dir}
D:\Temp\MySymLinkDir                    SymbolicLink {D:\exp\symlink_target_dir}
D:\Temp\MyHardLinkFile.txt              HardLink     {D:\temp\MyHardLinkFile2.txt, D:\exp\hlink_target.xml}
D:\Temp\MyHardLinkFile2.txt             HardLink     {D:\temp\MyHardLinkFile.txt, D:\exp\hlink_target.xml}
D:\Temp\MySymLinkFile.txt               SymbolicLink {D:\exp\symlink_target.xml}
D:\Temp\MySymLinkDir\MySymLinkFile2.txt SymbolicLink {D:\temp\normal file.txt}

si vous vous souciez de cibles multiples pour les liens durs utilisez cette variation qui liste des cibles tab-séparé:

dir 'd:\Temp' -recurse -force | ?{$_.LinkType} | select FullName,LinkType,@{ Name = "Targets"; Expression={$_.Target -join "`t"} }

vous pourriez avoir besoin des privilèges d'administrateur pour exécuter ce script sur say C:\ .

11
répondu Anton Krouglov 2017-02-09 10:27:00

Mes résultats sur Vista, à l'aide de Keith Hill script powershell pour tester les liens symboliques et les liens:

c:\markus\other>mklink symlink.doc \temp06rsltns.doc
symbolic link created for symlink.doc <<===>> \temp06rsltns.doc

c:\markus\other>fsutil hardlink create HARDLINK.doc  \temp06rsltns.doc
Hardlink created for c:\markus\other\HARDLINK.doc <<===>> c:\temp06rsltns.doc

c:\markus\other>dir
 Volume in drive C has no label.
 Volume Serial Number is C8BC-2EBD

 Directory of c:\markus\other

02/12/2010  05:21 PM    <DIR>          .
02/12/2010  05:21 PM    <DIR>          ..
01/10/2006  06:12 PM            25,088 HARDLINK.doc
02/12/2010  05:21 PM    <SYMLINK>      symlink.doc [\temp06rsltns.doc]
               2 File(s)         25,088 bytes
               2 Dir(s)   6,805,803,008 bytes free

c:\markus\other>powershell \script\IsSymLink.ps1 HARDLINK.doc
False

c:\markus\other>powershell \script\IsSymLink.ps1 symlink.doc
True

il montre que les liens symboliques sont des points de reparse, et ont le bit Repsepoint FileAttribute défini, tandis que les liens durs ne le sont pas.

3
répondu Cheeso 2010-02-12 22:26:40

le script PowerShell suivant listera tous les fichiers d'un ou de plusieurs répertoires avec le commutateur-recurse. Il affichera le nom du fichier, qu'il s'agisse d'un fichier régulier ou d'un fichier relié, et la taille, séparée par des points.

il doit être exécuté à partir de la ligne de commande PowerShell. Peu importe le répertoire dans lequel vous l'exécutez, tel qu'il est défini dans le script.

il utilise l'utilitaire fslink livré avec Windows et fonctionne que pour chaque fichier utilisant le lien dur et les commutateurs de liste et compte les lignes de sortie. Si deux ou plus, c'est un hardlinked fichier.

vous pouvez bien sûr changer le répertoire de départ de la recherche en changeant le c:\windows\system dans la commande. En outre, le script écrit simplement les résultats dans un fichier, c:\hardlinks.txt . Vous pouvez changer le nom ou simplement tout supprimer du caractère > sur et il sortira à l'écran.

Get-ChildItem -path C:\Windows\system -file -recurse -force | 
    foreach-object {
        if ((fsutil hardlink list $_.fullname).count -ge 2) {
            $_.PSChildname + ":Hardlinked:" + $_.Length
        } else {
            $_.PSChildname + ":RegularFile:" + $_.Length
        }
    } > c:\hardlinks.txt
2
répondu b_ball 2015-06-13 02:16:31