PowerShell foreach file in folder using a lot of memory -
i'm new powershell , programming, i'm sure code can optimized more.
however, biggest problem code puts it's data foreach loop in memory. best way prevent this?
i started rewriting script script found here: powershell: delete files older x days
edit: oh, there 60 000~ files in each targetfolder way.
## set window title $title = $host.ui.rawui.windowtitle $titdef = $title $host.ui.rawui.windowtitle = "checking files. not close " + "($title)" ## debug (0=nothing, 1=extended log, 2=extended log+screen) $debug = "2" ## log file $log = "c:\status\status.txt" add-content $log "nul" ## clear log before adding new data remove-item $log ## folders check $targetfolder1 = “\\server\c$\biztalkprojects\udc\output\ume” $targetfolder2 = “\\server\c$\biztalkprojects\udc\output\upp” ## required stuff $now = get-date $days = “2” $twodays = $now.adddays(-$days) $folder1 = get-childitem $targetfolder1 -include * $folder2 = get-childitem $targetfolder2 -include * ## window message "checking files newer $days days in:" "$targetfolder1" "$targetfolder2" "" "this may take 5-15 minutes . . . (will commit 250mb~ ram during period)" ## reset variable $ok "0" $ok = 0 if ($debug -eq "2") {"check1"} foreach ($file in $folder1) { $filelastwrite = $file.lastwritetime if ($file.lastwritetime -le $twodays) { $ok = $ok + "0" if ($debug -eq "2") { "ok + 0 (=$ok) $file ($filelastwrite)" } } else { $ok = $ok + "1" if ($debug -eq "2") { "ok + 1 (=$ok) $file ($filelastwrite)" } } } if ($debug -eq "2") {"check2"} foreach ($file in $folder2) { $filelastwrite = $file.lastwritetime if ($file.lastwritetime -le $twodays) { $ok = $ok + "0" if ($debug -eq "2") { "ok + 0 (=$ok) $file ($filelastwrite)" } } else { $ok = $ok + "1" if ($debug -eq "2") { "ok + 1 (=$ok) $file ($filelastwrite)" } } } if ($ok -gt "0") { if ($debug -eq "2") { "" "found $ok file(s) newer $days days" } add-content $log "ok" if ($debug -ge "1") { add-content $log "found $ok file(s) newer $days days" } } else { if ($debug -eq "2") { "" "found $ok file(s) newer $days days" } add-content $log "error" if ($debug -ge "1") { add-content $log "found $ok file(s) newer $days days" } } $host.ui.rawui.windowtitle = $titdef
this version works. helped!
## set window title $title = $host.ui.rawui.windowtitle $titdef = $title $host.ui.rawui.windowtitle = "checking files. not close " + "($title)" ## debug (0=nothing, 1=extended log, 2=extended log+screen) $debug = "2" ## log file $log = "c:\status\status.txt" add-content $log "nul" ## clear log before adding new data remove-item $log ## folders check $targetfolder1 = “\\server\c$\biztalkprojects\udc\output\ume” $targetfolder2 = “\\server\c$\biztalkprojects\udc\output\upp” ## required stuff $now = get-date $days = “2” $twodays = $now.adddays(-$days) ## window message "checking files newer $days days in:" "$targetfolder1" "$targetfolder2" "" "this may take 5-15 minutes . . ." ## reset variable $ok "0" $ok = 0 get-childitem $targetfolder1,$targetfolder2 -filter *.xml |where-object { $filelastwrite = $_.lastwritetime if ($filelastwrite -le $twodays) { $ok = $ok + "0" } else { $ok = $ok + "1" } } if ($ok -gt "0") { if ($debug -eq "2") { "" "found $ok file(s) newer $days days" } add-content $log "ok" if ($debug -ge "1") { add-content $log "found $ok file(s) newer $days days" } } else { if ($debug -eq "2") { "" "found $ok file(s) newer $days days" } add-content $log "error" if ($debug -ge "1") { add-content $log "found $ok file(s) newer $days days" } } $host.ui.rawui.windowtitle = $titdef
try:
$folder1 = get-childitem $targetfolder1 -filter *.xml
much more performant using include
(on large set of files). or better:
get-childitem $targetfolder1 -filter *.xml | % {}
edit
i see now, problems due include
! if need use wildcards , nor regular expressions child item, use filter
instead. more performant because not use regular expression matching.
try:
$folder1 = get-childitem $targetfolder1 -filter *
even if it's not clear filtering there (or want include)...everything? may don't need wildcard @ all.
in humble opinion, best way prevent foreach loop in memory piping. however, due nature of script (many nested controls inside loop) it's not easy.
try with:
$folder1 | % { # ... }
even if doubt improve performances.
or:
get-childitem $targetfolder1 -include * | % { # ... }
Comments
Post a Comment