概要
カレントディレクトリ以下のフォルダから、
ウィンドウズのショートカット「LNKファイル」を再帰的に見つけ出し、
LNKファイルのプロパティを一覧にして収集します。
その結果をCSVファイルとして出力します。
CSVの文字コードはExcelで読み込めるようにunicodeとします。
想定する状況
- NAS「A」の共有フォルダ内にある大量のファイルにはショートカットファイルが含まれます。
- このショートカットのリンク先は大半がNAS「B」の共有フォルダ内になっています。
- ある日、NAS「B」の共有フォルダの名称を変更することになりました。
- NAS「A」「B」ともにフォルダ階層が入り組んでおり、すべて人力で探すのは困難です。
- 最優先で、どのようなリンクが形成されているのか状況把握する必要があります。
※NAS(Network Attached Storage)としましたが、フォルダなら何でもいいと思います。
環境
スクリプトを実行する場所がWindowsであればよいので、
対象の共有フォルダがLinuxやUnix上にあっても動作します。
- Windows 10
- Powershell 7
起動スクリプト
@echo off
echo "Launch ShortCut Crawler !!"
pushd %~dp0
pwsh -Noprofile -ExecutionPolicy RemoteSigned -File ./main.ps1
echo "Fin"
pause > nul
exit
下記のmain.ps1と同じ階層に置いて利用するようにしています。
メインスクリプト
filter Get-ShortcutProperty()
{
$Wshell = New-Object -comobject WScript.Shell
return $Wshell.CreateShortcut($_)
}
Get-ChildItem -Recurse -Include "*.lnk" |
Get-ShortcutProperty |
Select-Object -Property Fullname, TargetPath, Arguments |
Export-Csv -LiteralPath "$env:USERPROFILE/desktop/link.csv" -Encoding Unicode -UseQuotes Always -Delimiter "`t"
実行しているユーザーのデスクトップにCSVファイルが出力されます。
Get-ChildItem
の後ろに-LiteralPath "検索したいフォルダパス"
を付ければ、
カレントディレクトリ以外のフォルダを検索することも可能です。
-UseQuotes Always
を指定しているので、
項目にスペース入りの文字列があってもそのまま動きます。
他の書き方
メインスクリプトは、こんな書き方もありですね。
filter Get-ShortcutProperty()
{
$Wshell = New-Object -comobject WScript.Shell
return $Wshell.CreateShortcut($_)
}
$TargetShortcutFiles = (Get-ChildItem -Recurse -Include "*.lnk")
$ShortcutProperties = ($TargetShortcutFiles | Get-ShortcutProperty)
$ShortcutPropertiesFiltered = ($ShortcutProperty | Select-Object -Property Fullname, TargetPath, Arguments)
$ShortcutPropertiesFiltered |
Export-Csv -LiteralPath "$env:USERPROFILE/desktop/link.csv" -Encoding Unicode -UseQuotes Always -Delimiter "`t"
結果
以下のような感じでCSVファイルを出力できました。
そして、Excelでもキレイに開くことができました。
"FullName" "TargetPath" "Arguments"
"C:\Users\?????\Desktop\test\新しいフォルダー\新しいフォルダー\新しいフォルダー\新しいフォルダー\新しいフォルダー\duralumin (192.168.0.180).lnk" "\\192.168.0.180\duralumin" ""
"C:\Users\?????\Desktop\test\steel (192.168.0.170).lnk" "\\192.168.0.170\steel" ""
"C:\Users\?????\Desktop\test\tungsten (192.168.0.180).lnk" "\\192.168.0.180\tungsten" ""
所要時間
参考程度に処理時間を記載します。
検索対象の共有フォルダ全体で50GB程度でしたが、7分程度でCSV出力が完了しました。
今後の課題
他の書き方とか書いてみたものの、最後にExport-CSVを使うことを考慮して、あまり分解ができませんでした。
pythonでいうtqdmみたいにプログレスバーを表示したいときはどうするのかが焦点です。
使い捨てのスクリプトのスクリプトとして作成しましたが、結構使いまわせると思います。
「今回の対象は前回の100倍だよ」とかいう攻撃に対処する防衛術を身に着けておきたいものです。
参考
- ショートカットの内容を取得する
- PowerShellでタブ区切りのcsvファイルを読み込む
- Docs / Windows コマンド / サーバーの役割別のコマンド / icacls
- Docs / Windows コマンド / サーバーの役割別のコマンド / robocopy
Excelsior!!