Welcome to the Chocolatey Community Package Repository! The packages found in this section of the site are provided, maintained, and moderated by the community.
Moderation
Every version of each package undergoes a rigorous moderation process before it goes live that typically includes:
- Security, consistency, and quality checking
- Installation testing
- Virus checking through VirusTotal
- Human moderators who give final review and sign off
More detail at Security and Moderation.
Organizational Use
If you are an organization using Chocolatey, we want your experience to be fully reliable. Due to the nature of this publicly offered repository, reliability cannot be guaranteed. Packages offered here are subject to distribution rights, which means they may need to reach out further to the internet to the official locations to download files at runtime.
Fortunately, distribution rights do not apply for internal use. With any edition of Chocolatey (including the free open source edition), you can host your own packages and cache or internalize existing community packages.
Disclaimer
Your use of the packages on this site means you understand they are not supported or guaranteed in any way. Learn more...
-
STEP1
Package Review
-
STEP2
Integration Method
-
STEP3
Internal Repo Url
-
STEP4
Environment Setup
-
STEP5
Install Script
Step 1: Review Your Packages
Step 2: Choose Your Integration Method
Step 3: Enter Your Internal Repository Url
(this should look similar to https://community.chocolatey.org/api/v2/)
Step 3: Copy Your Script or Download Config
Option 1: Copy Script
Option 2: Download Config
Step 4: Setup Your Environment
1. Ensure you are set for organizational deployment
Please see the organizational deployment guide
2. Get the package into your environment
Option 1: Cached Package (Unreliable, Requires Internet - Same As Community)-
Open Source or Commercial:
- Proxy Repository - Create a proxy nuget repository on Nexus, Artifactory Pro, or a proxy Chocolatey repository on ProGet. Point your upstream to https://community.chocolatey.org/api/v2/. Packages cache on first access automatically. Make sure your choco clients are using your proxy repository as a source and NOT the default community repository. See source command for more information.
-
You can also just download the packages and push them to a repository
Download Packages
-
Open Source
-
Download the packages:
Download Packages - Follow manual internalization instructions
-
-
Package Internalizer (C4B)
-
Run: (additional options)
-
For package and dependencies run:
- Automate package internalization
-
Run: (additional options)
Step 5: Copy Your Script
See options you can pass to upgrade.
See best practices for scripting.
Add this to a PowerShell script or use a Batch script with tools and in places where you are calling directly to Chocolatey. If you are integrating, keep in mind enhanced exit codes.
If you do use a PowerShell script, use the following to ensure bad exit codes are shown as failures:
## 1. REQUIREMENTS ##
### Here are the requirements necessary to ensure this is successful.
### a. Internal/Private Cloud Repository Set Up ###
#### You'll need an internal/private cloud repository you can use. These are
#### generally really quick to set up and there are quite a few options.
#### Chocolatey Software recommends Nexus, Artifactory Pro, or ProGet as they
#### are repository servers and will give you the ability to manage multiple
#### repositories and types from one server installation.
### b. Download Chocolatey Package and Put on Internal Repository ###
#### You need to have downloaded the Chocolatey package as well.
#### Please see https://chocolatey.org/install#organization
### c. Other Requirements ###
#### We initialize a few things that are needed by this script - there are no other requirements.
$ErrorActionPreference = "Stop"
#### Set TLS 1.2 (3072) as that is the minimum required by various up-to-date repositories.
#### Use integers because the enumeration value for TLS 1.2 won't exist
#### in .NET 4.0, even though they are addressable if .NET 4.5+ is
#### installed (.NET 4.5 is an in-place upgrade).
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
#### We use this variable for future REST calls.
$RequestArguments = @{
UseBasicParsing = $true
}
## 2. TOP LEVEL VARIABLES ##
### a. Your internal repository url (the main one). ###
#### Should be similar to what you see when you browse
#### to https://community.chocolatey.org/api/v2/
$NugetRepositoryUrl = "INTERNAL REPO URL"
### b. Internal Repository Credential ###
#### If required, add the repository access credential here
# $NugetRepositoryCredential = [PSCredential]::new(
# "username",
# ("password" | ConvertTo-SecureString -AsPlainText -Force)
# )
# $RequestArguments.Credential = $NugetRepositoryCredential
### c. Chocolatey nupkg download url ###
#### This url should result in an immediate download when you navigate to it
$ChocolateyDownloadUrl = "$($NugetRepositoryUrl.TrimEnd('/'))/package/chocolatey.1.1.0.nupkg"
### d. Chocolatey Central Management (CCM) ###
#### If using CCM to manage Chocolatey, add the following:
#### i. Endpoint URL for CCM
# $ChocolateyCentralManagementUrl = "https://chocolatey-central-management:24020/ChocolateyManagementService"
#### ii. If using a Client Salt, add it here
# $ChocolateyCentralManagementClientSalt = "clientsalt"
#### iii. If using a Service Salt, add it here
# $ChocolateyCentralManagementServiceSalt = "servicesalt"
## 3. ENSURE CHOCOLATEY IS INSTALLED ##
### Ensure Chocolatey is installed from your internal repository
#### Download the Nupkg, appending .zip to the filename to handle archive cmdlet limitations
if (-not (Get-Command choco.exe -ErrorAction SilentlyContinue)) {
$TempDirectory = Join-Path $env:Temp "chocolateyInstall"
if (-not (Test-Path $TempDirectory -PathType Container)) {
$null = New-Item -Path $TempDirectory -ItemType Directory
}
$DownloadedNupkg = Join-Path $TempDirectory "$(Split-Path $ChocolateyDownloadUrl -Leaf).zip"
Invoke-WebRequest -Uri $ChocolateyDownloadUrl -OutFile $DownloadedNupkg @RequestArguments
#### Extract the Nupkg, and run the chocolateyInstall script
if (Get-Command Microsoft.PowerShell.Archive\Expand-Archive -ErrorAction SilentlyContinue) {
Microsoft.PowerShell.Archive\Expand-Archive -Path $DownloadedNupkg -DestinationPath $TempDirectory -Force
} else {
# PowerShell versions <4.0 do not have this function available
try {
$shellApplication = New-Object -ComObject Shell.Application
$zipPackage = $shellApplication.NameSpace($DownloadedNupkg)
$destinationFolder = $shellApplication.NameSpace($TempDirectory)
$destinationFolder.CopyHere($zipPackage.Items(), 0x10)
} catch {
Write-Warning "Unable to unzip package using built-in compression."
throw $_
}
}
& $(Join-Path $TempDirectory "tools\chocolateyInstall.ps1")
}
if (-not (Get-Command choco.exe -ErrorAction SilentlyContinue)) {
refreshenv
}
## 4. CONFIGURE CHOCOLATEY BASELINE ##
### a. FIPS Feature ###
#### If you need FIPS compliance - make this the first thing you configure
#### before you do any additional configuration or package installations
# choco feature enable -n useFipsCompliantChecksums
### b. Apply Recommended Configuration ###
#### Move cache location so Chocolatey is very deterministic about
#### cleaning up temporary data and the location is secured to admins
choco config set --name cacheLocation --value C:\ProgramData\chocolatey\cache
#### Increase timeout to at least 4 hours
choco config set --name commandExecutionTimeoutSeconds --value 14400
#### Turn off download progress when running choco through integrations
choco feature disable --name showDownloadProgress
### c. Sources ###
#### Remove the default community package repository source
choco source list --limitoutput | ConvertFrom-Csv -Header 'Name', 'Location' -Delimiter '|' | ForEach-Object {
if ($_.Location -eq 'https://community.chocolatey.org/api/v2/') {
choco source remove -n $_.Name
}
}
#### Add internal default sources
#### You could have multiple sources here, so we will provide an example
#### of one using the remote repo variable here
#### NOTE: This EXAMPLE may require changes
if ($NugetRepositoryCredential) {
choco source add --name ChocolateyInternal --source $NugetRepositoryUrl --user $NugetRepositoryCredential.UserName --password $NugetRepositoryCredential.GetNetworkCredential().Password --priority 1
} else {
choco source add --name ChocolateyInternal --source $NugetRepositoryUrl --priority 1
}
### b. Keep Chocolatey Up To Date ###
#### Keep chocolatey up to date based on your internal source
#### You control the upgrades based on when you push an updated version
#### to your internal repository.
#### Note the source here is to the OData feed, similar to what you see
#### when you browse to https://community.chocolatey.org/api/v2/
choco upgrade chocolatey --confirm
## 5. ENSURE CHOCOLATEY FOR BUSINESS ##
### If you don't have Chocolatey for Business (C4B), you'll want to remove from here down.
### a. Ensure The License File Is Installed ###
#### Create a license package using script from https://docs.chocolatey.org/en-us/how-tos/setup-offline-installation#exercise-4-create-a-package-for-the-license
choco install chocolatey-license --source $NugetRepositoryUrl --confirm
### b. Disable The Licensed Source ###
#### The licensed source cannot be removed, so it must be disabled.
#### This must occur after the license has been set by the license package.
if ("chocolatey-license" -in (choco list --localonly --limitoutput | ConvertFrom-Csv -Header "Name" -Delimiter "|").Name) {
choco source disable --name chocolatey.licensed
} else {
Write-Warning "Not disabling 'chocolatey.licensed' feed, as Chocolatey-License has not been installed."
}
### c. Ensure Chocolatey Licensed Extension ###
#### You will have downloaded the licensed extension to your internal repository
#### as you have disabled the licensed repository in step 5b.
#### Ensure the chocolatey.extension package (aka Chocolatey Licensed Extension)
if ("chocolatey-license" -in (choco list --localonly --limitoutput | ConvertFrom-Csv -Header "Name" -Delimiter "|").Name) {
choco install chocolatey.extension --source $NugetRepositoryUrl --confirm
} else {
Write-Warning "Not installing 'chocolatey.extension', as Chocolatey-License has not been installed."
}
#### The Chocolatey Licensed Extension unlocks all of the following, which also have configuration/feature items available with them. You may want to visit the feature pages to see what you might want to also enable:
#### - Package Builder - https://docs.chocolatey.org/en-us/features/paid/package-builder
#### - Package Internalizer - https://docs.chocolatey.org/en-us/features/paid/package-internalizer
#### - Package Synchronization (3 components) - https://docs.chocolatey.org/en-us/features/paid/package-synchronization
#### - Package Reducer - https://docs.chocolatey.org/en-us/features/paid/package-reducer
#### - Package Audit - https://docs.chocolatey.org/en-us/features/paid/package-audit
#### - Package Throttle - https://docs.chocolatey.org/en-us/features/paid/package-throttle
#### - CDN Cache Access - https://docs.chocolatey.org/en-us/features/paid/private-cdn
#### - Branding - https://docs.chocolatey.org/en-us/features/paid/branding
#### - Self-Service Anywhere (more components will need to be installed and additional configuration will need to be set) - https://docs.chocolatey.org/en-us/features/paid/self-service-anywhere
#### - Chocolatey Central Management (more components will need to be installed and additional configuration will need to be set) - https://docs.chocolatey.org/en-us/features/paid/chocolatey-central-management
#### - Other - https://docs.chocolatey.org/en-us/features/paid/
### d. Ensure Self-Service Anywhere ###
#### If you have desktop clients where users are not administrators, you may
#### to take advantage of deploying and configuring Self-Service anywhere
choco feature disable --name showNonElevatedWarnings
choco feature enable --name useBackgroundService
choco feature enable --name useBackgroundServiceWithNonAdministratorsOnly
choco feature enable --name allowBackgroundServiceUninstallsFromUserInstallsOnly
choco config set --name allowedBackgroundServiceCommands --value "install,upgrade,uninstall"
### e. Ensure Chocolatey Central Management ###
#### If you want to manage and report on endpoints, you can set up and configure
### Central Management. There are multiple portions to manage, so you'll see
### a section on agents here along with notes on how to configure the server
### side components.
if ($ChocolateyCentralManagementUrl) {
choco install chocolatey-agent --source $NugetRepositoryUrl --confirm
choco config set --name CentralManagementServiceUrl --value $ChocolateyCentralManagementUrl
if ($ChocolateyCentralManagementClientSalt) {
choco config set --name centralManagementClientCommunicationSaltAdditivePassword --value $ChocolateyCentralManagementClientSalt
}
if ($ChocolateyCentralManagementServiceSalt) {
choco config set --name centralManagementServiceCommunicationSaltAdditivePassword --value $ChocolateyCentralManagementServiceSalt
}
choco feature enable --name useChocolateyCentralManagement
choco feature enable --name useChocolateyCentralManagementDeployments
}
See docs at https://docs.ansible.com/ansible/latest/modules/win_chocolatey_module.html.
If Applicable - Chocolatey Configuration/Installation
## 1. REQUIREMENTS ##
### Here are the requirements necessary to ensure this is successful.
### a. Internal/Private Cloud Repository Set Up ###
#### You'll need an internal/private cloud repository you can use. These are
#### generally really quick to set up and there are quite a few options.
#### Chocolatey Software recommends Nexus, Artifactory Pro, or ProGet as they
#### are repository servers and will give you the ability to manage multiple
#### repositories and types from one server installation.
### b. Download Chocolatey Package and Put on Internal Repository ###
#### You need to have downloaded the Chocolatey package as well.
#### Please see https://chocolatey.org/install#organization
### c. Other Requirements ###
#### i. chocolatey.chocolatey
##### You will require the chocolatey.chocolatey collection to be installed
##### on all machines using this playbook.
##### Please see https://github.com/chocolatey/chocolatey-ansible/#installing-the-collection-from-ansible-galaxy
- name: Install and Configure Chocolatey
hosts: all
## 2. TOP LEVEL VARIABLES ##
vars:
### a. Your internal repository url (the main one). ###
#### Should be similar to what you see when you browse
#### to https://community.chocolatey.org/api/v2/
nuget_repository_url: INTERNAL REPO URL
### b. Internal Repository Credential ###
#### If required, add the repository access credential here and
#### uncomment lines with source_username and source_password below
# nuget_repository_username: username
# nuget_repository_password: password
### c. Chocolatey Central Management (CCM) ###
#### If using CCM to manage Chocolatey, add the following:
#### i. Endpoint URL for CCM
# chocolatey_central_management_url: https://chocolatey-central-management:24020/ChocolateyManagementService
#### ii. If using a Client Salt, add it here
# chocolatey_central_management_client_salt: clientsalt
#### iii. If using a Service Salt, add it here
# chocolatey_central_management_service_salt: servicesalt
## 3. ENSURE CHOCOLATEY IS INSTALLED ##
### Ensure Chocolatey is installed from your internal repository
tasks:
- name: Install chocolatey
win_chocolatey:
name: chocolatey
source: {{ nuget_repository_url }}
# source_username: {{ nuget_repository_username }}
# source_password: {{ nuget_repository_password }}
## 4. CONFIGURE CHOCOLATEY BASELINE ##
### a. FIPS Feature ###
#### If you need FIPS compliance - make this the first thing you configure
#### before you do any additional configuration or package installations
# - name: Enable FIPS compliance
# win_chocolatey_feature:
# name: useFipsCompliantChecksums
# state: enabled
### b. Apply Recommended Configuration ###
#### Move cache location so Chocolatey is very deterministic about
#### cleaning up temporary data and the location is secured to admins
- name: Set the cache location
win_chocolatey_config:
name: cacheLocation
state: present
value: C:\ProgramData\chocolatey\cache
#### Increase timeout to at least 4 hours
- name: Set the command execution timeout
win_chocolatey_config:
name: commandExecutionTimeoutSeconds
state: present
value: 14400
#### Turn off download progress when running choco through integrations
- name: Disable showing download progress
win_chocolatey_feature:
name: showDownloadProgress
state: disabled
### c. Sources ###
#### Remove the default community package repository source
- name: Remove Chocolatey Community Repository
win_chocolatey_source:
name: chocolatey
state: absent
#### Add internal default sources
#### You could have multiple sources here, so we will provide an example
#### of one using the remote repo variable here
#### NOTE: This EXAMPLE may require changes
- name: Add Internal Repository
win_chocolatey_source:
name: ChocolateyInternal
state: present
source: {{ nuget_repository_url }}
# source_username: {{ nuget_repository_username }}
# source_password: {{ nuget_repository_password }}
priority: 1
### b. Keep Chocolatey Up To Date ###
#### Keep chocolatey up to date based on your internal source
#### You control the upgrades based on when you push an updated version
#### to your internal repository.
#### Note the source here is to the OData feed, similar to what you see
#### when you browse to https://community.chocolatey.org/api/v2/
- name: Upgrade Chocolatey
win_chocolatey:
name: chocolatey
state: latest
## 5. ENSURE CHOCOLATEY FOR BUSINESS ##
### If you don't have Chocolatey for Business (C4B), you'll want to remove from here down.
### a. Ensure The License File Is Installed ###
#### Create a license package using script from https://docs.chocolatey.org/en-us/how-tos/setup-offline-installation#exercise-4-create-a-package-for-the-license
- name: Install Chocolatey License
win_chocolatey:
name: chocolatey-license
source: ChocolateyInternal
state: latest
### b. Disable The Licensed Source ###
#### The licensed source cannot be removed, so it must be disabled.
#### This must occur after the license has been set by the license package.
- name: Disable Chocolatey Community Repository
win_chocolatey_source:
name: chocolatey.licensed
state: disabled
### c. Ensure Chocolatey Licensed Extension ###
#### You will have downloaded the licensed extension to your internal repository
#### as you have disabled the licensed repository in step 5b.
#### Ensure the chocolatey.extension package (aka Chocolatey Licensed Extension)
- name: Install Chocolatey Extension
win_chocolatey:
name: chocolatey.extension
source: ChocolateyInternal
state: latest
#### The Chocolatey Licensed Extension unlocks all of the following, which also have configuration/feature items available with them. You may want to visit the feature pages to see what you might want to also enable:
#### - Package Builder - https://docs.chocolatey.org/en-us/features/paid/package-builder
#### - Package Internalizer - https://docs.chocolatey.org/en-us/features/paid/package-internalizer
#### - Package Synchronization (3 components) - https://docs.chocolatey.org/en-us/features/paid/package-synchronization
#### - Package Reducer - https://docs.chocolatey.org/en-us/features/paid/package-reducer
#### - Package Audit - https://docs.chocolatey.org/en-us/features/paid/package-audit
#### - Package Throttle - https://docs.chocolatey.org/en-us/features/paid/package-throttle
#### - CDN Cache Access - https://docs.chocolatey.org/en-us/features/paid/private-cdn
#### - Branding - https://docs.chocolatey.org/en-us/features/paid/branding
#### - Self-Service Anywhere (more components will need to be installed and additional configuration will need to be set) - https://docs.chocolatey.org/en-us/features/paid/self-service-anywhere
#### - Chocolatey Central Management (more components will need to be installed and additional configuration will need to be set) - https://docs.chocolatey.org/en-us/features/paid/chocolatey-central-management
#### - Other - https://docs.chocolatey.org/en-us/features/paid/
### d. Ensure Self-Service Anywhere ###
#### If you have desktop clients where users are not administrators, you may
#### to take advantage of deploying and configuring Self-Service anywhere
- name: Hide not-elevated warnings
win_chocolatey_feature:
name: showNonElevatedWarnings
state: disabled
- name: Use background mode for self-service
win_chocolatey_feature:
name: useBackgroundService
state: enabled
- name: Use background service for non-admins
win_chocolatey_feature:
name: useBackgroundServiceWithNonAdministratorsOnly
state: enabled
- name: Allow background uninstallation for user installs
win_chocolatey_feature:
name: allowBackgroundServiceUninstallsFromUserInstallsOnly
state: enabled
- name: Set allowed background service commands
win_chocolatey_config:
name: backgroundServiceAllowedCommands
state: present
value: install,upgrade,uninstall
### e. Ensure Chocolatey Central Management ###
#### If you want to manage and report on endpoints, you can set up and configure
### Central Management. There are multiple portions to manage, so you'll see
### a section on agents here along with notes on how to configure the server
### side components.
- name: Install Chocolatey Agent
when: chocolatey_central_management_url is defined
win_chocolatey:
name: chocolatey-agent
source: ChocolateyInternal
state: latest
- name: Set the Central Management Service URL
when: chocolatey_central_management_url is defined
win_chocolatey_config:
name: CentralManagementServiceUrl
state: present
value: {{ chocolatey_central_management_url }}
- name: Set the Central Management Client Salt
when: chocolatey_central_management_client_salt is defined
win_chocolatey_config:
name: centralManagementClientCommunicationSaltAdditivePassword
state: present
value: {{ chocolatey_central_management_client_salt }}
- name: Set the Central Management Service Salt
when: chocolatey_central_management_service_salt is defined
win_chocolatey_config:
name: centralManagementServiceCommunicationSaltAdditivePassword
state: present
value: {{ chocolatey_central_management_service_salt }}
- name: Use Central Management
when: chocolatey_central_management_url is defined
win_chocolatey_feature:
name: useChocolateyCentralManagement
state: enabled
- name: Use Central Management Deployments
when: chocolatey_central_management_url is defined
win_chocolatey_feature:
name: useChocolateyCentralManagementDeployments
state: enabled
See docs at https://docs.chef.io/resource_chocolatey_package.html.
If Applicable - Chocolatey Configuration/Installation
## 1. REQUIREMENTS ##
### Here are the requirements necessary to ensure this is successful.
### a. Internal/Private Cloud Repository Set Up ###
#### You'll need an internal/private cloud repository you can use. These are
#### generally really quick to set up and there are quite a few options.
#### Chocolatey Software recommends Nexus, Artifactory Pro, or ProGet as they
#### are repository servers and will give you the ability to manage multiple
#### repositories and types from one server installation.
### b. Download Chocolatey Package and Put on Internal Repository ###
#### You need to have downloaded the Chocolatey package as well.
#### Please see https://chocolatey.org/install#organization
### c. Other Requirements ###
#### The Chocolatey resources are available with any recent version of Chef.
#### We utilise the Chocolatey recipe to install the Chocolatey binaries.
include_recipe "chocolatey"
## 2. TOP LEVEL VARIABLES ##
### a. Your internal repository url (the main one). ###
#### Should be similar to what you see when you browse
#### to https://community.chocolatey.org/api/v2/
NugetRepositoryUrl = "INTERNAL REPO URL"
### b. Internal Repository Credential ###
#### If required, add the repository access credential here
# NugetRepositoryUsername = "username"
# NugetRepositoryPassword = "password"
### c. Chocolatey nupkg download url ###
#### This url should result in an immediate download when you navigate to it in
#### a web browser
ChocolateyNupkgUrl = "INTERNAL REPO URL/package/chocolatey.1.1.0.nupkg",
### d. Chocolatey Central Management (CCM) ###
#### If using CCM to manage Chocolatey, add the following:
#### i. Endpoint URL for CCM
# ChocolateyCentralManagementUrl = "https://chocolatey-central-management:24020/ChocolateyManagementService"
#### ii. If using a Client Salt, add it here
# ChocolateyCentralManagementClientSalt = "clientsalt"
#### iii. If using a Service Salt, add it here
# ChocolateyCentralManagementServiceSalt = "servicesalt"
## 3. ENSURE CHOCOLATEY IS INSTALLED ##
### Ensure Chocolatey is installed from your internal repository
node['chocolatey']['install vars'] = {
'chocolateyDownloadUrl' => "#{ChocolateyNupkgUrl}",
}
## 4. CONFIGURE CHOCOLATEY BASELINE ##
### a. FIPS Feature ###
#### If you need FIPS compliance - make this the first thing you configure
#### before you do any additional configuration or package installations
# chocolatey_feature 'useFipsCompliantChecksums' do
# action :enable
# end
### b. Apply Recommended Configuration ###
#### Move cache location so Chocolatey is very deterministic about
#### cleaning up temporary data and the location is secured to admins
chocolatey_config 'cacheLocation' do
value 'C:\ProgramData\chocolatey\cache'
end
#### Increase timeout to at least 4 hours
chocolatey_config 'commandExecutionTimeoutSeconds' do
value '14400'
end
#### Turn off download progress when running choco through integrations
chocolatey_feature 'showDownloadProgress' do
action :disable
end
### c. Sources ###
#### Remove the default community package repository source
chocolatey_source 'chocolatey' do
action :remove
end
#### Add internal default sources
#### You could have multiple sources here, so we will provide an example
#### of one using the remote repo variable here
#### NOTE: This EXAMPLE may require changes
chocolatey_source 'ChocolateyInternal' do
source "#{NugetRepositoryUrl}"
priority 1
action :add
end
execute 'ChocolateyInternal' do
command "choco source add --name ChocolateyInternal -s #{NugetRepositoryUrl} -u=#{NugetRepositoryUsername} -p=#{NugetRepositoryPassword} --priority=1"
only_if { NugetRepositoryUsername != nil || NugetRepositoryPassword != nil }
end
### b. Keep Chocolatey Up To Date ###
#### Keep chocolatey up to date based on your internal source
#### You control the upgrades based on when you push an updated version
#### to your internal repository.
#### Note the source here is to the OData feed, similar to what you see
#### when you browse to https://community.chocolatey.org/api/v2/
chocolatey_package 'chocolatey' do
action :upgrade
source "#{NugetRepositoryUrl}"
end
## 5. ENSURE CHOCOLATEY FOR BUSINESS ##
### If you don't have Chocolatey for Business (C4B), you'll want to remove from here down.
### a. Ensure The License File Is Installed ###
#### Create a license package using script from https://docs.chocolatey.org/en-us/how-tos/setup-offline-installation#exercise-4-create-a-package-for-the-license
chocolatey_package 'chocolatey-license' do
action :install
source "#{NugetRepositoryUrl}"
end
### b. Disable The Licensed Source ###
#### The licensed source cannot be removed, so it must be disabled.
#### This must occur after the license has been set by the license package.
chocolatey_source 'chocolatey.licensed' do
action :disable
end
### c. Ensure Chocolatey Licensed Extension ###
#### You will have downloaded the licensed extension to your internal repository
#### as you have disabled the licensed repository in step 5b.
#### Ensure the chocolatey.extension package (aka Chocolatey Licensed Extension)
chocolatey_package 'chocolatey.extention' do
action install
source "#{NugetRepositoryUrl}"
end
#### The Chocolatey Licensed Extension unlocks all of the following, which also have configuration/feature items available with them. You may want to visit the feature pages to see what you might want to also enable:
#### - Package Builder - https://docs.chocolatey.org/en-us/features/paid/package-builder
#### - Package Internalizer - https://docs.chocolatey.org/en-us/features/paid/package-internalizer
#### - Package Synchronization (3 components) - https://docs.chocolatey.org/en-us/features/paid/package-synchronization
#### - Package Reducer - https://docs.chocolatey.org/en-us/features/paid/package-reducer
#### - Package Audit - https://docs.chocolatey.org/en-us/features/paid/package-audit
#### - Package Throttle - https://docs.chocolatey.org/en-us/features/paid/package-throttle
#### - CDN Cache Access - https://docs.chocolatey.org/en-us/features/paid/private-cdn
#### - Branding - https://docs.chocolatey.org/en-us/features/paid/branding
#### - Self-Service Anywhere (more components will need to be installed and additional configuration will need to be set) - https://docs.chocolatey.org/en-us/features/paid/self-service-anywhere
#### - Chocolatey Central Management (more components will need to be installed and additional configuration will need to be set) - https://docs.chocolatey.org/en-us/features/paid/chocolatey-central-management
#### - Other - https://docs.chocolatey.org/en-us/features/paid/
### d. Ensure Self-Service Anywhere ###
#### If you have desktop clients where users are not administrators, you may
#### to take advantage of deploying and configuring Self-Service anywhere
chocolatey_feature 'showNonElevatedWarnings' do
action :disable
end
chocolatey_feature 'useBackgroundService' do
action :enable
end
chocolatey_feature 'useBackgroundServiceWithNonAdministratorsOnly' do
action :enable
end
chocolatey_feature 'allowBackgroundServiceUninstallsFromUserInstallsOnly' do
action :enable
end
chocolatey_config 'backgroundServiceAllowedCommands' do
value 'install,upgrade,uninstall'
end
### e. Ensure Chocolatey Central Management ###
#### If you want to manage and report on endpoints, you can set up and configure
### Central Management. There are multiple portions to manage, so you'll see
### a section on agents here along with notes on how to configure the server
### side components.
chocolatey_package 'chocolatey-agent' do
action install
source "#{NugetRepositoryUrl}"
# user "#{NugetRepositoryUsername}"
# password "#{NugetRepositoryPassword}"
only_if { ChocolateyCentralManagementUrl != nil }
end
chocolatey_config 'CentralManagementServiceUrl' do
value "#{ChocolateyCentralManagementUrl}"
only_if { ChocolateyCentralManagementUrl != nil }
end
chocolatey_config 'centralManagementClientCommunicationSaltAdditivePassword' do
value "#{ChocolateyCentralManagementClientSalt}"
only_if { ChocolateyCentralManagementClientSalt != nil }
end
chocolatey_config 'centralManagementServiceCommunicationSaltAdditivePassword' do
value "#{ChocolateyCentralManagementServiceSalt}"
only_if { ChocolateyCentralManagementServiceSalt != nil }
end
chocolatey_feature 'useChocolateyCentralManagement' do
action :enable
only_if { ChocolateyCentralManagementUrl != nil }
end
chocolatey_feature 'useChocolateyCentralManagementDeployments' do
action :enable
only_if { ChocolateyCentralManagementUrl != nil }
end
Requires cChoco DSC Resource. See docs at https://github.com/chocolatey/cChoco.
If Applicable - Chocolatey Configuration/Installation
#requires -Modules cChoco
## 1. REQUIREMENTS ##
### Here are the requirements necessary to ensure this is successful.
### a. Internal/Private Cloud Repository Set Up ###
#### You'll need an internal/private cloud repository you can use. These are
#### generally really quick to set up and there are quite a few options.
#### Chocolatey Software recommends Nexus, Artifactory Pro, or ProGet as they
#### are repository servers and will give you the ability to manage multiple
#### repositories and types from one server installation.
### b. Download Chocolatey Package and Put on Internal Repository ###
#### You need to have downloaded the Chocolatey package as well.
#### Please see https://chocolatey.org/install#organization
### c. Other Requirements ###
#### i. Requires chocolatey\cChoco DSC module to be installed on the machine compiling the DSC manifest
#### NOTE: This will need to be installed before running the DSC portion of this script
if (-not (Get-Module cChoco -ListAvailable)) {
$null = Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
if (($PSGallery = Get-PSRepository -Name PSGallery).InstallationPolicy -ne "Trusted") {
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
}
Install-Module -Name cChoco
if ($PSGallery.InstallationPolicy -ne "Trusted") {
Set-PSRepository -Name PSGallery -InstallationPolicy $PSGallery.InstallationPolicy
}
}
#### ii. Requires a hosted copy of the install.ps1 script
##### This should be available to download without authentication.
##### The original script can be found here: https://community.chocolatey.org/install.ps1
Configuration ChocolateyConfig {
## 2. TOP LEVEL VARIABLES ##
param(
### a. Your internal repository url (the main one). ###
#### Should be similar to what you see when you browse
#### to https://community.chocolatey.org/api/v2/
$NugetRepositoryUrl = "INTERNAL REPO URL",
### b. Chocolatey nupkg download url ###
#### This url should result in an immediate download when you navigate to it in
#### a web browser
$ChocolateyNupkgUrl = "INTERNAL REPO URL/package/chocolatey.1.1.0.nupkg",
### c. Internal Repository Credential ###
#### If required, add the repository access credential here
# $NugetRepositoryCredential = [PSCredential]::new(
# "username",
# ("password" | ConvertTo-SecureString -AsPlainText -Force)
# ),
### d. Install.ps1 URL
#### The path to the hosted install script:
$ChocolateyInstallPs1Url = "https://community.chocolatey.org/install.ps1"
### e. Chocolatey Central Management (CCM) ###
#### If using CCM to manage Chocolatey, add the following:
#### i. Endpoint URL for CCM
# $ChocolateyCentralManagementUrl = "https://chocolatey-central-management:24020/ChocolateyManagementService",
#### ii. If using a Client Salt, add it here
# $ChocolateyCentralManagementClientSalt = "clientsalt",
#### iii. If using a Service Salt, add it here
# $ChocolateyCentralManagementServiceSalt = "servicesalt"
)
Import-DscResource -ModuleName PSDesiredStateConfiguration
Import-DscResource -ModuleName cChoco
Node 'localhost' {
## 3. ENSURE CHOCOLATEY IS INSTALLED ##
### Ensure Chocolatey is installed from your internal repository
Environment chocoDownloadUrl {
Name = "chocolateyDownloadUrl"
Value = $ChocolateyNupkgUrl
}
cChocoInstaller installChocolatey {
DependsOn = "[Environment]chocoDownloadUrl"
InstallDir = Join-Path $env:ProgramData "chocolatey"
ChocoInstallScriptUrl = $ChocolateyInstallPs1Url
}
## 4. CONFIGURE CHOCOLATEY BASELINE ##
### a. FIPS Feature ###
#### If you need FIPS compliance - make this the first thing you configure
#### before you do any additional configuration or package installations
# cChocoFeature featureFipsCompliance {
# FeatureName = "useFipsCompliantChecksums"
# }
### b. Apply Recommended Configuration ###
#### Move cache location so Chocolatey is very deterministic about
#### cleaning up temporary data and the location is secured to admins
cChocoConfig cacheLocation {
DependsOn = "[cChocoInstaller]installChocolatey"
ConfigName = "cacheLocation"
Value = "C:\ProgramData\chocolatey\cache"
}
#### Increase timeout to at least 4 hours
cChocoConfig commandExecutionTimeoutSeconds {
DependsOn = "[cChocoInstaller]installChocolatey"
ConfigName = "commandExecutionTimeoutSeconds"
Value = 14400
}
#### Turn off download progress when running choco through integrations
cChocoFeature showDownloadProgress {
DependsOn = "[cChocoInstaller]installChocolatey"
FeatureName = "showDownloadProgress"
Ensure = "Absent"
}
### c. Sources ###
#### Remove the default community package repository source
cChocoSource removeCommunityRepository {
DependsOn = "[cChocoInstaller]installChocolatey"
Name = "chocolatey"
Ensure = "Absent"
}
#### Add internal default sources
#### You could have multiple sources here, so we will provide an example
#### of one using the remote repo variable here.
#### NOTE: This EXAMPLE may require changes
cChocoSource addInternalSource {
DependsOn = "[cChocoInstaller]installChocolatey"
Name = "ChocolateyInternal"
Source = $NugetRepositoryUrl
Credentials = $NugetRepositoryCredential
Priority = 1
}
### b. Keep Chocolatey Up To Date ###
#### Keep chocolatey up to date based on your internal source
#### You control the upgrades based on when you push an updated version
#### to your internal repository.
#### Note the source here is to the OData feed, similar to what you see
#### when you browse to https://community.chocolatey.org/api/v2/
cChocoPackageInstaller updateChocolatey {
DependsOn = "[cChocoSource]addInternalSource", "[cChocoSource]removeCommunityRepository"
Name = "chocolatey"
AutoUpgrade = $true
}
## 5. ENSURE CHOCOLATEY FOR BUSINESS ##
### If you don't have Chocolatey for Business (C4B), you'll want to remove from here down.
### a. Ensure The License File Is Installed ###
#### Create a license package using script from https://docs.chocolatey.org/en-us/how-tos/setup-offline-installation#exercise-4-create-a-package-for-the-license
cChocoPackageInstaller chocolateyLicense {
DependsOn = "[cChocoPackageInstaller]updateChocolatey"
Name = "chocolatey-license"
}
### b. Disable The Licensed Source ###
#### The licensed source cannot be removed, so it must be disabled.
#### This must occur after the license has been set by the license package.
Script disableLicensedSource {
DependsOn = "[cChocoPackageInstaller]chocolateyLicense"
GetScript = {
$Source = choco source list --limitoutput | `
ConvertFrom-Csv -Delimiter '|' -Header Name, Source, Disabled | `
Where-Object Name -eq "chocolatey.licensed"
return @{
Result = if ($Source) {
[bool]::Parse($Source.Disabled)
} else {
Write-Warning "Source 'chocolatey.licensed' was not present."
$true # Source does not need disabling
}
}
}
SetScript = {
$null = choco source disable --name "chocolatey.licensed"
}
TestScript = {
$State = [ScriptBlock]::Create($GetScript).Invoke()
return $State.Result
}
}
### c. Ensure Chocolatey Licensed Extension ###
#### You will have downloaded the licensed extension to your internal repository
#### as you have disabled the licensed repository in step 5b.
#### Ensure the chocolatey.extension package (aka Chocolatey Licensed Extension)
cChocoPackageInstaller chocolateyLicensedExtension {
DependsOn = "[Script]disableLicensedSource"
Name = "chocolatey.extension"
}
#### The Chocolatey Licensed Extension unlocks all of the following, which also have configuration/feature items available with them. You may want to visit the feature pages to see what you might want to also enable:
#### - Package Builder - https://docs.chocolatey.org/en-us/features/paid/package-builder
#### - Package Internalizer - https://docs.chocolatey.org/en-us/features/paid/package-internalizer
#### - Package Synchronization (3 components) - https://docs.chocolatey.org/en-us/features/paid/package-synchronization
#### - Package Reducer - https://docs.chocolatey.org/en-us/features/paid/package-reducer
#### - Package Audit - https://docs.chocolatey.org/en-us/features/paid/package-audit
#### - Package Throttle - https://docs.chocolatey.org/en-us/features/paid/package-throttle
#### - CDN Cache Access - https://docs.chocolatey.org/en-us/features/paid/private-cdn
#### - Branding - https://docs.chocolatey.org/en-us/features/paid/branding
#### - Self-Service Anywhere (more components will need to be installed and additional configuration will need to be set) - https://docs.chocolatey.org/en-us/features/paid/self-service-anywhere
#### - Chocolatey Central Management (more components will need to be installed and additional configuration will need to be set) - https://docs.chocolatey.org/en-us/features/paid/chocolatey-central-management
#### - Other - https://docs.chocolatey.org/en-us/features/paid/
### d. Ensure Self-Service Anywhere ###
#### If you have desktop clients where users are not administrators, you may
#### to take advantage of deploying and configuring Self-Service anywhere
cChocoFeature hideElevatedWarnings {
DependsOn = "[cChocoPackageInstaller]chocolateyLicensedExtension"
FeatureName = "showNonElevatedWarnings"
Ensure = "Absent"
}
cChocoFeature useBackgroundService {
DependsOn = "[cChocoPackageInstaller]chocolateyLicensedExtension"
FeatureName = "useBackgroundService"
Ensure = "Present"
}
cChocoFeature useBackgroundServiceWithNonAdmins {
DependsOn = "[cChocoPackageInstaller]chocolateyLicensedExtension"
FeatureName = "useBackgroundServiceWithNonAdministratorsOnly"
Ensure = "Present"
}
cChocoFeature useBackgroundServiceUninstallsForUserInstalls {
DependsOn = "[cChocoPackageInstaller]chocolateyLicensedExtension"
FeatureName = "allowBackgroundServiceUninstallsFromUserInstallsOnly"
Ensure = "Present"
}
cChocoConfig allowedBackgroundServiceCommands {
DependsOn = "[cChocoFeature]useBackgroundService"
ConfigName = "backgroundServiceAllowedCommands"
Value = "install,upgrade,uninstall"
}
### e. Ensure Chocolatey Central Management ###
#### If you want to manage and report on endpoints, you can set up and configure
### Central Management. There are multiple portions to manage, so you'll see
### a section on agents here along with notes on how to configure the server
### side components.
if ($ChocolateyCentralManagementUrl) {
cChocoPackageInstaller chocolateyAgent {
DependsOn = "[cChocoPackageInstaller]chocolateyLicensedExtension"
Name = "chocolatey-agent"
}
cChocoConfig centralManagementServiceUrl {
DependsOn = "[cChocoPackageInstaller]chocolateyAgent"
ConfigName = "CentralManagementServiceUrl"
Value = $ChocolateyCentralManagementUrl
}
if ($ChocolateyCentralManagementClientSalt) {
cChocoConfig centralManagementClientSalt {
DependsOn = "[cChocoPackageInstaller]chocolateyAgent"
ConfigName = "centralManagementClientCommunicationSaltAdditivePassword"
Value = $ChocolateyCentralManagementClientSalt
}
}
if ($ChocolateyCentralManagementServiceSalt) {
cChocoConfig centralManagementServiceSalt {
DependsOn = "[cChocoPackageInstaller]chocolateyAgent"
ConfigName = "centralManagementServiceCommunicationSaltAdditivePassword"
Value = $ChocolateyCentralManagementServiceSalt
}
}
cChocoFeature useCentralManagement {
DependsOn = "[cChocoPackageInstaller]chocolateyAgent"
FeatureName = "useChocolateyCentralManagement"
Ensure = "Present"
}
cChocoFeature useCentralManagementDeployments {
DependsOn = "[cChocoPackageInstaller]chocolateyAgent"
FeatureName = "useChocolateyCentralManagementDeployments"
Ensure = "Present"
}
}
}
}
# If working this into an existing configuration with a good method for
$ConfigData = @{
AllNodes = @(
@{
NodeName = "localhost"
PSDscAllowPlainTextPassword = $true
}
)
}
try {
Push-Location $env:Temp
$Config = ChocolateyConfig -ConfigurationData $ConfigData
Start-DscConfiguration -Path $Config.PSParentPath -Wait -Verbose -Force
} finally {
Pop-Location
}
Requires Puppet Chocolatey Provider module. See docs at https://forge.puppet.com/puppetlabs/chocolatey.
If Applicable - Chocolatey Configuration/Installation
## 1. REQUIREMENTS ##
### Here are the requirements necessary to ensure this is successful.
### a. Internal/Private Cloud Repository Set Up ###
#### You'll need an internal/private cloud repository you can use. These are
#### generally really quick to set up and there are quite a few options.
#### Chocolatey Software recommends Nexus, Artifactory Pro, or ProGet as they
#### are repository servers and will give you the ability to manage multiple
#### repositories and types from one server installation.
### b. Download Chocolatey Package and Put on Internal Repository ###
#### You need to have downloaded the Chocolatey package as well.
#### Please see https://chocolatey.org/install#organization
### c. Other Requirements ###
#### i. Requires puppetlabs/chocolatey module
#### See https://forge.puppet.com/puppetlabs/chocolatey
## 2. TOP LEVEL VARIABLES ##
### a. Your internal repository url (the main one). ###
#### Should be similar to what you see when you browse
#### to https://community.chocolatey.org/api/v2/
$_repository_url = 'INTERNAL REPO URL'
### b. Chocolatey nupkg download url ###
#### This url should result in an immediate download when you navigate to it in
#### a web browser
$_choco_download_url = 'INTERNAL REPO URL/package/chocolatey.1.1.0.nupkg'
### c. Chocolatey Central Management (CCM) ###
#### If using CCM to manage Chocolatey, add the following:
#### i. Endpoint URL for CCM
# $_chocolatey_central_management_url = 'https://chocolatey-central-management:24020/ChocolateyManagementService'
#### ii. If using a Client Salt, add it here
# $_chocolatey_central_management_client_salt = "clientsalt"
#### iii. If using a Service Salt, add it here
# $_chocolatey_central_management_service_salt = 'servicesalt'
## 3. ENSURE CHOCOLATEY IS INSTALLED ##
### Ensure Chocolatey is installed from your internal repository
### Note: `chocolatey_download_url is completely different than normal
### source locations. This is directly to the bare download url for the
### chocolatey.nupkg, similar to what you see when you browse to
### https://community.chocolatey.org/api/v2/package/chocolatey
class {'chocolatey':
chocolatey_download_url => $_choco_download_url,
use_7zip => false,
}
## 4. CONFIGURE CHOCOLATEY BASELINE ##
### a. FIPS Feature ###
#### If you need FIPS compliance - make this the first thing you configure
#### before you do any additional configuration or package installations
#chocolateyfeature {'useFipsCompliantChecksums':
# ensure => enabled,
#}
### b. Apply Recommended Configuration ###
#### Move cache location so Chocolatey is very deterministic about
#### cleaning up temporary data and the location is secured to admins
chocolateyconfig {'cacheLocation':
value => 'C:\ProgramData\chocolatey\cache',
}
#### Increase timeout to at least 4 hours
chocolateyconfig {'commandExecutionTimeoutSeconds':
value => '14400',
}
#### Turn off download progress when running choco through integrations
chocolateyfeature {'showDownloadProgress':
ensure => disabled,
}
### c. Sources ###
#### Remove the default community package repository source
chocolateysource {'chocolatey':
ensure => absent,
location => 'https://community.chocolatey.org/api/v2/',
}
#### Add internal default sources
#### You could have multiple sources here, so we will provide an example
#### of one using the remote repo variable here
#### NOTE: This EXAMPLE requires changes
chocolateysource {'internal_chocolatey':
ensure => present,
location => $_repository_url,
priority => 1,
username => 'optional',
password => 'optional,not ensured',
bypass_proxy => true,
admin_only => false,
allow_self_service => false,
}
### b. Keep Chocolatey Up To Date ###
#### Keep chocolatey up to date based on your internal source
#### You control the upgrades based on when you push an updated version
#### to your internal repository.
#### Note the source here is to the OData feed, similar to what you see
#### when you browse to https://community.chocolatey.org/api/v2/
package {'chocolatey':
ensure => latest,
provider => chocolatey,
source => $_repository_url,
}
## 5. ENSURE CHOCOLATEY FOR BUSINESS ##
### If you don't have Chocolatey for Business (C4B), you'll want to remove from here down.
### a. Ensure The License File Is Installed ###
#### Create a license package using script from https://docs.chocolatey.org/en-us/guides/organizations/organizational-deployment-guide#exercise-4-create-a-package-for-the-license
# TODO: Add resource for installing/ensuring the chocolatey-license package
package {'chocolatey-license':
ensure => latest,
provider => chocolatey,
source => $_repository_url,
}
### b. Disable The Licensed Source ###
#### The licensed source cannot be removed, so it must be disabled.
#### This must occur after the license has been set by the license package.
## Disabled sources still need all other attributes until
## https://tickets.puppetlabs.com/browse/MODULES-4449 is resolved.
## Password is necessary with user, but not ensurable, so it should not
## matter what it is set to here. If you ever do get into trouble here,
## the password is your license GUID.
chocolateysource {'chocolatey.licensed':
ensure => disabled,
priority => '10',
user => 'customer',
password => '1234',
require => Package['chocolatey-license'],
}
### c. Ensure Chocolatey Licensed Extension ###
#### You will have downloaded the licensed extension to your internal repository
#### as you have disabled the licensed repository in step 5b.
#### Ensure the chocolatey.extension package (aka Chocolatey Licensed Extension)
package {'chocolatey.extension':
ensure => latest,
provider => chocolatey,
source => $_repository_url,
require => Package['chocolatey-license'],
}
#### The Chocolatey Licensed Extension unlocks all of the following, which also have configuration/feature items available with them. You may want to visit the feature pages to see what you might want to also enable:
#### - Package Builder - https://docs.chocolatey.org/en-us/features/paid/package-builder
#### - Package Internalizer - https://docs.chocolatey.org/en-us/features/paid/package-internalizer
#### - Package Synchronization (3 components) - https://docs.chocolatey.org/en-us/features/paid/package-synchronization
#### - Package Reducer - https://docs.chocolatey.org/en-us/features/paid/package-reducer
#### - Package Audit - https://docs.chocolatey.org/en-us/features/paid/package-audit
#### - Package Throttle - https://docs.chocolatey.org/en-us/features/paid/package-throttle
#### - CDN Cache Access - https://docs.chocolatey.org/en-us/features/paid/private-cdn
#### - Branding - https://docs.chocolatey.org/en-us/features/paid/branding
#### - Self-Service Anywhere (more components will need to be installed and additional configuration will need to be set) - https://docs.chocolatey.org/en-us/features/paid/self-service-anywhere
#### - Chocolatey Central Management (more components will need to be installed and additional configuration will need to be set) - https://docs.chocolatey.org/en-us/features/paid/chocolatey-central-management
#### - Other - https://docs.chocolatey.org/en-us/features/paid/
### d. Ensure Self-Service Anywhere ###
#### If you have desktop clients where users are not administrators, you may
#### to take advantage of deploying and configuring Self-Service anywhere
chocolateyfeature {'showNonElevatedWarnings':
ensure => disabled,
}
chocolateyfeature {'useBackgroundService':
ensure => enabled,
}
chocolateyfeature {'useBackgroundServiceWithNonAdministratorsOnly':
ensure => enabled,
}
chocolateyfeature {'allowBackgroundServiceUninstallsFromUserInstallsOnly':
ensure => enabled,
}
chocolateyconfig {'backgroundServiceAllowedCommands':
value => 'install,upgrade,uninstall',
}
### e. Ensure Chocolatey Central Management ###
#### If you want to manage and report on endpoints, you can set up and configure
### Central Management. There are multiple portions to manage, so you'll see
### a section on agents here along with notes on how to configure the server
### side components.
if $_chocolatey_central_management_url {
package {'chocolatey-agent':
ensure => latest,
provider => chocolatey,
source => $_repository_url,
require => Package['chocolatey-license'],
}
chocolateyconfig {'CentralManagementServiceUrl':
value => $_chocolatey_central_management_url,
}
if $_chocolatey_central_management_client_salt {
chocolateyconfig {'centralManagementClientCommunicationSaltAdditivePassword':
value => $_chocolatey_central_management_client_salt,
}
}
if $_chocolatey_central_management_service_salt {
chocolateyconfig {'centralManagementClientCommunicationSaltAdditivePassword':
value => $_chocolatey_central_management_client_salt,
}
}
chocolateyfeature {'useChocolateyCentralManagement':
ensure => enabled,
require => Package['chocolatey-agent'],
}
chocolateyfeature {'useChocolateyCentralManagementDeployments':
ensure => enabled,
require => Package['chocolatey-agent'],
}
}
Need Help? View our docs or file an issue.
There is already a version of this package in your Script Builder
Current Version | New Version |
---|---|
- Passing
- Failing
- Pending
- Unknown / Exempted

Downloads:
786,438
Downloads of v 2.4.149:
1,321
Last Update:
26 Dec 2014
Package Maintainer(s):
Software Author(s):
- Matt Wrock
Tags:
Boxstarter chocolatey environment setup- Software Specific:
- Software Site
- Software License
- Package Specific:
- Possible Package Source
- Package outdated?
- Package broken?
- Contact Maintainers
- Contact Site Admins
- Software Vendor?
- Report Abuse
- Download

Boxstarter Chocolatey Module
This is not the latest version of Boxstarter Chocolatey Module available.
- 1
- 2
- 3
2.4.149 | Updated: 26 Dec 2014
- Software Specific:
- Software Site
- Software License
- Package Specific:
- Possible Package Source
- Package outdated?
- Package broken?
- Contact Maintainers
- Contact Site Admins
- Software Vendor?
- Report Abuse
- Download
Downloads:
786,438
Downloads of v 2.4.149:
1,321
Software Author(s):
- Matt Wrock
Edit Package
To edit the metadata for a package, please upload an updated version of the package.
Chocolatey's Community Package Repository currently does not allow updating package metadata on the website. This helps ensure that the package itself (and the source used to build the package) remains the one true source of package metadata.
This does require that you increment the package version.
- 1
- 2
- 3
Boxstarter Chocolatey Module
2.4.149
This is not the latest version of Boxstarter Chocolatey Module available.
- 1
- 2
- 3
Some Checks Have Failed or Are Not Yet Complete
Not All Tests Have Passed
Validation Testing Unknown
Verification Testing Unknown
Scan Testing Resulted in Investigate
Deployment Method: Individual Install, Upgrade, & Uninstall
To install Boxstarter Chocolatey Module, run the following command from the command line or from PowerShell:
To upgrade Boxstarter Chocolatey Module, run the following command from the command line or from PowerShell:
To uninstall Boxstarter Chocolatey Module, run the following command from the command line or from PowerShell:
Deployment Method:
📝 NOTE: This applies to both open source and commercial editions of Chocolatey.
1. Enter Your Internal Repository Url
(this should look similar to https://community.chocolatey.org/api/v2/)
2. Setup Your Environment
1. Ensure you are set for organizational deployment
Please see the organizational deployment guide
2. Get the package into your environment
Option 1: Cached Package (Unreliable, Requires Internet - Same As Community)-
Open Source or Commercial:
- Proxy Repository - Create a proxy nuget repository on Nexus, Artifactory Pro, or a proxy Chocolatey repository on ProGet. Point your upstream to https://community.chocolatey.org/api/v2/. Packages cache on first access automatically. Make sure your choco clients are using your proxy repository as a source and NOT the default community repository. See source command for more information.
- You can also just download the package and push it to a repository Download
-
Open Source
-
Download the package:
Download - Follow manual internalization instructions
-
-
Package Internalizer (C4B)
-
Run: (additional options)
choco download boxstarter.chocolatey --internalize --version=2.4.149 --source=https://community.chocolatey.org/api/v2/
-
For package and dependencies run:
choco push --source="'INTERNAL REPO URL'"
- Automate package internalization
-
Run: (additional options)
3. Copy Your Script
choco upgrade boxstarter.chocolatey -y --source="'INTERNAL REPO URL'" --version="'2.4.149'" [other options]
See options you can pass to upgrade.
See best practices for scripting.
Add this to a PowerShell script or use a Batch script with tools and in places where you are calling directly to Chocolatey. If you are integrating, keep in mind enhanced exit codes.
If you do use a PowerShell script, use the following to ensure bad exit codes are shown as failures:
choco upgrade boxstarter.chocolatey -y --source="'INTERNAL REPO URL'" --version="'2.4.149'"
$exitCode = $LASTEXITCODE
Write-Verbose "Exit code was $exitCode"
$validExitCodes = @(0, 1605, 1614, 1641, 3010)
if ($validExitCodes -contains $exitCode) {
Exit 0
}
Exit $exitCode
- name: Install boxstarter.chocolatey
win_chocolatey:
name: boxstarter.chocolatey
version: '2.4.149'
source: INTERNAL REPO URL
state: present
See docs at https://docs.ansible.com/ansible/latest/modules/win_chocolatey_module.html.
chocolatey_package 'boxstarter.chocolatey' do
action :install
source 'INTERNAL REPO URL'
version '2.4.149'
end
See docs at https://docs.chef.io/resource_chocolatey_package.html.
cChocoPackageInstaller boxstarter.chocolatey
{
Name = "boxstarter.chocolatey"
Version = "2.4.149"
Source = "INTERNAL REPO URL"
}
Requires cChoco DSC Resource. See docs at https://github.com/chocolatey/cChoco.
package { 'boxstarter.chocolatey':
ensure => '2.4.149',
provider => 'chocolatey',
source => 'INTERNAL REPO URL',
}
Requires Puppet Chocolatey Provider module. See docs at https://forge.puppet.com/puppetlabs/chocolatey.
4. If applicable - Chocolatey configuration/installation
See infrastructure management matrix for Chocolatey configuration elements and examples.
This package was approved as a trusted package on 26 Dec 2014.
Creates a fresh developer (or non developer) environment from a bare OS utilizing powershell and chocolatey. Installs chocolatey, cutomizes windows settings, installs windows updates, handles reboots, installs windows features and your favorite applications.
@echo off
powershell -NoProfile -ExecutionPolicy bypass -command "Import-Module '%~dp0Boxstarter.Chocolatey\Boxstarter.Chocolatey.psd1';Invoke-ChocolateyBoxstarter %*"
$unNormalized=(Get-Item "$PSScriptRoot\..\Boxstarter.Bootstrapper\Boxstarter.Bootstrapper.psd1")
Import-Module $unNormalized.FullName -global -DisableNameChecking -Force
Resolve-Path $PSScriptRoot\*.ps1 |
% { . $_.ProviderPath }
Export-ModuleMember Invoke-ChocolateyBoxstarter, New-BoxstarterPackage, Invoke-BoxstarterBuild, Get-PackageRoot, Set-BoxstarterShare, Get-BoxstarterConfig, Set-BoxstarterConfig, Install-BoxstarterPackage, New-PackageFromScript, Enable-BoxstarterClientRemoting, Enable-BoxstarterCredSSP, Resolve-VMPlugin
Export-ModuleMember Install-ChocolateyInstallPackageOverride,
Write-HostOverride
Export-ModuleMember -alias Install-ChocolateyInstallPackage, Write-Host, Enable-BoxstarterVM
$source = @"
public class BoxstarterConnectionConfig {
public BoxstarterConnectionConfig(System.Uri connectionURI, System.Management.Automation.PSCredential credential, System.Management.Automation.Remoting.PSSessionOption psSessionOption) {
ConnectionURI=connectionURI;
Credential=credential;
PSSessionOption=psSessionOption;
}
public System.Uri ConnectionURI;
public System.Management.Automation.PSCredential Credential;
public System.Management.Automation.Remoting.PSSessionOption PSSessionOption;
}
"@
Add-Type -TypeDefinition $source
function Check-Chocolatey ([switch]$ShouldIntercept){
Enable-Net40
if(-not $env:ChocolateyInstall -or -not (Test-Path "$env:ChocolateyInstall")){
Write-BoxstarterMessage "Chocolatey not installed. Downloading and installing..."
$env:ChocolateyInstall = "$env:programdata\chocolatey"
New-Item $env:ChocolateyInstall -Force -type directory | Out-Null
$config = Get-BoxstarterConfig
$url=$config.ChocolateyPackage
Enter-BoxstarterLogable {
Get-HttpToFile $config.ChocolateyRepo "$env:temp\choco.ps1"
$currentLogging=$Boxstarter.Suppresslogging
if($VerbosePreference -eq "SilentlyContinue"){$Boxstarter.Suppresslogging=$true}
. "$env:temp\choco.ps1"
if($global:error[0].CategoryInfo.Activity -eq 'Remove-Module'){ $global:error.RemoveAt(0) } #this is so terrible
$Boxstarter.SuppressLogging = $currentLogging
}
}
Import-Module $env:ChocolateyInstall\chocolateyinstall\helpers\chocolateyInstaller.psm1 -Global
if(!$BoxstarterIntrercepting)
{
Write-BoxstarterMessage "Chocolatey installed, setting up interception of Chocolatey methods." -Verbose
if($ShouldIntercept){Intercept-Chocolatey}
}
}
function Is64Bit { [IntPtr]::Size -eq 8 }
function Enable-Net40 {
if(Is64Bit) {$fx="framework64"} else {$fx="framework"}
if(!(test-path "$env:windir\Microsoft.Net\$fx\v4.0.30319")) {
if((Test-PendingReboot) -and $Boxstarter.RebootOk) {return Invoke-Reboot}
Write-BoxstarterMessage "Downloading .net 4.5..."
Get-HttpToFile "http://download.microsoft.com/download/b/a/4/ba4a7e71-2906-4b2d-a0e1-80cf16844f5f/dotnetfx45_full_x86_x64.exe" "$env:temp\net45.exe"
Write-BoxstarterMessage "Installing .net 4.5..."
if(Get-IsRemote) {
Invoke-FromTask @"
Start-Process "$env:temp\net45.exe" -verb runas -wait -argumentList "/quiet /norestart /log $env:temp\net45.log"
"@
}
else {
$proc = Start-Process "$env:temp\net45.exe" -verb runas -argumentList "/quiet /norestart /log $env:temp\net45.log" -PassThru
while(!$proc.HasExited){ sleep -Seconds 1 }
}
}
}
function Get-HttpToFile ($url, $file){
Write-BoxstarterMessage "Downloading $url to $file" -Verbose
Invoke-RetriableScript -RetryScript {
if(Test-Path $args[1]){Remove-Item $args[1] -Force}
$downloader=new-object net.webclient
$wp=[system.net.WebProxy]::GetDefaultProxy()
$wp.UseDefaultCredentials=$true
$downloader.Proxy=$wp
try {
$downloader.DownloadFile($args[0], $args[1])
}
catch{
if($VerbosePreference -eq "Continue"){
Write-Error $($_.Exception | fl * -Force | Out-String)
}
throw $_
}
} $url $file
}
function Install-ChocolateyInstallPackageOverride {
param(
[string] $packageName,
[string] $fileType = 'exe',
[string] $silentArgs = '',
[string] $file,
$validExitCodes = @(0)
)
Wait-ForMSIEXEC
if(Get-IsRemote){
Invoke-FromTask @"
Import-Module $env:ChocolateyInstall\chocolateyinstall\helpers\chocolateyInstaller.psm1 -Global
Install-ChocolateyInstallPackage $(Expand-Splat $PSBoundParameters)
"@
}
else{
chocolateyInstaller\Install-ChocolateyInstallPackage @PSBoundParameters
}
}
function Write-HostOverride {
param(
[Parameter(Position=0,Mandatory=$false,ValueFromPipeline=$true, ValueFromRemainingArguments=$true)][object] $Object,
[Parameter()][switch] $NoNewLine,
[Parameter(Mandatory=$false)][ConsoleColor] $ForegroundColor,
[Parameter(Mandatory=$false)][ConsoleColor] $BackgroundColor,
[Parameter(Mandatory=$false)][Object] $Separator
)
if($Boxstarter.ScriptToCall -ne $null) { Log-BoxStarterMessage $object }
if($Boxstarter.SuppressLogging){
$caller = (Get-Variable MyInvocation -Scope 1).Value.MyCommand.Name
if("Describe","Context","write-PesterResult" -contains $caller) {
Microsoft.PowerShell.Utility\Write-Host @PSBoundParameters
}
return;
}
if(get-Module chocolateyInstaller){
chocolateyInstaller\Write-Host @PSBoundParameters
}
else {
Microsoft.PowerShell.Utility\Write-Host @PSBoundParameters
}
}
new-alias Install-ChocolateyInstallPackage Install-ChocolateyInstallPackageOverride -force
new-alias Write-Host Write-HostOverride -force
function cinst {
<#
.SYNOPSIS
Intercepts Chocolatey call to check for reboots
#>
param([int[]][email protected]())
chocolatey Install @PSBoundParameters
}
function choco {
<#
.SYNOPSIS
Intercepts Chocolatey call to check for reboots
#>
param([int[]][email protected]())
chocolatey @PSBoundParameters
}
function cup {
<#
.SYNOPSIS
Intercepts Chocolatey call to check for reboots
#>
param([int[]][email protected]())
chocolatey Update @PSBoundParameters
}
function cinstm {
<#
.SYNOPSIS
Intercepts Chocolatey call to check for reboots
#>
param([int[]][email protected]())
chocolatey InstallMissing @PSBoundParameters
}
function chocolatey {
<#
.SYNOPSIS
Intercepts Chocolatey call to check for reboots
#>
param([int[]][email protected]())
$RebootCodes=Add-DefaultRebootCodes $RebootCodes
$PSBoundParameters.Remove("RebootCodes") | Out-Null
$packageNames=-split $packageNames
Write-BoxstarterMessage "Installing $($packageNames.Count) packages" -Verbose
#backwards compatibility for Chocolatey versions prior to 0.9.8.21
if(!$packageNames){$packageNames=$packageName}
foreach($packageName in $packageNames){
$PSBoundParameters.packageNames = $packageName
if($source -eq "WindowsFeatures"){
$dismInfo=(DISM /Online /Get-FeatureInfo /FeatureName:$packageName)
if($dismInfo -contains "State : Enabled" -or $dismInfo -contains "State : Enable Pending") {
Write-BoxstarterMessage "$packageName is already installed"
return
}
else{
$winFeature=$true
}
}
if(((Test-PendingReboot) -or $Boxstarter.IsRebooting) -and $Boxstarter.RebootOk) {return Invoke-Reboot}
$session=Start-TimedSection "Calling Chocolatey to install $packageName. This may take several minutes to complete..."
try {
if($winFeature -eq $true -and (Get-IsRemote)){
#DISM Output is more confusing than helpful.
$currentLogging=$Boxstarter.Suppresslogging
if($VerbosePreference -eq "SilentlyContinue"){$Boxstarter.Suppresslogging=$true}
Invoke-FromTask @"
."$env:ChocolateyInstall\chocolateyinstall\chocolatey.ps1" $(Expand-Splat $PSBoundParameters)
"@
$Boxstarter.SuppressLogging = $currentLogging
}
else{
Call-Chocolatey @PSBoundParameters
Write-BoxstarterMessage "Exit Code: $LastExitCode" -Verbose
if($LastExitCode -ne 0) {
Write-Error "Chocolatey reported an unsuccessful exit code of $LastExitCode"
}
}
}
catch {
Write-BoxstarterMessage "There was an error calling chocolatey" -Verbose
$ex=$_
Log-BoxstarterMessage $_
#Only write the error to the error stream if it was not previously
#written by chocolatey
if($global:error.Count -gt 1){
if(($global:error[1].Exception.Message | Out-String).Contains($_.Exception.Message)){
$errorWritten=$true
}
}
if(!$errorWritten){
Write-Error $_
}
}
Stop-Timedsection $session
if(!$Boxstarter.rebootOk) {continue}
if($Boxstarter.IsRebooting){
Remove-ChocolateyPackageInProgress $packageName
return
}
if($global:error.count -gt 0) {
if ($ex -ne $null -and ($ex -match "code was '(-?\d+)'")) {
$errorCode=$matches[1]
if($RebootCodes -contains $errorCode) {
Write-BoxstarterMessage "Chocolatey Install returned a reboot-able exit code"
Remove-ChocolateyPackageInProgress $packageName
Invoke-Reboot
}
}
}
}
}
function Call-Chocolatey {
if($PSBoundParameters.Keys -notcontains "Source"){
$PSBoundParameters.Source = "$($Boxstarter.LocalRepo);$((Get-BoxstarterConfig).NugetSources)"
}
."$env:ChocolateyInstall\chocolateyinstall\chocolatey.ps1" @PSBoundParameters
}
function Intercept-Command {
param(
$commandName,
$targetCommand = "$env:ChocolateyInstall\chocolateyinstall\chocolatey.ps1",
[switch]$omitCommandParam
)
$metadata=Get-MetaData $targetCommand
$srcMetadata=Get-MetaData $commandName
if($commandName.Split("\").Length -eq 2){
$commandName = $commandName.Substring($commandName.IndexOf("\")+1)
}
$metadata.Parameters.Remove("Verbose") | out-null
$metadata.Parameters.Remove("Debug") | out-null
$metadata.Parameters.Remove("ErrorAction") | out-null
$metadata.Parameters.Remove("WarningAction") | out-null
$metadata.Parameters.Remove("ErrorVariable") | out-null
$metadata.Parameters.Remove("WarningVariable") | out-null
$metadata.Parameters.Remove("OutVariable") | out-null
$metadata.Parameters.Remove("OutBuffer") | out-null
if($omitCommandParam) {
$metadata.Parameters.Remove("command") | out-null
}
$params = [Management.Automation.ProxyCommand]::GetParamBlock($metadata)
if($srcMetadata.Parameters.count -gt 0) {
$srcParams = [Management.Automation.ProxyCommand]::GetParamBlock($srcMetadata)
$params += ",`r`n" + $srcParams
}
$cmdLetBinding = [Management.Automation.ProxyCommand]::GetCmdletBindingAttribute($metadata)
$strContent = (Get-Content function:\$commandName).ToString()
if($strContent -match "param\(.+\)") {
$strContent = $strContent.Replace($matches[0],"")
}
Set-Item Function:\$commandName -value "$cmdLetBinding `r`n param ( $params )Process{ `r`n$strContent}" -force
}
function Get-MetaData ($command){
$cmdDef = Get-Command $command | ? {$_.CommandType -ne "Application"}
return New-Object System.Management.Automation.CommandMetaData ($cmdDef)
}
function Intercept-Chocolatey {
if($Script:BoxstarterIntrercepting){return}
Intercept-Command cinst -omitCommandParam
Intercept-Command cup -omitCommandParam
Intercept-Command cinstm -omitCommandParam
Intercept-Command chocolatey
Intercept-Command choco
Intercept-Command call-chocolatey
$Script:BoxstarterIntrercepting=$true
}
function Add-DefaultRebootCodes($codes) {
if($codes -eq $null){[email protected]()}
$codes += 3010 #common MSI reboot needed code
$codes += -2067919934 #returned by SQL Server when it needs a reboot
return $codes
}
function Remove-ChocolateyPackageInProgress($packageName) {
$pkgDir = (dir $env:ChocolateyInstall\lib\$packageName.*)
if($pkgDir.length -gt 0) {$pkgDir = $pkgDir[-1]}
if($pkgDir -ne $null) {
remove-item $pkgDir -Recurse -Force -ErrorAction SilentlyContinue
}
}
function Expand-Splat($splat){
$ret=""
ForEach($item in $splat.KEYS.GetEnumerator()) {
$ret += "-$item$(Resolve-SplatValue $splat[$item]) "
}
return $ret
}
function Resolve-SplatValue($val){
if($val -is [switch]){
if($val.IsPresent){
return ":`$True"
}
else{
return ":`$False"
}
}
if($val -is [Array]){
$ret=" @("
$firstVal=$False
foreach($arrayVal in $val){
if($firstVal){$ret+=","}
if($arrayVal -is [int]){
$ret += "$arrayVal"
}
else{
$ret += "`"$arrayVal`""
}
$firstVal=$true
}
$ret += ")"
return $ret
}
$ret = " `"$($val.Replace('"','`' + '"'))`""
return $ret
}
function Wait-ForMSIEXEC{
Do{
Get-Process | ? {$_.Name -eq "MSIEXEC"} | % {
if(!($_.HasExited)){
$proc=Get-WmiObject -Class Win32_Process -Filter "ProcessID=$($_.Id)"
if($proc.CommandLine -ne $null -and $proc.CommandLine.EndsWith(" /V")){ break }
Write-BoxstarterMessage "Another installer is running: $($proc.CommandLine). Waiting for it to complete..."
$_.WaitForExit()
}
}
} Until ((Get-Process | ? {$_.Name -eq "MSIEXEC"} ) -eq $null)
}
TOPIC
About_Boxstarter_Chocolatey
SYNOPSIS
Describes how to use Boxstarter's Chocolatey module to setup a new
environment with your favorite Chocolatey packages.
DESCRIPTION
Boxstarter's Chocolatey module compliments the Boxstarter Bootstrap
module by augmenting its unattended script execution environment
with Chocolatey goodness making it easy to setup a new box with
Chocolatey packages.
Installing Chocolatey
Boxstarter will check to ensure if Chocolatey is installed. If
Chocolatey is not installed it will install it before running any
Chocolatey commands. Boxstarter will also check to see if the .Net
4.5 Framework is installed before installing Chocolatey since the
.Net 4 runtime is a prerequisite.
Chocolatey Boxstarter Packages
When calling Install-BoxstarterPackage or just Boxstarter, a
Package name must be passed to the command. This is a
special Chocolatey package provided by the user that boxstarter asks
Chocolatey to install and it contains the script that is intended to
install all the applications and settings the user wants setup on the
target machine.
This package script has access to all of the Chocolatey helper
functions as well as all Boxstarter logging, WinConfig and
Bootstrapper commands. See About_Boxstarter_Bootstrapper and
About_Boxstarter_Logging for information regarding those comands.
This can also be a script file containing the chocolatey install
script. If the package name provided is a URL or resolves to a file.
Then it is assumed that this contains the chocolatey install
script and a .nupkg file will be created using the script.
Creating Packages
Boxstarter provides some functions to make creation and deployment of
packages easy. Use New-BoxstarterPackage to either create a skeleton
package with a minimal nuspec and ChocolateyInstall.ps1 or to import an
existing package into boxstarter. This will put the package source files
in $($Boxstarter.LocalRepo)\<package name>. To pack these source files
use Invoke-BoxstarterBuild <package name>. You may also pack all
package in your repo with Invoke-BoxstarterBuild -all. If you would like
to make your local repo a network share, use Set-BoxstarterShare.
Consuming Boxstarter Packages
The primary gateway to kicking off a Boxstarter.Chocolatey installation
session is Install-BoxstarterPackage. While you may use this
powershell function, you can also call Boxstarter.bat which takes the
exact same parameters as Invoke-CocolateyBoxstarter. If you installed
Boxstarter.Chocolatey via Chocolatey or the setup.bat installer,
boxstarter.bat is placed in your path. Boxstarter.bat will import the
Boxstarter.Chocolatey module and create a powershell session bypassing
ExecutionPolicy. Boxstarter.bat is ideal for calling Boxstarter
remotely. Simply share the Boxstarter base directory and you can access
it via \\serverName\Boxstarter\Boxstarter.bat.
Package Sources
Install-BoxstarterPackage (or Boxstarter) expects just the name of the
bootstrapping package - just like CINST or Nuget. Boxstarter will search
the following locations in this order:
- $Boxstarter.LocalRepo: This is the local repository that by default is
in the BuildPackages directory in the Boxstarter Base Boxstarter Module
directory ($Boxstarter.BaseDir). You can change the default by using the
Set-BoxstarterConfig function with the -LocalRepo argument.
- Chocolatey.org: The public chocolatey feed at http://chocolatey.org/api/v2
- Myget: The Boxstarter Community Feed at http://www.myget.org/F/boxstarter/api/v2
The last two remote sources can be configured by editing
$($Boxstarter.BaseDir)\Boxstarter.Config.
Running Boxstarter Remotely
When using the Computername, ConnectionURI or Session parameters of
Install-BoxstarterPackage, Boxstarter will attempt to install the package
the the remote maching it is directed at. Boxstarter will check to ensure
that all necessary client side Powershell Remoting settings are correctly
configured. If they are not, Boxstarter will prompt to confirm whether it
should enable them unless the -Force parameter is used. The -Force
parameter will suppress prompts. As part of this configuration, Boxstarter
will enable CredSSP authentication to ensure that any network connection
that the package may try to establish will pass the users credentials.
Boxstarter will also attempt to enable Powershell remoting on the target
machine if it is not already installed. Boxstarter can only do this if the
WMI firewall ports are open on the target computer. If they are not and
powershell remoting is not enabled on the target machine, the installation
will fail. Users can easily enable powershell remoting manually on the
target machine by opening an administrative powershell console on the remote
computer and then issuing 'Enable-PSRemoting -Force'.
Reboot detection
Perhaps the most compelling feature of Boxstarter is its way to handle
reboots during an involved environment setup package. Especially when
you are running patches, installing services and downloading complex
applications. Boxstarter intercepts all calls to Chocolatey install
commands and checks for pending reboots prior to calling Chocolatey. If
a pending reboot exists, Boxstarter reboots the machine and automatically
logs on with the credentials you provided providing an unattended
installation session. After the Chocolatey package completes, if the
package fails and returns the common MSI reboot needed exit code of
3010, Boxstarter will reboot which will likely cause the package to
succeed on the next run. See about_boxstarter_bootstrapper for more
details about the rebooting logic and how you can disable or manually
invoke them.
Package Authoring Considerations
Boxstarter can run any Chocolatey package and any valid powershell
inside that package. However, there are a few things to consider
that may make a Boxstarter Chocolatey package a better installation
experience.
- Boxstarter Chocolatey packages should be repeatable. This is
especially true if you anticipate the need to reboot. When Boxstarter
reboots, it starts running the package from the beginning. So ensure
that there is nothing that would cause the package to break if run
twice.
- If you have several Chocolatey packages that you want to install
during the Boxstarter session, it is preferable to call CINST
directly from inside your ChocolateyInstall instead of declaring
them as dependencies. This is because Boxstarter cannot intercept
Chocolatey dependencies so those packages will not have any reboot
protections.
SEE ALSO
http://boxstarter.org
Install-BoxstarterPackage
Invoke-ChocolateyBoxstarter
about_boxstarter_logging
Invoke-Boxstarter
Invoke-Reboot
New-BoxstarterPackage
Invoke-BoxstarterBuild
Set-BoxstarterShare
about_boxstarter_variable_in_bootstrapper
about_boxstarter_logging
about_boxstarter_variable_in_chocolatey
Set-BoxstarterConfig
TOPIC
About_Boxstarter_Variable_In_Chocolatey
SYNOPSIS
A Hashtable for persisting Boxstarter settings.
DESCRIPTION
The Boxstarter variable is a hashtable that is globaly accesible.
Different Boxstarter modules may store different settings.
Some of the Chocolatey module settings available from the
Boxstarter variable can also be set from the
Invoke-ChocolateyBoxstarter Command.
BOXSTARTER VARIABLE SETTINGS
ProgramFiles86
Unless the environment has been specilly conficured, this
points to the 'Program Files' folder in the system drive on
x86 machines and the 'Program Files (x86)' folder in the
system drive on 64 bit machines.
ChocolateyBin
This points to the path of the chocolatey bin directory which
by default is c:\chocolatey\bin.
Package
The name of the bootstrapper package running in Boxstarter.
LocalRepo
Path to the local directory containing packages that
boxstarter will scan when looking for a package. By default
this is the BuildPackeged directory under the base Boxstarter
directory usually in the user's AppData directory. The
default can be changed by using the Set-BoxstarterConfig
function with the -LocalRepo argument.
NugetSources
The Nuget feeds that Boxstarter checks for the Boxstarter
Bootstrap package. By default this is the chocolatey and
Myget Boxstarter community feed. This can be changed by
using the Set-BoxstarterConfig function with the -NugetSources
argument.
SEE ALSO
http://boxstarter.org
About_Boxstarter_Variable_In_Bootstrapper
Invoke-ChocolateyBoxstarter
Set-BoxstarterConfig
function Enable-BoxstarterClientRemoting {
<#
.SYNOPSIS
Enables and configures PowerShell remoting from the client
.DESCRIPTION
Enable-BoxstarterClientRemoting will check if PowerShell Remoting is enabled on the local
machine. If not, it will enable it and it will also add all remote hosts to trust to the
WSMAN trusted hosts list. The original trusted host list will be returned. When running
Install-BoxstarterPackage, Boxstarter will roll back to the original trusted hosts when
the package install is complete.
.PARAMETER RemoteHostsToTrust
A list of ComputerNames to add to the WSMAN Trusted hosts list.
.OUTPUTS
A list of the original trusted hosts on the local machine as well as a bool indicating
if PowerShell Remoting was successfully completed.
.EXAMPLE
Enable-BoxstarterClientRemoting box1,box2
.LINK
http://boxstarter.org
Install-BoxstarterPackage
#>
param(
[string[]] $RemoteHostsToTrust
)
if(Test-Admin) { $elevated = $true }
[email protected]{
Success=$False;
PreviousTrustedHosts=$null;
}
Write-BoxstarterMessage "Configuring local PowerShell Remoting settings..."
if(!(Get-Command Test-WSMan -ErrorAction SilentlyContinue)) {
#I have only seen this on VisualStudio.Com Hosted build servers
$Result.Success=$True
return $Result
}
try { $wsman = Test-WSMan -ErrorAction Stop } catch { $credssp = $_}
if($credssp.Exception -ne $null){
Write-BoxstarterMessage "Local PowerShell Remoting is not enabled" -Verbose
Write-BoxstarterMessage "Error returned $($credssp.ToString())" -Verbose
if($elevated -and ($Force -or (Confirm-Choice "PowerShell remoting is not enabled locally. Should Boxstarter enable PowerShell remoting?")))
{
Write-BoxstarterMessage "Enabling PowerShell Remoting on local machine"
[email protected]{Force=$true}
$command=Get-Command Enable-PSRemoting
if($command.Parameters.Keys -contains "skipnetworkprofilecheck"){
$enableArgs.skipnetworkprofilecheck=$true
}
Enable-PSRemoting @enableArgs | Out-Null
}else {
Write-BoxstarterMessage "Not enabling local PowerShell Remoting aborting package install"
return $Result
}
}
$newHosts = @()
$Result.PreviousTrustedHosts=(Get-Item "wsman:\localhost\client\trustedhosts").Value
$hostArray=$Result.PreviousTrustedHosts.Split(",")
if($hostArray -contains "*") {
$Result.PreviousTrustedHosts = $null
}
else {
$RemoteHostsToTrust | ? { $hostArray -NotContains $_ } | % { $newHosts += $_ }
if($newHosts.Count -gt 0) {
$strNewHosts = $newHosts -join ","
if($Result.PreviousTrustedHosts.Length -gt 0){
$strNewHosts = $Result.PreviousTrustedHosts + "," + $strNewHosts
}
Write-BoxstarterMessage "Adding $strNewHosts to allowed wsman hosts" -Verbose
Set-Item "wsman:\localhost\client\trustedhosts" -Value $strNewHosts -Force
}
}
$Result.Success=$True
return $Result
}
function Enable-BoxstarterCredSSP {
<#
.SYNOPSIS
Enables and configures CredSSP Authentication to be used in PowerShell remoting sessions
.DESCRIPTION
Enabling CredSSP allows a caller from one remote session to authenticate on other remote
resources. This is known as credential delegation. By default, PowerShell sessions do not
use credSSP and therefore cannot bake a "second hop" to use other remote resources that
require their authentication token.
Enable-BoxstarterCredSSP allows remote boxstarter installs to use credential delegation
in the case where one might keep some resources on another remote machine that need to be
installed into their current remote session.
This command will enable CredSSP and add all RemoteHostsToTrust to the CredSSP trusted
hosts list. It will also edit the users group policy to allow Fresh Credential Delegation.
.PARAMETER RemoteHostsToTrust
A list of ComputerNames to add to the CredSSP Trusted hosts list.
.OUTPUTS
A list of the original trusted hosts on the local machine.
.EXAMPLE
Enable-BoxstarterCredSSP box1,box2
.LINK
http://boxstarter.org
Install-BoxstarterPackage
#>
param(
[string[]] $RemoteHostsToTrust
)
[email protected]{
Success=$False;
PreviousCSSPTrustedHosts=$null;
PreviousFreshCredDelegationHostCount=0
}
if(!(Test-Admin)) {
return $result
}
Write-BoxstarterMessage "Configuring CredSSP settings..."
$credssp = Get-WSManCredSSP
$ComputersToAdd = @()
$idxHosts=$credssp[0].IndexOf(": ")
if($idxHosts -gt -1){
$credsspEnabled=$True
$Result.PreviousCSSPTrustedHosts=$credssp[0].substring($idxHosts+2)
$hostArray=$Result.PreviousCSSPTrustedHosts.Split(",")
$RemoteHostsToTrust | ? { $hostArray -notcontains "wsman/$_" } | % { $ComputersToAdd += $_ }
}
else {
$ComputersToAdd = $RemoteHostsToTrust
}
if($ComputersToAdd.Count -gt 0){
Write-BoxstarterMessage "Adding $($ComputersToAdd -join ',') to allowed credSSP hosts" -Verbose
try {
Enable-WSManCredSSP -DelegateComputer $ComputersToAdd -Role Client -Force -ErrorAction Stop | Out-Null
}
catch {
Write-BoxstarterMessage "Enable-WSManCredSSP failed with: $_" -Verbose
return $result
}
}
$key = Get-CredentialDelegationKey
if (!(Test-Path "$key\CredentialsDelegation")) {
New-Item $key -Name CredentialsDelegation | Out-Null
}
$key = Join-Path $key "CredentialsDelegation"
New-ItemProperty -Path "$key" -Name "ConcatenateDefaults_AllowFresh" -Value 1 -PropertyType Dword -Force | Out-Null
New-ItemProperty -Path "$key" -Name "ConcatenateDefaults_AllowFreshNTLMOnly" -Value 1 -PropertyType Dword -Force | Out-Null
$result.PreviousFreshNTLMCredDelegationHostCount = Set-CredentialDelegation $key 'AllowFreshCredentialsWhenNTLMOnly' $RemoteHostsToTrust
$result.PreviousFreshCredDelegationHostCount = Set-CredentialDelegation $key 'AllowFreshCredentials' $RemoteHostsToTrust
$Result.Success=$True
return $Result
}
function Set-CredentialDelegation($key, $subKey, $allowed){
New-ItemProperty -Path "$key" -Name $subKey -Value 1 -PropertyType Dword -Force | Out-Null
$policyNode = Join-Path $key $subKey
if (!(Test-Path $policyNode)) {
md $policyNode | Out-Null
}
[email protected]()
(Get-Item $policyNode).Property | % {
$currentHostProps += (Get-ItemProperty -Path $policyNode -Name $_).($_)
}
$currentLength = $currentHostProps.Length
$idx=$currentLength
$allowed | ? { $currentHostProps -notcontains "wsman/$_"} | % {
++$idx
New-ItemProperty -Path $policyNode -Name "$idx" -Value "wsman/$_" -PropertyType String -Force | Out-Null
}
return $currentLength
}
function Get-CredentialDelegationKey {
return "HKLM:\SOFTWARE\Policies\Microsoft\Windows"
}
function Enable-RemotePsRemoting {
##############################################################################
##
## Enable-RemotePsRemoting
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################
<#
.SYNOPSIS
Enables PowerShell Remoting on a remote computer. Requires that the machine
responds to WMI requests, and that its operating system is Windows Vista or
later.
.EXAMPLE
Enable-RemotePsRemoting <Computer>
#>
param(
## The computer on which to enable remoting
$Computername,
## The credential to use when connecting
[Management.Automation.PsCredential]$Credential
)
$credential = Get-Credential $credential
$username = $credential.Username
$password = $credential.GetNetworkCredential().Password
$script = @"
`$log = Join-Path `$env:TEMP Enable-RemotePsRemoting.output.txt
Remove-Item -Force `$log -ErrorAction SilentlyContinue
Start-Transcript -Path `$log
if(!(1,3,4,5 -contains (Get-WmiObject win32_computersystem).DomainRole)) {
`$networkListManager = [Activator]::CreateInstance([Type]::GetTypeFromCLSID([Guid]'{DCB00C01-570F-4A9B-8D69-199FDBA5723B}'))
`$connections = `$networkListManager.GetNetworkConnections()
`$connections | % {`$_.GetNetwork().SetCategory(1)}
}
## Create a task that will run with full network privileges.
## In this task, we call Enable-PsRemoting
schtasks /CREATE /TN 'Temp Enable Remoting' /SC WEEKLY /RL HIGHEST ``
/RU $username /RP "$password" ``
/TR "powershell -noprofile -command Enable-PsRemoting -Force | Out-File (Join-Path `$env:TEMP Enable-PSRemoting.txt)" /F |
Out-String
##Give task a normal priority
`$taskFile = Join-Path `$env:TEMP RemotingTask.txt
[xml]`$xml = schtasks /QUERY /TN 'Temp Enable Remoting' /XML
`$xml.Task.Settings.Priority="4"
`$xml.Save(`$taskFile)
schtasks /CREATE /TN 'Enable Remoting' /RU $username /RP "$password" /XML "`$taskFile" /F | Out-String
schtasks /DELETE /TN 'Temp Enable Remoting' /F | Out-String
schtasks /RUN /TN 'Enable Remoting' | Out-String
`$securePass = ConvertTo-SecureString "$password" -AsPlainText -Force
`$credential =
New-Object Management.Automation.PsCredential $username,`$securepass
## Wait for the remoting changes to come into effect
for(`$count = 1; `$count -le 10; `$count++)
{
`$output = Invoke-Command localhost { 1 } -Cred `$credential ``
-ErrorAction SilentlyContinue
if(`$output -eq 1) { break; }
"Attempt `$count : Not ready yet."
Sleep 5
}
## Delete the temporary task
schtasks /DELETE /TN 'Enable Remoting' /F | Out-String
Stop-Transcript
"@
$commandBytes = [System.Text.Encoding]::Unicode.GetBytes($script)
$encoded = [Convert]::ToBase64String($commandBytes)
Write-BoxstarterMessage "Configuring $computername" -Verbose
$command = "powershell -NoProfile -EncodedCommand $encoded"
$null = Invoke-WmiMethod -Computer $computername -Credential $credential `
Win32_Process Create -Args $command
Sleep 10
Write-BoxstarterMessage "Testing connection" -Verbose
for($count = 1; $count -le 100; $count++) {
$wmiResult = Invoke-Command $computername {
Get-WmiObject Win32_ComputerSystem } -Credential $credential -ErrorAction SilentlyContinue
if($wmiResult -ne $Null){
Write-BoxstarterMessage "PowerShell Remoting enabled successfully"
break
}
else {
Write-BoxstarterMessage "Attempt $count failed." -Verbose
}
if($global:Error.Count -gt 0){
Write-BoxstarterMessage "$($global:Error[0])" -Verbose
$global:Error.RemoveAt(0)
}
}
}
function Get-BoxStarterConfig {
<#
.SYNOPSIS
Retrieves persisted Boxstarter configuration settings.
.DESCRIPTION
Boxstarter stores configuration data in an xml file in the Boxstarter base
directory. The Get-BoxstarterConfig function is a convenience function
for reading those settings.
.LINK
http://boxstarter.org
about_boxstarter_chocolatey
about_boxstarter_variable_in_chocolatey
Set-BoxstarterConfig
#>
[xml]$configXml = Get-Content (Join-Path $Boxstarter.BaseDir BoxStarter.config)
if($configXml.config.LocalRepo -ne $null){
$localRepo=$configXml.config.LocalRepo
}
else {
if($Boxstarter.baseDir){
$localRepo=(Join-Path $Boxstarter.baseDir BuildPackages)
}
}
return @{
LocalRepo=$localRepo;
NugetSources=$configXml.config.NugetSources;
ChocolateyRepo=$configXml.config.ChocolateyRepo;
ChocolateyPackage=$configXml.config.ChocolateyPackage
}
}
function Get-PackageRoot{
<#
.SYNOPSIS
Returns the Root path of a Boxstarter Package given the Chocolatey $MyInvocation
.DESCRIPTION
This function is intended to be called from inside a running
ChocolateyInstall.ps1 file. It returns the root path of the package
which is one level above the Tools directory. This can be helpful
when you need to reference any files that you copied to your
Boxstarter Repository which copies them to this location using
New-BoxstarterPackage.
.PARAMETER Invocation
This is $MyInvocation instance accessible from ChocolateyInstall.ps1
.EXAMPLE
Copy-Item "$env:programfiles\Sublime Text 2\Data\*" Package\Sublime -recurse
New_BoxstarterPackage MyPackage .\Package
#Edit install script
Notepad $($Boxstarter.LocalRepo)\MyPackage\Tools\chocolateyInstall.ps1
Invoke-BoxstarterBuild MyPackage
Invoke-ChocolateyBoxstarter MyPackage
--ChocolateyInstall.ps1--
try {
cinst sublimetext2
$sublimeDir = "$env:programfiles\Sublime Text 2"
mkdir "$sublimeDir\data"
copy-item (Join-Path Get-PackageRoot($MyInvocation) 'sublime\*') "$sublimeDir\data" -Force -Recurse
Write-ChocolateySuccess 'MyPackage'
} catch {
Write-ChocolateyFailure 'MyPackage' $($_.Exception.Message)
throw
}
.NOTES
Get-PackageRoot is intended to be called from ChocolateyInstall.ps1
and will throw if it is called from another file.
.LINK
http://boxstarter.org
about_boxstarter_chocolatey
New_BoxstarterPackage
Invoke-ChocolateyBoxstarter
Invoke-BoxstarterBuild
#>
param(
[Parameter(Mandatory=$true)]
[System.Management.Automation.InvocationInfo]$invocation
)
if($invocation.MyCommand.Definition -eq $null -or !($invocation.MyCommand.Definition.ToLower().EndsWith("tools\chocolateyinstall.ps1"))){
throw "Get-PackageRoot can only be used inside of chocolateyinstall.ps1. You Tried to call it from $($invocation.MyCommand.Definition)"
}
return (Split-Path -parent(Split-Path -parent $invocation.MyCommand.Definition))
}
$config = Get-BoxstarterConfig
if(!$BoxStarter.LocalRepo){
$BoxStarter.LocalRepo=$config.LocalRepo
}
$Boxstarter.NugetSources=$config.NugetSources
$Boxstarter.RebootOk=$true
function Install-BoxstarterPackage {
<#
.SYNOPSIS
Installs a Boxstarter package
.DESCRIPTION
This function wraps a Chocolatey Install and provides these additional features
- Installs chocolatey if it is not already installed
- Installs the .net 4.5 framework if it is not installed which is a chocolatey requirement
- Disables windows update service during installation to prevent installation conflicts and minimize the need for reboots
- Imports the Boxstarter.WinConfig module that provides functions for customizing windows
- Detects pending reboots and restarts the machine when necessary to avoid installation failures
- Provides Reboot Resiliency by ensuring the package installation is immediately restarted up on reboot if there is a reboot during the installation.
- Ensures Installation runs under administrator permissions
- Supports remote installations allowing packages to be installed on a remote machine
The .nupkg file for the provided package name is searched in the following locations and order:
- .\BuildPackages relative to the parent directory of the module file
- The Chocolatey feed
- The Boxstarter feed on MyGet
This can be configured by editing $($Boxstarter.BaseDir)\Boxstarter.Config
If the package name provided is a URL or resolves to a file, then
it is assumed that this contains the chocolatey install script and
a .nupkg file will be created using the script.
Boxstarter can install packages onto a remote machine. To accomplish this,
use either the ComputerName, Session or ConnectionURI parameters. Boxstarter uses
PowerShell remoting to establish an interactive session on the remote computer.
Boxstarter configures all the necessary client side remoting settings necessary if
they are not already configured. Boxstarter will prompt the user to verify that
this is OK. Using the -Force switch will suppress the prompt. Boxstarter also ensures
that CredSSP authentication is enabled so that any network calls made by a package will
forward the users credentials.
PowerShell Remoting must be enabled on the target machine in order to establish a connection.
If that machine's WMI ports are accessible, Boxstarter can enable PowerShell remoting
on the remote machine on its own. Otherwise, it can be manually enabled by entering
Enable-PSRemoting -Force
In an administrative PowerShell console on the remote machine.
.PARAMETER ComputerName
If provided, Boxstarter will install the specified package name on all computers.
Boxstarter will create a Remote Session on each computer using the Credentials
given in the Credential parameter.
.PARAMETER ConnectionURI
Specifies one or more Uniform Resource Identifiers (URI) that Boxstarter will use
to establish a connection with the remote computers upon which the package should
be installed. Use this parameter if you need to use a non default PORT or SSL.
.PARAMETER Session
If provided, Boxstarter will install the specified package in all given Windows
PowerShell sessions. Note that these sessions may be closed by the time
Install-BoxstarterPackage finishes. If Boxstarter needs to restart the remote
computer, the session will be discarded and a new session will be created using
the ConnectionURI of the original session.
.PARAMETER BoxstarterConnectionConfig
If provided, Boxstarter will install the specified package name on all computers
included in the BoxstarterConnectionConfig. This object contains a ComputerName
and a PSCredential. Use this object if you need to pass different computers
requiring different credentials.
.PARAMETER PackageName
The names of one or more Nuget Packages to be installed or URIs or
file paths pointing to a chocolatey script. If using package names,
the .nupkg file for the provided package names are searched in the
following locations and order:
- .\BuildPackages relative to the parent directory of the module file
- The Chocolatey feed
- The Boxstarter feed on MyGet
.PARAMETER DisableReboots
If set, reboots are suppressed.
.PARAMETER Credential
The credentials to use for auto logins after reboots. If installing on
a remote machine, this credential will also be used to establish the
connection to the remote machine and also for any scheduled task that
boxstarter needs to create and run under a local context.
.PARAMETER KeepWindowOpen
Enabling this switch will prevent the command window from closing and
prompt the user to pres the Enter key before the window closes. This
is ideal when not invoking boxstarter from a console.
.Parameter LocalRepo
This is the path to the local boxstarter repository where boxstarter
should look for .nupkg files to install. By default this is located
in the BuildPackages directory just under the root Boxstarter
directory but can be changed with Set-BoxstarterConfig.
.NOTES
If specifying only one package, Boxstarter calls chocolatey with the
-force argument and deletes the previously installed package directory.
This means that regardless of whether or not the package had been
installed previously, Boxstarter will attempt to download and reinstall it.
This only holds true for the outer package. If the package contains calls
to CINST for additional packages, those installs will not reinstall if
previously installed.
If an array of package names are passed to Install-BoxstarterPackage,
Boxstarter will NOT apply the above reinstall logic and will skip the
install for any package that had been previously installed.
When establishing a remote connection, Boxstarter uses CredSSP
authentication so that the session can access any network resources
normally accessible to the Credential. If necessary, Boxstarter
configures CredSSP authentication on both the local and remote
machines as well as the necessary Group Policy and WSMan settings
for credential delegation. When the installation completes,
Boxstarter rolls back all settings that it changed to their original
state.
If Boxstarter is not running in an elevated console, it will not attempt
to enable CredSSP locally if it is not already enabled. It will also not
try to enable PowerShell remoting if not running as administrator.
When using a Windows PowerShell session instead of ComputerName or
ConnectionURI, Boxstarter will use the authentication mechanism of the
existing session and will not configure CredSSP if the session provided
is not using CredSSP. If the session is not using CredSSP, it may be
denied access to network resources normally accessible to the Credential
being used. If you do need to access network resources external to the
session, you should use CredSSP when establishing the connection.
.INPUTS
ComputerName, ConnrectionURI and Session may all be specified on the
pipeline.
.OUTPUTS
Returns a PSObject for each session, ComputerName or ConnectionURI or a
single PSObject for local installations. The PSObject has the following
properties:
ComputerName: The name of the computer where the package was installed
StartTime: The time that the installation began
FinishTime: The time that Boxstarter finished the installation
Completed: True or False indicating if Boxstarter was able to complete
the installation without a terminating exception interrupting the install.
Even if this value is True, it does not mean that all components installed
in the package succeeded. Boxstarter will not terminate an installation if
individual Chocolatey packages fail. Use the Errors property to discover
errors that were raised throughout the installation.
Errors: An array of all errors encountered during the duration of the
installation.
.EXAMPLE
Invoke-ChocolateyBoxstarter "example1","example2"
This installs the example1 and example2 .nupkg files. If pending
reboots are detected, boxstarter will restart the machine. Boxstarter
will not perform automatic logins after restart since no Credential
was given.
.EXAMPLE
$cred=Get-Credential mwrock
Install-BoxstarterPackage -Package https://gist.github.com/mwrock/6771863/raw/b579aa269c791a53ee1481ad01711b60090db1e2/gistfile1.txt `
-Credential $cred
This installs the script uploaded to the github gist. The credentials
of the user mwrock are used to automatically login the user if
boxstarter needs to reboot the machine.
.EXAMPLE
$cred=Get-Credential mwrock
Install-BoxstarterPackage -ComputerName MyOtherComputer.mydomain.com -Package MyPackage -Credential $cred
This installs the MyPackage package on MyOtherComputer.mydomain.com.
.EXAMPLE
$cred=Get-Credential mwrock
$session=New-PSSession SomeComputer -Credential $cred
Install-BoxstarterPackage -Session $session -Package MyPackage -Credential $cred
This installs the MyPackage package on an existing session established with
SomeComputer. A Credential is still passed to Boxstarter even though it is
also used to establish the session because Boxstarter will need it for logons
and creating Scheduled Tasks on SomeComputer. If Boxstarter does need to
reboot SomeComputer, it will need to create a new session after SomeComputer
has rebooted and then $session will no longer be in an Available state when
Install-BoxstarterPackage completes.
.EXAMPLE
$cred=Get-Credential mwrock
Install-BoxstarterPackage -ConnectionURI http://RemoteComputer:59876/wsman -Package MyPackage -Credential $cred
This installs the MyPackage package on RemoteComputer which does not
listen on the default wsman port but has been configured to listen
on port 59876.
.EXAMPLE
$cred=Get-Credential mwrock
Install-BoxstarterPackage -ComputerName MyOtherComputer.mydomain.com -Package MyPackage -Credential $cred -Force
This installs the MyPackage package on MyOtherComputer.mydomain.com.
Because the -Force parameter is used, Boxstarter will not prompt the
user to confirm that it is OK to enable PowerShell remoting if it is
not already enabled. It will attempt to enable it without prompts.
.EXAMPLE
$cred=Get-Credential mwrock
"computer1","computer2" | Install-BoxstarterPackage -Package MyPackage -Credential $cred -Force
This installs the MyPackage package on computer1 and computer2
Because the -Force parameter is used, Boxstarter will not prompt the
user to confirm that it is OK to enable PowerShell remoting if it is
not already enabled. It will attempt to enable it without prompts.
Using -Force is especially advisable when installing packages on multiple
computers because otherwise, if one computer is not accessible, the command
will prompt the user if it is OK to try and configure the computer before
proceeding to the other computers.
.EXAMPLE
$cred1=Get-Credential mwrock
$cred2=Get-Credential domain\mwrock
(New-Object -TypeName BoxstarterConnectionConfig -ArgumentList "computer1",$cred1), `
(New-Object -TypeName BoxstarterConnectionConfig -ArgumentList "computer2",$cred2) |
Install-BoxstarterPackage -Package MyPackage
This installs the MyPackage package on computer1 and computer2 and uses
different credentials for each computer.
.EXAMPLE
$cred=Get-Credential mwrock
Install-BoxstarterPackage script.ps1 -Credential $cred
This installs the script located at script.ps1
in the command line's current directory.
.EXAMPLE
$cred=Get-Credential mwrock
Install-BoxstarterPackage \\server\share\script.ps1 -Credential $cred
This invokes boxstarter and installs the script located at the
specified share.
.EXAMPLE
$cred=Get-Credential mwrock
Install-BoxstarterPackage win8Install -LocalRepo \\server\share\boxstarter -Credential $cred
This installs the Win8Install .nupkg. Boxstarter will look
for the Win8Install .nupkg file in the \\serer\share\boxstarter
directory.
.LINK
http://boxstarter.org
about_boxstarter_chocolatey
#>
[CmdletBinding(DefaultParameterSetName="Package")]
param(
[parameter(Mandatory=$true, Position=0, ValueFromPipeline=$True, ParameterSetName="BoxstarterConnectionConfig")]
[BoxstarterConnectionConfig[]]$BoxstarterConnectionConfig,
[parameter(Mandatory=$true, Position=0, ValueFromPipeline=$True, ParameterSetName="ComputerName")]
[string[]]$ComputerName,
[parameter(Mandatory=$true, Position=0, ValueFromPipeline=$True, ParameterSetName="ConnectionUri")]
[Uri[]]$ConnectionUri,
[parameter(Mandatory=$true, Position=0, ValueFromPipeline=$True, ParameterSetName="Session")]
[System.Management.Automation.Runspaces.PSSession[]]$Session,
[parameter(Mandatory=$true, Position=0, ParameterSetName="Package")]
[parameter(Mandatory=$true, Position=1, ParameterSetName="ComputerName")]
[parameter(Mandatory=$true, Position=1, ParameterSetName="ConnectionUri")]
[parameter(Mandatory=$true, Position=1, ParameterSetName="Session")]
[parameter(Mandatory=$true, Position=1, ParameterSetName="BoxstarterConnectionConfig")]
[string[]]$PackageName,
[Management.Automation.PsCredential]$Credential,
[switch]$Force,
[switch]$DisableReboots,
[parameter(ParameterSetName="Package")]
[switch]$KeepWindowOpen,
[string]$LocalRepo,
[switch]$DisableRestart
)
$CurrentVerbosity=$global:VerbosePreference
try {
if($PSBoundParameters["Verbose"] -eq $true) {
$global:VerbosePreference="Continue"
}
#If no PSRemoting based param's are present, we just run locally
if($PsCmdlet.ParameterSetName -eq "Package"){
Invoke-Locally @PSBoundParameters
return
}
#me me me!
Write-BoxstarterLogo
#Convert pipeline to array
[email protected]($input)
if($list.Count){
Set-Variable -Name $PsCmdlet.ParameterSetName -Value $list
}
[email protected]{}
if($Credential){
$sessionArgs.Credential=$Credential
}
#If $sessions are being provided we assume remoting is setup on both ends
#and don't need to test, configure and tear down
if($Session -ne $null){
Process-Sessions $Session $sessionArgs
return
}
#We need the computer names to configure remoting
if(!$ComputerName){
if($BoxstarterConnectionConfig){
$uris = $BoxstarterConnectionConfig | % { $_.ConnectionURI }
}
else{
$uris = $ConnectionUri
}
$ComputerName = Get-ComputerNames $uris
}
try{
#Enable remoting settings if necessary on client
$ClientRemotingStatus=Enable-BoxstarterClientRemoting $ComputerName
#If unable to enable remoting on the client, abort
if(!$ClientRemotingStatus.Success){return}
$CredSSPStatus=Enable-BoxstarterCredSSP $ComputerName
if($ConnectionURI){
$ConnectionUri | %{
$sessionArgs.ConnectionURI = $_
Write-BoxstarterMessage "Installing $packageName on $($_.ToString())"
Install-BoxstarterPackageOnComputer $_.Host $sessionArgs $PackageName $DisableReboots $CredSSPStatus
}
}
elseif($BoxstarterConnectionConfig) {
$BoxstarterConnectionConfig | %{
$sessionArgs.ConnectionURI = $_.ConnectionURI
if($_.Credential){
$sessionArgs.Credential = $_.Credential
}
if($_.PSSessionOption){
$sessionArgs.SessionOption = $_.PSSessionOption
}
Install-BoxstarterPackageOnComputer $_.ConnectionURI.Host $sessionArgs $PackageName $DisableReboots $CredSSPStatus $false
}
}
else {
$ComputerName | %{
$sessionArgs.ComputerName = $_
Install-BoxstarterPackageOnComputer $_ $sessionArgs $PackageName $DisableReboots $CredSSPStatus
}
}
}
finally{
#Client settings should be as they were when we started
Rollback-ClientRemoting $ClientRemotingStatus $CredSSPStatus
}
}
finally{
$global:VerbosePreference=$CurrentVerbosity
}
}
function Get-ComputerNames([URI[]]$ConnectionUris) {
$computerNames = @()
Write-BoxstarterMessage "resolving URIs to computer names..." -Verbose
$ConnectionUris | %{
if($_ -eq $null) {
Write-BoxstarterMessage "Tried to resolve Null URI" -Verbose
}
else {
Write-BoxstarterMessage "$($_ -is [uri]) found $($_.Host) for $($_.ToString())" -Verbose
$computerNames+=$_.Host
}
}
return $computerNames
}
function Process-Sessions($sessions, $sessionArgs){
$Sessions | %{
Write-BoxstarterMessage "Processing Session..." -Verbose
Set-SessionArgs $_ $sessionArgs
$record = Start-Record $_.ComputerName
try {
if(-not (Install-BoxstarterPackageForSession $_ $PackageName $DisableReboots $sessionArgs)){
$record.Completed=$false
}
}
catch {
$record.Completed=$false
}
finally{
Finish-Record $record
}
}
}
function Start-Record($computerName) {
$global:error.Clear()
$props = @{
StartTime = Get-Date
Completed = $true
ComputerName = $computerName
Errors = @()
FinishTime = $null
}
return (New-Object PSObject -Prop $props)
}
function Finish-Record($obj) {
Write-BoxstarterMessage "Composing record for pipeline..." -Verbose
$obj.FinishTime = Get-Date
$global:error | %{
if($_.CategoryInfo -ne $null -and $_.CategoryInfo.Category -eq "OperationStopped"){
Log-BoxstarterMessage $_
}
else {
$obj.Errors += $_
}
}
Write-BoxstarterMessage "writing object..." -Verbose
Write-Output $obj
Write-BoxstarterMessage "object written..." -Verbose
}
function Install-BoxstarterPackageOnComputer ($ComputerName, $sessionArgs, $PackageName, $DisableReboots, $CredSSPStatus, $TestRemoting = $true){
$record = Start-Record $ComputerName
try {
if($TestRemoting -and !(Enable-RemotingOnRemote $sessionArgs $ComputerName)){
Write-Error "Unable to access remote computer via PowerShell Remoting or WMI. You can enable it by running: Enable-PSRemoting -Force from an Administrator PowerShell console on the remote computer."
$record.Completed=$false
return
}
if($CredSSPStatus.Success){
$enableCredSSP = Should-EnableCredSSP $sessionArgs $computerName
}
write-BoxstarterMessage "Creating a new session with $computerName..." -Verbose
$session = New-PSSession @sessionArgs -Name Boxstarter
if(-not (Install-BoxstarterPackageForSession $session $PackageName $DisableReboots $sessionArgs $enableCredSSP)){
$record.Completed=$false
}
}
catch {
$record.Completed=$false
Write-Error $_
}
finally{
Finish-Record $record
}
}
function Install-BoxstarterPackageForSession($session, $PackageName, $DisableReboots, $sessionArgs, $enableCredSSP) {
try{
if($session.Availability -ne "Available"){
write-Error (New-Object -TypeName ArgumentException -ArgumentList "The Session is not Available")
return $false
}
for($count = 1; $count -le 5; $count++) {
try {
Write-BoxstarterMessage "Attempt #$count to copy Boxstarter modules to $($session.ComputerName)" -Verbose
Setup-BoxstarterModuleAndLocalRepo $session
break
}
catch {
if($global:Error.Count -gt 0){$global:Error.RemoveAt(0)}
if($count -eq 5) { throw $_ }
}
}
if($enableCredSSP){
$credSSPSession = Enable-RemoteCredSSP $sessionArgs
if($session -ne $null -and $credSSPSession -ne $null){
Write-BoxstarterMessage "CredSSP session succeeded. Replacing sessions..."
Remove-PSSession $session -ErrorAction SilentlyContinue
$session=$credSSPSession
}
}
Invoke-Remotely $session $PackageName $DisableReboots $sessionArgs
return $true
}
finally {
Write-BoxstarterMessage "checking if session should be removed..." -Verbose
if($session -ne $null -and $session.Name -eq "Boxstarter") {
Write-BoxstarterMessage "Removing session..." -Verbose
Remove-PSSession $Session
Write-BoxstarterMessage "Session removed..." -Verbose
$Session = $null
}
if($sessionArgs.Authentication){
$sessionArgs.Remove("Authentication")
}
if($enableCredSSP){
Disable-RemoteCredSSP $sessionArgs
}
}
}
function Invoke-Locally {
param(
[string[]]$PackageName,
[Management.Automation.PsCredential]$Credential,
[switch]$Force,
[switch]$DisableReboots,
[switch]$KeepWindowOpen,
[switch]$DisableRestart
)
if($PSBoundParameters.ContainsKey("Credential")){
if($Credential -ne $null) {
$PSBoundParameters.Add("Password",$PSBoundParameters["Credential"].Password)
}
$PSBoundParameters.Remove("Credential") | out-Null
}
else {
$PSBoundParameters.Add("NoPassword",$True)
}
if($PSBoundParameters.ContainsKey("Force")){
$PSBoundParameters.Remove("Force") | out-Null
}
$PSBoundParameters.Add("BootstrapPackage", $PSBoundParameters.PackageName)
$PSBoundParameters.Remove("PackageName") | out-Null
$record = Start-Record 'localhost'
try {
Invoke-ChocolateyBoxstarter @PSBoundParameters | Out-Null
}
catch {
$record.Completed=$false
throw
}
finally{
Finish-Record $record
}
}
function Enable-RemotingOnRemote ($sessionArgs, $ComputerName){
Write-BoxstarterMessage "Testing remoting access on $ComputerName..."
try {
$remotingTest = Invoke-Command @sessionArgs { Get-WmiObject Win32_ComputerSystem } -ErrorAction Stop
}
catch {
Write-BoxstarterMessage $_.ToString() -Verbose
$sessionArgs.Keys | % {
Write-BoxstarterMessage "session arg key: $_ has value $($sessionArgs[$_])" -Verbose
}
Write-BoxstarterMessage "using credential username $($sessionArgs.Credential.UserName)" -Verbose
$global:error.RemoveAt(0)
}
if($remotingTest -eq $null){
Write-BoxstarterMessage "PowerShell Remoting is not enabled or accessible on $ComputerName" -Verbose
if(Test-Admin) {
$wmiTest=Invoke-WmiMethod -ComputerName $ComputerName -Credential $sessionArgs.Credential Win32_Process Create -Args "cmd.exe" -ErrorAction SilentlyContinue
}
if($wmiTest -eq $null){
if($global:Error.Count -gt 0){ $global:Error.RemoveAt(0) }
return $false
}
if($Force -or (Confirm-Choice "PowerShell Remoting is not enabled on Remote computer. Should Boxstarter enable PowerShell remoting? This will also change the Network Location type on the remote machine to PRIVATE if it is currently PUBLIC.")){
Write-BoxstarterMessage "Enabling PowerShell Remoting on $ComputerName"
Enable-RemotePSRemoting $ComputerName $sessionArgs.Credential
}
else {
Write-BoxstarterMessage "Not enabling local PowerShell Remoting on $ComputerName. Aborting package install"
return $False
}
}
else {
Write-BoxstarterMessage "Remoting is accessible on $ComputerName"
}
return $True
}
function Setup-BoxstarterModuleAndLocalRepo($session){
if($LocalRepo){$Boxstarter.LocalRepo=$LocalRepo}
Write-BoxstarterMessage "Copying Boxstarter Modules and LocalRepo packages at $($Boxstarter.BaseDir) to $env:temp on $($Session.ComputerName)..."
Invoke-Command -Session $Session { mkdir $env:temp\boxstarter\BuildPackages -Force | out-Null }
Send-File "$($Boxstarter.BaseDir)\Boxstarter.Chocolatey\Boxstarter.zip" "Boxstarter\boxstarter.zip" $session
Get-ChildItem "$($Boxstarter.LocalRepo)\*.nupkg" | % {
Write-BoxstarterMessage "Copying $($_.Name) to $($Session.ComputerName)" -Verbose
Send-File "$($_.FullName)" "Boxstarter\BuildPackages\$($_.Name)" $session
}
Invoke-Command -Session $Session {
Set-ExecutionPolicy Bypass -Force
$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace("$env:temp\Boxstarter\Boxstarter.zip")
$destinationFolder = $shellApplication.NameSpace("$env:temp\boxstarter")
$destinationFolder.CopyHere($zipPackage.Items(),0x10)
[xml]$configXml = Get-Content (Join-Path $env:temp\Boxstarter BoxStarter.config)
if($configXml.config.LocalRepo -ne $null) {
$configXml.config.RemoveChild(($configXml.config.ChildNodes | ? { $_.Name -eq "LocalRepo"}))
$configXml.Save((Join-Path $env:temp\Boxstarter BoxStarter.config))
}
Import-Module $env:temp\Boxstarter\Boxstarter.Chocolatey\Boxstarter.Chocolatey.psd1
}
}
function Invoke-RemoteBoxstarter($Package, $Password, $DisableReboots, $session) {
Write-BoxstarterMessage "Running remote install..."
$remoteResult = Invoke-Command -session $session {
param($SuppressLogging,$pkg,$password,$DisableReboots, $verbosity, $ProgressArgs)
$global:VerbosePreference=$verbosity
Import-Module $env:temp\Boxstarter\Boxstarter.Chocolatey\Boxstarter.Chocolatey.psd1
$Boxstarter.SuppressLogging=$SuppressLogging
$global:Boxstarter.ProgressArgs=$ProgressArgs
$result=$null
try {
$result = Invoke-ChocolateyBoxstarter $pkg -Password $password -DisableReboots:$DisableReboots
if($Boxstarter.IsRebooting){
return @{Result="Rebooting"}
}
if($result=$true){
return @{Result="Completed"}
}
}
catch{
throw $_
}
} -ArgumentList $Boxstarter.SuppressLogging, $Package, $Password, $DisableReboots, $global:VerbosePreference, $global:Boxstarter.ProgressArgs
Write-BoxstarterMessage "Result from Remote Boxstarter: $($remoteResult.Result)" -Verbose
return $remoteResult
}
function Test-RebootingOrDisconnected($RemoteResult) {
if($remoteResult -eq $null -or $remoteResult.Result -eq $null -or $remoteResult.Result -eq "Rebooting") {
return $true
}
else {
return $false
}
}
function Wait-ForSessionToClose($session) {
Write-BoxstarterMessage "Waiting for $($session.ComputerName) to sever remote session..."
$timeout=0
while($session.State -eq "Opened" -and $timeout -lt 120){
$timeout += 2
start-sleep -seconds 2
}
}
function Test-ShutDownInProgress($Session) {
$response=Invoke-Command -Session $Session {
$systemMetrics = Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public static class SystemMetrics
{
private const int SM_SHUTTINGDOWN = 0x2000;
[DllImport("user32.dll")]
public static extern int GetSystemMetrics(int smIndex);
public static bool IsShuttingdown()
{
return (GetSystemMetrics(SM_SHUTTINGDOWN) != 0);
}
}
"@ -PassThru
return $systemMetrics::IsShuttingdown()
}
if($response -eq $false) {
Write-BoxstarterMessage "System Shutdown not in progress" -Verbose
}
else {
Write-BoxstarterMessage "System Shutdown in progress" -Verbose
}
return $response
}
function Test-Reconnection($Session, $sessionPID) {
$reconnected = $false
#If there is a pending reboot then session is in the middle of a restart
$response=Invoke-Command -Session $session {
Import-Module $env:temp\Boxstarter\Boxstarter.Chocolatey\Boxstarter.Chocolatey.psd1
return Test-PendingReboot
} -ErrorAction SilentlyContinue
Write-BoxstarterMessage "Reboot check returned $response" -Verbose
if($response -ne $null -and $response -eq $false){
#Check for a system shutdown in progress
$response = Test-ShutDownInProgress $session
if($response -eq $false) {
$reconnected = $true #Session is connectible
try{
#In case previous session's task is still alive kill it so it does not lock anything
Write-BoxstarterMessage "Killing $sessionPID" -Verbose
Invoke-Command -Session $session {
param($p)
if(Get-Process -Id $p -ErrorAction SilentlyContinue){
KILL $p -ErrorAction Stop -Force
}
else {
$global:Error.RemoveAt(0)
}
} -ArgumentList $sessionPID
} catch{
Write-BoxstarterMessage "Failed to kill $sessionPID : $($global:Error[0])" -Verbose
$global:Error.RemoveAt(0)
}
}
}
#if the session is pending a reboot but not in the middle of a system shutdown,
#try to invoke a reboot to prevent us from hanging while waiting
elseif($response -eq $true -and !(Test-ShutDownInProgress $session)){
Write-BoxstarterMessage "Attempting to restart $($session.ComputerName)" -Verbose
Invoke-Command -Session $session {
Import-Module $env:temp\Boxstarter\Boxstarter.Chocolatey\Boxstarter.Chocolatey.psd1
$Boxstarter.RebootOK=$true
if(Test-PendingReboot){restart-Computer -Force }
} -ErrorAction SilentlyContinue
}
return $reconnected
}
function Invoke-Remotely($session,$Package,$DisableReboots,$sessionArgs){
Write-BoxstarterMessage "Invoking remote install" -verbose
while($session.Availability -eq "Available") {
$sessionPID = Invoke-Command -Session $session { return $PID }
Write-BoxstarterMessage "Session's process ID is $sessionPID" -verbose
$remoteResult = Invoke-RemoteBoxstarter $Package $sessionArgs.Credential.Password $DisableReboots $session
if(Test-RebootingOrDisconnected $remoteResult) {
Wait-ForSessionToClose $session
$reconnected=$false
Write-BoxstarterMessage "Waiting for $($session.ComputerName) to respond to remoting..."
Do{
if($session -ne $null){
Remove-PSSession $session
$session = $null
}
$response=$null
start-sleep -seconds 2
$session = New-PSSession @sessionArgs -Name Boxstarter -ErrorAction SilentlyContinue
if($session -eq $null) {
$global:Error.RemoveAt(0)
}
elseif($session -ne $null -and $Session.Availability -eq "Available"){
if($remoteResult.Result -eq "Rebooting"){$sessionPID=-1}
$reconnected = Test-Reconnection $session $sessionPID
}
}
Until($reconnected -eq $true)
}
else {
break
}
}
}
function Set-SessionArgs($session, $sessionArgs) {
$uri = try { Invoke-Command $session {return $PSSenderInfo.ConnectionString} -ErrorAction SilentlyContinue } catch{}
if($uri){
$sessionArgs.ConnectionURI=$uri
}
else{
$sessionArgs.ComputerName=$session.ComputerName
}
}
function Should-EnableCredSSP($sessionArgs, $computerName) {
Write-BoxstarterMessage "Testing remote CredSSP..." -Verbose
if($sessionArgs.Credential){
[email protected]{}
if($sessionArgs.ConnectionURI){
$uri = [URI]$sessionArgs.ConnectionURI
$uriArgs = @{Port=$uri.port;UseSSL=($uri.scheme -eq "https")}
}
try {
$credsspEnabled = Test-WsMan -ComputerName $ComputerName @uriArgs -Credential $SessionArgs.Credential -Authentication CredSSP -ErrorAction SilentlyContinue
}
catch {
Write-BoxstarterMessage "Exception from testing WSMan for CredSSP access" -Verbose
try { $xml=[xml]$_ } catch { $global:Error.RemoveAt(0) }
if($xml -ne $null) {
Write-BoxstarterMessage "WSMan Fault Found" -Verbose
Write-BoxstarterMessage "$($xml.OuterXml)" -Verbose
}
else {
Write-BoxstarterMessage $_ -Verbose
}
}
if($credsspEnabled -eq $null){
Write-BoxstarterMessage "Need to enable CredSSP on server" -Verbose
if($global:Error.Count -gt 0){ $global:Error.RemoveAt(0) }
return $True
}
else{
Write-BoxstarterMessage "CredSSP test response:" -Verbose
[System.Xml.XmlElement]$xml=$credsspEnabled
if($xml -ne $null) {
Write-BoxstarterMessage "WSMan XML Found..." -Verbose
Write-BoxstarterMessage "$($xml.OuterXml)" -Verbose
}
$sessionArgs.Authentication="CredSSP"
}
}
Write-BoxstarterMessage "Do not need to enable CredSSP on server" -Verbose
return $false
}
function Enable-RemoteCredSSP($sessionArgs) {
Write-BoxstarterMessage "Creating a scheduled task to enable CredSSP Authentication on $ComputerName..."
$n=Invoke-RetriableScript {
$splat=$args[0]
Invoke-Command @splat {
param($Credential)
Import-Module $env:temp\Boxstarter\Boxstarter.Common\Boxstarter.Common.psd1 -DisableNameChecking
Create-BoxstarterTask $Credential
Invoke-FromTask "Enable-WSManCredSSP -Role Server -Force | out-Null"
Remove-BoxstarterTask
} -ArgumentList $args[0].Credential
} $sessionArgs
$sessionArgs.Authentication="CredSSP"
Write-BoxstarterMessage "Creating New session with CredSSP Authentication..." -Verbose
try {
$session = Invoke-RetriableScript {
$splat=$args[0]
$s = New-PSSession @splat -Name Boxstarter -ErrorAction Stop
return $s
} $sessionArgs
}
catch {
$sessionArgs.Remove("Authentication")
$session=$null
Write-BoxstarterMessage "Unable to create CredSSP session. Error was: $($_.ToString())" -Verbose
$global:error.RemoveAt(0)
}
return $session
}
function Disable-RemoteCredSSP ($sessionArgs){
Write-BoxstarterMessage "Disabling CredSSP Authentication on $ComputerName" -Verbose
Invoke-Command @sessionArgs {
param($Credential, $verbosity)
$Global:VerbosePreference = $verbosity
Import-Module $env:temp\Boxstarter\Boxstarter.Common\Boxstarter.Common.psd1 -DisableNameChecking
Create-BoxstarterTask $Credential
$taskResult = Invoke-FromTask "Disable-WSManCredSSP -Role Server"
Write-BoxstarterMessage "result from disabling CredSSP is: $taskResult" -Verbose
Remove-BoxstarterTask
} -ArgumentList $sessionArgs.Credential, $Global:VerbosePreference
Write-BoxstarterMessage "Finished disabling CredSSP Authentication on $ComputerName" -Verbose
}
function Rollback-ClientRemoting($ClientRemotingStatus, $CredSSPStatus) {
Write-BoxstarterMessage "Rolling back remoting settings changed by Boxstarter..."
if($ClientRemotingStatus.PreviousTrustedHosts -ne $null){
$currentHosts=Get-Item "wsman:\localhost\client\trustedhosts"
if($currentHosts.Value -ne $ClientRemotingStatus.PreviousTrustedHosts) {
Write-BoxstarterMessage "Reseting wsman Trusted Hosts to $($ClientRemotingStatus.PreviousTrustedHosts)" -Verbose
Set-Item "wsman:\localhost\client\trustedhosts" -Value "$($ClientRemotingStatus.PreviousTrustedHosts)" -Force
}
}
if($CredSSPStatus -ne $null -and $CredSSPStatus.Success){
try {Disable-WSManCredSSP -Role Client -ErrorAction SilentlyContinue } catch{ Write-BoxstarterMessage "Unable to disable CredSSP locally" }
if($CredSSPStatus.PreviousCSSPTrustedHosts -ne $null){
try{
Write-BoxstarterMessage "Reseting CredSSP Trusted Hosts to $($CredSSPStatus.PreviousCSSPTrustedHosts.Replace('wsman/',''))" -Verbose
Enable-WSManCredSSP -DelegateComputer $CredSSPStatus.PreviousCSSPTrustedHosts.Replace("wsman/","") -Role Client -Force | Out-Null
}
catch{}
}
Write-BoxstarterMessage "Reseting GroupPolicy for Credentials Delegation" -Verbose
if(Test-Path "$(Get-CredentialDelegationKey)\CredentialsDelegation\AllowFreshCredentialsWhenNTLMOnly") {
(Get-Item "$(Get-CredentialDelegationKey)\CredentialsDelegation\AllowFreshCredentialsWhenNTLMOnly").Property | % {
if([int]$_ -gt $CredSSPStatus["PreviousFreshNTLMCredDelegationHostCount"]) {
Remove-ItemProperty "$(Get-CredentialDelegationKey)\CredentialsDelegation\AllowFreshCredentialsWhenNTLMOnly" -Name $_
}
}
}
if(Test-Path "$(Get-CredentialDelegationKey)\CredentialsDelegation\AllowFreshCredentials") {
(Get-Item "$(Get-CredentialDelegationKey)\CredentialsDelegation\AllowFreshCredentials").Property | % {
if([int]$_ -gt $CredSSPStatus["PreviousFreshCredDelegationHostCount"]) {
Remove-ItemProperty "$(Get-CredentialDelegationKey)\CredentialsDelegation\AllowFreshCredentials" -Name $_
}
}
}
}
}
function Invoke-BoxStarterBuild {
<#
.SYNOPSIS
Packs a specific package or all packages in the Boxstarter Repository
.DESCRIPTION
Invoke-BoxStarterBuild packs either a single package or all packages
in the local repository. The packed .nupkg is placed in the root of
the LocalRepo and is then able to be consumed by
Invoke-ChocolateyBoxstarter.
.PARAMETER Name
The name of the package to pack
.PARAMETER All
Indicates that all package directories in the repository should be packed
.LINK
http://boxstarter.org
about_boxstarter_chocolatey
Invoke-BoxstarterBuild
New-BoxstarterPackage
#>
[CmdletBinding()]
param(
[Parameter(Position=0,ParameterSetName='name')]
[string]$name,
[Parameter(Position=0,ParameterSetName='all')]
[switch]$all,
[switch]$quiet
)
Check-Chocolatey
$choco="$env:ChocolateyInstall\chocolateyinstall\chocolatey.ps1"
if(!$boxstarter -or !$boxstarter.LocalRepo){
throw "No Local Repository has been set in `$Boxstarter.LocalRepo."
}
pushd $Boxstarter.LocalRepo
try{
if($name){
$searchPath = join-path $name "$name.nuspec"
Write-BoxstarterMessage "Searching for $searchPath" -Verbose
if(!(Test-Path $searchPath)){
throw "Cannot find $($Boxstarter.LocalRepo)\$searchPath"
}
.$choco Pack (join-path $name "$name.nuspec") | out-null
if(!$quiet){
Write-BoxstarterMessage "Your package has been built. Using Boxstarter.bat $name or Install-BoxstarterPackage $name will run this package." -nologo
}
} else {
if($all){
Write-BoxstarterMessage "Scanning $($Boxstarter.LocalRepo) for package folders"
Get-ChildItem . | ? { $_.PSIsContainer } | % {
$directoriesExist=$true
Write-BoxstarterMessage "Found directory $($_.name). Looking for $($_.name).nuspec"
if(Test-Path (join-path $_.name "$($_.name).nuspec")){
.$choco Pack (join-path . "$($_.Name)\$($_.Name).nuspec") | out-null
if(!$quiet){
Write-BoxstarterMessage "Your package has been built. Using Boxstarter.bat $($_.Name) or Install-BoxstarterPackage $($_.Name) will run this package." -nologo
}
}
}
if($directoriesExist -eq $null){
Write-BoxstarterMessage "No Directories exist under $($boxstarter.LocalRepo)"
}
}
}
}
finally {
popd
}
}
function Invoke-ChocolateyBoxstarter{
<#
.SYNOPSIS
Invokes the installation of a Boxstarter package
.DESCRIPTION
This essentially wraps Chocolatey Install and provides these additional features
- Installs chocolatey if it is not already installed
- Installs the .net 4.5 framework if it is not installed which is a chocolatey requirement
- Disables windows update service during installation to prevent installation conflicts and minimize the need for reboots
- Imports the Boxstarter.WinConfig module that provides functions for customizing windows
- Detects pending reboots and restarts the machine when necessary to avoid installation failures
- Provides Reboot Resiliency by ensuring the package installation is immediately restarted up on reboot if there is a reboot during the installation.
- Ensures everything runs under administrator permissions
The .nupkg file for the provided package name is searched in the following locations and order:
- .\BuildPackages relative to the parent directory of the module file
- The Chocolatey feed
- The Boxstarter feed on MyGet
This can be configured by editing $($Boxstarter.BaseDir)\Boxstarter.Config
If the package name provided is a URL or resolves to a file. Then
it is assumed that this contains the chocolatey install script and
a .nupkg file will be created using the script.
.PARAMETER BootstrapPackage
The names of one or more Nuget Packages to be installed or URIs or
file paths pointing to a chocolatey script. If using package names,
the .nupkg file for the provided package names are searched in the
following locations and order:
- .\BuildPackages relative to the parent directory of the module file
- The Chocolatey feed
- The Boxstarter feed on MyGet
.Parameter LocalRepo
This is the path to the local boxstarter repository where boxstarter
should look for .nupkg files to install. By default this is located
in the BuildPackages directory just under the root Boxstarter
directory but can be changed with Set-BoxstarterConfig.
.PARAMETER DisableReboots
If set, reboots are suppressed.
.PARAMETER Password
User's password as a Secure string to be used for reboot autologon's.
This will suppress the password prompt at the beginning of the
Boxstarter installer.
.PARAMETER KeepWindowOpen
Enabling this switch will prevent the command window from closing and
prompt the user to pres the Enter key before the window closes. This
is ideal when not invoking boxstarter from a console.
.PARAMETER NoPassword
When set, Boxstarter will never prompt for logon. Use this if using
an account without password validation.
.NOTES
If specifying only one package, Boxstarter calls chocolatey with the
-force argument and deletes the previously installed package directory.
This means that regardless of whether or not the package had been
installed previously, Boxstarter will attempt to download and reinstall it.
This only holds true for the outer package. If the package contains calls
to CINST for additional packages, those installs will not reinstall if
previously installed.
If an array of package names are passed to Invoke-ChocolateyBoxstarter,
Boxstarter will NOT apply the above reinstall logic and will skip the
install for any package that had been previously installed.
.EXAMPLE
Invoke-ChocolateyBoxstarter "example1","example2"
This invokes boxstarter and installs the example1 and example2 .nupkg
files. If pending reboots are detected, boxstarter will restart the
machine. Boxstarter will prompt the user to enter a password which will
be used for automatic logins in the event a restart is required.
.EXAMPLE
Invoke-ChocolateyBoxstarter https://gist.github.com/mwrock/6771863/raw/b579aa269c791a53ee1481ad01711b60090db1e2/gistfile1.txt
This invokes boxstarter and installs the script uploaded to the github gist.
.EXAMPLE
Invoke-ChocolateyBoxstarter script.ps1
This invokes boxstarter and installs the script located at script.ps1
in the command line's current directory.
.EXAMPLE
Invoke-ChocolateyBoxstarter \\server\share\script.ps1
This invokes boxstarter and installs the script located at the
specified share.
.EXAMPLE
Invoke-ChocolateyBoxstarter win8Install -LocalRepo \\server\share\boxstarter
This installs the Win8Install .nupkg and specifies that it is OK to
reboot the machine if a pending reboot is needed. Boxstarter will look
for the Win8Install .nupkg file in the \\serer\share\boxstarter
directory.
.EXAMPLE
Invoke-ChocolateyBoxstarter example -Password (ConvertTo-SecureString "mypassword" -AsPlainText -Force)
This installs the example package and uses "mypassword" for any reboot
autologon's. The user is now not prompted for a password.
.LINK
http://boxstarter.org
about_boxstarter_chocolatey
about_boxstarter_variable_in_chocolatey
Set-BoxstarterConfig
#>
[CmdletBinding()]
param(
[string[]]$BootstrapPackage=$null,
[string]$LocalRepo,
[switch]$DisableReboots,
[System.Security.SecureString]$Password,
[switch]$KeepWindowOpen,
[switch]$NoPassword,
[switch]$DisableRestart
)
try{
if($DisableReboots){
Write-BoxstarterMessage "Disabling reboots" -Verbose
$Boxstarter.RebootOk=$false
}
if($Boxstarter.ScriptToCall -eq $null){
if($bootstrapPackage -ne $null -and $bootstrapPackage.length -gt 0){
write-BoxstarterMessage "Installing package $($bootstrapPackage -join ', ')" -Color Cyan
}
else{
write-BoxstarterMessage "Installing Chocolatey" -Color Cyan
}
[email protected]{}
if($bootstrapPackage){$scriptArgs.bootstrapPackage=$bootstrapPackage}
if($LocalRepo){$scriptArgs.Localrepo=$localRepo}
if($DisableReboots){$scriptArgs.DisableReboots = $DisableReboots}
[email protected]"
Import-Module (Join-Path "$($Boxstarter.baseDir)" BoxStarter.Chocolatey\Boxstarter.Chocolatey.psd1) -global -DisableNameChecking;
Invoke-ChocolateyBoxstarter $(if($bootstrapPackage){"-bootstrapPackage '$($bootstrapPackage -join ''',''')'"}) $(if($LocalRepo){"-LocalRepo $localRepo"}) $(if($DisableReboots){"-DisableReboots"})
"@
return Invoke-Boxstarter ([ScriptBlock]::Create($script)) -RebootOk:$Boxstarter.RebootOk -password $password -KeepWindowOpen:$KeepWindowOpen -NoPassword:$NoPassword -DisableRestart:$DisableRestart
}
if(${env:ProgramFiles(x86)} -ne $null){ $programFiles86 = ${env:ProgramFiles(x86)} } else { $programFiles86 = $env:ProgramFiles }
$Boxstarter.ProgramFiles86="$programFiles86"
$Boxstarter.LocalRepo=Resolve-LocalRepo $localRepo
Check-Chocolatey -ShouldIntercept
del "$env:ChocolateyInstall\ChocolateyInstall\ChocolateyInstall.log" -ErrorAction SilentlyContinue
if($bootstrapPackage -ne $null){
Download-Package $bootstrapPackage
}
}
finally {
$Boxstarter.ScriptToCall = $null
}
}
function Resolve-LocalRepo([string]$localRepo) {
if($localRepo){
$localRepo = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($localRepo)
} else {$Localrepo = $Boxstarter.Localrepo}
write-BoxstarterMessage "LocalRepo is at $localRepo" -Verbose
return $localRepo
}
function Download-Package([string[]]$bootstrapPackage) {
$BootstrapPackage = $BootstrapPackage | % {
if($_ -like "*://*" -or (Test-Path $_ -PathType Leaf)){
New-PackageFromScript $_
}
else {
$_
}
}
$Boxstarter.Package=$bootstrapPackage
if($bootstrapPackage.Count -eq 1){
Write-BoxstarterMessage "Deleting previous $bootstrapPackage package" -Verbose
$chocoRoot = $env:ChocolateyInstall
if($chocoRoot -eq $null) {
$chocoRoot = "$env:programdata\chocolatey"
}
Write-BoxstarterMessage "Deleting $chocoRoot\lib\$bootstrapPackage.*" -verbose
del "$chocoRoot\lib\$bootstrapPackage.*" -recurse -force -ErrorAction SilentlyContinue
Write-BoxstarterMessage "Deleted $chocoRoot\lib\$bootstrapPackage.*" -verbose
$force=$true
}
$source = "$($Boxstarter.LocalRepo);$((Get-BoxstarterConfig).NugetSources)"
write-BoxstarterMessage "Installing $($bootstrapPackage.Count) packages from $source" -Verbose
Chocolatey install $bootstrapPackage -source $source -force:$force
}
function New-BoxstarterPackage {
<#
.SYNOPSIS
Creates a new Chocolatey package source directory intended for a Boxstarter Install
.DESCRIPTION
New-BoxstarterPackage creates a new Directory in your local
Boxstarter repository located at $Boxstarter.LocalRepo. If no path is
provided, Boxstarter creates a minimal nuspec and
ChocolateyInstall.ps1 file. If a path is provided, Boxstarter will
copy the contents of the path to the new package directory. If the
path does not include a nuspec or ChocolateyInstall.ps1, Boxstarter
will create one. You can use Invoke-BoxstarterBuild to pack the
repository directory to a Chocolatey nupkg. If your path includes
subdirectories, you can use Get-PackageRoot inside
ChocolateyInstall.ps1 to reference the parent directory of the copied
content.
.PARAMETER Name
The name of the package to create
.PARAMETER Description
Description of the package to be written to the nuspec
.PARAMETER Path
Optional path whose contents will be copied to the repository
.LINK
http://boxstarter.org
New-PackageFromScript
about_boxstarter_chocolatey
about_boxstarter_variable_in_chocolatey
Invoke-BoxstarterBuild
Get-PackageRoot
#>
[CmdletBinding()]
param(
[string]$Name,
[string]$description,
[string]$path,
[switch]$quiet
)
if(!$boxstarter -or !$boxstarter.LocalRepo){
throw "No Local Repository has been set in `$Boxstarter.LocalRepo."
}
Check-Chocolatey
$nugetExe = "$env:ChocolateyInstall\ChocolateyInstall\nuget.exe"
if(!($name -match "^\w+(?:[_.-]\w+)*$") -or ($name.length -gt 100)){
throw "Invalid Package ID"
}
$pkgDir = Join-Path $Boxstarter.LocalRepo $Name
if(test-path $pkgDir) {
throw "A LocalRepo already exists at $($boxstarter.LocalRepo)\$name. Delete the directory before calling New-BoxstarterPackage"
}
MkDir $pkgDir | out-null
Pushd $pkgDir
if($path){
if(!(test-path $Path)){
popd
throw "$path could not be found"
}
if(test-path "$Path\$Name.nuspec") {
Copy-Item "$path\*" . -recurse
}
else { Copy-Item $path . -recurse }
}
$pkgFile = Join-Path $pkgDir "$name.nuspec"
if(!(test-path $pkgFile)){
$nugetResult = .$nugetExe spec $Name -NonInteractive 2>&1
if($LASTEXITCODE -ne 0){
Throw "Nuspec creation failed with exit code $LASTEXITCODE and message: $nugetResult"
}
Write-BoxstarterMessage "Nuget.exe result: $nugetResult" -Verbose
Invoke-RetriableScript {
[xml]$xml = Get-Content $args[0]
$metadata = $xml.package.metadata
$nodesToDelete = @()
$nodesNamesToDelete = @("licenseUrl","projectUrl","iconUrl","requireLicenseAcceptance","releaseNotes", "copyright","dependencies")
$metadata.ChildNodes | ? { $nodesNamesToDelete -contains $_.Name } | % { $nodesToDelete += $_ }
$nodesToDelete | %{ $metadata.RemoveChild($_) } | out-null
if($args[1]){$metadata.Description=$args[1]}
$metadata.tags="Boxstarter"
$xml.Save($args[0])
} $pkgFile $description
}
if(!(test-path "tools")){
Mkdir "tools" | out-null
}
[email protected]"
try {
Write-ChocolateySuccess '$name'
} catch {
Write-ChocolateyFailure '$name' `$(`$_.Exception.Message)
throw
}
"@
if(!(test-path "tools\ChocolateyInstall.ps1")){
new-Item "tools\ChocolateyInstall.ps1" -type file -value $installScript| out-null
}
Popd
if(!$quiet){
Write-BoxstarterMessage "A new Chocolatey package has been created at $pkgDir." -nologo
Write-BoxstarterMessage "You may now edit the files in this package and build the final .nupkg using Invoke-BoxstarterBuild." -nologo
}
}
function New-PackageFromScript {
<#
.SYNOPSIS
Creates a Nuget package from a Chocolatey script
.DESCRIPTION
This creates a .nupkg file from a script file. It adds a dummy nuspec
and packs the nuspec and script to a nuget package saved to
$Boxstarter.LocalRepo. The function returns a string that is the
Package Name of the package.
.PARAMETER Source
Either a file path or URI pointing to a resource containing a script.
.PARAMETER PackageName
The name of the package. If not provided, this will be "temp_BoxstarterPackage"
.EXAMPLE
$packageName = New-PackageFromScript myScript.ps1
Creates a Package from the myScript.ps1 file in the current directory.
.EXAMPLE
$packageName = New-PackageFromScript myScript.ps1 MyPackage
Creates a Package named "MyPackage" from the myScript.ps1 file in the current directory.
.EXAMPLE
$packageName = New-PackageFromScript c:\path\myScript.ps1
Creates a Package from the myScript.ps1 file in c:\path\myScript.ps1.
.EXAMPLE
$packageName = New-PackageFromScript \\server\share\myScript.ps1
Creates a Package from the myScript.ps1 file the share at \\server\share\myScript.ps1.
.EXAMPLE
$packageName = New-PackageFromScript https://gist.github.com/mwrock/6771863/raw/b579aa269c791a53ee1481ad01711b60090db1e2/gistfile1.txt
Creates a Package from the gist located at
https://gist.github.com/mwrock/6771863/raw/b579aa269c791a53ee1481ad01711b60090db1e2/gistfile1.txt
.LINK
http://boxstarter.org
about_boxstarter_chocolatey
#>
[CmdletBinding()]
param (
[Parameter(Mandatory=1)]
[string] $Source,
[string] $PackageName="temp_BoxstarterPackage"
)
if(!(test-path function:\Get-WebFile)){
Check-Chocolatey
. "$env:ChocolateyInstall\chocolateyinstall\helpers\functions\Get-WebFile.ps1"
}
if($source -like "*://*"){
try {$text = Get-WebFile -url $Source -passthru } catch{
throw "Unable to retrieve script from $source `r`nInner Exception is:`r`n$_"
}
}
else {
if(!(Test-Path $source)){
throw "Path $source does not exist."
}
$text=Get-Content $source
}
if(Test-Path "$($boxstarter.LocalRepo)\$PackageName"){
Remove-Item "$($boxstarter.LocalRepo)\$PackageName" -recurse -force
}
New-BoxstarterPackage $PackageName -quiet
Set-Content "$($boxstarter.LocalRepo)\$PackageName\tools\ChocolateyInstall.ps1" -value $text
Invoke-BoxstarterBuild $PackageName -quiet
Write-BoxstarterMessage "Created a temporary package $PackageName from $source in $($boxstarter.LocalRepo)"
return $PackageName
}
function Resolve-VMPlugin {
[CmdletBinding()]
[OutputType([BoxstarterConnectionConfig])]
param(
$Provider
)
DynamicParam {
if($provider -eq $null -or $Provider.Length -eq 0){$provider="HyperV"}
$unNormalized=(Get-Item "$PSScriptRoot\..\Boxstarter.$provider\Boxstarter.$provider.psd1")
Import-Module $unNormalized.FullName -global -DisableNameChecking -Force -ErrorAction SilentlyContinue | Out-Null
$module=Get-Module "Boxstarter.$provider"
$command = Get-Command "$module\Enable-BoxstarterVM"
$metadata=New-Object System.Management.Automation.CommandMetaData($command)
$paramDictionary = new-object `
-Type System.Management.Automation.RuntimeDefinedParameterDictionary
$metadata.Parameters.Keys | % {
$param=$metadata.Parameters[$_]
$dynParam = new-object `
-Type System.Management.Automation.RuntimeDefinedParameter($param.Name, $param.ParameterType, $param.Attributes[1])
$paramDictionary.Add($param.Name, $dynParam)
}
return $paramDictionary
}
Process{
if($provider -eq $null -or $Provider.Length -eq 0){$provider="HyperV"}
$module=Get-Module "Boxstarter.$provider"
$command = Get-Command "$module\Enable-BoxstarterVM"
$PSBoundParameters.Remove("Provider") | Out-Null
&($command) @PSBoundParameters
}
}
new-alias Enable-BoxstarterVM Resolve-VMPlugin -force
function Send-File {
##############################################################################
##
## Send-File
##
## From Windows PowerShell Cookbook (O'Reilly)
## by Lee Holmes (http://www.leeholmes.com/guide)
##
##############################################################################
<#
.SYNOPSIS
Sends a file to a remote session.
.EXAMPLE
PS >$session = New-PsSession leeholmes1c23
PS >Send-File c:\temp\test.exe c:\temp\test.exe $session
#>
param(
## The path on the local computer
[Parameter(Mandatory = $true)]
$Source,
## The target path on the remote computer
[Parameter(Mandatory = $true)]
$Destination,
## The session that represents the remote computer
[Parameter(Mandatory = $true)]
[System.Management.Automation.Runspaces.PSSession] $Session
)
Set-StrictMode -Version Latest
## Get the source file, and then get its content
$sourcePath = (Resolve-Path $source).Path
$sourceBytes = [IO.File]::ReadAllBytes($sourcePath)
$streamChunks = @()
## Now break it into chunks to stream
$streamSize = 1MB
for($position = 0; $position -lt $sourceBytes.Length;
$position += $streamSize)
{
$remaining = $sourceBytes.Length - $position
$remaining = [Math]::Min($remaining, $streamSize)
$nextChunk = New-Object byte[] $remaining
[Array]::Copy($sourcebytes, $position, $nextChunk, 0, $remaining)
$streamChunks += ,$nextChunk
}
$remoteScript = {
param($destination, $length)
## Convert the destination path to a full file system path (to support
## relative paths)
$Destination = $executionContext.SessionState.`
Path.GetUnresolvedProviderPathFromPSPath("$env:temp\$Destination")
## Create a new array to hold the file content
$destBytes = New-Object byte[] $length
$position = 0
## Go through the input, and fill in the new array of file content
foreach($chunk in $input)
{
[GC]::Collect()
[Array]::Copy($chunk, 0, $destBytes, $position, $chunk.Length)
$position += $chunk.Length
}
## Write the content to the new file
[IO.File]::WriteAllBytes($destination, $destBytes)
[GC]::Collect()
}
## Stream the chunks into the remote script
$streamChunks | Invoke-Command -Session $session $remoteScript `
-ArgumentList $destination,$sourceBytes.Length -ErrorAction Stop
}
function Set-BoxStarterConfig {
<#
.SYNOPSIS
Sets persist-able Boxstarter configuration settings.
.DESCRIPTION
Boxstarter stores configuration data in an xml file in the Boxstarter base
directory. The Set-BoxstarterConfig function is a convenience function
for changing those settings.
.Parameter LocalRepo
The path where Boxstarter will search for local packages.
.Parameter NugetSources
A semicolon delimited list of Nuget Feed URLs where Boxstarter will search for packages
.LINK
http://boxstarter.org
about_boxstarter_chocolatey
about_boxstarter_variable_in_chocolatey
Get-BoxstarterConfig
#>
[CmdletBinding()]
param([string]$LocalRepo, [string]$NugetSources)
[xml]$configXml = Get-Content (Join-Path $Boxstarter.BaseDir BoxStarter.config)
if($NugetSources){
$boxstarter.NugetSources = $configXml.config.NugetSources = $NugetSources
}
if($LocalRepo){
if($configXml.config.LocalRepo -eq $null) {
$localRepoElement = $configXml.CreateElement("LocalRepo")
$configXml.config.AppendChild($localRepoElement) | Out-Null
}
$boxstarter.LocalRepo = $configXml.config.LocalRepo = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($LocalRepo)
}
$configXml.Save((Join-Path $Boxstarter.BaseDir BoxStarter.config))
}
function Set-BoxstarterShare {
<#
.SYNOPSIS
Shares the Boxstarter root directory - $Boxstarter.BaseDir
.DESCRIPTION
Shares the Boxstarter root directory - $Boxstarter.BaseDir - so that
it can be accessed remotely. This allows remote machines to Invoke
ChocolateyBoxstarter via \\server\shareName\Boxstarter.bat. Unless
specified otherwise, the share name is Boxstarter and Everyone is
given Read permissions.
.PARAMETER ShareName
The name to give to the share. This is the name by which other
machines can access it. Boxstarter is the default.
.PARAMETER Accounts
A list of accounts to be given read access to the share. Everyone is
the default.
.EXAMPLE
Set-BoxstarterShare
Shares the Boxstarter root as Boxstarter to everyone.
.EXAMPLE
Set-BoxstarterShare BuildRepo
Shares the Boxstarter Root as BuildRepo to everyone.
.EXAMPLE
Set-BoxstarterShare -Accounts "corp\mwrock","corp\gmichaels"
Shares the Boxstarter root as Boxstarter to mwrock and gmichaels in the corp domain.
.LINK
http://boxstarter.org
about_boxstarter_chocolatey
Invoke-ChocolateyBoxstarter
New-BoxstarterPackage
Invoke-BoxstarterBuild
#>
param(
[string]$shareName="Boxstarter",
[string[]][email protected]("Everyone")
)
if(!(Test-Admin)) {
$unNormalized=(Get-Item "$($Boxstarter.Basedir)\Boxstarter.Chocolatey\BoxStarter.Chocolatey.psd1")
$command = "-ExecutionPolicy bypass -command Import-Module `"$($unNormalized.FullName)`";Set-BoxstarterShare @PSBoundParameters"
Start-Process powershell -verb runas -argumentlist $command
return
}
foreach($account in $accounts){
$acctOption += "/GRANT:'$account,READ' "
}
IEX "net share $shareName='$($Boxstarter.BaseDir)' $acctOption"
if($LastExitCode -ne 0) {
Throw "Sharing $shareName on $($Boxstarter.BaseDir) to $acctOption was not successful. Use NET SHARE $ShareName to see if share already exists. To Delete the share use NET SHARE $ShareName /DELETE."
}
}
<config>
<ChocolateyPackage>http://chocolatey.org/api/v2/package/chocolatey/</ChocolateyPackage>
<ChocolateyRepo>http://chocolatey.org/install.ps1</ChocolateyRepo>
<NugetSources>http://chocolatey.org/api/v2;http://www.myget.org/F/boxstarter/api/v2</NugetSources>
</config>
$here = Split-Path -parent $MyInvocation.MyCommand.Definition
Resolve-Path $here\Boxstarter.*\*.psd1 |
% { Import-Module $_.ProviderPath -DisableNameChecking -Force -ErrorAction SilentlyContinue }
Import-Module $here\Boxstarter.Common\Boxstarter.Common.psd1 -Function Test-Admin
if(!(Test-Admin)) {
Write-BoxstarterMessage "Not running with administrative rights. Attempting to elevate..."
$command = "-ExecutionPolicy bypass -noexit -command &'$here\BoxstarterShell.ps1'"
Start-Process powershell -verb runas -argumentlist $command
Exit
}
$Host.UI.RawUI.WindowTitle="Boxstarter Shell"
cd $env:SystemDrive\
Write-Output @"
Welcome to the Boxstarter shell!
The Boxstarter commands have been imported from $here and are available for you to run in this shell.
You may also import them into the shell of your choice.
Here are some commands to get you started:
Install a Package: Install-BoxstarterPackage
Create a Package: New-BoxstarterPackage
Build a Package: Invoke-BoxstarterBuild
Enable a VM: Enable-BoxstarterVM
For Command help: Get-Help <Command Name> -Full
For Boxstarter documentation, source code, to report bugs or participate in discussions, please visit http://boxstarter.org
"@
$tools = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
. (Join-Path $tools Setup.ps1)
try {
$ModuleName = (Get-ChildItem $tools | ?{ $_.PSIsContainer }).BaseName
Install-Boxstarter "$(Split-Path -parent $MyInvocation.MyCommand.Definition)" $ModuleName
Write-ChocolateySuccess $ModuleName
} catch {
Write-ChocolateyFailure $ModuleName "$($_.Exception.Message)"
throw
}
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
function Install-Boxstarter($here, $ModuleName) {
$boxstarterPath=Join-Path $env:AppData Boxstarter
if(!(test-Path $boxstarterPath)){
mkdir $boxstarterPath
}
$packagePath=Join-Path $boxstarterPath BuildPackages
if(!(test-Path $packagePath)){
mkdir $packagePath
}
foreach($ModulePath in (Get-ChildItem $here | ?{ $_.PSIsContainer })){
$target=Join-Path $boxstarterPath $modulePath.BaseName
if(test-Path $target){
Remove-Item $target -Recurse -Force
}
}
Copy-Item "$here\*" $boxstarterPath -Recurse -Force -Exclude ChocolateyInstall.ps1, Setup.*
PersistBoxStarterPathToEnvironmentVariable "PSModulePath"
PersistBoxStarterPathToEnvironmentVariable "Path"
$binPath = "$here\..\..\..\bin"
$boxModule=Get-Module Boxstarter.Chocolatey
if($boxModule) {
if($boxModule.Path -like "$env:LOCALAPPDATA\Apps\*") {
$clickonce=$true
}
}
if(!$clickonce){
Import-Module "$boxstarterPath\$ModuleName" -DisableNameChecking -Force -ErrorAction SilentlyContinue
}
$successMsg = @"
The $ModuleName Module has been copied to $boxstarterPath and added to your Module path.
You will need to open a new console for the path to be visible.
Use 'Get-Module Boxstarter.* -ListAvailable' to list all Boxstarter Modules.
To list all available Boxstarter Commands, use:
PS:>Import-Module $ModuleName
PS:>Get-Command -Module Boxstarter.*
To find more info visit http://Boxstarter.org or use:
PS:>Import-Module $ModuleName
PS:>Get-Help Boxstarter
"@
Write-Host $successMsg
if($ModuleName -eq "Boxstarter.Chocolatey") {
$desktop = $([System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::DesktopDirectory))
$startMenu=$("$env:appdata\Microsoft\Windows\Start Menu\Programs\Boxstarter")
if(!(Test-Path $startMenu)){
mkdir $startMenu
}
$target="powershell.exe"
$targetArgs="-ExecutionPolicy bypass -NoExit -Command `"&'$boxstarterPath\BoxstarterShell.ps1'`""
$link = Join-Path $desktop "Boxstarter Shell.lnk"
Create-Shortcut $link $target $targetArgs $boxstarterPath
$link = Join-Path $startMenu "Boxstarter Shell.lnk"
Create-Shortcut $link $target $targetArgs $boxstarterPath
Set-Content -Path "$binPath\BoxstarterShell.bat" -Force -Value "$target $TargetArgs"
}
}
function Create-Shortcut($location, $target, $targetArgs, $boxstarterPath) {
$wshshell = New-Object -ComObject WScript.Shell
$lnk = $wshshell.CreateShortcut($location)
$lnk.TargetPath = $target
$lnk.Arguments = "$targetArgs"
$lnk.WorkingDirectory = $boxstarterPath
$lnk.IconLocation="$boxstarterPath\BoxLogo.ico"
$lnk.Save()
$tempFile = "$env:temp\TempShortcut.lnk"
$writer = new-object System.IO.FileStream $tempFile, ([System.IO.FileMode]::Create)
$reader = new-object System.IO.FileStream $location, ([System.IO.FileMode]::Open)
while ($reader.Position -lt $reader.Length)
{
$byte = $reader.ReadByte()
if ($reader.Position -eq 22) {
$byte = 34
}
$writer.WriteByte($byte)
}
$reader.Close()
$writer.Close()
Move-Item -Path $tempFile $location -Force
}
function PersistBoxStarterPathToEnvironmentVariable($variableName){
$value = [Environment]::GetEnvironmentVariable($variableName, 'User')
if($value){
$values=($value -split ';' | ?{ !($_.ToLower() -match "\\boxstarter$")}) -join ';'
$values+=";$boxstarterPath"
}
elseif($variableName -eq "PSModulePath") {
$values=[environment]::getfolderpath("mydocuments")
$values +="\WindowsPowerShell\Modules;$boxstarterPath"
}
else {
$values ="$boxstarterPath"
}
if(!$value -or !($values -contains $boxstarterPath)){
$values = $values.Replace(';;',';')
[Environment]::SetEnvironmentVariable($variableName, $values, 'User')
$varValue = Get-Content env:\$variableName
$varValue += ";$boxstarterPath"
$varValue = $varValue.Replace(';;',';')
Set-Content env:\$variableName -value $varValue
}
}
Log in or click on link to see number of positives.
- boxstarter.chocolatey.2.4.149.nupkg (f3e631a70985) - ## / 57
- Boxstarter.zip (3a63e8de5e20) - ## / 57
In cases where actual malware is found, the packages are subject to removal. Software sometimes has false positives. Moderators do not necessarily validate the safety of the underlying software, only that a package retrieves software from the official distribution point and/or validate embedded software against official distribution point (where distribution rights allow redistribution).
Chocolatey Pro provides runtime protection from possible malware.
Add to Builder | Version | Downloads | Last Updated | Status |
---|---|---|---|---|
Boxstarter Chocolatey Module 3.0.0-beta-20220427-21 | 36 | Wednesday, April 27, 2022 | Exempted | |
Boxstarter Chocolatey Module 2.13.0 | 137630 | Thursday, October 15, 2020 | Approved | |
Boxstarter Chocolatey Module 2.12.0 | 390277 | Tuesday, October 30, 2018 | Approved | |
Boxstarter Chocolatey Module 2.11.0 | 64980 | Wednesday, May 16, 2018 | Approved | |
Boxstarter Chocolatey Module 2.10.3 | 52392 | Thursday, August 31, 2017 | Approved | |
Boxstarter Chocolatey Module 2.9.26 | 5470 | Monday, June 19, 2017 | Approved | |
Boxstarter Chocolatey Module 2.9.24 | 754 | Sunday, June 18, 2017 | Approved | |
Boxstarter Chocolatey Module 2.9.14 | 6887 | Friday, May 5, 2017 | Approved | |
Boxstarter Chocolatey Module 2.9.5 | 4686 | Thursday, March 30, 2017 | Approved | |
Boxstarter Chocolatey Module 2.8.29 | 31270 | Sunday, May 22, 2016 | Approved | |
Boxstarter Chocolatey Module 2.8.27 | 365 | Sunday, May 22, 2016 | Approved | |
Boxstarter Chocolatey Module 2.8.21 | 966 | Thursday, April 28, 2016 | Approved | |
Boxstarter Chocolatey Module 2.8.18 | 663 | Tuesday, April 26, 2016 | Approved | |
Boxstarter Chocolatey Module 2.8.12 | 1028 | Thursday, April 21, 2016 | Approved | |
Boxstarter Chocolatey Module 2.8.0 | 1100 | Friday, April 15, 2016 | Approved | |
Boxstarter Chocolatey Module 2.7.0 | 1937 | Sunday, April 3, 2016 | Approved | |
Boxstarter Chocolatey Module 2.6.41 | 3646 | Sunday, February 28, 2016 | Approved | |
Boxstarter Chocolatey Module 2.6.25 | 6469 | Friday, December 18, 2015 | Approved | |
Boxstarter Chocolatey Module 2.6.20 | 437 | Thursday, December 17, 2015 | Approved | |
Boxstarter Chocolatey Module 2.6.16 | 641 | Tuesday, December 15, 2015 | Approved | |
Boxstarter Chocolatey Module 2.6.2 | 611 | Monday, December 14, 2015 | Approved | |
Boxstarter Chocolatey Module 2.6.0 | 412 | Sunday, December 13, 2015 | Approved | |
Boxstarter Chocolatey Module 2.5.21 | 9014 | Thursday, August 13, 2015 | Approved | |
Boxstarter Chocolatey Module 2.5.19 | 1901 | Sunday, July 26, 2015 | Approved | |
Boxstarter Chocolatey Module 2.5.10 | 1648 | Friday, July 10, 2015 | Approved | |
Boxstarter Chocolatey Module 2.5.3 | 1246 | Wednesday, July 1, 2015 | Approved | |
Boxstarter Chocolatey Module 2.5.1 | 485 | Wednesday, July 1, 2015 | Approved | |
Boxstarter Chocolatey Module 2.4.209 | 4428 | Sunday, April 26, 2015 | Approved | |
Boxstarter Chocolatey Module 2.4.205 | 2552 | Sunday, April 5, 2015 | Approved | |
Boxstarter Chocolatey Module 2.4.196 | 1407 | Friday, March 20, 2015 | Approved | |
Boxstarter Chocolatey Module 2.4.188 | 1206 | Monday, March 9, 2015 | Approved | |
Boxstarter Chocolatey Module 2.4.183 | 792 | Wednesday, March 4, 2015 | Approved | |
Boxstarter Chocolatey Module 2.4.180 | 390 | Tuesday, March 3, 2015 | Approved | |
Boxstarter Chocolatey Module 2.4.179 | 386 | Tuesday, March 3, 2015 | Approved | |
Boxstarter Chocolatey Module 2.4.159 | 2685 | Sunday, January 18, 2015 | Approved | |
Boxstarter Chocolatey Module 2.4.157 | 612 | Thursday, January 15, 2015 | Approved | |
Boxstarter Chocolatey Module 2.4.152 | 748 | Monday, January 12, 2015 | Approved | |
Boxstarter Chocolatey Module 2.4.149 | 1321 | Friday, December 26, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.146 | 426 | Friday, December 26, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.128 | 1866 | Thursday, November 27, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.123 | 3766 | Wednesday, September 24, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.110 | 775 | Wednesday, September 17, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.93 | 736 | Friday, September 12, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.88 | 965 | Wednesday, September 3, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.87 | 362 | Wednesday, September 3, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.80 | 2702 | Monday, August 4, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.76 | 427 | Sunday, August 3, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.70 | 603 | Thursday, July 31, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.67 | 648 | Wednesday, July 30, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.61 | 549 | Monday, July 28, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.57 | 395 | Sunday, July 27, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.54 | 572 | Wednesday, July 23, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.53 | 398 | Wednesday, July 23, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.51 | 372 | Wednesday, July 23, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.48 | 457 | Tuesday, July 22, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.46 | 537 | Saturday, July 19, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.41 | 616 | Sunday, July 13, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.39 | 372 | Sunday, July 13, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.38 | 405 | Saturday, July 12, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.35 | 369 | Saturday, July 12, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.32 | 377 | Friday, July 11, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.29 | 1200 | Friday, July 4, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.26 | 1009 | Monday, June 23, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.15 | 2952 | Sunday, April 20, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.12 | 396 | Saturday, April 19, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.4 | 754 | Saturday, April 5, 2014 | Approved | |
Boxstarter Chocolatey Module 2.4.0 | 405 | Friday, April 4, 2014 | Approved | |
Boxstarter Chocolatey Module 2.3.24 | 1852 | Saturday, February 1, 2014 | Approved | |
Boxstarter Chocolatey Module 2.3.15 | 498 | Monday, January 27, 2014 | Approved | |
Boxstarter Chocolatey Module 2.3.13 | 395 | Saturday, January 25, 2014 | Approved | |
Boxstarter Chocolatey Module 2.3.8 | 440 | Thursday, January 23, 2014 | Approved | |
Boxstarter Chocolatey Module 2.3.0 | 462 | Monday, January 20, 2014 | Approved | |
Boxstarter Chocolatey Module 2.2.78 | 615 | Thursday, January 9, 2014 | Approved | |
Boxstarter Chocolatey Module 2.2.59 | 723 | Sunday, December 29, 2013 | Approved | |
Boxstarter Chocolatey Module 2.2.23 | 775 | Saturday, December 14, 2013 | Approved | |
Boxstarter Chocolatey Module 2.2.16 | 377 | Friday, December 13, 2013 | Approved | |
Boxstarter Chocolatey Module 2.2.15 | 383 | Friday, December 13, 2013 | Approved | |
Boxstarter Chocolatey Module 2.2.12 | 378 | Friday, December 13, 2013 | Approved | |
BoxStarter Chocolatey Module 2.2.0 | 429 | Thursday, December 12, 2013 | Approved | |
BoxStarter Chocolatey Module 2.1.0 | 486 | Saturday, November 30, 2013 | Approved | |
BoxStarter Chocolatey Module 2.0.25 | 425 | Wednesday, November 20, 2013 | Approved | |
BoxStarter Chocolatey Module 2.0.11 | 439 | Monday, November 11, 2013 | Approved | |
BoxStarter Chocolatey Module 2.0.4 | 425 | Saturday, November 9, 2013 | Approved | |
BoxStarter Chocolatey Module 2.0.1 | 407 | Friday, November 8, 2013 | Approved | |
BoxStarter Chocolatey Module 1.1.40 | 495 | Tuesday, October 1, 2013 | Approved | |
BoxStarter Chocolatey Module 1.1.35 | 454 | Monday, August 12, 2013 | Approved | |
BoxStarter Chocolatey Module 1.1.30 | 418 | Sunday, August 11, 2013 | Approved | |
BoxStarter Chocolatey Module 1.1.22 | 388 | Thursday, August 8, 2013 | Approved | |
BoxStarter Chocolatey Module 1.1.18 | 405 | Tuesday, August 6, 2013 | Approved | |
BoxStarter Chocolatey Module 1.1.12 | 360 | Sunday, August 4, 2013 | Approved | |
BoxStarter Chocolatey Module 1.1.0 | 428 | Thursday, August 1, 2013 | Approved | |
BoxStarter Chocolatey Module 1.0.33 | 497 | Thursday, April 18, 2013 | Approved | |
BoxStarter Chocolatey Module 1.0.20 | 387 | Monday, April 15, 2013 | Approved | |
BoxStarter Chocolatey Module 1.0.13 | 443 | Monday, March 25, 2013 | Approved | |
BoxStarter Chocolatey Module 1.0.3 | 425 | Wednesday, March 13, 2013 | Approved |
- Fixes issue where windows update reboots maching in the midst of a run.
- Fixes failures from exceptions thrown from bitlocker module even when bitlocker is not in use.
- Fixes Invoke-Reboot from a nested package and bubbles up the reboot signal
- Update docs to reflect github as repo home and remove all codeplex links
- Fix for all write-host calls being logged to Boxstarter log file even when there is no install session in progress
- fixing issue where auto login is not disabled after boxstarter run
- fixing wait for published version to retry for a minute if the new version is not yet marked published
- Improve initial connectin performance by skipping remoting check if it has already been tested in enable-BoxstarterVM
- provide messaging for some winconfig functions
- fix the setting of azure storage account by looking for https endpoints
- load storage module before azure to workaround bug with the storage module loading
- copy the root path passed to New_BoxstarerPackage
- add a DisableRestart parameter which will suppress the restart file and UAC enabling
- Greatly improve progress messaging during windows updates runs
- Fix hang scenarios when waiting for remote machine to reboot and landing in a pending reboot state shortly after reboot
- Support for auto login and restart in winrm sessions
- Fix issue with remote check causing an indefinite loop
- Silencing some handled errors and keep them from leaking to the pipeline
- Reduce WMI calls and Improve performance of testing if the current session is remote
- When forcing the install of the outer boxstarter package, make sure to delete the last install from the right repo
- Check scheduled task output for pending reboots after a remote windows update since 32 bit processes cant read the wsus registry keys
- Fix Remote check when running as a servise
- System user logs to programdata
- when accessing a 64 bit machine from a 32bit process, the windowsupdate reg key is hidden so skip it
- Bubble up errors from windows update
- Provide the same scheduled task wrapping for winrm as we do for ps remoting
- fix explorer restart when there is no explorer process
- Correcting fallback Chocolatey install path to match release 0.9.8.24
- Fixing typo param name in redirect call to set-WindowsExplorerOptions
- Fix InvalidArgument from Set-TaskbarOptions when using lock or unlock params
- Fix issues where explorer terminates and cannot restart after caling one of the winconfig functions
- Import azure module from the pipeline to avoid errors when loading Boxstarter.azure
- Suppress errors when reenabling windows update in case they had alrady been reenabled
- Fix mis encoded dash in Install-Boxstarterackage
- Fix issues when Chocolatey packages create a new module and call chocolatey functions from that module
- When building packages, skip folders without a nuspec instead of throwing an error
- Only restart the explore process of the current user when calling windows config functions
- Fixing .net 4.5 install for local installs
- Fixing TestRunner module loading for PSv2 clients
- Add the following windows config features:
- Enable/Disable showing charms when mouse is in the upper right corner
- Enable/Disable switching apps when pointing in the upper left corner
- Enable/Disable the option to launch powershell from win-x
- Enable/Disable boot to desktop
- Enable/Disable desktop background on the start screen
- Enable/Disable showing the start screen on the active display
- Enable/Disable showing the Apps View by default on the start screen
- Enable/Disable searching everywhere in apps view. Not just apps.
- Enable/Disable showing desktop apps first in results
- Lock/Unlock task bar
- Change taskbar icon size
- Change location of taskbar docking
- Add test and publish automation that can point to remote deployment targets
- Provide build scripts for integration of tests and publishing in CI servers
- Include configured nuget sources and local repo to all chocolatey install calls and not just the initial package
- Fix enabling powershell remoting via WMI when password has ampersands
- Avoid explorer.exe crashes when configuring explorer options
- Fix Hyper-V heartbeat check in non US locales
- Fix Azure module loading in 32 bit consoles
- Fix shell shortcuts when user name has a space
- Fix Azure VM Checkpoint listing when there are more than one VM in a service
- Install .net 4.5 ONLY without affecting IIS settings when .net 4 is not present
- Fix Azure VM integration when multiple subscriptions are present
- Allow remote installs to be run by a non amin user
-
- Boxstarter.Common (≥ 2.4.149)
- Boxstarter.WinConfig (≥ 2.4.149)
- Boxstarter.Bootstrapper (≥ 2.4.149)
Ground Rules:
- This discussion is only about Boxstarter Chocolatey Module and the Boxstarter Chocolatey Module package. If you have feedback for Chocolatey, please contact the Google Group.
- This discussion will carry over multiple versions. If you have a comment about a particular version, please note that in your comments.
- The maintainers of this Chocolatey Package will be notified about new comments that are posted to this Disqus thread, however, it is NOT a guarantee that you will get a response. If you do not hear back from the maintainers after posting a message below, please follow up by using the link on the left side of this page or follow this link to contact maintainers. If you still hear nothing back, please follow the package triage process.
- Tell us what you love about the package or Boxstarter Chocolatey Module, or tell us what needs improvement.
- Share your experiences with the package, or extra configuration or gotchas that you've found.
- If you use a url, the comment will be flagged for moderation until you've been whitelisted. Disqus moderated comments are approved on a weekly schedule if not sooner. It could take between 1-5 days for your comment to show up.