C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

PowerShellでファイルバージョン取得

[トピック内 13 記事 (1 - 13 表示)]  << 0 >>

■97113 / inTopicNo.1)  PowerShellでファイルバージョン取得
  
□投稿者/ けん (1回)-(2021/03/30(Tue) 16:03:24)

分類:[その他の言語] 

よろしくお願いいたします。けんです。

この掲示板が適切か不明ですが、「PowerShell」で検索してこの掲示板に
来ました。
よろしくお願いいたします。

「PowerShell」で指定したパスのフォルダ内のファイルバージョンを取得
したいと試行錯誤しています。(初心者)

以下にて指定フォルダ内のファイル名及びファイルバージョンを取得でき
ますが、パス内の配下フォルダ内のファイル名及びファイルバージョンを
取得ができない状況です。

バージョン情報のみの取得(パスを含むファイル名も取得)
(Get-ItemProperty "C:\Program Files・・・・・・・・").VersionInfo

ファイル名とバージョン情報取得
cd "C:\Program Files・・・・・・・・"
ls | sort | ?{ $_.Name -like '*.dll' -or $_.Name -like '*.exe'} | %{echo $($_.name + "`t" + (Get-ItemProperty $_).VersionInfo.FileVersion)}



取得したい情報

配下のフォルダ@ ディレクトリ:フォルダパス
 ファイル名(拡張子を含む。) ファイルバージョン

配下のフォルダA ディレクトリ:フォルダパス
 ファイル名(拡張子を含む。) ファイルバージョン


Get-ChildItem C:\Work -Recurse
で「Mode」「LastWriteTime」「LengthNmae」の取得は確認できたいます。

初心者で申し訳ありませんが、ご教授お願いいたします。


引用返信 編集キー/
■97114 / inTopicNo.2)  Re[1]: PowerShellでファイルバージョン取得
□投稿者/ 魔界の仮面弁士 (3032回)-(2021/03/30(Tue) 16:21:06)
2021/03/30(Tue) 16:32:05 編集(投稿者)

No97113 (けん さん) に返信
> 以下にて指定フォルダ内のファイル名及びファイルバージョンを取得でき
> ますが、パス内の配下フォルダ内のファイル名及びファイルバージョンを
> 取得ができない状況です。
> Get-ChildItem C:\Work -Recurse
Get-ChileItem の -Recurse パラメーターで良いはずなので、
渡し方に問題があるのだと思います。


ls 'C:\Program Files\*' -Include ('*.dll', '*.exe') -Recurse | select FullName, Mode, LastWriteTime, @{Name='Version'; Expression={(gp $_).VersionInfo.FileVersion}} | Out-GridView
引用返信 編集キー/
■97115 / inTopicNo.3)  Re[2]: PowerShellでファイルバージョン取得
□投稿者/ けん (3回)-(2021/03/30(Tue) 19:11:21)


No97114 (魔界の仮面弁士 さん) に返信
返信の仕方が不明で、間違っていましたらご容赦ください。

> ls 'C:\Program Files\*' -Include ('*.dll', '*.exe') -Recurse | select FullName, Mode, LastWriteTime, @{Name='Version'; Expression={(gp $_).VersionInfo.FileVersion}} | Out-GridView

ご教授有難うございます。
バージョン情報等取得することが出来ました。

欲しい情報は、フォルダのディレクトリ、ファイル名(拡張子付)、バージョン情報ですので
次のように変更しました。
ls 'C:\Program Files・・・・・・\*' -Recurse | select Name, @{Name='Version'; Expression={(gp $_).VersionInfo.FileVersion}}

出来れば
「Get-ChildItem 'C:\Program Files・・・・・・' -Recurse」
で出力される形でバージョン情報を取得したいと思っています。

ディレクトリ: C:\Program・・・・・
Name Versiot
---- -------
〇〇〇.exe 12.0.557.0
〇〇〇.dll 0.1.1.0

ディレクトリ: C:\Program・・・・・
Name Versiot
---- -------
〇〇〇.dll 12.0.557.0
〇〇〇.dll 0.1.1.0

このような出力は可能なのでしょうか。
ちなみに、実行はスクリプトファイルで実施しています。

申し訳ありませんがご教授をお願いいたします。
(コマンド等わからず、丸投げみたいで申し訳ありません。)


引用返信 編集キー/
■97116 / inTopicNo.4)  Re[3]: PowerShellでファイルバージョン取得
□投稿者/ 魔界の仮面弁士 (3033回)-(2021/03/30(Tue) 21:15:33)
No97115 (けん さん) に返信
> 〇〇〇.exe 12.0.557.0

こういう場合には、
〇 漢数字のゼロ ではなく
○ 白丸記号 を使った方が良いかと。


> ディレクトリ: C:\Program・・・・・
> Name Versiot
> ---- -------

$dirs = Get-ChildItem -Path 'C:\Program Files\Common Files\*' -Recurse
foreach($d in $dirs | Where-Object { $_.PSIsContainer }) {
 $f = @(Get-ChildItem -Path ($d.FullName + '\*') -Include @('*.dll','*.exe'))
 if ($f.Length -gt 0 ) {
  '[' + $d.FullName + ']'
  $f | Select-Object Name, @{Name='Version'; Expression={(gp $_).VersionInfo.FileVersion}} | Format-Table
 }
}
引用返信 編集キー/
■97117 / inTopicNo.5)  Re[4]: PowerShellでファイルバージョン取得
□投稿者/ 魔界の仮面弁士 (3034回)-(2021/03/30(Tue) 22:08:50)
No97116 (魔界の仮面弁士) に追記
> $dirs = Get-ChildItem -Path 'C:\Program Files\Common Files\*' -Recurse
> foreach($d in $dirs | Where-Object { $_.PSIsContainer }) {

$_.PSIsContainer で絞り込むのは、古いバージョンの PowerShell 向けの構文のようです。
PowerShell 3.0 以降では -Directory パラメーターを使えるので、少し書き換え。


foreach($d in ls 'C:\Program Files\Common Files\*' -Directory -Recurse) {
 $f = @(ls "$($d)\*" -Include @('*.dll','*.exe'))
 if ($f.Length -gt 0 ) {
  '[' + $d.FullName + ']'
  $f | select Name, @{Name='Version'; Expression={(gp $_).VersionInfo.FileVersion}} | ft
 }
}
引用返信 編集キー/
■97118 / inTopicNo.6)  Re[5]: PowerShellでファイルバージョン取得
□投稿者/ けん (5回)-(2021/03/31(Wed) 08:48:19)
No97117 (魔界の仮面弁士 さん) に返信

ご教授、有難うございます。

> 〇〇〇.exe 12.0.557.0
>
>こういう場合には、
>〇 漢数字のゼロ ではなく
>○ 白丸記号 を使った方が良いかと。

拝承しました。申し訳ありませんでした。


> ■No97116 (魔界の仮面弁士) に追記
>>$dirs = Get-ChildItem -Path 'C:\Program Files\Common Files\*' -Recurse
>>foreach($d in $dirs | Where-Object { $_.PSIsContainer }) {
>
> $_.PSIsContainer で絞り込むのは、古いバージョンの PowerShell 向けの構文のようです。
> PowerShell 3.0 以降では -Directory パラメーターを使えるので、少し書き換え。
>
>
> foreach($d in ls 'C:\Program Files\Common Files\*' -Directory -Recurse) {
>  $f = @(ls "$($d)\*" -Include @('*.dll','*.exe'))
>  if ($f.Length -gt 0 ) {
>   '[' + $d.FullName + ']'
>   $f | select Name, @{Name='Version'; Expression={(gp $_).VersionInfo.FileVersion}} | ft
>  }
> }

取得したい出力を確認しました。(べた書きの出力の確認です。)
PowerShellのバージョンに応じたコマンドもアップいただき有難うございます。

まだ初心者ですので、コマンド内容を確認し、不明な点等がありましたらご教授等の対応
をお願いいたします。

今少しお時間をいただきますようお願いいたします。
引用返信 編集キー/
■97121 / inTopicNo.7)  Re[6]: PowerShellでファイルバージョン取得
□投稿者/ けん (7回)-(2021/03/31(Wed) 13:37:45)
No97117 (魔界の仮面弁士 さん) に返信

よろしくお願いいたします。

今回PowerShellについてお教えいただいておりますが、初心者で申し訳ありません。
多少エクセルVBAを実施しており、以下について確認です。

> foreach($d in ls 'C:\Program Files\Common Files\*' -Directory -Recurse) {
 For Each コレクションの値 In コレクション(パスを含むファイル名(拡張子を含む。)及び各種情報)

>  $f = @(ls "$($d)\*" -Include @('*.dll','*.exe'))
  $f:変数にコレクションのうちファイル名(拡張子を含む。)を格納(拡張子「dll」「exe」のファイル)

>  if ($f.Length -gt 0 ) {
  IF $f変数に値がある場合

>   '[' + $d.FullName + ']'
   パス(コレクションの値)

>   $f | select Name, @{Name='Version'; Expression={(gp $_).VersionInfo.FileVersion}} | ft
   $f変数の値及びバージョンを取得、ft:出力形式をテーブル型式

と言うことでしょうか。

現状は、batファイルでレジストリ及びファイル情報を取得しているのですが、batファイルで
バージョン情報の取得を確認していたところ、「PowerShell」が簡単とのことでしたので取得を
調べておりました。
batファイル(コマンドプロンプト)でも、コマンドは違うにしても同様の取得は可能なのでしょうか。
(すべて「PowerShell」で実行した方がいいのかもしれませんが。)


申し訳ありませんが、よろしくお願いいたします。


引用返信 編集キー/
■97122 / inTopicNo.8)  Re[6]: PowerShellでファイルバージョン取得
□投稿者/ 魔界の仮面弁士 (3035回)-(2021/03/31(Wed) 14:11:17)
No97118 (けん さん) に返信
> まだ初心者ですので、コマンド内容を確認し、不明な点等がありましたらご教授等の対応
> をお願いいたします。

参考までに、先のコードの解説をば。


>>foreach($d in ls 'C:\Program Files\Common Files\*' -Directory -Recurse) {

ls すなわち Get-ChildItem コマンドレットに対して -Directory -Recurse を付与することで、
その下のすべてのディレクトリを列挙しています。

例:
 (Get-ChildItem 'C:\Program Files\Common Files\*' -Directory -Recurse).FullName

そしてそれを、foreach ステートメントでループ処理し、各ディレクトリごとに処理します。
この場合の $d はディレクトリ情報である [System.IO.DirectoryInfo] 型のデータが渡されます。


>> $f = @(ls "$($d)\*" -Include @('*.dll','*.exe'))

$d で渡されたディレクトリの直下にある、*.dll や *.exe を探します。
子ディレクトリまで探す必要は無いので、ここでは -Recurse を付けません。

列挙された結果は配列として $f に代入されますが、ここの処理が
 $f = ls "$($d)\*" -Include @('*.dll','*.exe')
ではなく、@( ) で囲む必要があることに注意してください。


例:
 # ファイルが 1 個だけの場合、ファイルサイズが返されます。
 # これは [System.IO.FileInfo] の Length プロパティとして解釈されるためです。
 (ls C:\Windows\System32\Calc.exe ).Length

 # @( ) で囲むと配列として扱われるので、
 # 見つかったファイルの個数「1」が得られます。
 @(ls C:\Windows\System32\Calc.exe ).Length


>> if ($f.Length -gt 0 ) {
>>  '[' + $d.FullName + ']'

列挙されたファイル数が 0 よりも大きかった時に、
そのディレクトリのパスを表示しています。
そのディレクトリに *.dll や *.exe が見つからなかったときは何もしません。


>>  $f | select Name, @{Name='Version'; Expression={(gp $_).VersionInfo.FileVersion}} | ft

gp というのは、Get-ItemProperty コマンドレットのエイリアスです。

個々のファイル情報を、select すなわち Select-Object コマンドレットで成形し、
それを ft すなわち Format-Table コマンドレットに渡して表示する処理です。

なお、@{ } の部分は「ハッシュテーブル」の構文です。
https://www.vwnet.jp/Windows/PowerShell/2017060701/PowerShellHashTable.htm

Select-Object の -Property に対して「式」を渡す場合には、
「Name (または Label)」と「Expression」をキーとしたハッシュテーブルを使います。

ハッシュテーブルの Name や Label は n または l、Expression は e と省略できるので
「@{Name='Version'; Expression={(gp $_).VersionInfo.FileVersion}}」を
「@{l='Version';e={(gp $_).VersionInfo.FileVersion}}」と書くこともできます。


>> }
>>}
引用返信 編集キー/
■97123 / inTopicNo.9)  Re[7]: PowerShellでファイルバージョン取得
□投稿者/ 魔界の仮面弁士 (3036回)-(2021/03/31(Wed) 14:24:33)
2021/03/31(Wed) 14:56:52 編集(投稿者)

No97121 (けん さん) に返信
> batファイル(コマンドプロンプト)でも、コマンドは違うにしても同様の取得は可能なのでしょうか。

バッチファイル(*.cmd または *.bat) からだと、ファイルの列挙まではできますが、
肝心の「バージョン情報」を取得することができません。
ファイル名を渡すとバージョン情報を返すような exe やスクリプトを併用しないと駄目ですね。
https://www.atmarkit.co.jp/fwin2k/win2ktips/316filever/filever.html


先のコードの肝は、FileVersionInfo プロパティから得られる
[System.Diagnostics.FileVersionInfo] です。


VBA からの場合は、VerQueryValue API を呼び出すようなコードを記述すれば
同様の機能を実装できますが、PowerShell の方がずっとお手軽です。
(あるいは C# や VB.NET を使うなど)
引用返信 編集キー/
■97127 / inTopicNo.10)  Re[8]: PowerShellでファイルバージョン取得
□投稿者/ けん (9回)-(2021/03/31(Wed) 17:25:27)
No97123 (魔界の仮面弁士 さん) に返信

>>batファイル(コマンドプロンプト)でも、コマンドは違うにしても同様の取得は可能なのでしょうか。
>
> バッチファイル(*.cmd または *.bat) からだと、ファイルの列挙まではできますが、
> 肝心の「バージョン情報」を取得することができません。
> ファイル名を渡すとバージョン情報を返すような exe やスクリプトを併用しないと駄目ですね。
>
> 先のコードの肝は、FileVersionInfo プロパティから得られる
> [System.Diagnostics.FileVersionInfo] です。
>
>
> VBA からの場合は、VerQueryValue API を呼び出すようなコードを記述すれば
> 出来なくは無いですが…まぁ、PowerShell の方が楽ですね。
> C# や VB.NET でも良いですけど。

コードに対する詳細説明、大変参考になります。今一度よく説明内容を確認いたします。
ご教授いただき誠に有難うございます。

レジストリ及びファイル情報等はエクセルで取得可能ですが、仮想環境からの取得となりますので
エクセルは使用できない状況です。

今実施しようとしていることは、レジストリの取得はbatファイルで行い、ファイル情報取得を
「PowerShell」で行うこと考えていました。(C#やVB.NETは経験がありません。)

batファイルのファイル情報取得コードを以下に変更して情報を取得する。
「powershell -file "C:\Users・・・・\sample02.ps1")」

ここまで実行し結果を得ることが出来ました。

ここからは単純に結果をテキストファイルとして出力すればと思っておりましたが上手く
いきませんでした。

batファイル側
set mypath=%USERPROFILE%\Desktop\Result
set /p TestNo="Please enter a number. =>"

引数も「PowerShell」に渡します。
powershell -file "C:\Users・・・・\sample02.ps1" mypath TestNo


samle02.ps1側

「Out-File -FilePath mypath + '\DirNo' + TestNo.txt」

を記述すれば良いと思っていますが、取得コードにどのように記述すれば
テキストファイルとして保存できるでしょうか。

色々実施しましたが、出力されません。(sample02.ps1単独で躓いています。)
「Out-File -FilePath C:\Users\Desktop\Result.txt」

タイトルと違う投稿となりますが、ご教授ください。
よろしくお願いいたします。

引用返信 編集キー/
■97130 / inTopicNo.11)  Re[9]: PowerShellでファイルバージョン取得
□投稿者/ 魔界の仮面弁士 (3039回)-(2021/03/31(Wed) 23:46:02)
No97127 (けん さん) に返信
> ご教授いただき誠に有難うございます。
概要程度ですので、教授ではなく教示ですね。


> 今実施しようとしていることは、レジストリの取得はbatファイルで行い、
全部 PowerShell で済ませるわけにはいかないのでしょうか?
レジストリの値も ls で取得できますよ。
https://qiita.com/mima_ita/items/1e6c74c7fb641852edff

例:
 ls HKLM:SYSTEM\CurrentControlSet*\Control\Nls\Calendars\Japanese\Eras


> batファイルのファイル情報取得コードを以下に変更して情報を取得する。
> 「powershell -file "C:\Users・・・・\sample02.ps1")」
DLL 一つ一つを調べるなら、.bat を下記のように記述することもできます。

@ECHO OFF
SET DLL="C:\Program Files\Common Files\System\ado\msado15.dll"
PowerShell -Command "& { (gp '%DLL%').VersionInfo.FileVersion }"
PAUSE

まぁ、ファイルを一つ調べるごとに PowerShell.exe を呼び出すのも無駄なので、
ファイルの列挙も .ps1 側で行った方がスマートでしょうけれどね。


> ここからは単純に結果をテキストファイルとして出力すればと思っておりましたが上手く
> いきませんでした。
もちろん PowerShell 側で Out-File 等を使うこともできますが、
現状のコードは、結果を標準出力に吐きだしているだけなので、
それを bat ファイル側で直接拾うこともできます。

@ECHO OFF
PowerShell.exe "C:\Example\test.ps1" > "C:\Example\result.txt" 2>&1
PAUSE


> 引数も「PowerShell」に渡します。
> powershell -file "C:\Users・・・・\sample02.ps1" mypath TestNo
PowerShell で引数を受け取るには、このようにします。
https://microsoftou.com/ps-arguments/
引用返信 編集キー/
■97131 / inTopicNo.12)  Re[10]: PowerShellでファイルバージョン取得
□投稿者/ けん (10回)-(2021/04/01(Thu) 19:28:46)
No97130 (魔界の仮面弁士 さん) に返信

ご教授いただき誠に有難うございます。
初心者で理解が中々できない中、非常に助かっております。

>> 今実施しようとしていることは、レジストリの取得はbatファイルで行い、
>全部 PowerShell で済ませるわけにはいかないのでしょうか?
全部 PowerShellに移行しようと思っておりますが、今はcmdの一部の取得
コードのみでしたので、「cmd←→PowerShell」としておりました。
レジストリ取得のURL及びコードをいただきましたので「PowerShell」単独
も早めに移行できそうな感じです。
レジストリも取得を確認しました。
New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT
Set-Location HKCR:
Get-ItemProperty 'HKCR:\・・・・・'

テキストファイル出力は、ご提示いただいたコードで実施したところ出力
されたテキストファイルに以下のエラーが出力されたため、修正したところ
「PowerShell」で取得した値が出力されることを確認いたしました。

〇提示コード
 PowerShell.exe "C:\Example\test.ps1" > "C:\Example\result.txt" 2>&1

 「文字列に終端記号 ' がありません。
  + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
 + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString」

 「test.ps1」
>foreach($d in ls 'C:\Program Files\Common Files\*' -Directory -Recurse) {
> $f = @(ls "$($d)\*" -Include @('*.dll','*.exe'))
> if ($f.Length -gt 0 ) {
>  '[' + $d.FullName + ']'
>  $f | select Name, @{Name='Version'; Expression={(gp $_).VersionInfo.FileVersion}} | ft
> }
>}

〇修正
 PowerShell -file "C:\Example\test.ps1" > "C:\Example\result.txt" 2>&1

引数につきましては、現在確認等を実施中です。

業務等忙しく、確認等が遅くなり返信も遅くなりました。
申し訳ありませんでした。

引用返信 編集キー/
■97136 / inTopicNo.13)  Re[11]: PowerShellでファイルバージョン取得
□投稿者/ けん (12回)-(2021/04/04(Sun) 13:45:25)
No97130 (魔界の仮面弁士 さん) に返信

所要等で遅くなりましたが、現状について報告させていただきます。
(実質昨日の夜から確認・作成となりました。)

○batファイル←→PowerSell
 引数も含めて連携取得することが出来ました。
 (正しい記述かは不明ですが、連携が出来ているので問題ないかなと言うところです。)
 ・batファイル側
  set mypath=%USERPROFILE%\Desktop\Result
  set name="C:\Program・・・・・・・*"
  set shellPath=%~dp0test.ps1
  set /p TestNo="Please enter a number. =>"
  @ECHO OFF
  PowerShell -file %shellPath% %name% > %mypath%\dirNo%TestNo%.txt 2>&1

 ・PowerShell側
  $Args=$Args[0]
  foreach($d in ls $Args -Directory -Recurse) {
   $f = @(ls "$($d)\*")
   if ($f.Length -gt 0 ) {
    ' ディレクトリ:' + $d.FullName
     $f | select Name, @{Name='Version'; Expression={(gp $_).VersionInfo.FileVersion}} | ft
   }
  }


○PowerShell単独での実行
 ・単独実行の場合の実行方法(ダブルクリックで実行)
  レジストリの書き換えにより実行が可能とのことであり確認中です。
 ・ファイルバージョン取得結果の出力
  出力方法確認中です。  
 ・レジストリ取得の詳細取得確認中です。


まだ確認中なことがありますが、お教えいただいたリンク先及びコードの説明を基に、ネットにて調べながら
単独実行を作成していきます。

今回は、ファイルバージョン取得のコード提示及び丁寧な説明をいただき誠に有難うございます。
今後単独実行作成時に、不明な点等がありましたら、ご教授等をお願いいたします。

遅くなり申し訳ありませんでした。解決とさせていただきます。
有難うございました。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ