Native .tar extraction in Powershell

bfieck picture bfieck · Aug 4, 2016 · Viewed 35.4k times · Source

I have a .tar.gz file that I need to extract. I've handled the gunzip bit with the GzipStream object from System.IO.Compression, but I couldn't find anything for dealing with tarballs in that namespace. Is there a way to deal with .tar files natively in Powershell? Note that it's only important that I be able to call any such function/method/object construction/system binary from a Powershell script; it doesn't need to actually be written in powershell. (If it matters I'm using 64-bit windows 10)

P.S. please don't say "use 7zip"; that's not native

Answer

Don Cruickshank picture Don Cruickshank · Oct 22, 2017

Update in 2019:

As pointed out in other answers, BSD tar was added to Windows 10 as a built-in command in 2018. This answer is still applicable if you need to support earlier versions of Windows.


I'm fairly sure that Windows 10 did not have support for extracting tar files by default prior to 2018.

1. The quick easy solution for (early versions of) Windows 10

If you can expect the script to have access to an active Internet connection, then you can simply get 7Zip support using the built-in package manager. This solution:

  • Is entirely automated via script (does not require user interaction)
  • Does not require administrator privileges
  • Only installs the 7Zip support module if it isn't already available

Here it is:

function Expand-Tar($tarFile, $dest) {

    if (-not (Get-Command Expand-7Zip -ErrorAction Ignore)) {
        Install-Package -Scope CurrentUser -Force 7Zip4PowerShell > $null
    }

    Expand-7Zip $tarFile $dest
}

To use it:

Expand-Tar archive.tar dest

It does the job but it makes a persistent change to the client system. There is a better, but slightly more involved, solution:

2. The better solution

The better solution is to bundle 7Zip4PowerShell with your script. This solution:

  • Is entirely automated via script (does not require user interaction)
  • Does not require administrative privileges
  • Does not install any software on the client system
  • Does not require internet connectivity
  • Should work on earlier versions of Windows

a. Download a copy of the 7Zip4PowerShell package

It's distributed under the LGPL-2.1 licence and so it's OK to bundle the package with your product. You should add a note to your documentation that it uses the package and provide a link since you are required to provide access to the source code for GNU licenced products.

Save-Module -Name 7Zip4Powershell -Path .

This will download it to the current directory. It's easiest to do this on Windows 10 but there are instructions on how to add PowerShell Gallery to your system on earlier versions of Windows from the link above.

b. Import the module when you need to extract the tar file

I've made a simple function just to demonstrate how you could do this based on the first solution:

function Expand-Tar($tarFile, $dest) {

    $pathToModule = ".\7Zip4Powershell\1.9.0\7Zip4PowerShell.psd1"

    if (-not (Get-Command Expand-7Zip -ErrorAction Ignore)) {
        Import-Module $pathToModule
    }

    Expand-7Zip $tarFile $dest
}

You'll need to adjust $pathToModule to where the bundled module is actually stored when your script runs, but you should get the idea. I've written this example such that you can simply paste in both of the code blocks above into a PowerShell window and get a working Expand-Tar cmdlet:

Expand-Tar archive.tar dest