我想为从CSV生成的现有数组添加列和值。
这是我的代码:
$mycsv = "C:\Users\test\Documents\serveurs.csv"
$servers = Import-Csv $mycsv
结果如下:
ServerName Ip ---------- -- Castor 172.22.0.64 Pollux 172.22.0.67
我想为每个ServerName添加带有值的新列,如下所示:
ServerName Ip Available ---------- -- --------- Castor 172.22.0.64 Yes Pollux 172.22.0.67 No
我尝试了以下代码:
$item = New-Object PSObject
$item | Add-Member -Type NoteProperty -Name 'Available' -Value 'Yes'
$servers += $item
但它实际上不起作用,任何人都可以帮助我吗?
最后的想法是使用Test-Connection
cmdlet在服务器可通过网络访问时分配值。
答案 0 :(得分:6)
您可以使用计算属性来确定每台服务器的可用性:
$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
答案 1 :(得分:2)
我不确定是否存在用于操作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}
答案 2 :(得分:2)
除了填充字段值之外,添加属性的另一个选项是使用Select-Object。
$csv = 'C:\Users\test\Documents\serveurs.csv'
$servers = Import-Csv $csv | select *,Availability
然后根据您的选择填充可用性。
如果您要使用后台作业进行多线程,我认为您最好将服务器名称分组并设置后台作业以处理每个组。设置和拆除后台作业大约需要5秒钟,将它们用于ping一台计算机等琐碎任务可能会适得其反。
编写代码需要做更多工作,但如果你想要多线程,我认为运行空间池会比这个应用程序中的后台作业产生更快的结果。
答案 3 :(得分:0)
如果要创建自定义对象并添加值,可以通过执行以下操作来实现:
[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或sort或其他任何内容