What I want to achieve:
Create a list of files, show their name and version and sort alphabetically.
My attempt:
class File_Information
{
[ValidateNotNullOrEmpty()][string]$Name
[ValidateNotNullOrEmpty()][string]$FileVersion
}
$FileList = New-Object System.Collections.Generic.List[File_Information]
foreach ($file in Get-Item("*.dll")){
$C = [File_Information]@{
Name = $file.Name
FileVersion = $file.VersionInfo.FileVersion
}
$FileList = $FileList.Add($C)
}
foreach ($file in Get-Item("*.exe")){
$C = [File_Information]@{
Name = $file.Name
FileVersion = $file.VersionInfo.FileVersion
}
$FileList = $FileList.Add($C)
}
Write-Output $FileList | Sort-Object -Property "Name" | Format-Table
My Powershell version:
Prompt> Get-Host | Select-Object Version
Version
-------
5.1.19041.1320
My problems and/or questions (first is the major question, second and third are optional):
I don't know how to initialise a list of custom objects (I've been looking on the site, but this question only gives the possibility to initialise with an existing value, while I want to initialise to an empty list).
The error I receive is:
You cannot call a method on a null-valued expression.
At line:... char:...
+ $FileList = $FileList.Add($C)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Currently I ask for the same thing twice: I have tried Get-Item(*.dll,*.exe)
, Get-Item(*.dll;*.exe)
and Get-Item(*.dll|*.exe)
but none of them worked.
Is it even possible to search for different patterns?
Until now I am struggling just to get Write-Output $FileList
working. Are the other two commands (Sort-Object -Property "Name"
, Format-Table
) correct?
Why use a class and a List object for that at all?
You can just use Select-Object
on the files of interest you gather using Get-ChildItem
and output the needed properties there:
# capture the resulting objects in a variable $result
$result = Get-ChildItem -Path 'X:\path\to\the\files' -File -Include '*.dll','*.exe' -Recurse |
Select-Object Name, @{Name = 'FileVersion'; Expression = {$_.VersionInfo.FileVersion}}
# output on screen
$result | Sort-Object Name | Format-Table -AutoSize
To use two different name patterns on Get-ChildItem
, you need to also add switch -Recurse
, or append \*
to the path.
If you do not want recursion, you will need to add a Where-Object
clause like:
$result = Get-ChildItem -Path 'X:\path with spaces' | Where-Object {$_.Extension -match '\.(dll|exe)'} |
Select-Object Name, @{Name = 'FileVersion'; Expression = {$_.VersionInfo.FileVersion}}