我需要使用 PowerShell 歸檔一個沒有一些子檔案夾和檔案的檔案夾。我的檔案/檔案夾排除可能發生在任何層次結構級別。為了解釋,這里有一個 WinForms VS 專案的簡單示例。如果我們在 VS 中打開它并構建,VS 會創建包含可執行內容的 bin/obj 子檔案夾、包含用戶設定的隱藏 .vs 檔案夾,以及可能包含在解決方案中的專案的 *.user 檔案。我想歸檔這樣一個 VS 解決方案檔案夾,而沒有所有那些可以在下次構建解決方案時重新創建的檔案和檔案夾專案。
使用 7-Zip 使用它的 -x 可以很容易地完成它!命令列開關:
"C:\Program Files\7-Zip\7z.exe" a -tzip "D:\Temp\WindowsFormsApp1.zip" "D:\Temp\WindowsFormsApp1\" -r -x!bin -x!obj -x!.vs -x!*.suo -x!*.user
但是,我無法構建等效的 PowerShell 腳本。我得到的最好的東西是這樣的:
$exclude = "bin", "obj", ".vs", "*.suo", "*.user"
$files = Get-ChildItem -Path $path -Exclude $exclude -Force
Compress-Archive -Path $files -DestinationPath $dest -Force
如果我執行此腳本,排除串列僅適用于第一層級的子檔案夾。如果我將 -Recurse 開關添加到腳本中的Get-ChildItem cmdlet 或嘗試使用Where-Object過濾檔案/檔案夾,我將丟失存檔中的檔案夾層次結構。
我的問題有解決方案嗎?我需要僅使用 PowerShell 解決問題,而無需任何外部工具。
uj5u.com熱心網友回復:
這與how-to-compress-log-files-older-than-30-days-in-windows類似。
該ArchiveOldLogs.ps1腳本將保留檔案夾結構,而不需要中間復制。
您可以更改-Filter引數以按名稱而不是日期排除某些檔案:
$filter = {($_.Name -notlike '*.vs') -and ($_.Name -notlike '*.suo') -and ($_.Name -notlike '*.user') -and ($_.FullName -notlike '*bin\*') -and ($_.FullName -notlike '*obj\*')}
.\ArchiveOldLogs.ps1 -FileSpecs @('*.*') -Filter $filter -DeleteAfterArchiving:$false
這是一個不包含精美進度條的最小示例:
$ParentFolder = 'C:\projects\Code\' #a path that doesn't include your destination zip
$ZipPath = 'c:\temp\projects.zip'
$filter = {($_.Name -notlike '*.vs') -and ($_.Name -notlike '*.suo') -and ($_.Name -notlike '*.user') -and ($_.FullName -notlike '*bin\*') -and ($_.FullName -notlike '*obj\*')}
@( 'System.IO.Compression','System.IO.Compression.FileSystem') | % { [void][System.Reflection.Assembly]::LoadWithPartialName($_) }
Push-Location $ParentFolder
$FileList = (Get-ChildItem '*.*' -Recurse | Where-Object $Filter)
Try{
$WriteArchive = [IO.Compression.ZipFile]::Open( $ZipPath, [System.IO.Compression.ZipArchiveMode]::Update)
ForEach ($File in $FileList){
#$RelativePath = (Resolve-Path -LiteralPath "$($File.FullName)" -Relative).TrimStart(".\") #trimstart takes a set of characters, not a string. As a result, '.gitignore' is renamed to 'gitignore'
$RelativePath = (Resolve-Path -LiteralPath "$($File.FullName)" -Relative) -replace '^.\\'
Try{ [IO.Compression.ZipFileExtensions]::CreateEntryFromFile($WriteArchive, $File.FullName, $RelativePath, 'Optimal').FullName
}Catch{
Write-Warning "$($File.FullName) could not be archived. `n $($_.Exception.Message)"
}
}
}Catch [Exception]{
Write-Error $_.Exception
}Finally{
$WriteArchive.Dispose() #close the zip file so it can be read later
}
Pop-Location
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/372598.html
