簡體   English   中英

Powershell | 如何為我的文件刪除器 Powershell 腳本使用多線程?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM