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)?
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 .
utilise Where-Object
pour rechercher L'attribut Repsepoint file.
Get-ChildItem | Where-Object { $_.Attributes -match "ReparsePoint" }
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:\
.
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.
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