41

Calling clist -l gives me a list of packages with versions:

7zip.install 16.04
ccleaner 5.28.6005
ConEmu 17.3.16.0
...

How do I get this list without version information?

My intention is to use this output to call choco install 7zip.install ccleaner ConEmu ... on another machine. An alternative answer could be how to use the output of clist directly into cinst.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Natan
  • 4,216
  • 4
  • 27
  • 45

6 Answers6

26

If you have a look at the help information for the choco install command (you can do this using choco install -h, you will find the following usage:

cinst <pkg|packages.config> [<pkg2> <pkgN>] [<options/switches>]

As you will see, it is possible to pass a packages.config file, which would contain all the packages that you want to install. The format of this packages.config file is very simple and looks like the following:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="calibre" version="2.81.0" />
  <package id="chocolatey" version="0.10.3" />
  <package id="chocolatey.extension" version="1.9.6" />
  <package id="chocolatey-core.extension" version="1.1.0" />
</packages>

Once you have this file, installing all the packages again on another machine is a simple one line command.

A simple way to generate this packages.config file would be to install ChocolateyGUI (choco install chocolateygui), which includes an option to export the currently installed list of applications.

Bernard Vander Beken
  • 4,315
  • 5
  • 46
  • 70
Gary Ewan Park
  • 13,805
  • 4
  • 29
  • 53
16

This was my poor-man's solution to the same problem, i.e. take all the Chocolatey packages on one machine and install them on another, without worrying about specific versions (i.e. I want the latest versions).

  1. Use the Export button on Chocolately-GUI to save a packages.config file (to a shared network drive).
  2. Edit that .config file and remove the version="X.Y.Z" fields from each <package ... /> line.
  3. On the new machine run choco install \\mypc\shared\packages.config -y.

For example, my edited packages.config file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="audacity" />
  <package id="autohotkey" />
  <package id="autohotkey.install" />
  <package id="ccleaner" />
  <package id="chocolatey" />
  <package id="chocolatey-core.extension" />
  <package id="chocolateygui" />
</packages>

PS.: Don't make the same mistake I did: I used a simple regular expression in Notepad++ to delete all the version="1.1.1" entries and inadvertently removed the same field from the first <?xml ... ?> line. This breaks the XML file. Be more careful/clever than me!

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Justin
  • 1,777
  • 13
  • 24
14

Here is how I generated my packages.config:

$packageXml = ''
choco list -lo -r | % { $_ -split '\|' | select -first 1 } | % { $packageXml += "`n`t<package id=""$_"" />" }
Set-Content "<?xml version=`"1.0`" encoding=`"utf-8`"?>`n<packages>$packageXml`n</packages>" -Path .\packages.config

Once you have that, you take that file to the other machine and do:

choco install packages.config
scls
  • 12,653
  • 9
  • 36
  • 49
Ben Richards
  • 3,183
  • 1
  • 12
  • 18
  • 3
    Replace 'Id' with 'id', otherwise 'choco install' will throw error. – Qi Luo Aug 17 '18 at 00:33
  • 1
    In addition, I needed to add a `-Path` before the path in the Set-Content command: `Set-Content "$packageXml\`n" -Path .\packages.config` – Coperator Aug 08 '20 at 13:56
6

Since you want to omit the version I used the choco upgrade:

# Filter for selecting packages, if empty will match all.
# I do this at times to see whats installed for my company packages
$PkgPrefix = ""

$cmd = "cup -y "
Test-WSMan $server | Out-Null
$session = New-PSSession -ComputerName $server -Credential ( Import-Clixml -Path $CredenitalFile ) -Verbose -Authentication Negotiate

$(clist -lo -r --id-starts-with "$PkgPrefix" )| % { $cmd += "$($_.Split( "|" )[0]),"}

Invoke-Command -Session $session -ScriptBlock $cmd

As Gary suggested, a configuration file might be an easier solution to maintain. I server up my configurations on a web-server, so I can just shell in and execute one command to install everything and have the ability to make a simple XSL style sheet for viewing.

cinst -y $( ( [xml]( Invoke-WebRequest -Uri http://softwareList.config) ).packages.package | Select id ).id

Or you could just save it locally and call it with all the information:

(iwr -Uri http://softwareList.config).content | Out-File "$($env:LOCALAPPDATA)\list.config" -Encoding utf8;
cinst "$($env:LOCALAPPDATA)\list.config -y
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Flightdeck73
  • 183
  • 1
  • 7
5

I would like to summarize the two general approaches given by other answers to this post.

1. Export a plain list of package names, and use it to build a cinst command.

This is aligned with the question as asked: how to clist -l without version information.

I like the simple answer of clist -l --idonly, but to automate this, one must still account for the first and last lines. So, a simple script is probably necessary -- and on Windows, this is a bit of a pain (which is why this question is even being asked).

If the primary goal is to backup and re-install Choclatey packages, then there are some good choices without writing your own scripts. Hence the next type of solution...

2. Export a packages.config file, which can be installed by cinst natively.

This is a nice way to do it, because installing a packages.config is natively supported by cinst.
Unfortunately, Chocolatey lacks native support for exporting packages.config.

Here are a few common ways to export packages.config:

For background to this approach, and to track progress of a built-in solution, see https://github.com/chocolatey/choco/issues/357.

J. Christian
  • 465
  • 1
  • 7
  • 13
  • 1
    Not sure when it was added, but `--limit-output` skips the header and footer line (and also changs the separator between package name and version to the `|` pipe character), so no need for filtering any more. Thanks to your `--id-onIy`, I use `choco list --local-only --limit-output --id-only` to list installed package names. More options at https://github.com/chocolatey/choco/wiki/CommandsList – Jeroen Wiert Pluimers Dec 28 '19 at 22:00
1

Chocolatey doesn't provide that command. The question (plus additional requirements you mentioned) can only be answered with an ETL solution. There's no command to accomplish this proposal.

A .ps1 script would work fine.

That being said, by removing the version, you'll be jumping some packages to the latest published version on the target server. If you need a clone of the installs, you'll need to consume the versions as well.

Brent
  • 11
  • 4