在Foreach之前加速测试连接

时间:2014-06-27 01:35:58

标签: powershell csv foreach

我制作了一个脚本来检查用户桌面文件夹是否属于cuota限制,如果他们受到cuota限制,则对服务器的备份将正确完成。

每个用户都有他的计算机,因此源CSV看起来像:

pc1,user1
pc2,user2
pc800,user800

有些计算机是Windows Xp和一些W7,路径可能不同,因为我使用的是测试路径

W7 = C:\users\$user\desktop
XP = C:\document and settings\$user\desktop

但Test-Path是SUPER SLOW,我开始在每个测试路径之前使用Test-Connection -count 1

无论如何,脚本仍然缓慢,在每次"坏的ping测试"我失去了很多时间。

CODE:

$csvLocation = '~\desktop\soourceReport.csv'
$csv = import-csv $csvLocation -Header PCName, User

$OuputReport = '~\desktop\newReport.csv'

# info:
# "209715200" Bytes = 200 MB

$cuota = "209715200"
$cuotaTranslate = "$($cuota / 1MB) MB"
Write-Host "Cuota is set to $cuotaTranslate"

$count=1

foreach($item in $csv)
{
    write-host "$count# Revisando" $item.User "en" $item.PCName "..." #For debug

    if (Test-Connection -Quiet -count 1 -computer $($item.PCname)){

        $w7path = "\\$($item.PCname)\c$\users\$($item.User)\desktop"
        #echo $w7path #debug

        $xpPath = "\\$($item.PCname)\c$\Documents and Settings\$($item.User)\Escritorio"
        #echo $xp #debug

                if(Test-Path $W7path){

                    $desktopSize = (Get-ChildItem -Recurse -force $w7path | Measure-Object -ErrorAction "SilentlyContinue" -property length -sum) 

                    write-host -ForegroundColor Green "access succeed"

                        if($($desktopSize.sum) -gt $cuota){


                            $newLine =  "{0},{1},{2}" -f $($item.PCname),$($item.User),"$("{0:N0}" -f $($desktopSize.sum / 1MB)) MB"
                            $newLine |  add-content $outputReport

                             Write-Host -ForegroundColor Yellow "cuota exceeded! -- added"
                         }

                        else{
                         Write-Host -ForegroundColor DarkYellow  "cuota OK"
                        }


                }

                elseif(Test-Path $xpPath){

                    $desktopSize = (Get-ChildItem -Recurse -force $xpPath | Measure-Object -ErrorAction "SilentlyContinue" -property length -sum) 

                    write-host -ForegroundColor Green "access succeed"

                        if($($desktopSize.sum) -gt $cuota){


                            $newLine =  "{0},{1},{2}" -f $($item.PCname),$($item.User),"$("{0:N0}" -f $($desktopSize.sum / 1MB)) MB"
                            $newLine |  add-content $outputReport

                             Write-Host -ForegroundColor Yellow "cuota exceeded! -- added"
                         }

                        else{
                         Write-Host -ForegroundColor DarkYellow  "cuota OK"
                        }
                else{
                     write-host -ForegroundColor Red "Error! - bad path"
                }
    }

    else{
        write-host -ForegroundColor Red "Error! - no ping"
    }
    $count++
}
Write-Host -ForegroundColor green -BackgroundColor DarkGray "All done! new report stored in $report"

为了改进它,我在第一次提到的SLOW-Foreach循环之前,使用另一个Foreach将所有计算机存储在$ list中。

foreach($pcs in $csv){

    $alivelist += @( $pcs.PCName )
}

Test-Connection -quiet -count 2 -computer $alivelist

现在,我现在还不知道如何在进入第二个Foreach之前更新或删除SOURCE CSV中的行("死" pc,用户)。

我需要你的一些魔法"或至少一些想法!

感谢

2 个答案:

答案 0 :(得分:3)

要加快脚本速度,您需要并行运行检查(正如其他人已经提到的那样)。将您的支票和工人代码放在一个scriptblock中:

$sb = {
    Param($computer, $username)

    if (Test-Connection -Quiet -Count 2 $computer) { return }

    $w7path = "\\$computer\c$\users\$username\desktop"
    $xpPath = "\\$computer\c$\Documents and Settings\$username.TUITRA..."

    if (Test-Path $W7path) {
        #...
    } elseif (Test-Path $xpPath) {
        #...
    } else {
        #...
    }
}

然后将scriptblock作为并行作业运行:

$csv | ForEach-Object {
    Start-Job -ScriptBlock $sb -ArgumentList $_.PCName, $_.User
}

# wait for completion
do {
    Start-Sleep -Milliseconds 100
} while (Get-Job -State 'Running')

# cleanup
Get-Job | ForEach-Object {
    Receive-Job -Id $_.Id
    Remove-Job -Id $_.Id
} | Out-File $outputReport

如果您需要限制并行作业的数量,请使用queue

答案 1 :(得分:0)

使用-asjob参数的测试连接速度很快,在4秒内可对200台计算机执行ping操作:

$list = cat hp.txt
test-connection $list -AsJob ; job | receive-job -wait -AutoRemoveJob