我是 Powershell 新手。我有一个需求,我认为它非常适合我。然而,我很快就发现我力不从心。基本上,我需要创建一个 .zip 文件。
我有一个如下所示的目录:
MyStuff
Dir1
Child1
File1.txt
Child2
File1.png
Child3
File1.txt
Dir2
File1.txt
File1.txt
File2.txt
File3.txt
...
我需要创建一个名为 bundle.zip 的 .zip 文件。Bundle.zip 不应包含 MyStuff 内的所有文件。相反,我需要将 MyStuff/File1.txt、MyStuff/File2.txt、MyStuff/File3.txt 和 MyStuff/Dir1/* 包含到 .zip 文件中。我不知道如何使用 PowerShell 执行此操作。
我的机器上安装了 PowerShell v1.0。我一直在尝试使用 PowerShell 社区扩展中的“Write-Zip”,但是,我收到一条错误消息:“术语‘Write-Zip’未被识别为 cmdlet、函数、脚本文件或可运行程序的名称”。
我究竟做错了什么?
答案1
您需要下载与您安装的 Powershell 版本兼容的 Powershell 社区扩展并安装。安装完成后,您需要将 PSCX 模块从程序文件位置移动到 Powershell 模块,然后尝试使用 Write-Zip 命令。
答案2
可以使用CreateFromDirectory
.NET 类的方法进行压缩System.IO.Compression.ZipFile
。我更喜欢使用 .NET 而不是安装社区扩展和其他附加组件,以便尽可能保持服务器环境干净。
我相信您不能使用它来添加到 zip 存档,但需要将文件和文件夹以正确的结构临时复制到暂存目录。从那里您可以创建 zip 文件并删除暂存内容。
要使用 .NET 进行压缩,首先需要加载类程序集:
[System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem")
然后你就可以调用该类:
[System.IO.Compression.ZipFile]::CreateFromDirectory($DirPath, $ZipFilePath, $CompressionLevel, $includeBaseDir)
在哪里:
$DirPath
是您要压缩的目录。
$ZipFilePath
是您要创建的 zip 文件的名称。
$Compressionlevel
可以设置为Optimal
、Fastest
或NoCompression
。
$includeBaseDir
可以是$true
或$false
。
我写了一个函数来省去查找.NET 参考页面一直都是。如果你看一下这个页面,你会看到还有一个解压的方法。
需要 .NET 4.5,我强烈建议您也升级 powershell。每个版本都带来了巨大的改进。事实证明,使用 .NET 非常高效,与流行的第三方 zip 应用程序进行基准测试后,它表现强劲。
该函数非常容易理解,只需确保在调用它之前运行该函数本身即可。如果您需要,这里有一个简短的语法概述:
New-ZipFile {DirToZip} {ZipfilePathAndName} {fastORoptimalORnocompression} {IncludeBaseDirectoryInZip($true or $false)}
因此,要E:\stuff
使用D:\zipfile.zip
最佳压缩并将 basedir 包含.\stuff
在 zip 文件中,您需要运行:
New-ZipFile 'E:\stuff' 'D:\zipfile.zip' Optimal $true
该函数如下:
#region function New-ZipFile
<#
.Synopsis
Creates a zip file from a directory.
.DESCRIPTION
Creates a zip file from a directory. Options include compression level and wether or not to include the base directory. Class reference: https://msdn.microsoft.com/en-us/library/hh875104(v=vs.110).aspx
.EXAMPLE
New-ZipFile c:\dir c:\zipfile.zip Fastest $True
.EXAMPLE
New-ZipFile c:\dir c:\zipfile.zip Optimal $True
.INPUTS
Inputs to this cmdlet (if any)
.OUTPUTS
Output from this cmdlet (if any)
.NOTES
General notes
.COMPONENT
The component this cmdlet belongs to
.ROLE
The role this cmdlet belongs to
.FUNCTIONALITY
The functionality that best describes this cmdlet
#>
function New-ZipFile
{
Param
(
# The directory to zip.
[Parameter(Mandatory=$true,
Position=0)]
[ValidateNotNullOrEmpty()]
[string]$DirPath,
# The zipfile name.
[Parameter(Mandatory=$true,
Position=1)]
[ValidateNotNullOrEmpty()]
[string]$ZipFilePath,
# Specifies values that indicate whether a compression operation emphasizes speed or compression size.
[Parameter(Mandatory=$true,
Position=2)]
[ValidateNotNullOrEmpty()]
[ValidateSet("Fastest", "NoCompression", "Optimal", ignorecase=$True)]
[string]$CompressionLevel,
# $True to include the directory name from sourceDirectoryName at the root of the archive; $False to include only the contents of the directory.
[Parameter(Mandatory=$true,
Position=3)]
[ValidateNotNullOrEmpty()]
[bool]$includeBaseDir
)
#Load the .NET 4.5 zip-assembly
[System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null
# Zip the directory.
[System.IO.Compression.ZipFile]::CreateFromDirectory($DirPath, $ZipFilePath, $CompressionLevel, $includeBaseDir)
}
#endregion
编辑:脚本专家写了一篇文章,展示了一个加载程序集的另一种方法,看上去更干净一些。