9

I need to be able to have a class in powershell where I can create the names of the properties of that class dynamically. For example,

$binFiles = Get-ChildItem $files -Include *.BIN -recurse
$binFiles.Name

This would print something like:

File1.BIN

ThisFile.BIN

...

FileOther.BIN

I want these file names to be the names of the properties in my class that I will create multiple times. Is this even possible?

Class myItem {
    [String]$"File1.BIN"
    [String]$"ThisFile.BIN"
    ....
    [String]$"FileOther.BIN"
}

1 Answer 1

8

You can use Invoke-Expression (the solution is PSv5+, due to using custom PS classes):

Invoke-Expression @"
Class myItem {
  $((Get-ChildItem $files -Include *.BIN -recurse).ForEach({"[string] `${$($_.Name)}`n "}))
}
"@

Note: While this particular use of Invoke-Expression is safe, because you fully control the string being evaluated, Invoke-Expression should generally be avoided.

The here-string produces the class definition as a string, which Invoke-Expression then evaluates, which defines class [myItem] for later use (e.g., $instance = [myItem]::new()).

Note:

  • The class definition statically creates properties based on the files present at the time you call Invoke-Expression.
  • Extending a class dynamically isn't directly supported[1], but you can recreate the class later based on the then-current set of files, simply by repeating the Invoke-Expression call.[2]

The here-string produced above looks something like this - note the need to enclose the property names in {...}, because they contain .:

Class myItem {
  
  [string] ${File1.Bin}
  [string] ${File2.Bin}
  # ...
 
}

[1] A class is immutable once defined, although you could add properties dynamically to its instances using PowerShell's ETS (extended type system), typically via the Add-Member cmdlet.
Adding instance properties on demand would enable TheMadTechnician's suggestion of alternatively defining the class without properties and only an (instance) method that populates / updates a given instance's properties on demand.

[2] Technically, the recreated class is a distinct .NET type, though that typically won't matter, given that referring to it via a type literal - [myItem] in this case - works the same.

Sign up to request clarification or add additional context in comments.

1 Comment

Good point, @Blaisem: it will; please see my update.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.