So I am pulling in an array and then cleaning it to just the unique values I need and then running that though a foreach loop to create
$ZoneArray = Import-Csv -Path "Test.csv" | select Zone
$Zones = @()
foreach ($Zone in $ZoneArray){
$Zones = $Zone.Zone
}
$Zones = $Zones | select -Unique
foreach ($ZonesTest in $Zones){
Set-Variable -Name "Zone$_" -Value $ZonesTest -Force
New-UDTab -Text $ZonesTest -Content {
New-Variable -Name 'CurrentZone'
New-UDmuButton -Id 'Zone1Test' -Text ( " On") -Variant contained -FullWidth -OnClick {
Show-UDToast -Message "Starting" -Duration 1000 -Position center
$ZoneFullArray = $FullArray | Where-Object Zone -eq $ZonesTest
foreach ($ZoneFullArrayTest in $ZoneFullArray){
Set-UDButtonStateChange -Id 'Zone1Test' -Text $ZoneFullArrayTest.ReceiverIPAddress
Start-Sleep -Milliseconds 1000
}
}
}
}
Using Set-Variable -Name "Zone$_" -Value $ZonesTest -Force
I am able to call the correct value while it is running.
I have tried using
$Q=1
Set-Variable -Name "Zone$Q" -Value $ZonesTest -Force`
$Q
But then I don't know how to dynamically call back the correct $Zone$Q for the later button press.
Is there anyway to program a dynamic variable that remembers the state it was made and then I can recall it later without knowing it's name? I know that sounds really confusing.
Ideas?
Edit:
I am banging my head against the wall. I know that the $ZoneFullArray = ...
and foreach ($ZoneFullArrayTest in $ZoneFullArray){...
is what is breaking it but can't think of another way to write it. The problem I am trying to solve with the second foreach
to create a button dynamically based off the CSV table and then pull the value of the IP addresses that match the main row value making $Zones
. The issue is that the code within the button is not run until it is pressed so it is hard to write them dynamically.
CodePudding user response:
As iRon points out, variable indirection (referring to variables indirectly, via dynamically created variable names) is best avoided - see this post.
It sounds like what you're really looking for are script-block closures that lock in then-current variable values in each iteration of a loop, along the following lines:
# Sample input zones.
$zones = 'foo', 'bar', 'baz'
# Create a script block with a closure for each zone.
$scriptBlocks =
foreach ($zone in $zones) {
# .GetNewClosure() locks in the iteration-specific value of $zone
{ "This zone: $zone" }.GetNewClosure()
}
# Execute the script blocks to demonstrate that the values where
# captured as intended.
$scriptBlocks | ForEach-Object { & $_ }
Output:
This zone: foo
This zone: bar
This zone: baz
CodePudding user response:
So I ended up using the code blocks @mklement0 suggested but added the param option I found to pass data into the code block.
$CodeBlock = { param($par1, $par2)
foreach ($Row in $par1){
$SwitchIPCurrent = $Row.SwitchIP
$SwitchUsernameCurrent = $Row.SwitchUsername
$SwitchPasswordCurrent = $Row.SwitchPassword
$SwitchPortCurrent = $Row.SwitchPort
}
}
To run the code just pass the param into the code block
&$CodeBlock -par1 $ImportedArray -par2 $Variable