我有一个脚本,通过服务器运行,并打印出他们是否可以连接到特定的端口。问题似乎是它一直在循环通过现有的服务器,它已经完成了......因此我看到了多个服务器的结果,CSV文件一直在被重新编写,因为每次迭代都会重新启动循环,以添加到下一个服务器上。
有什么办法可以确保每次只循环一个服务器,而不是每次重复同一个服务器?最后的CSV是很好的,因为它包含了所有的服务器,但它需要花很多时间才能到达那里。
输出结果如下--你可以看到它是如何不断地重做现有的服务器,并且每次运行时只是增加一个服务器。
Destination Port 3389 Port 445 Port 80
----------- --------- -------- -------
10.104.122.21 Failure Failure Failure
10.104.122.50 Failure Failure Failure
10.104.125.237 Failure Failure Failure
Destination Port 3389 Port 445 Port 80
----------- --------- -------- -------
10.104.122.21 Failure Failure Failure
10.104.122.50 Failure Failure Failure
10.104.125.237 Failure Failure Failure
10.104.125.66 Failure Failure Failure
Destination Port 3389 Port 445 Port 80
----------- --------- -------- -------
10.104.122.21 Failure Failure Failure
10.104.122.50 Failure Failure Failure
10.104.125.237 Failure Failure Failure
10.104.125.66 Failure Failure Failure
10.104.125.95 Failure Failure Failure
代码如下
Function Test-PortConnections {
[CmdletBinding()]
# Parameters used in this function
Param
(
[Parameter(Position=0, Mandatory = $True, HelpMessage="Provide destination source", ValueFromPipeline = $true)]
$Destination,
[Parameter(Position=1, Mandatory = $False, HelpMessage="Provide port numbers", ValueFromPipeline = $true)]
$Ports = "80"
)
$ErrorActionPreference = "SilentlyContinue"
$Results = @()
ForEach($D in $Destination){
# Create a custom object
$Object = New-Object PSCustomObject
$Object | Add-Member -MemberType NoteProperty -Name "Destination" -Value $D
Write-Verbose "Checking $D"
ForEach ($P in $Ports){
#write-host "Port is $p"
$timeout=100
$requestCallback = $state = $null
$client = New-Object System.Net.Sockets.TcpClient
$beginConnect = $client.BeginConnect($d,$p,$requestCallback,$state)
Start-Sleep -milli $timeOut
if ($client.Connected -eq "True") { $Result = "True" } else { $Result = "False" }
$client.Close()
If($Result -eq "False"){ $status = "Failure" } else { $status = "Success" }
$Object | Add-Member Noteproperty "$("Port " + "$p")" -Value "$($status)"
}
$Results += $Object
If($Results){
$date = $(get-date -f yyyy-MM-dd)
$Results | Format-Table -AutoSize
$Results | Export-Csv -NoTypeInformation -Delimiter "," -Path H:\MyDocuments\Scripts\server_check_$($date).csv
}
}
}
Test-PortConnections -Destination (Get-Content -Path "H:\MyDocuments\Scripts\servers.txt") -Ports 3389,445,80
每次外 foreach()
循环运行,在最后你。
$Results += $object
)$Results | Format-Table -AutoSize
)$Results | Export-Csv ...
)Export-Csv
会简单地覆盖之前写入的文件,所以你不会看到最终的结果有什么不同。
为了解决这个问题,我建议将你的函数输出简单地设置为 $object
当你到达环形体的末端时,你就可以自行移动环形体,然后或者将 Export-Csv
踏出圈外。
ForEach ($D in $Destination) {
# Create a custom object
$Object = New-Object PSCustomObject
$Object | Add-Member -MemberType NoteProperty -Name "Destination" -Value $D
Write-Verbose "Checking $D"
ForEach ($P in $Ports) {
#write-host "Port is $p"
$timeout = 100
$requestCallback = $state = $null
$client = New-Object System.Net.Sockets.TcpClient
$beginConnect = $client.BeginConnect($d, $p, $requestCallback, $state)
Start-Sleep -milli $timeOut
if ($client.Connected -eq "True") { $Result = "True" } else { $Result = "False" }
$client.Close()
If ($Result -eq "False") { $status = "Failure" } else { $status = "Success" }
$Object | Add-Member Noteproperty "$("Port " + "$p")" -Value "$($status)"
}
Write-Output $Object
$Results += $object
}
If ($Results) {
$date = $(Get-Date -f yyyy-MM-dd)
$Results | Export-Csv -NoTypeInformation -Delimiter "," -Path H:\MyDocuments\Scripts\server_check_$($date).csv
}
...或使用 Export-Csv
与 -Append
在这一点上,你不需要 $Results
完全没有。
$date = Get-Date -Format yyyy-MM-dd
$ExportFileName = 'H:\MyDocuments\Scripts\server_check_${date}.csv'
ForEach ($D in $Destination) {
# Create a custom object
$Object = New-Object PSCustomObject
$Object | Add-Member -MemberType NoteProperty -Name "Destination" -Value $D
Write-Verbose "Checking $D"
ForEach ($P in $Ports) {
#write-host "Port is $p"
$timeout = 100
$requestCallback = $state = $null
$client = New-Object System.Net.Sockets.TcpClient
$beginConnect = $client.BeginConnect($d, $p, $requestCallback, $state)
Start-Sleep -milli $timeOut
if ($client.Connected -eq "True") { $Result = "True" } else { $Result = "False" }
$client.Close()
If ($Result -eq "False") { $status = "Failure" } else { $status = "Success" }
$Object | Add-Member Noteproperty "$("Port " + "$p")" -Value "$($status)"
}
Write-Output $object
$object | Export-Csv -Append -NoTypeInformation -Delimiter "," -Path $ExportFileName
}