Powershell에서 파일의 압축을 푸는 방법은 무엇입니까?


224

나는이 .zip파일 및 PowerShell을 사용하여 전체 내용을 압축 해제해야합니다. 나는 이것을하고 있지만 작동하지 않는 것 같습니다 :

$shell = New-Object -ComObject shell.application
$zip = $shell.NameSpace("C:\a.zip")
MkDir("C:\a")
foreach ($item in $zip.items()) {
  $shell.Namespace("C:\a").CopyHere($item)
}

뭐가 문제 야? 디렉토리 C:\a가 여전히 비어 있습니다.


6
Powershell 2.0을 사용 중이거나 .NET 4.5를 설치하지 않은 경우 언급 한 방법은 타사 경로 (예 : 7zip)를 사용하지 않는 유일한 경로입니다. 누군가가이 방법이 효과가없는 이유를 설명해 주지만 시간이 지나도 다른 방법으로는 효과가 없습니다
kenny

답변:


248

System.IO.Compression.ZipFile 에서 ExtractToDirectory 를 사용하는 간단한 방법은 다음과 같습니다 .

Add-Type -AssemblyName System.IO.Compression.FileSystem
function Unzip
{
    param([string]$zipfile, [string]$outpath)

    [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath)
}

Unzip "C:\a.zip" "C:\a"

대상 폴더가 존재하지 않으면 ExtractToDirectory가이를 생성합니다. 다른 경고 :

또한보십시오:


10
단일 함수 호출을 대체하는 함수를 작성하는 이유는 무엇입니까?

17
이론적으로는 그렇지 않습니다. 함수에서 복잡하거나 비 전통적인 호출을 숨기려고 시도하므로 나중에 사용 위치에 대해 걱정하지 않고 메소드를 바꿀 수 있습니다. Keith가 언급했듯이 V5에는 새로운 방법이 있습니다.
Micky Balladelli

1
이를 위해서는 최소한 .NET Framework 4.5가 필요합니다. 하단 참조 msdn.microsoft.com/en-us/library/...을
ferventcoder

10
나는 이것을 시도했지만 오류 아래에, Exception calling "ExtractToDirectory" with "2" argument(s): "End of Central Directory record could not be found." At line:5 char:5 + [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $ou ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : InvalidDataException
Karthi1234

4
이로 인해 다음과 같은 오류가 발생 Add-Type : Cannot add type. The assembly 'System.IO.Compression.FileSystem' could not be found.합니다.. .NET 4.6.2가 설치되어 있고 어셈블리가 GAC에 있는지 확인했지만이 오류가 발생하는 이유를 알지 못했습니다.
Sam

500

PowerShell v5 +에는 다음과 같은 확장 아카이브 명령 (압축 아카이브)이 내장되어 있습니다.

Expand-Archive c:\a.zip -DestinationPath c:\a

26
$PSVersionTable.PSVersion실행중인 PowerShell 버전을 확인하는 데 사용 합니다.
Brad C

1
@LoneCoder 나는 당신이 Ballmer를 비난 할 수 있다고 생각하지 않습니다. 1992 년 gzip이 나오고 tar가 더 오래되었지만 Windows에는 압축 파일을 처리하기위한 명령 줄 도구가 내장되어 있지 않습니다 .
jpmc26

2
@Ghashange PowerShell 5는 시험판으로도이 답변이 게시 된 Windows 10 및 Server 2012 이하에서는 사용할 수 없었습니다.
jpmc26

11
매개 변수 OutputPathDestinationPath(참조 msdn.microsoft.com/powershell/reference/5.1/… ) 으로 변경된 것 같습니다
Elijah W. Gagne

1
Expand-Archive -Path .\a.zip -DestinationPath .
Culip

24

PowerShell v5.1에서는 v5와 약간 다릅니다. MS 문서에 따르면 -Path, 아카이브 파일 경로를 지정 하는 매개 변수가 있어야합니다 .

Expand-Archive -Path Draft.Zip -DestinationPath C:\Reference

그렇지 않으면 실제 경로가 될 수 있습니다.

Expand-Archive -Path c:\Download\Draft.Zip -DestinationPath C:\Reference

확장 아카이브 문서


3
이 Cmdlet에서는 v5와 v5.1간에 차이가 없습니다. 첫 번째 매개 변수의 이름을 지정할 필요는 없습니다. 자동으로 경로가됩니다. 예를 들어 Expand-Archive Draft.Zip -DestinationPath C:\Reference문제없이 작동합니다. 또한 실제 경로가 아니라 절대 경로입니다.
Franklin Yu

13

Expand-Archive매개 변수 집합 중 하나와 함께 cmdlet을 사용하십시오 .

Expand-Archive -LiteralPath C:\source\file.Zip -DestinationPath C:\destination
Expand-Archive -Path file.Zip -DestinationPath C:\destination

12

저기요 ..

$shell = New-Object -ComObject shell.application
$zip = $shell.NameSpace("put ur zip file path here")
foreach ($item in $zip.items()) {
  $shell.Namespace("destination where files need to unzip").CopyHere($item)
}

2
파일 또는 디렉토리 중 하나가 대상 위치에 이미 존재하면, 목적을 무효화하는 작업 (무시, 덮어 쓰기)을 묻는 대화 상자가 나타납니다. 누구나 자동으로 덮어 쓰는 방법을 알고 있습니까?
Oleg Kazakov

@OlegKazakov의 의견에 대한 답변 : CopyHere메소드를 제어하는 옵션 세트가 있습니다 . @OlegKazakov가 이미 그의 문제를 해결했다고 생각합니다. 그럼에도 불구하고이 주제를 찾을 수있는 다른 서퍼들을 위해이 링크를 여기에 넣었습니다. docs.microsoft.com/en-us/previous-versions/windows/desktop/…
jsxt

4

Shell.Application.Namespace.Folder.CopyHere () 를 사용 하고 복사하는 동안 진행률 표시 줄을 숨기거나 더 많은 옵션을 사용하려는 경우 설명서는 다음과 같습니다.
https://docs.microsoft.com/en-us / windows / desktop / shell / 폴더 복사

powershell을 사용하고 진행률 표시 줄을 숨기고 확인을 비활성화하려면 다음과 같은 코드를 사용할 수 있습니다.

# We should create folder before using it for shell operations as it is required
New-Item -ItemType directory -Path "C:\destinationDir" -Force

$shell = New-Object -ComObject Shell.Application
$zip = $shell.Namespace("C:\archive.zip")
$items = $zip.items()
$shell.Namespace("C:\destinationDir").CopyHere($items, 1556)

Windows 핵심 버전에서 Shell.Application 사용 제한 사항 :
https://docs.microsoft.com/en-us/windows-server/administration/server-core/what-is-server-core

Windows 핵심 버전에서는 기본적으로 Microsoft-Windows-Server-Shell-Package 가 설치되어 있지 않으므로 shell.applicaton이 작동하지 않습니다.

참고 :이 방법으로 아카이브를 추출하면 시간이 오래 걸리고 Windows GUI 속도가 느려질 수 있습니다


3

expand-archive아카이브 이름을 따서 명명 된 디렉토리를 사용 하지만 자동 작성하는 경우 :

function unzip ($file) {
    $dirname = (Get-Item $file).Basename
    New-Item -Force -ItemType directory -Path $dirname
    expand-archive $file -OutputPath $dirname -ShowProgress
}

이것은 반드시 현재 디렉토리에서 확장되지 않습니까?
jpmc26

자동 생성의 부가 가치를 실제로 보지 마십시오. outputPath허용 된 답변과 같이 두 번째 매개 변수를 추가하는 것이 더 유연합니다 . 이 솔루션 (jpmc26이 말했듯이)에서는 항상 현재 디렉토리에 새 디렉토리를 작성하므로 전화하기 전에 현재 디렉토리를 설정해야합니다.unzip
Rubanov

대부분의 아카이버는 아카이브와 동일한 위치에 아카이브 이름을 딴 디렉토리로 추출합니다. 다른 것을 원한다면 매개 변수 추가를 멈추지 않아도되지만 합리적인 기본값입니다.
mikemaccana

1
function unzip {
    param (
        [string]$archiveFilePath,
        [string]$destinationPath
    )

    if ($archiveFilePath -notlike '?:\*') {
        $archiveFilePath = [System.IO.Path]::Combine($PWD, $archiveFilePath)
    }

    if ($destinationPath -notlike '?:\*') {
        $destinationPath = [System.IO.Path]::Combine($PWD, $destinationPath)
    }

    Add-Type -AssemblyName System.IO.Compression
    Add-Type -AssemblyName System.IO.Compression.FileSystem

    $archiveFile = [System.IO.File]::Open($archiveFilePath, [System.IO.FileMode]::Open)
    $archive = [System.IO.Compression.ZipArchive]::new($archiveFile)

    if (Test-Path $destinationPath) {
        foreach ($item in $archive.Entries) {
            $destinationItemPath = [System.IO.Path]::Combine($destinationPath, $item.FullName)

            if ($destinationItemPath -like '*/') {
                New-Item $destinationItemPath -Force -ItemType Directory > $null
            } else {
                New-Item $destinationItemPath -Force -ItemType File > $null

                [System.IO.Compression.ZipFileExtensions]::ExtractToFile($item, $destinationItemPath, $true)
            }
        }
    } else {
        [System.IO.Compression.ZipFileExtensions]::ExtractToDirectory($archive, $destinationPath)
    }
}

사용 :

unzip 'Applications\Site.zip' 'C:\inetpub\wwwroot\Site'

처분 $archive하고 $archiveFile마지막에 잊지 마십시오
tom.maruska

0

ForEach루프는 $filepath변수 내에있는 각 ZIP 파일을 처리 합니다.

    foreach($file in $filepath)
    {
        $zip = $shell.NameSpace($file.FullName)
        foreach($item in $zip.items())
        {
            $shell.Namespace($file.DirectoryName).copyhere($item)
        }
        Remove-Item $file.FullName
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.