在Foreach之前加速测试连接 [英] Speed up Test-Connection before Foreach
问题描述
我制作了一个脚本来检查用户桌面文件夹是否在cuota限制下,如果他们在cuota限制下,则将正确完成对服务器的备份.
I made a script to check if users desktop folder are under the cuota limitation, if they're under the cuota limitation the backup to the server will be done correctly.
每个用户都有自己的计算机,因此源CSV如下:
each user have his computer, so source CSV looks like:
pc1,user1
pc2,user2
pc800,user800
某些计算机是Windows Xp和某些W7,并且路径可能会有所不同,因为我使用的是Test-Path
Some computers are Windows Xp and some W7, and the paths can be different 'cause of that I'm using Test-Path
W7 = C:\users\$user\desktop
XP = C:\document and settings\$user\desktop
但是Test-Path超级慢,我开始在每个Test-path之前使用Test-Connection -count 1
But Test-Path is SUPER SLOW and I started to use a Test-Connection -count 1 before each Test-path
无论如何,脚本仍然很慢,在每次不良ping测试"中,我都浪费了很多时间.
Anyway, the script still SLOW, in each "bad ping test" I lose lot of time.
代码:
$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中.
To improve it I stored all computers in a $list using another Foreach, before the firstly mentioned SLOW-Foreach loop.
foreach($pcs in $csv){
$alivelist += @( $pcs.PCName )
}
Test-Connection -quiet -count 2 -computer $alivelist
现在,在进入第二个Foreach之前,我现在不怎么更新或从SOURCE CSV中删除行(死"的个人计算机,用户).
Now, I don't now how to UPDATE or remove the rows ("dead" pc,user) from the SOURCE CSV before to enter into the second Foreach.
我需要一些您的魔术",或者至少一些主意!
I need some of your "magic", or at least some ideas!
谢谢
推荐答案
要加快脚本运行速度,您需要并行运行检查(正如其他人已经提到的那样).将检查和辅助代码放在脚本块中:
To speed up your script you need to run the checks in parallel (as others have already mentioned). Put your checks and the worker code in a 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 {
#...
}
}
然后将脚本块作为并行作业运行:
Then run the scriptblock as parallel jobs:
$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
如果需要限制并行作业的数量,请使用队列.
Use a queue if you need to limit the number of parallel jobs.
这篇关于在Foreach之前加速测试连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!