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)?

War es hilfreich?

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top