Dynamic Variables

Hi everyone, I have a gap in my knowledge i am hoping someone can fill, here is my problem:
I wish to dynamically query some info at runtime to then create a dynamic number of variables, which i then want to query also, the code i have is below:

$AllNodes = Get-StorageNode
$i=0
Foreach ($Node in $AllNodes)
    {
        $i++
        New-Variable -Name $("Node$i`Disks") -Value (Get-PhysicalDisks)
        New-Variable -Name $("Node$i`Disksize") -Value 0
        $Temp = (Get-Variable -Name $("Node$i`Disks"))
        $TempSize = (GetVariable -Name $("Node$i`Disksize"))
                Foreach ($item in $Temp)
                    {
                        $TempSize = $TempSize + $item.Value.Size
                    }
        $("Node$i`Disksize") = $TempSize              
    }


The error is on this line $(“Node$i`Disksize”) = $TempSize, it cannot assign the value in $TempSize to the variable, what is the correct way to do this?
Regards
Wayne

This?

Set-Variable -Name $("Node$i`Disksize") -Value $TempSize

I guess what you’re doing here

$(“Node$i`Disksize”) = $TempSize 
is trying to assign a variable to a string. That won’t work.

Hi Paal,

yes this looks like my problem, the $item.value.size variable doesnt have an op method. However i need to get all of those disk sizes and store them in a variable, still working on it, i will post back as soon as i find anything

I suppose then the only other way is if i can do:

Foreach ($item in $(“Node$i`Disks”)) and loop through that, but i cant seem to get that to work either :frowning:

Got it, it was simple…

$AllNodes = Get-StorageNode
$i=0
Foreach ($Node in $AllNodes)
    {
        $i++
        New-Variable -Name $("Node$i`Disks") -Value (Get-PhysicalDisks)
        New-Variable -Name $("Node$i`Disksize") -Value 0
        $Temp = (Get-Variable -Name $("Node$i`Disks"))
                Foreach ($item in $(get-variable -Name Node$i`Disks -ValueOnly))
                    {
                        [Int64]$TempSize = Get-variable -Name "Node$i`Disksize" -Valueonly
                        Set-Variable -Name "Node$i`Disksize" -Value ($TempSize + $item.size)
                    }         
    }

Thanks for the input Paal :slight_smile:

Personally, I’d say any time you’re trying to dynamically create variable names like this, what you really want is a collection of some sort. Maybe an array, maybe a dictionary, whatever makes more sense at the time. For example:

$hash = @{}

$AllNodes = Get-StorageNode
$i=0
Foreach ($Node in $AllNodes)
    {
        $i++
        $hash[$i] = @{
            Disks = Get-PhysicalDisks
            DiskSize = 0
        }
                Foreach ($item in $hash[$i].Disks)
                    {
                        $hash[$i].DiskSize += $item.Size
                    }
    }

Incidentally, every single $i in that hashtable should wind up with identical data. You’re looping over the $AllNodes array, but not using $Node anywhere inside the loop (such as in the call to Get-PhysicalDisks.)

Interesting Dave, il look at the array / dictionary method thanks, and I wouldn’t examine the code too carefully, it was changed to protect its identity lol, it was more the logic i was trying to understand :slight_smile:

I’m not familiar with Get-StorageNode or the Get-PhysicalDisk, but I guess I would do something like

$Nodes = Get-StorageNode

$NodeSizes = @{}

foreach ($Node in $Nodes) {
$Disks = Get-PhysicalDisk -StorageNode $Node
$SizeSum = $Disks | Measure-Object -Sum -Property “Size” | Select-Object -ExpandProperty “Sum”
$NodeSizes[$Node.Name] = $SizeSum
}

Then the hashtable, $NodeSizes, will have the node name and total disk size as key-value pairs.

I see that the size of the PhysicalDisk object is an uint64. Measure-Object converts this and gives the sum as a double. You probably don’t need to worry about this, but keep the type in mind if you want to pass the value on :slight_smile:

Cool thanks Paal, il look at this too, very helpful indeed :slight_smile: