Summary: Guest blogger and Honorary Scripting Guy, June Blender, talks about using Windows PowerShell and Chocolatey.
Microsoft Scripting Guy, Ed Wilson, is here. Today, I welcome back guest blogger, June Blender.
I’m probably one of five people on earth who really do not like chocolate, so I wasn’t too keen to learn about something called “Chocolatey.” But I kept hearing about Chocolatey and other “package installers,” such as NuGet, and I wanted to know what all of the fuss was about. Then along comes Windows PowerShell 5.0 Preview with a module called OneGet that works with Chocolatey. It was clearly past time to figure it out.
What’s a package installer?
Package installers install programs and groups of related programs called packages. In this guise, they’re not much different than an EXE or MSI file. But unlike simple installers, package installers also know about dependencies, which are other programs that the to-be-installed program requires, and they’ll install any missing dependencies for you automatically. Beyond that, they solve easy problems, such as expanding zip files and installing tools in a consistent place. They can also solve very difficult installation problems for you, including installing programs on your computer that are designed for a different platform or operating system.
This last feature is truly the most appealing. I took a great Android app programming class from Coursera called Creative, Serious, and Playful Science of Android Apps. It’s a terrific class, and I really recommend it. For me, the most difficult part of the class was installing the programming tools on my PC, which is running Windows, because they’re designed for an iOS or UNIX platform. I had to install five tools to install the tools that I needed. These include a tool to unzip (or whatever) TGZ files, appropriately called “tarballs.” Well-designed package installers handle this mess for you.
Package installers are also great for open-source collaborative projects, like those on GitHub. Contributors can collect their files into packages and submit the package in a pull request. When other contributors clone the project, they can use the package installer to install all of the contributed pieces.
What’s Chocolatey?
Chocolatey is a package installer that’s designed especially for working with Windows PowerShell. You can learn all about Chocolatey at the Chocolatey Gallery site. Chocolatey is also an open-source project. You can view and contribute to the Chocolatey source at Chocolatey GitHub.
You can use Windows PowerShell to script Chocolatey installations, but you can also use the search feature on the pretty Chocolatey Packages website:
What’s OneGet?
OneGet is a Windows PowerShell module that is included in Windows Management Framework 5.0 Preview. The cmdlets in the module manage packages, including those on the Chocolatey site. They find packages, get installed packages, get the source of a package, and uninstall packages, among other things.
OneGet includes Windows PowerShell cmdlets with names like Find-Package, Get-Package, and Install-Package. The preview version gets only Chocolatey packages, but I bet that will change. Also, the preview version doesn’t yet have Help files, although it’s set up for updatable Help. Again, we’ll probably see those when the full product is released.
Installing OneGet and/or Chocolatey
You can install OneGet or Chocolatey or both. They’re completely independent, and they don’t require each other.
You can install Windows Management Framework 5.0 Preview (with OneGet) from the Microsoft Download Center: Windows Management Framework 5.0 Preview May 2014.
To install Chocolatey, run the Install.ps1 script from the Chocolatey website (inspect it first):
- Start Windows PowerShell with the “Run as administrator” option.
- At the Windows PowerShell prompt, run the following command. It starts a web-based script (Install.ps1), which installs Chocolatey. You don’t need to replace any values.
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
Try OneGet!
Let’s play with the OneGet module so we have a sense of how it works.
Find-Package cmdlet
The Find-Package cmdlet gets information about all available packages. It returns a SoftwareIdentity object (Microsoft.OneGet.Core.Packaging.SoftwareIdentity) for each package.
Be patient. The cmdlet can take a full minute to run because it’s getting data from a website.
In the preview, the source is always “Chocolatey” and the status is always “Available,” but it’s only a preview.
PS C:\> Find-Package | Group-Object –Property Source
Count Name Group
----- ---- -----
2050 chocolatey {Microsoft.OneGet.Core.Packaging.SoftwareIdentity, Mi
PS C:\> Find-Package | Group-Object –Property Status
Count Name Group
----- ---- -----
2050 Available {Microsoft.OneGet.Core.Packaging.SoftwareIdentity, Mi
You can use the Name parameter of Find-Package to filter by package name. You can enter part of the package name, but this cmdlet does not support wildcard characters. Cmdlets that launch REST APIs (web page queries) rarely do.
This command gets packages with names that include Autorun:
PS C:\> Find-Package -Name Autorun
Name Version Status Source Summary
---- ------- ------ ------ -------
AutoRuns 12.0 Available chocolatey Shows what programs are
AutorunscPortable 12.0.0.0 Available chocolatey
AutorunsPortable 12.0.0.0 Available chocolatey
PS C:\> Find-Package -Name Autorun*
WARNING: No Package Found:Autorun*
The SoftwareIdentity object includes useful information about the package. This command gets the Autoruns package and formats all (*) of its properties in a list:
PS C:\> Find-Package -Name Autoruns | Format-List -Property *
ProviderName : Chocolatey
Source : chocolatey
Name : AutoRuns
Version : 12.0
VersionScheme : semver
Status : Available
Summary : Shows what programs are configured to run during system bootup or login
Install-Package cmdlet
To install a package, use the Install-Package cmdlet. You can also pipe a Find-Package command to the Install-Package cmdlet.
I use the parameters of the Find-Package cmdlet to create a command that gets only the package that I want to install. Then, I pipe it to Install-Package. I use the Verbose parameter to see where the package is installed.
Note To see all parameters of Find-Package, type: Get-Command Find-Package –Syntax.
PS C:\> Find-Package -Name Autoruns -RequiredVersion 12.0
Name Version Status Source Summary
---- ------- ------ ------ -------
AutoRuns 12.0 Available chocolatey Shows what programs are configured...
PS C:\> Find-Package -Name Autoruns -RequiredVersion 12.0 | Install-Package -Verbose
The Install-Package cmdlet prompts me to verify that I trust the package and then installs it. It begins by installing a ZIP file in a temporary directory in my user profile. Then it unzips the file and installs it in a C:\chocolatey directory.
PS C:\ps-test> Find-Package -Name Autoruns -RequiredVersion 12.0 | Install-Package –Verbose
Installing Package 'AutoRuns' from untrusted source
WARNING: This package source is not marked as safe. Are you sure you want to install software from 'chocolatey'
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"): y
VERBOSE: Performing the operation "Install Package" on target "AutoRuns".
VERBOSE: NuGet:Installing 'AutoRuns 12.0'.
VERBOSE: NuGet:Successfully installed 'AutoRuns 12.0'.
VERBOSE: InstallChocolateyZipPackage:AutoRuns
VERBOSE: CreateFolder
Success:C:\Users\juneb\AppData\Local\Temp\Microsoft.OneGet.Utility\11\chocolatey\AutoRuns
VERBOSE: GetChocolateyWebFile:AutoRuns => http://download.sysinternals.com/files/Autoruns.zip
VERBOSE: Downloading:'http://download.sysinternals.com/files/Autoruns.zip' to
'C:\Users\juneb\AppData\Local\Temp\Microsoft.OneGet.Utility\11\chocolatey\AutoRuns\AutoRunsinstall.zip'
VERBOSE:
GetChocolateyUnzip:C:\Users\juneb\AppData\Local\Temp\Microsoft.OneGet.Utility\11\chocolatey\AutoRuns\AutoRunsinstall.zip
VERBOSE: CreateFolder -- C:\Chocolatey\lib\AutoRuns.12.0
VERBOSE: Taking Snapshot:C:\Chocolatey\lib\AutoRuns.12.0\Tools
VERBOSE: CreateFolder -- C:\Chocolatey\lib\AutoRuns.12.0\Tools
VERBOSE: Diffing Snapshot:C:\Chocolatey\lib\AutoRuns.12.0\Tools
VERBOSE: Package Successfully Installed:AutoRuns
Name Version Status Source Summary
---- ------- ------ ------ -------
AutoRuns 12.0 Available chocolatey Shows what programs are configured...
To indicate that the installation was successful, Install-Package returns a SoftwareIdentity object that represents the package that it installed. You can use this feature in a script that includes a package installation, for example:
if (Get-Package Autoruns | Install-Package) { <do the next thing> }
-or-
Foreach ($pkg in $packages)
{
$result = Install-Package -Name $pkg
if ($result.Name –eq $pkg) {<do the next thing>}
}
Get-Package cmdlet
To get all packages that the OneGet cmdlets installed, use the Get-Package cmdlet. (Get-Package gets only packages that Install-Package installed. It does not get packages that you install by other means, including Chocolatey.
PS C:\>Get-Package
Name Version Status Source Summary
---- ------- ------ ------ -------
AutoRuns 12.0 Available chocolatey Shows what programs are configured...
To run the package, at the Windows PowerShell prompt, type Autoruns. (You can also use the Start page, Start menu, or Run box.) The starting method might differ for other tools.
To uninstall the package, use the Uninstall-Package cmdlet. I’ve installed and uninstalled packages repeatedly without any errors, so test away!
Try Chocolatey!
Now let’s try Chocolatey.
To install Chocolatey when you have the OneGet module, use the Install-Package cmdlet:
PS C:\> Find-Package –Name Chocolatey
Name Version Status Source Summary
---- ------- ------ ------ -------
chocolatey 0.9.8.28-alpha2 Available chocolatey Chocolatey is your machine level N...
PS C:\> Find-Package –Name Chocolatey | Install-Package -Verbose
I’ll use Windows PowerShell to run the Chocolatey commands, but you do not need to have Windows PowerShell or OneGet to run the commands. You can use the website or the native or GUI Chocolatey clients.
When you review the Chocolatey commands, you’ll notice immediately that the command names don’t have the familiar verb-noun format of cmdlets. And Get-Help won’t help you with these commands. The following Chocolatey wiki is useful: Command Reference.
To run Chocolatey commands without warnings, you must start Windows PowerShell with the “Run as administrator” option (also known as “elevated”).
To search for a package (the equivalent of Find-Package), use the List or Search commands. These commands are aliases of each other, and they can be used interchangeably.
For example, to search for the Autoruns tool, type:
[ADMIN] PS C:\> choco list Autoruns
AutoRuns 12.0
Again, you can type part of the name of the tool you’re searching for, such as choco list Auto, but you cannot use wildcard characters.
[ADMIN] PS C:> choco search Autorun
AutoRuns 12.0
AutorunsPortable 12.0.0.0
AutorunscPortable 12.0.0.0
bitdefender-usb-immunizer 2.0.1.90
cmdaliases 1.0.0.1
The List and Search commands search all fields for the Autorun phrase, not only the name field. In this case, the description of the cmdaliases tool includes “autorun.” Also, the Chocolatey commands return strings of the package names. They don’t return SoftwareIdentity objects.
To install a package, use the choco install or cinst command. The following command installs the Autoruns tool.
PS C:\> choco install Autoruns
Chocolatey doesn’t have a command like Get-Package, but it does have commands to uninstall packages and get the source code for the package.
Using OneGet and Chocolatey together
You can use both OneGet and Chocolatey. However, in OneGet preview and the current incarnation of Chocolatey, they’re not aware of each other. For example, Get-Package gets only the packages that Install-Package installs. It doesn’t get the packages that Chocolatey installs.
The installation location might vary with the package that you install, but Chocolatey installs the Autoruns tool in a different place than Install-Package installs it. If you use both, the installations are independent. This isn’t a problem for a simple tool like Autoruns, but it might create problems for more complex packages.
OneGet: C:\Chocolatey\lib\AutoRuns.12.0\Tools\Autoruns.exe
Chocolatey: C:\ProgramData\chocolatey\lib\AutoRuns.12.0\Tools
Is Find-Package temporary?
One more hint before you start scripting.
The Find-Package command gets data from a website (or websites) where the data changes frequently. The results of Find-Package time out, even if you save them in a variable. If you save the output for more than a few minutes, it disappears.
For example, if you save the results of the Find-Package cmdlet in an $a variable, you can display the value of $a as usual. But if you wait a few minutes and repeat the command that displays the value of $a, the value is gone!
PS C:\> $a = Find-Package
PS C:\> $a | Format-Table –Property Name, Summary -Autosize
Name Summary
---- -------
1password 1Password - Have you ever forgotten a password?
7zip 7-Zip is a file archiver with a high compression
7zip.commandline 7-Zip is a file archiver with a high compression
7zip.install 7-Zip is a file archiver with a high compression
ack ack is a tool like grep, designed
acr
ActiveMQ Apache ActiveMQ is a messaging and integration server
ActivePerl ActivePerl is the leading commercial-grade ActivePerl-EqEmu-x86 ActivePerl-EqEmu-x86
ActiveTcl
Wait 3 minutes...
PS C:\> $a | Format-Table -Property Name, Summary -Autosize
Name Summary
---- -------
The objects are still there, but their content is missing.
PS C:\ps-test> $a | Get-Member
TypeName: Microsoft.OneGet.Core.Packaging.SoftwareIdentity
Name MemberType Definition
---- ---------- ----------
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetLifetimeService Method System.Object GetLifetimeService()
GetType Method type GetType()
InitializeLifetimeService Method System.Object InitializeLifetimeService()
ToString Method string ToString()
Name Property string Name {get;set;}
ProviderName Property string ProviderName {get;set;}
Source Property string Source {get;set;}
Status Property string Status {get;set;}
Summary Property string Summary {get;set;}
Version Property string Version {get;set;}
VersionScheme Property string VersionScheme {get;set;}
PS C:\> $a[0]
Name Version Status Source Summary
---- ------- ------ ------ -------
You might never encounter this in a script, but if you’re playing around in the console, it might surprise you.
Now, go off and have fun. There are some amazing Chocolatey packages. I installed a trial version of my favorite tool, .NET Reflector from Red Gate Software. And ironically, I installed 7Zip, which unzips any file type, even though I might never need to use it again.
~June
Thanks, June. This is useful and fun. Great job.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy