[英]Powershell | How can I use Multi Threading for my File Deleter Powershell script?
所以我寫了一個腳本來在 5 天后刪除特定文件夾中的文件。 我目前正在一個包含數十萬個文件的目錄中實現它,這會花費很多時間。
這是目前我的代碼:
#Variables
$path = "G:\AdeptiaSuite\AdeptiaSuite-6.9\AdeptiaServer\ServerKernel\web\repository\equalit\PFRepository"
$age = (Get-Date).AddDays(-5) # Defines the 'x days old' (today's date minus x days)
# Get all the files in the folder and subfolders | foreach file
Get-ChildItem $path -Recurse -File | foreach{
# if creationtime is 'le' (less or equal) than $age
if ($_.CreationTime -le $age){
Write-Output "Older than $age days - $($_.name)"
Remove-Item $_.fullname -Force -Verbose # remove the item
}
else{
Write-Output "Less than $age days old - $($_.name)"
}
}
我已經在 inte.net 上搜索了一段時間,以了解如何使用運行空間,但我發現它非常令人困惑,而且我不確定如何使用此腳本來實現它。 任何人都可以給我一個如何為這段代碼使用運行空間的例子嗎?
非常感謝你!
編輯:我發現這篇文章: https://adamtheautomator.com/powershell-multithreading/
最后將我的腳本更改為:
$Scriptblock = {
# Variables
$path = "G:\AdeptiaSuite\AdeptiaSuite-6.9\AdeptiaServer\ServerKernel\web\repository\equalit\PFRepository"
$age = (Get-Date).AddDays(-5) # Defines the 'x days old' (today's date minus x days)
# Get all the files in the folder and subfolders | foreach file
Get-ChildItem $path -Recurse -File | foreach{
# if creationtime is 'le' (less or equal) than $age
if ($_.CreationTime -le $age){
Write-Output "Older than $age days - $($_.name)"
Remove-Item $_.fullname -Force -Verbose # remove the item
}
else{
Write-Output "Less than $age days old - $($_.name)"
}
}
}
$MaxThreads = 5
$RunspacePool = [runspacefactory]::CreateRunspacePool(1, $MaxThreads)
$RunspacePool.Open()
$Jobs = @()
1..10 | Foreach-Object {
$PowerShell = [powershell]::Create()
$PowerShell.RunspacePool = $RunspacePool
$PowerShell.AddScript($ScriptBlock).AddArgument($_)
$Jobs += $PowerShell.BeginInvoke()
}
while ($Jobs.IsCompleted -contains $false) {
Start-Sleep 1
}
但是我不確定這現在是否正常工作,我沒有收到任何錯誤但是終端沒有做任何事情,所以我不確定它是有效還是什么都不做。
我希望對此有任何反饋!
最簡單的答案是:獲取PowerShell v7.2.5 (查看PowerShell-7.2.5-win-x64.zip
的資產),下載並解壓縮。 這是一個無需安裝的 PowerShell 7 ,它具有簡單的多線程並允許您將foreach {
更改為foreach -parallel {
。 可執行文件是 pwsh.exe。
但是,如果服務器嚴重超載,多次運行只會讓事情變得更糟,對吧? 而且我認為Get-ChildItem
將是最慢的部分,給服務器帶來最大的負載,因此並行刪除可能無濟於事。
我會首先嘗試將腳本更改為這種形狀:
$path = "G:\AdeptiaSuite\AdeptiaSuite-6.9\AdeptiaServer\ServerKernel\web\repository\equalit\PFRepository"
$age = (Get-Date).AddDays(-5)
$logOldFiles = [System.IO.StreamWriter]::new('c:\temp\log-oldfiles.txt')
$logNewFiles = [System.IO.StreamWriter]::new('c:\temp\log-newfiles.txt')
Get-ChildItem $path -Recurse -File | foreach {
if ($_.CreationTime -le $age){
$logOldFiles.WriteLine("Older than $age days - $($_.name)")
$_ # send file down pipeline to remove-item
}
else{
$logNewFiles.WriteLine("Less than $age days old - $($_.name)")
}
} | Remove-Item -Force
$logOldFiles.Close()
$logNewFiles.Close()
因此它通過管道傳輸到 remove-item 並且不會向控制台發送數十萬行文本(這也是一件很慢的事情)。
如果這沒有幫助,我會切換到robocopy /L
並且可能會查看robocopy /L /MINAGE...
來列出文件,然后處理它以進行刪除。
(我還刪除了只是重復代碼行的注釋 # 刪除了重復代碼所說內容的注釋。代碼告訴你代碼說了什么 # 閱讀代碼以查看代碼的作用。注釋應該告訴你為什么代碼這樣做東西,比如誰寫了腳本,它解決了什么業務案例,什么是 PFRepository,為什么有 5 天的截止日期,等等。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.