Scopri se un file è un collegamento simbolico in PowerShell
-
03-07-2019 - |
Domanda
Sto avendo uno script PowerShell che sta camminando su un albero di directory, ea volte ho dei file ausiliari collegati lì che non dovrebbero essere elaborati. C'è un modo semplice per scoprire se un file (ovvero System.IO.FileInfo
) è un collegamento reale o no?
In caso contrario, sarebbe più facile con i collegamenti simbolici (collegamenti simbolici)?
Soluzione
Prova questo:
function Test-ReparsePoint([string]$path) {
$file = Get-Item $path -Force -ea SilentlyContinue
return [bool]($file.Attributes -band [IO.FileAttributes]::ReparsePoint)
}
È un'implementazione piuttosto minimale, ma dovrebbe fare il trucco. Si noti che ciò non distingue tra un collegamento reale e un collegamento simbolico. Sotto, entrambi sfruttano semplicemente Reparse points NTFS , IIRC .
Altri suggerimenti
Se si dispone di Powershell 5+, il seguente one-liner elenca in modo ricorsivo tutti i file hardlink, giunzioni di directory e collegamenti simbolici e i relativi target a partire da d: \ Temp \
:
dir 'd:\Temp' -recurse -force | ?{ Se si dispone di Powershell 5+, il seguente one-liner elenca in modo ricorsivo tutti i file hardlink, giunzioni di directory e collegamenti simbolici e i relativi target a partire da d: \ Temp \
:
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}
Output:
dir 'd:\Temp' -recurse -force | ?{ Se si dispone di Powershell 5+, il seguente one-liner elenca in modo ricorsivo tutti i file hardlink, giunzioni di directory e collegamenti simbolici e i relativi target a partire da d: \ Temp \
:
dir 'd:\Temp' -recurse -force | ?{ Se si dispone di Powershell 5+, il seguente one-liner elenca in modo ricorsivo tutti i file hardlink, giunzioni di directory e collegamenti simbolici e i relativi target a partire da d: \ Temp \
:
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}
Output:
<*>
Se ti interessano più target per hardlink, usa questa variante che elenca target separati da tabulazione:
<*>
Potresti aver bisogno dei privilegi di amministratore per eseguire questo script dicendo C: \
.
.LinkType} | select FullName,LinkType,Target
Output:
<*>
Se ti interessano più target per hardlink, usa questa variante che elenca target separati da tabulazione:
<*>
Potresti aver bisogno dei privilegi di amministratore per eseguire questo script dicendo C: \
.
.LinkType} | select FullName,LinkType,@{ Name = "Targets"; Expression={ Se si dispone di Powershell 5+, il seguente one-liner elenca in modo ricorsivo tutti i file hardlink, giunzioni di directory e collegamenti simbolici e i relativi target a partire da d: \ Temp \
:
dir 'd:\Temp' -recurse -force | ?{ Se si dispone di Powershell 5+, il seguente one-liner elenca in modo ricorsivo tutti i file hardlink, giunzioni di directory e collegamenti simbolici e i relativi target a partire da d: \ Temp \
:
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}
Output:
<*>
Se ti interessano più target per hardlink, usa questa variante che elenca target separati da tabulazione:
<*>
Potresti aver bisogno dei privilegi di amministratore per eseguire questo script dicendo C: \
.
.LinkType} | select FullName,LinkType,Target
Output:
<*>
Se ti interessano più target per hardlink, usa questa variante che elenca target separati da tabulazione:
<*>
Potresti aver bisogno dei privilegi di amministratore per eseguire questo script dicendo C: \
.
.Target -join "`t"} }
Se ti interessano più target per hardlink, usa questa variante che elenca target separati da tabulazione:
<*>
Potresti aver bisogno dei privilegi di amministratore per eseguire questo script dicendo C: \
.
.LinkType} | select FullName,LinkType,Target
Output:
<*>Se ti interessano più target per hardlink, usa questa variante che elenca target separati da tabulazione:
<*> Potresti aver bisogno dei privilegi di amministratore per eseguire questo script dicendo C: \
.
Utilizza Where-Object
per cercare l'attributo del file ReparsePoint.
Get-ChildItem | Where-Object { Utilizza Where-Object
per cercare l'attributo del file ReparsePoint.
<*>.Attributes -match "ReparsePoint" }
I miei risultati su Vista, usando lo script PowerShell di Keith Hill per testare collegamenti simbolici e hardlink:
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
Mostra che i collegamenti simbolici sono punti di analisi e hanno impostato il bit ReparsePoint FileAttribute, mentre i collegamenti fisici no.
Il seguente script di PowerShell elencherà tutti i file in una directory o directory con l'opzione -recurse. Elencherà il nome del file, che si tratti di un file normale o di un file con collegamento fisico e la dimensione, separati da due punti.
Deve essere eseguito dalla riga di comando di PowerShell. Non importa da quale directory lo si esegue come è impostato nello script.
Utilizza l'utility fslink fornita con Windows e lo esegue su ogni file usando gli switch hardlink ed list e conta le righe di output. Se due o più è un file con collegamento fisico.
Puoi ovviamente cambiare la directory da cui inizia la ricerca cambiando c: \ windows \ system
nel comando. Inoltre, lo script scrive semplicemente i risultati in un file, c: \ hardlinks.txt
. Puoi cambiare il nome o semplicemente eliminare tutto da > carattere attivo e verrà visualizzato sullo schermo.
Get-ChildItem -path C:\Windows\system -file -recurse -force |
foreach-object {
if ((fsutil hardlink list Il seguente script di PowerShell elencherà tutti i file in una directory o directory con l'opzione -recurse. Elencherà il nome del file, che si tratti di un file normale o di un file con collegamento fisico e la dimensione, separati da due punti.
Deve essere eseguito dalla riga di comando di PowerShell. Non importa da quale directory lo si esegue come è impostato nello script.
Utilizza l'utility fslink fornita con Windows e lo esegue su ogni file usando gli switch hardlink ed list e conta le righe di output. Se due o più è un file con collegamento fisico.
Puoi ovviamente cambiare la directory da cui inizia la ricerca cambiando c: \ windows \ system
nel comando. Inoltre, lo script scrive semplicemente i risultati in un file, c: \ hardlinks.txt
. Puoi cambiare il nome o semplicemente eliminare tutto da > carattere attivo e verrà visualizzato sullo schermo.
<*>.fullname).count -ge 2) {
Il seguente script di PowerShell elencherà tutti i file in una directory o directory con l'opzione -recurse. Elencherà il nome del file, che si tratti di un file normale o di un file con collegamento fisico e la dimensione, separati da due punti.
Deve essere eseguito dalla riga di comando di PowerShell. Non importa da quale directory lo si esegue come è impostato nello script.
Utilizza l'utility fslink fornita con Windows e lo esegue su ogni file usando gli switch hardlink ed list e conta le righe di output. Se due o più è un file con collegamento fisico.
Puoi ovviamente cambiare la directory da cui inizia la ricerca cambiando c: \ windows \ system
nel comando. Inoltre, lo script scrive semplicemente i risultati in un file, c: \ hardlinks.txt
. Puoi cambiare il nome o semplicemente eliminare tutto da > carattere attivo e verrà visualizzato sullo schermo.
<*>.PSChildname + ":Hardlinked:" + Il seguente script di PowerShell elencherà tutti i file in una directory o directory con l'opzione -recurse. Elencherà il nome del file, che si tratti di un file normale o di un file con collegamento fisico e la dimensione, separati da due punti.
Deve essere eseguito dalla riga di comando di PowerShell. Non importa da quale directory lo si esegue come è impostato nello script.
Utilizza l'utility fslink fornita con Windows e lo esegue su ogni file usando gli switch hardlink ed list e conta le righe di output. Se due o più è un file con collegamento fisico.
Puoi ovviamente cambiare la directory da cui inizia la ricerca cambiando c: \ windows \ system
nel comando. Inoltre, lo script scrive semplicemente i risultati in un file, c: \ hardlinks.txt
. Puoi cambiare il nome o semplicemente eliminare tutto da > carattere attivo e verrà visualizzato sullo schermo.
<*>.Length
} else {
Il seguente script di PowerShell elencherà tutti i file in una directory o directory con l'opzione -recurse. Elencherà il nome del file, che si tratti di un file normale o di un file con collegamento fisico e la dimensione, separati da due punti.
Deve essere eseguito dalla riga di comando di PowerShell. Non importa da quale directory lo si esegue come è impostato nello script.
Utilizza l'utility fslink fornita con Windows e lo esegue su ogni file usando gli switch hardlink ed list e conta le righe di output. Se due o più è un file con collegamento fisico.
Puoi ovviamente cambiare la directory da cui inizia la ricerca cambiando c: \ windows \ system
nel comando. Inoltre, lo script scrive semplicemente i risultati in un file, c: \ hardlinks.txt
. Puoi cambiare il nome o semplicemente eliminare tutto da > carattere attivo e verrà visualizzato sullo schermo.
<*>.PSChildname + ":RegularFile:" + Il seguente script di PowerShell elencherà tutti i file in una directory o directory con l'opzione -recurse. Elencherà il nome del file, che si tratti di un file normale o di un file con collegamento fisico e la dimensione, separati da due punti.
Deve essere eseguito dalla riga di comando di PowerShell. Non importa da quale directory lo si esegue come è impostato nello script.
Utilizza l'utility fslink fornita con Windows e lo esegue su ogni file usando gli switch hardlink ed list e conta le righe di output. Se due o più è un file con collegamento fisico.
Puoi ovviamente cambiare la directory da cui inizia la ricerca cambiando c: \ windows \ system
nel comando. Inoltre, lo script scrive semplicemente i risultati in un file, c: \ hardlinks.txt
. Puoi cambiare il nome o semplicemente eliminare tutto da > carattere attivo e verrà visualizzato sullo schermo.
<*>.Length
}
} > c:\hardlinks.txt