I have 10 variables, called rows($row1, $row2, $row3...), I need the user to choose from one of this variables only knowing the right row, I'm struggling to understand how to connect text to a variable, that corrisponds to another variable and get the value, not to write it as text
$ChoosenRow = Read-Host
$rownumber = $("row" + $ChoosenRow)
$IP = Write-Output $rownumber
If I input 10, I get $IP = row10
I'm trying to get $IP to become the value of $row10, not as a string.
Sorry for my broken english and my stupid question, I tried to search similar questions but didn't found any
Edit: iRon asked me to put more of the script:
# Carica il file e crea le variabili per il file
$FilePath = '\\ntced\CED\AssistenzaPC\IP IN GESTIONE\2021-08-16 TabellaIP.xls'
$xl = New-Object -ComObject Excel.Application
$xl.Visible = $true
$wb = $xl.Workbooks.Open($filepath)
# Prendi la prima colonna
$data = $wb.Worksheets['Foglio1'].UsedRange.Rows.Columns[1].Value2
$data2 = $wb.Worksheets['Foglio1'].UsedRange.Rows.Columns[2].Value2
# Chiudi excel aperto per prendere i dati
$wb.close()
$xl.Quit()
While([System.Runtime.Interopservices.Marshal]::ReleaseComObject($wb) -ge 0){}
while([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl) -ge 0){}
Remove-Variable xl,wb # Rimuovi le due variabili create
# display results
$data | select -skip 1 # Rimuove il titolo sopra
# Variabili degli IP
$variables = @()
$i = 0
foreach ($row in ($data -split [Environment]::NewLine)) {
# Crea una variabile per ogni riga
New-Variable -Name "row$i" -Value $row
# e un membro dell'array
$variables += [pscustomobject]@{Name = "row$i"; Value = $row} # Copiato male, era troppo complicato arrivarci
$i++
}
$variables2 = @()
$ii = 0
foreach ($linea in ($data2 -split [Environment]::NewLine)) {
# Crea una variabile per ogni riga
New-Variable -Name "linea$ii" -Value $linea
# e un membro dell'array
$variables2 += [pscustomobject]@{Name = "linea$ii"; Value = $linea}
$ii++
}
function Show-Menu
{
param (
[string]$Title = 'Scegli IP'
)
Clear-Host
Write-Host "================ $Title ================"
Write-Host "1: Cambia IP da tabella IP nuovi"
Write-Host "Q: premi 'Q' per uscire."
}
Show-Menu –Title 'Scegli IP'
$selection = Read-Host 'Scegli la'
switch ($selection)
{
'1' {
' Scrivi la linea che contiene IP libero'
$LineaScelta = Read-Host
$rownumber = $("row" + $LineaScelta)
$IP = Write-Output $rownumber
$MaskBits = 20 # subnet mask in bits = 255.255.240.0
$Gateway = "172.16.111.254"
$Dns = "172.16.16.1"
$IPType = "IPv4"
}
'q' {
return
}
}
# Imposta su tutte le schede di rete attive, quindi tenere acceso solo quella necessaria!
$adapter = Get-NetAdapter | ? {$_.Status -eq "up"}
# Rimuove gli IP prima di metterli
If (($adapter | Get-NetIPConfiguration).IPv4Address.IPAddress) {
$adapter | Remove-NetIPAddress -AddressFamily $IPType -Confirm:$false
}
If (($adapter | Get-NetIPConfiguration).Ipv4DefaultGateway) {
$adapter | Remove-NetRoute -AddressFamily $IPType -Confirm:$false
}
# Configura gli IP, CHE BESTEMMIE PER CAPIRE COME USARE
$adapter | New-NetIPAddress `
-AddressFamily $IPType `
-IPAddress $IP `
-PrefixLength $MaskBits `
-DefaultGateway $Gateway
# Configura il primo server DNS, non so come configurare il secondo ancora.
$adapter | Set-DnsClientServerAddress -ServerAddresses $DNS
General (best practice) advice:
<verb>-Variable
cmdlets for dynamic variable names!PowerShell (as almost all other programming languages) has an internal dictionary were it keeps all the variable names and a (direct or indirect) reference to their containing value. This dictionary (quote wikipedia),
is a data structure that implements a set abstract data type, a structure that can map keys to values. A hash table uses a hash function to compute an index, also called a hash code, into an array of buckets or slots, from which the desired value can be found. During lookup, the key is hashed and the resulting hash indicates where the corresponding value is stored.
It is a general usage to create any (unique) variable name for a specific value, but at the moment that you find out that you start repeating yourself for a specific variable set, your program starts to become so called WET (as opposed to DRY). At this point you might come to the obvious conclusion to automate the variable names itself with statements using Set-Variable
, like:
New-Variable -Name "row$i" -Value $row
To automate variables with a common purpose is definitely a good thought, but using <verb>-Variable
cmdlets for this, is a bad practice as all the variables will eventually end up in the same dictionary. Therefore you might lose the oversight or even introduce conflicts with other variable names. Instead, you better create your own custom dictionary using a hashtable which is based on a similar data structure as the general variables.
Instead of this:
$variables = @()
$i = 0
foreach ($row in ($data -split [Environment]::NewLine)) {
# Crea una variabile per ogni riga
New-Variable -Name "row$i" -Value $row
# e un membro dell'array
$variables += [pscustomobject]@{Name = "row$i"; Value = $row} # Copiato male, era troppo complicato arrivarci
$i++
}
You might simply do this:
$Rows = @{}
$i = 0
foreach ($row in ($data -split [Environment]::NewLine)) { $Rows[$i++] = $Row }
And to get the specific value:
$LineaScelta = Read-Host
$IP = $Rows[[Int]$LineaScelta]
As the key of the dictionary appears to be a consecutive zero-based numeric serie, you might even simplify this further using an array:
$Rows = $data -split [Environment]::NewLine
$LineaScelta = Read-Host
$IP = $Rows[$LineaScelta]
As a side node: also try I avoid using the increase assignment operator (+=
) to create a collection