Powershell脚本多次重复同一个服务器。

问题描述 投票:0回答:1

我有一个脚本,通过服务器运行,并打印出他们是否可以连接到特定的端口。问题似乎是它一直在循环通过现有的服务器,它已经完成了......因此我看到了多个服务器的结果,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

powershell
1个回答
1
投票

每次外 foreach() 循环运行,在最后你。

  1. 将当前对象添加到现有的结果中 ($Results += $object)
  2. 格式和书写 全部 现有的结果在屏幕上($Results | Format-Table -AutoSize)
  3. 出口 全部 将现有的结果归档($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
}
© www.soinside.com 2019 - 2024. All rights reserved.