将多个成员添加到powershell哈希表

时间:2016-12-13 21:53:26

标签: powershell csv hashtable

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

五个变量(variableA-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,,,,

CODE:

$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 OUTPUT:

OutGrid Results

控制台输出:

Console output

预期产量: Expected Output

3 个答案:

答案 0 :(得分:4)

Out-GridView使用第一个对象的属性来呈现列。缺少所有新列(ServerGW1除外),因为未在$ hashArray的第一个对象中初始化。您可以使用$ 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

答案 1 :(得分:1)

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

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

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

$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]个实例)。

    < / LI>
  • 代码依赖的事实是,在表达式的上下文中,您可以分配给变量并使用该赋值的,例如如同在条件中一样(if ($subnet = ...))。

答案 2 :(得分:0)

试试这个,这个例子是动态的,你只需要像你想要的那样修改$ hash变量(或者如你所愿加载带有文件的$ hash变量)

$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