【问题标题】:Add multiple members to powershell hashtable将多个成员添加到 powershell 哈希表
【发布时间】:2023-04-08 00:42:01
【问题描述】:

我有一个包含子网信息的 CSV 文件,我将使用它来填充包含服务器信息的 CSV 文件。我从导入子网信息开始,在处理它时,我试图将多个成员添加到初始哈希表中,但它的行为不符合预期。 以下代码按预期处理第一项,创建一个包含正确信息的新列。该代码表明它至少处理了两个以上的部分,但没有添加成员。如何更改代码以允许为单个数组创建多个成员?目标是让每个子网的网关字段(列)对该子网唯一。

五个变量(变量A-E)的目的是模仿真实代码中发生的事情。真正的代码从哈希表运行比较,但这不是必需的。如果需要,我愿意更改该部分。

CSV file contents:
NetworkName,Subnet,VLANID,Gateway,VLAN
Servers,"192.168.1.0/24","2041","192.168.1.1","ServerVLAN-2041"
Workstations,"192.168.2.0/24","1001","192.168.2.1","WorkstationVLAN-1001"
DMZ,"172.16.0.0/28","340","172.16.0.1","DMZVLAN-340"
Servers,"192.168.3.0/24","2043","192.168.3.1","ServerVLAN-2043"
Workstations,"192.168.4.0/24","1004","192.168.4.1","WorkstationVLAN-1004"
DMZ,,,,

代码:

$csvfile = "C:\temp\testfile.csv"
$hashArray = Import-CSV $csvfile

$variableA = "192.168.1.0"
$variableB = "192.168.2.0"
$variableC = "192.168.3.0"
$variableD = "172.16.0.1"
$variableE = "192.168.5.0"

$hashArray | % {
if ($_.subnet) { $variable = ($_.subnet).split("/")[0] }
Else { $variable = $null }
if ($variable -eq $variableA -and $variable -ne $null)
{
    $_ | add-member "ServerGW1" -NotePropertyValue $_.gateway
    Write-Host "Added Server gateway 1: "$_.gateway -ForegroundColor Yellow
}

if ($variable -eq $variableC -and $variable -ne $null)
{
    $_ | add-member "ServerGW2" -NotePropertyValue $_.gateway
    Write-Host "Added Server gateway 2: "$_.gateway -ForegroundColor Yellow
}

if ($variable -eq $variableB -and $variable -ne $null)
{
    $_ | add-member "WorkstationGW1" -NotePropertyValue $_.gateway
    Write-Host "Added Workstation gateway 1: "$_.gateway -ForegroundColor Yellow
}

if ($variable -eq $variableD -and $variable -ne $null)
{
    $_ | add-member "DMZGW1" -NotePropertyValue $_.gateway
    Write-Host "Added DMZ gateway 1: "$_.gateway -ForegroundColor Yellow
}

if ($variable -eq $variableE -and $variable -ne $null)
{
    $_ | add-member "WorkstationGW2" -NotePropertyValue $_.gateway
    Write-Host "Added Workstation gateway 2: "$_.gateway -ForegroundColor Yellow
}
}
$hashArray | Out-GridView

Out-GridView 输出:

控制台输出:

预期输出:

【问题讨论】:

  • 可能存在复制粘贴错误。当满足 $variableE 和 $variableB 的条件时,您添加“WorkstationGW1”属性。
  • @cezarypiatek 是的,我在代码中更改了它。谢谢!
  • mklement0 打败了我,但为什么你要为你的对象使用唯一命名的属性呢?最佳做法是定义您的基对象类和成员变量,并让它们保持静态。

标签: powershell csv hashtable


【解决方案1】:

Out-GridView 使用第一个对象的属性来呈现列。由于没有在 $hashArray 中的第一个对象中初始化所有新列(ServerGW1 除外)。您可以使用 $null 值初始化所有行的所有属性,或者在将结果输出到 Out-GridView 之前提供要选择的属性列表

$hashArray | Select-Object NetworkName,Subnet,VLANID,Gateway,VLAN, ServerGW1, ServerGW2,WorkstationGW1,WorkstationGW2,DMZGW1  | Out-GridView

初始化所有属性:

$hashArray | % {
$variable =if ($_.subnet) {  ($_.subnet).split("/")[0] }Else { $null }
$_ | add-member "ServerGW1" -NotePropertyValue $(if ($variable -eq $variableA){ $_.gateway}Else { $null })
$_ | add-member "ServerGW2" -NotePropertyValue $(if ($variable -eq $variableC){ $_.gateway}Else { $null })
$_ | add-member "WorkstationGW1" -NotePropertyValue $(if($variable -eq $variableB){ $_.gateway}Else { $null })
$_ | add-member "DMZGW1" -NotePropertyValue $(if ($variable -eq $variableD ){ $_.gateway}Else { $null })
$_ | add-member "WorkstationGW2" -NotePropertyValue $(if ($variable -eq $variableE){ $_.gateway}Else { $null })
}
$hashArray | Out-GridView

【讨论】:

  • 啊。所以理论上 $hashArray 有所有的属性,但是 Out-GridView 没有显示出来?
  • 这回答了所提出的问题。但是 mklement0 的一个好点是返回对象而不是哈希表。
  • 没错。添加了所有属性,但对于 Out-GridView 不可见。您可以在 ISE 中使用调试器检查 $hashArray
【解决方案2】:

补充cezarypiatek's helpful answer,提供关键指针:

所有格式化 cmdlet,包括 Out-GridView,根据 first 输入对象决定要显示哪些属性(列),因此要保证显示所有感兴趣的列,您必须确保 (至少)第一个输入对象包含所有感兴趣的属性。

考虑到这一点,以下是您的方法的简化版本:

$csvfile = "C:\temp\testfile.csv"
$networks = Import-CSV $csvfile

# Define the subnets and their property names as an ordered hashtable.
$subnets = [ordered] @{
  '192.168.1.0' = 'ServerGW1'
  '192.168.2.0' = 'ServerGW2'
  '192.168.3.0' = 'WorkstationGW1'
  '172.16.0.0' = 'DMZGW1'
  '192.168.4.0' = 'WorkstationGW2'
}

# Add all properties of interest to the input objects, to ensure
# that Out-GridView (or other formatting cmdlets) show them all.
  # Construct an array of property names, where '*' stands for the original properties...
$propNames = @('*') + [string[]] $subnets.Values
  # ... and create augmented objects based on them.
$networks = $networks | Select-Object -property $propNames 

$networks | % {
  # See if the 'subnet' column has a value...
  if ($subnet = if ($_.subnet) { ($_.subnet).split("/")[0] } else { $null }) {
    # ... and, if so, see if a subnet name is defined for the part before '/' ...
    if ($subnets.Contains($subnet)) {
      # ... and, if so, fill the subnet-named property with the subnet address.
      $_.($subnets.$subnet) = $subnet
    }
  }
}
  • Import-CSV 不返回 散列表 它返回 自定义对象[pscustomobject] 实例)。

  • 代码依赖于这样一个事实:在表达式的上下文中,您既可以赋值给一个变量,也可以使用该赋值的,例如就像条件一样,就像这里的情况一样 (if ($subnet = ...))。

【讨论】:

  • 您的代码比我的代码有了很大的改进,但我仍然得到相同的结果:只添加了一个成员(第一个)。
  • @McKenning:cezarypiatek 的答案包含关键指针;请查看我的更新,了解更简化的解决方案,该解决方案考虑了该指针。
【解决方案3】:

试试这个,这个例子是动态的,你只需要修改你想要的 $hashvariable (或者如果你想用文件加载 $hashvariable)

$csvfile ="C:\temp\testfile.csv"
$hashArray = Import-CSV $csvfile

$hashvariable=[ordered]@{"192.168.1.0"="ServerGW1"; "192.168.2.0"="WorkstationGW1"; "192.168.3.0"="ServerGW2"; "172.16.0.1"="DMZGW1";  "192.168.5.0"="WorkstationGW2" }

$hashArray |  
%{
$result=$_ 
$variable = if ($_.subnet -ne $null) {($_.subnet).split("/")[0]} else {""}
foreach ($key in $hashvariable.Keys)
{
   $value=if ($variable -eq $key) {$key} else {""}
   $result | add-member $hashvariable[$key] -NotePropertyValue $value
}

}

$hashArray | Out-GridView

【讨论】:

    猜你喜欢
    • 2021-10-21
    • 2021-04-04
    • 1970-01-01
    • 2017-01-05
    • 1970-01-01
    • 2018-04-12
    • 2016-09-03
    • 2017-12-11
    • 1970-01-01
    相关资源
    最近更新 更多