Other repository servers don't necessarily require Windows.
NOTE
If you are using the same machine from Exercise 0 for setting up your repository, you can skip this Exercise and go to Exercise 2 (in other words, your machine already has Chocolatey installed).
c:\choco-setup
here on this machine (should match with where things were set in Exercise 0).powershell
to get into it).& $env:SystemDrive\choco-setup\files\ChocolateyLocalInstall.ps1
and press enter. This should install Chocolatey if you have everything set up correctly from the first set of instructions.choco source remove --name="'chocolatey'"
. This removes the default Chocolatey source.choco source add --name="'setup'" --source="'$env:SystemDrive\choco-setup\packages'"
New-Item $env:ChocolateyInstall\license -ItemType Directory -Force
- this creates the license directory.Copy-Item "$env:SystemDrive\choco-setup\files\chocolatey.license.xml" $env:ChocolateyInstall\license\chocolatey.license.xml -Force
.choco source disable --name="'chocolatey.licensed'"
. When the license is placed, Chocolatey automatically adds the license and we don’t want to use that source. Note we can’t remove the license because the existence of the license file will have Chocolatey adding it right back - so we just disable it. You will see what looks like an error message about not having chocolatey.extension installed. That’s a warning and we are going to take care of that in the next step.choco upgrade chocolatey.extension -y --pre
. You will see what looks like an error message about not having chocolatey.extension installed. That’s a warning and should clear up when this command completes.choco config set --name cacheLocation --value $env:ChocolateyInstall\choco-cache
. This moves the TEMP location in scripts to use this and makes clean up more deterministic.choco config set --name commandExecutionTimeoutSeconds --value 14400
. This increases the timeout more than the default 45 minutes, you may wish to set it higher.choco feature enable --name="'internalizeAppendUseOriginalLocation'"
. This sets Package Internalizer to append -UseOriginalLocation
to the end of Install-ChocolateyPackage
to make it behave more like Install-ChocolateyInstallPackage
. Since the files are local, we won’t need it copying them to temp prior to running it.choco feature enable --name="'reduceInstalledPackageSpaceUsage'"
to ensure Package Reducer is turned on.choco upgrade chocolatey-agent -y --pre
and then follow the link for other settings you will need to configure.# Ensure we can run everything
Set-ExecutionPolicy Bypass -Scope Process -Force
# Install Chocolatey
& $env:SystemDrive\choco-setup\files\ChocolateyLocalInstall.ps1
# Are you military, government, or for some other reason have FIPS compliance turned on?
#choco feature enable --name="'useFipsCompliantChecksums'"
# Sources - Remove community repository and add a local folder source
choco source remove --name="'chocolatey'"
choco source add --name="'local'" --source="'$env:SystemDrive\choco-setup\packages'"
# Add license to setup and to local install
New-Item "$env:ChocolateyInstall\license" -ItemType Directory -Force
Copy-Item -Path "$env:SystemDrive\choco-setup\files\chocolatey.license.xml" -Destination "$env:ChocolateyInstall\license\chocolatey.license.xml" -Force
# Sources - Disable licensed source
choco source disable --name="'chocolatey.licensed'"
Write-Host "You can ignore the red text in the output above, as it is more of a warning until we have chocolatey.extension installed"
# Install Chocolatey Licensed Extension
choco upgrade chocolatey.extension -y --pre
# Set Configuration
choco config set --name cacheLocation --value $env:ChocolateyInstall\choco-cache
choco config set --name commandExecutionTimeoutSeconds --value 14400
#TODO: Add other items you would configure here
# https://docs.chocolatey.org/en-us/configuration
# Set Licensed Configuration
choco feature enable --name="'internalizeAppendUseOriginalLocation'"
choco feature enable --name="'reduceInstalledPackageSpaceUsage'"
#TODO: Add other items you would configure here
# https://docs.chocolatey.org/en-us/configuration
#TODO: Are we installing the Chocolatey Agent Service? C4B Only
# https://docs.chocolatey.org/en-us/agent/setup
# choco upgrade chocolatey-agent -y --pre
#choco feature disable --name="'showNonElevatedWarnings'"
#choco feature enable --name="'useBackgroundService'"
#choco feature enable --name="'useBackgroundServiceWithNonAdministratorsOnly'"
#TODO: Check out other options and features to set at the url above.
#TODO: Also make sure you set your sources to allow for self-service
Now we have a machine where we have Chocolatey installed and configured, and we have the setup files we gathered in Exercise 0. So now we are going to set up a package repository for use for all of our clients - this is where you will push packages and get packages from with your Chocolatey clients. Some repositories do not require Windows as part of their setup (Artifactory Pro, Cloudsmith, and Nexus come to mind, but there are others). In choosing what you will use, it’s good to read over set up a package repository to learn about the advantages and disadvantages of each.
Pick one or more of the following paths:
Recommended Option:
The current recommendations for most organizational use cases are Artifactory, Nexus, or ProGet. All are quite robust, and two of those options can be used without cost.
Not recommended for most organizational use cases. Please look to set up Artifactory, Nexus, or ProGet as they are much more robust (and two do can be used without cost).
NOTE
If you have an IIS site for WSUS administration, Chocolatey.Server website will not come up at all, even if everything looks right. We have not yet been able to determine the issue, but believe it is related to ASP.NET 4.6+. Installing all of the required components for Chocolatey.Server may also affect your WSUS admin site. Please seek a different box.
Since we put the items on this machine in the previous exercise, we can just pick up where we left off.
NOTE
Use a real editor, like Notepad++ when working with text files like the web.config. Do NOT, I repeat, DO NOT use notepad.exe.
NOTE
It is important that you do not end with the default apikey in the web.config, as that is easily found. That would leave your install insecure in that anyone in your organization would be able to push packages. You want to keep that down to approved folks.
Best practices with Chocolatey.Server:
- Change the ApiKey in the web.config file
- Set up basic auth to restrict usage to approved folks (see the web.config for instructions)
- Use SSL if accessible from the internet
- Store the Chocolatey nupkg and other packages from Chocolatey Software on this server (next exercise covers this)
NOTE
Chocolatey.Server is a one package repository per setup and only has one apikey that can be used. So if you need multiple repositories, you would setup multiple Chocolatey.Server instances to cover your needs. Another option when you need multiple repositories and want ease of management is to look into Artifactory Pro, Cloudsmith, Nexus, and ProGet. They not only have multiple Chocolatey/NuGet repositories per instance, but also other repositories types as well. See the next section.
# Ensure we can run everything
Set-ExecutionPolicy Bypass -Scope Process -Force
# Install Chocolatey.Server
choco upgrade chocolatey.server -y --pre
Write-Warning "Follow the steps at https://docs.chocolatey.org/en-us/guides/organizations/set-up-chocolatey-server#additional-configuration for now."
# more may be added later
Recommended for most organizational use cases
If you are setting up something different than Chocolatey.Server, you may wish to read over How To Set Up an Internal Repository. This will give you options and links to repositories like Artifactory Pro, Nexus, and ProGet.
NOTE
Some repository server options don’t require Windows.
NOTE
Many repositories have a concept of a proxy repository. Unlike NuGet repositories, you likely DO NOT WANT a proxied NuGet/Chocolatey repository pointing to the community repository. They only cache packages - cached is not the same concept as internalized. To reuse packages from the community repository in a reliable way, you need to why (community packages repository notes).
Not recommended for most organizational use cases. Please look to set up Artifactory, Nexus, or ProGet as they are much more robust (and two do can be used without cost). Please see notes below on file share limitations.
Setting up a file share repository is typically quite simple. You put your nupkgs into a flat folder structure (no subfolders currently) and then can access them wherever you can reach the file share. However there are a couple of things to keep in mind and be careful with when it comes to file shares as repositories. File shares can be UNC, DFS, SMB, etc, as long as it supports Windows ACL permissions.
File Share notes:
- ACL/Share permissions should not let anyone put packages in the share
- ACLs control access to read permissions.
- Packages go into the share folder, not subfolders (Chocolatey is currently based in NuGet v2, which doesn’t allow subfolders)
- Be very careful never to overwrite a version of a nupkg, especially if it has been deployed to any clients. See package immutability
- Bigger-sized packages will slow down queries, so explore a different option when you see that.
- Enough bigger packages will start timing out queries, so if you’ve hit this it’s time to explore a different option.
- Migration to other repo formats is easy
- Set access properly if you need to connect from local machine accounts, Everyone share access does not give them network permission. See local share permissions.
NOTE
If you run into issues where Chocolatey can’t see the packages, check the last point above.
While setting up a file share is the quickest way to get started, you may find you outgrow it quite quickly. Fortunately migration to another repository is very simple.
Not recommended for most organizational use cases. Please look to set up Artifactory, Nexus, or ProGet as they are much more robust (and two do can be used without cost).
We won’t go into how to set up a distribution point, as you have places to learn how to set those up. To enable a distribution point, you are going to add a file share to it. Follow the previous exercise.
c:\choco-setup\packages
to the package repository. With Chocolatey.Server, we can cheat a little and simply copy the nupkg files to $env:ChocolateyToolsLocation\Chocolatey.Server\App_Data\Packages
.choco push <nupkg_path> --source http://<url_to_api> --api-key <apikey>
NOTE
We’ll put Chocolatey here, and use this location of Chocolatey for all further client installations. If we are using Chocolatey.Server, we’ll have an install.ps1 that it serves that is dynamic and will use a local chocolatey.nupkg if we have one in the repository (it will use the Chocolatey package at https://chocolatey.org/ otherwise, which we won’t want).
Here is a script for Chocolatey.Server:
# Ensure we can run everything
Set-ExecutionPolicy Bypass -Scope Process -Force
# Copy the packages to the Chocolatey.Server repo folder
Copy-Item "$env:SystemDrive\choco-setup\packages\*" -Destination "$env:ChocolateyToolsLocation\Chocolatey.Server\App_Data\Packages\" -Force -Recurse
# Copy the license to the Chocolatey.Server repo (for v0.2.3+ downloads)
#New-Item "$env:ChocolateyToolsLocation\Chocolatey.Server\App_Data\Downloads" -ItemType Directory -Force
#Copy-Item "$env:SystemDrive\choco-setup\files\chocolatey.license.xml" -Destination "$env:ChocolateyToolsLocation\Chocolatey.Server\App_Data\Downloads\chocolatey.license.xml" -Force -Recurse
For other things, just loop over the nupkg files and call choco push
.
NOTE
This is for C4B / MSP / C4BTRIAL ONLY. To make things easier for deployments, let’s create a package for the license file. We are going to grab the currently installed license to do this, but you could use the one in
c:\choco-setup\files
.
Save this script and run it on a machine where you’ve installed the license.
# Ensure we can run everything
Set-ExecutionPolicy Bypass -Scope Process -Force
$licenseLocation = "$env:ChocolateyInstall\license\chocolatey.license.xml"
$packagingFolder = "$env:SystemDrive\choco-setup\packaging"
$packagesFolder = "$env:SystemDrive\choco-setup\packages"
$packageId = "chocolatey-license"
$licensePackageFolder = "$packagingFolder\$packageId"
$licensePackageNuspec = "$licensePackageFolder\$packageId.nuspec"
# Validations
if (-Not(Test-Path $licenseLocation)) {
Write-Warning "Please add the license file manually to $licenseLocation prior to running this. Throwing error..."
throw "No license found to use. Please add license to $licenseLocation as per instructions PRIOR to running this script."
}
Write-Warning "Prior to running this, please ensure you've updated the license file manually in the Chocolatey installation at $env:ChocolateyInstall\license\chocolatey.license.xml"
Write-Warning "REPEATED: This script will OVERWRITE the license file you might have dropped into the packaging at '$licensePackageFolder'"
& choco
Write-Warning "If there is is a note about invalid license above, you're going to run into issues."
# Get license expiration from the license file for version and validation
[xml]$licenseFile = Get-Content $env:ChocolateyInstall\license\chocolatey.license.xml
$licenseExpiration = Get-Date($licenseFile.license.expiration)
# Validate the expiration date is in the future
if ($licenseExpiration -lt $(Get-Date)) {
Write-Warning "THE LICENSE FILE AT $env:ChocolateyInstall\license is EXPIRED. This is the file used by this script to generate this package, not at '$licensePackageFolder'"
Write-Warning "Please update the license file correctly in the environment FIRST, then rerun this script. Throwing error..."
throw "Please use an up to date license. License is expired as of $($licenseExpiration.ToString())."
}
# Use the license expiration as the license version
$licensePackageVersion = $licenseExpiration.ToString("yyyy.MM.dd")
# Ensure the packaging folder exists
Write-Output "Generating package/packaging folders at '$packagingFolder'"
New-Item $packagingFolder -ItemType Directory -Force | Out-Null
New-Item $packagesFolder -ItemType Directory -Force | Out-Null
# Create a new package
Write-Output "Creating package named '$packageId'"
New-Item $licensePackageFolder -ItemType Directory -Force | Out-Null
New-Item "$licensePackageFolder\tools" -ItemType Directory -Force | Out-Null
# Set the installation script
Write-Output "Setting install and uninstall scripts..."
@"
`$ErrorActionPreference = 'Stop'
`$toolsDir = "`$(Split-Path -parent `$MyInvocation.MyCommand.Definition)"
`$licenseFile = "`$toolsDir\chocolatey.license.xml"
New-Item "`$env:ChocolateyInstall\license" -ItemType Directory -Force
Copy-Item -Path `$licenseFile -Destination `$env:ChocolateyInstall\license\chocolatey.license.xml -Force
Write-Output "The license has been installed."
"@ | Out-File -FilePath "$licensePackageFolder\tools\chocolateyInstall.ps1" -Encoding UTF8 -Force
# Set the uninstall script
@"
Remove-Item -Path "`$env:ChocolateyInstall\license\chocolatey.license.xml" -Force
Write-Output "The license has been removed."
"@ | Out-File -FilePath "$licensePackageFolder\tools\chocolateyUninstall.ps1" -Encoding UTF8 -Force
# Copy the license to the package directory
Write-Output "Copying license to package from '$licenseLocation'..."
Copy-Item -Path $licenseLocation -Destination "$licensePackageFolder\tools\chocolatey.license.xml" -Force
# Set the nuspec
Write-Output "Setting nuspec..."
@"
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
<metadata>
<id>chocolatey-license</id>
<version>$licensePackageVersion</version>
<!--<owners>__REPLACE_YOUR_NAME__</owners>-->
<title>Chocolatey License</title>
<authors>__REPLACE_AUTHORS_OF_SOFTWARE_COMMA_SEPARATED__</authors>
<tags>chocolatey license</tags>
<summary>Installs the Chocolatey commercial license file.</summary>
<description>This package ensures installation of the Chocolatey commercial license file.
This should be installed internally prior to installing other packages, directly after Chocolatey is installed and prior to installing `chocolatey.extension` and `chocolatey-agent`.
The order for scripting is this:
* chocolatey
* chocolatey-license
* chocolatey.extension
* chocolatey-agent
If items are installed in any other order, it could have strange effects or fail.
</description>
<!-- <releaseNotes>__REPLACE_OR_REMOVE__MarkDown_Okay</releaseNotes> -->
</metadata>
<files>
<file src="tools\**" target="tools" />
</files>
</package>
"@ | Out-File -FilePath "$licensePackageNuspec" -Encoding UTF8 -Force
# Package up everything
Write-Output "Creating a package"
choco pack $licensePackageNuspec --output-directory="$packagesFolder"
Write-Output "Package has been created and is ready at $packagesFolder"
We need to ensure the repository is all set up correctly, the best way to test that is to push a package to the repository (and to test installation, which will do in the next exercise).
choco push $env:SystemDrive\choco-setup\packages\chocolatey-license.<insert version>.nupkg --source="'http://localhost/chocolatey'" --api-key="'<insert api key>'"
(url is different for different source repository types)--force
to the end of the command above.NOTE
If you are using open source Chocolatey, you will want to create a test package using
choco new
and use that to push and verify setup.
So now we’ll install Chocolatey using all internal resources and configure Chocolatey so that it doesn’t use any external sources or resources. If we’ve set up everything properly prior to this, this will be a breeze. If not, we are going to need to visit previous exercises to fix what we may have missed.
Starting with Chocolatey.Server v0.2.3, you get a similar experience where you just open an Administrative PowerShell.exe and follow the instructions like you see at https://chocolatey.org/install. This ease of install is very beneficial when setting up client machines directly.
NOTE
Perform the following steps on a different machine, not on the machine where you’ve already set up Chocolatey or a repository.
powershell
to get into it).choco feature enable --name="'useFipsCompliantChecksums'"
.choco source remove --name="'chocolatey'"
to remove the default community package repository.choco source add --name="'internal_server'" --source="'$baseUrl/chocolatey'" --priority="'1'" <other options>
. Other options noted at source command.choco upgrade chocolatey-license -y
. This may be a place you see an error if things are not configured correctly. If you run into an error, be sure that you have the source added properly with the right permissions (not api key - that is for pushes only).choco source disable --name="'chocolatey.licensed'"
. When the license is placed, Chocolatey automatically adds the license and we don’t want to use that source. Note we can’t remove the license because the existence of the license file will have Chocolatey adding it right back - so we just disable it. You will see what looks like an error message about not having chocolatey.extension installed. That’s a warning and we are going to take care of that in the next step.choco upgrade chocolatey.extension -y --pre
. You will see what looks like an error message about not having chocolatey.extension installed. That’s a warning and should clear up when this command completes.choco config set --name cacheLocation --value $env:ChocolateyInstall\choco-cache
. This moves the TEMP location in scripts to use this and makes clean up more deterministic.choco config set --name commandExecutionTimeoutSeconds --value 14400
. This increases the timeout more than the default 45 minutes, you may wish to set it higher.choco feature enable --name="'internalizeAppendUseOriginalLocation'"
. This sets Package Internalizer to append -UseOriginalLocation
to the end of Install-ChocolateyPackage
to make it behave more like Install-ChocolateyInstallPackage
. Since the files are local, we won’t need it copying them to temp prior to running it.choco feature enable --name="'reduceInstalledPackageSpaceUsage'"
to ensure Package Reducer is turned on.choco upgrade chocolatey-agent -y --pre
and then follow the link for other settings you will need to configure.# This is a base url and should not include the "/chocolatey" (for Chocolatey.Server) or any url path to a NuGet/Chocolatey Packages API
$baseUrl = "http://localhost"
# this is the sub path, it will combine the above with this in the script $baseUrl/$repositoryUrlPath
$repositoryUrlPath = "chocolatey"
# Ensure we can run everything
Set-ExecutionPolicy Bypass -Scope Process -Force;
# Reroute TEMP to a local location
New-Item $env:ALLUSERSPROFILE\choco-cache -ItemType Directory -Force
$env:TEMP = "$env:ALLUSERSPROFILE\choco-cache"
# Ignore proxies since we are using internal locations
$env:chocolateyIgnoreProxy = 'true'
# Set proxy settings if necessary
#$env:chocolateyProxyLocation = 'https://local/proxy/server'
#$env:chocolateyProxyUser = 'username'
#$env:chocolateyProxyPassword = 'password'
# Install Chocolatey
# This is for use with Chocolatey.Server only:
iex ((New-Object System.Net.WebClient).DownloadString("$baseUrl/install.ps1"))
# You'll need to also use the script you used for local installs to get Chocolatey installed.
# Are you military, government, or for some other reason have FIPS compliance turned on?
#choco feature enable --name="'useFipsCompliantChecksums'"
# Sources - Remove community repository
choco source remove --name="'chocolatey'"
# Sources - Add your internal repositories
# This is Chocolatey.Server specific (add other options like auth/allow self service as needed - https://docs.chocolatey.org/en-us/choco/commands/source):
choco source add --name="'internal_server'" --source="'$baseUrl/$repositoryUrlPath'" --priority="'1'" --bypass-proxy
#TODO: Add other sources here
# Add license to setup and to local install
choco upgrade chocolatey-license -y
# Sources - Disable licensed source
choco source disable --name="'chocolatey.licensed'"
Write-Host "You can ignore the red text in the output above, as it is more of a warning until we have chocolatey.extension installed"
# Install Chocolatey Licensed Extension
choco upgrade chocolatey.extension -y --pre
# Set Configuration
choco config set --name cacheLocation --value $env:ChocolateyInstall\choco-cache
choco config set --name commandExecutionTimeoutSeconds --value 14400
#TODO: Add other items you would configure here
# https://docs.chocolatey.org/en-us/configuration
# Set Licensed Configuration
choco feature enable --name="'internalizeAppendUseOriginalLocation'"
choco feature enable --name="'reduceInstalledPackageSpaceUsage'"
#TODO: Add other items you would configure here
# https://docs.chocolatey.org/en-us/configuration
#TODO: Are we installing the Chocolatey Agent Service?
# https://docs.chocolatey.org/en-us/agent/setup
# choco upgrade chocolatey-agent -y --pre
#choco feature disable --name="'showNonElevatedWarnings'"
#choco feature enable --name="'useBackgroundService'"
#choco feature enable --name="'useBackgroundServiceWithNonAdministratorsOnly'"
#TODO: Check out other options and features to set at the url above.
#TODO: Also make sure you set your sources to allow for self-service
This is likely to vary somewhat wildly based on what you have set up. We recommend choosing a tool and then looking at what is available.
We have Infrastructure Management Integration.
If you are using Chocolatey.Server, please login to that machine and check https://localhost for instructions specific to different infrastructure management tools in the admin section.
For common integrations, it’s handy to refer to the table below to know what configuration manager to choose. Most of the implementations below are written and managed by the companies behind the product. These implementations are typically open source and each part could be added by community contributions for those familiar with the code implementations. If you are unable to provide code implementations for adding necessary functionality to the integrations, we find it best if you create issues/tickets with those organizations if you are a customer as you will have more leverage into getting them implemented.
NOTE
If you are a configuration manager company identified in the table and you have implemented anything in the below or you find our information is incorrect, please let us know so we can get it fixed.
Configuration Managers | Puppet | x | x | ||||||
---|---|---|---|---|---|---|---|---|---|
Install Chocolatey from internal source | x | x | x | x | x |
NOTE
Each x is linked to the specific feature documentation.
For most of these, those configuration managers have some sort of exec you could use to manage those additional aspects, but it would be best if they supported all aspects of configuration of Chocolatey as part of the provider implementations.
In a fully internal environment, you need a way to know when new versions have been released and if they affect you so you can update those packages in your environment. Best to have a low traffic announce only type of email list you can join. Fortunately there is - chocolatey-announce
.
You can sign up for email delivery of new release announcements at chocolatey-announce.
If you’ve made it this far, you are ready to be quite successful with Chocolatey and Windows automation in your organization. If you are using open source Chocolatey, from time to time you might check in to see what we’ve been adding to the commercial options. We are building a complete software management solution with Chocolatey for Business, above and beyond the package management that Chocolatey open source does.
Now it’s time to take the next steps and learn about Chocolatey and packaging itself: