--- title: "UPack Command-line Interface" order: 2 ---
The Command-line reference is available on GitHub.

upack.exe is a cross-platform command-line tool for creating and installing universal packages; you can also see which packages are installed on a machine.

### Download, Installation, & Source Code

upack.exe is a stand-alone program and does not require installation. Visit the GitHub Releases section to download the latest version.

The source code for upack.exe is hosted on GitHub.

## Creating and Publishing a Universal Package with upack.exe

#### Prerequisites:

- Download the latest upack.exe from any of the locations here: https://inedo.com/upack/download
- Download Accounts.zip from: http://cdn.inedo.com/downloads/upack/Accounts.zip
- An installed instance of ProGet with a Universal feed configured
- Basic Shell knowledge (for Linux users), or Command Prompt / PowerShell (for Windows users)
- If running the .NET Core version (required for Linux users) of upack, you will need to install the .NET Core 3.1 Runtime. To learn how to run .NET Core version of upack, visit our command line reference on GitHub.

### Overview

In this tutorial, we will take an existing website and package it into a Universal Package using the upack.exe tool. The files in Accounts.zip are just the build output of a basic .NET web application. For those unfamiliar with .NET, it could just as easily be a Java WAR file, a collection of PHP files, or even static HTML.

We'll also be using a PowerShell prompt (hence the `PS >`) and `C:\tmp\accounts` as a working directory, but you can do this on Linux or in the command prompt just the same.

### Creating a Package

In this step, we will create a Universal Package. The format of the package is easy to understand and, thanks to some basic package properties, allows consistent deployment and distribution of the contents of Accounts.zip.

Note: In a typical usage scenario, the "pack" step would be executed by a Continuous Integration server such as TeamCity or Jenkins immediately after the build output is generated.

To begin, we will download the Accounts.zip file and extract its contents into a temporary directory. Additionally, we will download upack.exe to a directory already included in the `PATH` environment variable.

In PowerShell, navigate to `C:\tmp\accounts`, and enter the following command to package the contents into a Universal Package:

    PS C:\tmp\accounts> upack pack . --name=Accounts --version=1.0.0 --title="Accounts Website" --description="This package contains the build output for the Accounts demo website."

This will generate a universal package named `Accounts-1.0.0.upack` in the same directory.

### Pushing a package to a Universal feed in ProGet

Once a package is created, we can publish it to a Universal feed.

Note: In a typical usage scenario, the "push" step would also be performed by a Continuous Integration Server sometime after package creation.

Before we can push the package, we need to determine the endpoint of the ProGet feed to use as the push source. After logging into ProGet and accessing the feed, make a note of the endpoint URL:

With this value, we can now push our newly generated package into the feed using the following PowerShell command:

    PS C:\tmp\accounts> upack push Accounts-1.0.0.upack http://progetint/upack/Universe/ --user=Admin:Admin

Naturally, `Admin:Admin` should be replaced with a valid username/password combination for the specific feed, or omitted entirely to authenticate as the current Windows user or anonymously depending on how ProGet is configured.

Once the package is published to the feed successfully, we can view the package details in ProGet:

### Finding and installing a package to install on a server

Once the package is pushed to ProGet, it can be installed on any server that can access ProGet. In PowerShell, enter the following command to install the latest package contents to an existing directory:

    PS C:\tmp\accounts> upack install Accounts --source=http://progetint/upack/Universe/ --target=.\install

This will extract the package contents of the "Universe" feed in ProGet into `C:\tmp\accounts\install`.

### Listing installed packages on a server

Once a package has been installed, upack.exe can query the Universal Package Registry on the local machine for installed packages with the list command:

    PS C:\tmp\accounts> upack list

After performing the steps above, this list will contain (at a minimum):

    Accounts 1.0.0
    From http://progetint/upack/Universe/
    Installed to C:\tmp\accounts\install on 2018-04-30T17:01:51.8197700-04:00
    Installed by thoven using upack/2.2.0.1

This list is not limited to what is installed by upack.exe, the Universal Package Registry will also contain packages installed from Otter, BuildMaster, and Romp.

### Verifying a downloaded package hash against a Universal feed

We may obtain a package from a source other than installing it directly from ProGet, or it may have been obtained from another universal feed (i.e. the package was promoted ). In this case, it is useful to verify that the contents of the package are identical. This can be done using the verify command:

    PS C:\tmp\accounts> upack verify Accounts-1.0.0.upack http://progetint/upack/Universe/

The result of this command will either indicate that the hashes match, or issue an error to standard error if they are different.

If you only need to view the hash, you can use the `hash` command:

    PS C:\tmp\accounts> upack hash Accounts-1.0.0.upack

If the exact same `pack` command was used as described in this tutorial (and we haven’t changed Accounts.zip on our end), the output will be:

    0633d10b2223cd9ce94ca70e298c4edb752d6028

Of course, this is a standard SHA1 hash in hexadecimal format, so any existing tools (7zip, sha1sum, etc.) can be used to obtain a package hash. This hash could then be quickly compared to the SHA1 value displayed within ProGet to ensure the package contents are identical.

### Repackaging an existing package

When deploying packages, it is common to rewrite the package metadata, such as version information (e.g., removing pre-release identifiers ), adding/appending descriptions, or changing the group name. This is where repackaging comes in: repackaging involves creating a new package from an existing package that has exactly the same content as the original package. As the metadata of the package changes, a history of package names and versions is also recorded for auditing purposes.

The `repack` command can be used for this purpose; it will effectively create a new package with the exact same contents but different metadata. The newly created package will default to any metadata property values of the existing package, and the `repack` command accepts any property supported by the pack command. Alternatively, a upack.json file with values will be merged into the source package’s upack.json file. Here are some common use cases for the `repack` command:

#### Changing Package Version

    PS C:\tmp\accounts> upack repack Accounts-1.0.0-RC007.upack --version=1.0.0

#### Add metadata elements from a custom upack.json file

Note that when specifying the "manifest" file argument, arguments to overwrite other metadata (like version) will be ignored.

    PS C:\tmp\accounts> upack repack Accounts-1.0.0.upack --manifest=additional-upack.json --overwrite

additional-upack.json contents:

    {
      "description": "This additional metadata will overwrite the package's description, or add one if no description property exists",
      "tags": ["repackaged"]
    }