【问题标题】:Add column and assign value to an existing array添加列并将值分配给现有数组
【发布时间】:2014-08-07 04:38:43
【问题描述】:

我想将一列和一个值添加到从 CSV 生成的现有数组中。

这是我的代码:

$mycsv = "C:\Users\test\Documents\serveurs.csv"
$servers = Import-Csv $mycsv

这是结果:

服务器名IP ---------- -- 脚轮 172.22.0.64 波勒克斯 172.22.0.67

我想为每个 ServerName 添加具有值的新列,如下所示:

服务器名 IP 可用 ---------- -- --------- 脚轮 172.22.0.64 是 Pollux 172.22.0.67 否

我尝试了下面的代码:

$item = New-Object PSObject
$item | Add-Member -Type NoteProperty -Name 'Available' -Value 'Yes'

$servers += $item

但它实际上不起作用,任何人都可以帮助我吗?

最后的想法是使用Test-Connection cmdlet 分配服务器是否可通过网络访问的值。

【问题讨论】:

    标签: arrays powershell csv


    【解决方案1】:

    我不确定是否存在用于操作 CSV 文件的内置模块。

    您可以操作 CSV 文件以提供输出或将 NoteProperty 添加到现有变量。

    示例 1:

    (cat "C:\Users\test\Documents\serveurs.csv") -replace "Servername;IP", "Servername;IP;Available" -replace "64","64;" -replace "67","67;" | out-file "C:\Users\test\Documents\serveurs.csv"
    

    示例 2:

    $CSV | Add-Member -MemberType NoteProperty "Available" -Value "Yes"
    

    我猜这应该能解决你的需求。

    编辑:

    由于问题已得到澄清,因此这是建议的答案。

    我很确定有一个更简单的方法可以做到这一点,但它仍然有效

    $CSV | Add-Member -MemberType NoteProperty "Available" -Value "" 
    for ($i=0; $i -le $CSV.Length-1; $i++) {$CSV[$i].Available = Test-Connection $CSV[$i].Servername -quiet}
    

    【讨论】:

    • 您的第二个示例正在运行,但这并不是我真正想要的。因为它实际上将值“yes”分配给我所有的 ServerName
    • 很抱歉,您没有指定确切想要什么。您是否希望根据服务器是否可以通过网络访问来分配值?
    • 是的,我将使用测试连接 cmdlet。我知道如何使用它,但我想将最终结果放入我的数组(从我的 csv 生成)。我的问题是“如何将新列和新值分配给从 csv 生成的数组?”感谢您的帮助。
    • 已更新答案
    【解决方案2】:

    您可以使用计算属性来确定每个服务器的可用性:

    $csv1 = 'C:\Users\test\Documents\serveurs.csv'
    $csv2 = 'C:\Users\test\Documents\serveurs2.csv'
    
    Import-Csv $csv1 |
        Select-Object ServerName, Ip,
            @{n='Available';e={[bool](Test-Connection -Count 1 $_.Ip 2>$null)}} |
        Export-Csv $csv2 -NoType
    

    但是请注意,即使将测试限制为每台服务器的单个探测,这也可能需要一些时间,因为所有项目都是按顺序处理的。如果您有很多服务器要测试,您可能希望将检查作为并行作业运行:

    $csv = 'C:\Users\test\Documents\serveurs.csv'
    
    $servers = Import-Csv $csv
    
    # clear job queue
    Remove-Job *
    # load job queue with test jobs
    $servers | ForEach-Object {
        Start-Job -ScriptBlock {
            $args[0]
            [bool](Test-Connection -Count 1 $args[0] 2>$null)
        } -ArgumentList $_.Ip
    }
    # wait for jobs to finish
    do {
        Start-Sleep -Milliseconds 100
    } while (Get-Job -State 'Running')
    
    # gather job results into hashtable
    $availability = @{}
    Get-Job | ForEach-Object {
        $result = Receive-Job -Id $_.Id
        $availability[$result[0]] = $result[1]
        Remove-Job -Id $_.Id
    }
    
    # add availability column to server data and export back to CSV
    $servers |
        Select-Object ServerName, Ip, @{n='Available';e={$availability[$_.Ip]}} |
        Export-Csv $csv -NoType
    

    【讨论】:

    • 比我的答案要好得多,我需要仔细看看这个脚本,以了解更多关于哈希表和一般结构的信息。你能解释一下“e=”子句到底是什么吗? (在 e={$availability[$_.Ip]) 中?它只是从脚本表达式中获取价值,对吧?
    • @Koliat 检查TechNet article on calculated propertieseExpression 的缩写。
    【解决方案3】:

    除了填充字段值之外,添加属性的另一个选项是使用 Select-Object。

    $csv = 'C:\Users\test\Documents\serveurs.csv'
    $servers = Import-Csv $csv | select *,Availability
    

    然后根据您的选择填充可用性。

    如果您打算将后台作业用于多线程,我认为您最好将服务器名称分成组并设置后台作业以在每个组上工作。设置和关闭后台作业大约需要 5 秒钟,而将它们用于 ping 单台计算机等琐碎任务可能会适得其反。

    编写代码需要更多的工作,但如果您想要多线程,我认为运行空间池会比此应用程序中的后台作业更快地产生结果。

    【讨论】:

      【解决方案4】:

      如果您想创建自定义对象并添加值,这应该可以通过执行类似的操作来实现:

           [System.Collections.ArrayList]$myList = @()
           $mycsv = "C:\Users\test\Documents\serveurs.csv"
           $servers = Import-Csv $mycsv
           ForEach ( $server in $servers ) {
           $myobj = New-Object PSObject
           $test="No"
           if (Test-Connection $server.ip -Count 1 | Out-Null){
           $test="Yes"
           } 
           Add-Member -InputObject $myobj -NotePropertyName Name -NotePropertyValue $server.ServerName
           Add-Member -InputObject $myobj -NotePropertyName IP -NotePropertyValue $server.ip
           Add-Member -InputObject $myobj -NotePropertyName Available -NotePropertyValue $test
           $mylist.add($myobj)
           }$mylist
      

      您将收到您的对象列表,然后您可以将其导出到您的 csv 或排序或任何内容中

      【讨论】:

        猜你喜欢
        • 2020-09-14
        • 2021-10-25
        • 1970-01-01
        • 1970-01-01
        • 2020-07-04
        • 2022-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多