Finden Sie heraus, ob eine Datei ein symbolischer link in PowerShell
-
03-07-2019 - |
Frage
Ich habe ein PowerShell script, das Wandern ein Verzeichnis-Baum, und manchmal habe ich auch Hilfs-Dateien hardlinked gibt, die nicht bearbeitet werden soll.Gibt es eine einfache Möglichkeit herauszufinden, ob eine Datei (das ist, System.IO.FileInfo
) ist eine hard-link-oder nicht?
Wenn nicht, wäre es leichter, mit symbolischen links (symlinks)?
Lösung
Versuchen Sie folgendes:
function Test-ReparsePoint([string]$path) {
$file = Get-Item $path -Force -ea SilentlyContinue
return [bool]($file.Attributes -band [IO.FileAttributes]::ReparsePoint)
}
Es ist eine ziemlich minimale Implementierung, aber es sollte den Trick tun. Beachten Sie, dass diese nicht zwischen einer harten Verbindung und einem symbolischen Link unterscheiden. Darunter sie beide nehmen nur die Vorteile von NTFS Analysepunkte IIRC .
Andere Tipps
Wenn Sie Powershell haben 5+ folgende Einzeiler rekursiv listet alle Dateihardlinks, Verzeichnisverbindungen und symbolische Links und deren Ziele von d:\Temp\
Start:
dir 'd:\Temp' -recurse -force | ?{$_.LinkType} | select FullName,LinkType,Target
Ausgabe:
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}
Wenn Sie mehrere Ziele für harte Links Pflege verwenden diese Variante, die Listen Ziele Tabula getrennt:
dir 'd:\Temp' -recurse -force | ?{$_.LinkType} | select FullName,LinkType,@{ Name = "Targets"; Expression={$_.Target -join "`t"} }
Sie benötigen Administratorrechte können dieses Skript auf etwa C:\
auszuführen.
Nutzen Sie Where-Object
für das ReparsePoint Dateiattribut zu suchen.
Get-ChildItem | Where-Object { $_.Attributes -match "ReparsePoint" }
Meine Ergebnisse auf Vista, mit Keith Hill Powershell-Skript Symlinks und Hardlinks testen:
c:\markus\other>mklink symlink.doc \temp\2006rsltns.doc
symbolic link created for symlink.doc <<===>> \temp\2006rsltns.doc
c:\markus\other>fsutil hardlink create HARDLINK.doc \temp\2006rsltns.doc
Hardlink created for c:\markus\other\HARDLINK.doc <<===>> c:\temp\2006rsltns.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 [\temp\2006rsltns.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
Es zeigt, dass Symlinks Analysepunkte sind, und haben die ReparsePoint Fileattribute-Bit gesetzt, während Hardlinks nicht.
Das folgende PowerShell-Skript, das eine Liste aller Dateien in einem Verzeichnis oder die Verzeichnisse mit den-recurse-Schalter.Es wird eine Liste der Namen der Datei, ob es eine reguläre Datei oder ein hardlinked Datei und der Größe, die durch Doppelpunkte getrennt werden.
Es muss ausgeführt werden, von der PowerShell-Befehlszeile.Es spielt keine Rolle, in welchem Verzeichnis Sie es aus, wie in der Schrift.
Es verwendet die fslink utility mit Windows ausgeliefert und läuft, die gegen jede Datei mithilfe der hardlink und Liste-Schalter, und zählt die Zeilen der Ausgabe.Wenn zwei oder mehr es ist ein hardlinked-Datei.
Natürlich können Sie das Verzeichnis ändern, beginnt die Suche durch ändern der c:\windows\system
in dem Befehl.Auch das Skript schreibt die Ergebnisse in eine Datei, c:\hardlinks.txt
.Sie können den Namen ändern, oder löschen Sie einfach alles, was aus dem > Zeichen auf, und es wird auf dem Bildschirm ausgegeben.
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