Sorizon
Sorizon

Reputation: 43

Dynamically creating the name of an existing object to Set one of its properties

I have the following code in Powershell:

function New-Row-Object-Instance {
    New-Object PSObject -Property @{
        Zeros = 0
        Tens = 0
        Twentys = 0
        Thirtys = 0
        Fortys = 0
        Fiftys = 0
        Sixtys = 0
    }
    $Row_Details = New-Row-Object-Instance

I Updated $Row_Details with some values. Now I have the following Labels on a Windows Form that is displayed: $Zeros, $Tens, $Twentys, $Thirtys etc.

I want to update the Labels on Form with values using the property Content. So $Zeros.Content = 2 and so forth

foreach ($property in $Row_Details.PSObject.Properties) {
    $property.Name >> $OutFile
# following creates the label names $Zeros,....
    $v = -join('$',$property.Name)
# following gives error.. no property named Content
    $v.Content = 2
# following gives error.. no property named Content
    (-join('$',$property.Name)).Content = 2
# following gives error.. no property named Content
    $v | Set-ItemProperty -Name "Content" -Value 2
# following does not update the Labels on the Form itself
    Set-Variable $v -Value @{Content = "2"}

# Cannot use Set-ItemProperty -inputObject $v because cannot name property
}

I can hard code name of each Label, but was trying to do it dynamically or Elegantly...

Upvotes: 2

Views: 2501

Answers (3)

Matt
Matt

Reputation: 46710

You should be able to use Get-Variable for this is interact with those other objects. Shrinking your examples down to two you can proof of concept this fairly easily.

# Simulate your controls by creating object with those respective properties
$Zeros = New-Object PSObject -Property @{Content = 0}
$Tens = New-Object PSObject -Property @{Content = 0}

$Row_Details = New-Object PSObject -Property @{
    Zeros = 1
    Tens = 2
}

# Display the current Contents
write-host "Zeros: $($Zeros.Content)"
write-host "Tens: $($Tens.Content)"

foreach ($property in $Row_Details.PSObject.Properties){
    $singleVariable = Get-Variable $property.name
    $singleVariable.Value.content = $property.Value
}

# Show the updated Contents
write-host "Zeros: $($Zeros.Content)"
write-host "Tens: $($Tens.Content)"

The results of this being

Zeros: 0
Tens: 0
Zeros: 1
Tens: 2

The only problem I see is that all of this exists in the same scope so you my example should work as intended. However, depending where your variables are defined, you might have scope issues. If that happens you just need to experiment with the -Scope parameter of Get-Variable

Upvotes: 0

Cosmin
Cosmin

Reputation: 131

The question is unclear to me, but maybe this helps

If you just want to modify the values for each of them you an do this:

foreach ($property in $Row_Details.PSObject.Properties)
{
    $property.Value = 0
}

If you want to make new variables for each item:

foreach ($property in $Row_Details.PSObject.Properties)
{
    New-Variable -Name $property.Name -Value $property.Value
}

Upvotes: 0

David Brabant
David Brabant

Reputation: 43499

Not sure I really understand your question, but I'll give it a try with a small example that might put you on a track to follow:

$object =  New-Object PSObject -Property @{   
    Zeros = 0;
    Tens = 0;
}

$Zeros = New-Object PSObject -Property @{
    Content = "0"
}

$Tens = New-Object PSObject -Property @{
    Content = "0"
}

$Zeros
$Tens

$object.PSObject.Properties | %{

    $property = $_.Name
    $expression = "`$$($property).Content = `"2`""

    Invoke-Expression $expression
}

$Zeros
$Tens

Upvotes: 1

Related Questions