Update: Updated script location
I’ve been spending some time recently working on my own private Deployment Share, one of the downsides is the overhead of keeping my application packages up to date. The worst offenders are of course Google Chrome, and the Adobe Flash and PDF readers, seems like these packages are constantly changing, and I need to find and update frequently. If only there was a better way, something to make adding packages easier like my Dell Driver Pack Update tool, or the ZTIWindowsUpdate.wsf script found in MDT to run Windows Update/WSUS. Any way to keep my environment up to date without the manual hassle. :^)
There are several tools out there on the internet that help and assist you with application package management. At first I started looking at Ninite.com, however their tools are designed for End Users, and if you want to have an automated solution (like I need), then you must pay a per-machine licensing fee. (yuck)
Then I started looking at Chocolatey, which provides a command line interface for installing programs similar to Ninite.com without the UI fluff. I come across a couple of packages that were found in Ninite but not found in Chocolatey, but that list is small: (Google Talk, AIM, Yahoo!, KMPlayer, Winamp, K-Lite Codecs, Mozy, RealVNC) and the list of packages found in Chocolatey is very large. Cool!
Anther advantage of Chocolatey is that it’s in alignment with future Microsoft plans around packaging (see OneGet). However Oneget still requires some installation overhead that I didn’t want to deal with for this release, so something for the future.
So I spent some time experimenting, reverse engineering Chocolatey and scripting a workable solution, and I think I have something ready for use.
The Script
The script is fairly straight forwards. When calling the script, we pass in a list of parameters in through the command line, if no parameters are passed in, then we will default to the Chocolatey001 … Chocolatey00n variables you may be familiar with when using MDT and adding variables into your CustomSettings.ini file.
[CmdletBinding()] param( [parameter(ValueFromRemainingArguments=$true)] [string[]]$Packages = $TSEnvList:Chocolatey )
Then we determine a local path for the Chocolatey install, looking to see if it was already installed, then forcing it to use the local MDT temp directory (C:\MININT) if present. This means that Chocolatey won’t be available after MDT installation, great for image capture.
write-verbose "Construct a local path for Chocolatey" if ($env:ChocolateyInstall -eq $Null) { $env:ChocolateyInstall = [Environment]::GetEnvironmentVariable( "ChocolateyInstall" , [System.EnvironmentVariableTarget]::User) if ($env:ChocolateyInstall -eq $Null) { $env:ChocolateyInstall = join-path ([System.Environment]::GetFolderPath("CommonApplicationData")) "Chocolatey" if ($tsenv:LogPath -ne $null) { $env:ChocolateyInstall = join-path $tsenv:LogPath "Chocolatey" } } }
We look to see if the Choco.exe program is found locally, and if not we will install Chocolatey from the internet.
$ChocoExe = join-path $env:ChocolateyInstall "bin\choco.exe" write-verbose "Chocolatey Program: $ChocoExe" if ( ! (test-path $ChocoExe ) ) { write-verbose "Install Chocolatey..." Invoke-Expression ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')) if (!(test-path $ChocoExe)) { throw "Chocolatey Install not found!" } }
Finally, we will go through all the packages requested, and kick off the installation. The list of requested packages will come from the command line
write-verbose "Install Chocolatey packages from within MDT" foreach ( $Package in $Packages ) { write-verbose "Install Chocolatey Package: $ChocoExe $Package" & $ChocoExe install $Package 2>&1 | out-string } write-verbose "Chocolatey install done"
Had some problems with Chocolatey and the MDT PowerShell provider with some overly verbose output, so I redirect all errors to the Standard Console, that’s what the weird 2>&1 is all about.
Integration with MDT LiteTouch
To add into your MDT LiteTouch environment, simply download the ZTIChocolatey-Wrapper.ps1 into your \\Server\DeploymentShare$\Scripts folder.
Then add a new step into your task sequence pointing to the powershell script: %ScriptRoot%\ZTIChocolatey-Wrapper.ps1
You can add entries into your CustomSettings.ini file, here is a snippet from my server:
[Settings] Priority=UUID,Role,Default Properties=ModelAlias,UseWindowsUpdate,CustomizeStartScreen,Chocolatey(*) [Default] OSInstall=Y SkipCapture=YES ... Chocolatey001=VLC Chocolatey002=7zip Chocolatey003=speccy Chocolatey004=WindowsADK Applications001={91a974c5-6a30-4924-bec2-ade0f82793bc} Applications002={631f0a5a-ed76-47b8-8ed4-74aeb43f4b49}
The Install Applications step will install the Applications001 and Applications002 Guid I selected above, and the Chocolatey install will install the VLC, 7zip, speccy, and WindowsADK steps above.
Adding the Chocolatey wrapper as an Application
Alternatively you can create an application package (without source files), and use the following command:
powershell.exe -NoProfile -ExecutionPolicy unrestricted "%ScriptRoot%\ZTICHocolatey-Wrapper.ps1" -verbose -Packages "AdobeReader"
Future
The next logical step is to create a Litetouch Wizard page for Chocolatey, allowing you to select packages from a list in the GUI. But I’m a bit stumped on the best way to get a list of all available packages ( clist.exe ), *and* get the package metadata in a graceful way. Right now, I only know how to download each package from the server as *.zip file, extract out the *.xml file and display. If you know how to use PowerShell to get the list of packages *and* get a list of descriptions, versions, and icons, please let me know.
Nice one! I wasn’t event heard about Chocolatey before this. There is also free PatchMyPC updater that is free and has commandline support. We are using PatchMyPC SCUP catalog with ConfigMgr and we have been quite satisfied with it.
I followed your steps for Chocolatey in MDT and I got the following error message:
Failed to run the last action: Chocolatey Install.
DNS Server not authoritative for zone (Error: 00002331)
Possible that Chocolately does not work behind your firewall.
Try installing a couple of Chocolatey packages from the powershell console.
Awesome script, and if you want to do multiple apps you do -verbose -Packages “AdobeReader” “RDCman” ?
Pingback: How To Use Chocolatey with MDT 2013 - xenappblog
Hello,
This script used to work fine, but it seems now we have to push enter after each line (we do the installations separatly), so the script can execute. Is there any option to force the execution of each line, so the installation can be done silently without any action from us ?
YEs there appears to be a breaking change in Chocolatey, you know, #Security https://github.com/chocolatey/choco/issues/52
I have coded a solution and uploaded to: http://mdtex.codeplex.com/SourceControl/latest#Templates.Common/Distribution/Scripts/Extras/Install-Chocolatey.ps1
My preference is that you would instead use choco install somepackage -y instead of making a global change.
Fixed as suggested. :^o
Thanks for this solution Keith. I am using it now also in my MDT tasks. There is however a little error in the script. At line 69 it says $ChocoExe feature enable -n allowGlobalConfirmation this should be & $ChocoExe feature enable -n allowGlobalConfirmation. Just like you do in line 76.
I have updated the external source.
A file named ZTICHocolatey-Wrapper.ps1 is mentionned but the downloable script file is named Install-Chocolatey.ps1. Did you just rename Install-Chocolatey.ps1 to ZTIChocolatey-Wrapper.ps1 or is it a different file ?
ZTIChocolatey-Wrapper.ps1 is the old name. I migrated over to the powershell style of -.ps1 in the more recent script on http://mdtex.codeplex.com
Hi!
Awesome script!
Just did som Chocolatey applications for our migration to Windows 10.
The applications installs just fine, however “Choco.exe” does not register itself in the global environment path. How do I acomplish that?
I have a GPO that hits all machines migratet to windows 10, that will automatically update all Chocolatey apps (choco -upgrade all -y)
How should i format my command for an install that requires an additional parameter?
ie – https://chocolatey.org/packages/jre8
This was my most recent attempt running it as an application.
powershell.exe -NoProfile -ExecutionPolicy unrestricted “%ScriptRoot%\ZTIChocolatey-Wrapper.ps1” -verbose -Packages jre8 -PackageParameters “/exclude:64” -y
I’ve got the same question. I wan to control the installation of both JRE and Firefox.
This looks like it’s exactly what I need, but for whatever reason, the link to the PowerShell script mentioned in your article is not working (CodePlex shows an error instead of the source). Any chance I can get this script from you another way?? Thanks a million… Nate
Thanks, the latest version is located at:
http://mdtex.codeplex.com/SourceControl/latest#Templates/Distribution/Scripts/Extras/Install-Chocolatey.ps1
Hi, great script. Does this work with MDT 2013 update 2? as i am getting the following errors:
”
“batch file could not be found” is also safe to ignore
“the system could not find the file specified” – also safe
the term ‘out-verbose’ is not recognized as the name of a cmdlet, function, script file or operable program. check the spelling of the name, or if a path was included, verify that the path is correct and try again.
it then references location of the install-chocolatey.ps1:77 char:88
+ invoke-expression “cmd.exe /c $chocoExe Install $package -y -v 2>&1” | out-verbose
<<<<<<
objectnotfound: (out-verbose:String) [], commandnotfoundexception
any help/advice on this would be appreciated.
I just dropped the string “| out-verbose” from the end of line 77, and it seemed to work okay. I’m sure it means I’m losing logging information, but for right now I’m okay with that.
I have fixed the out-verbose line to out-string |write-verbose
mea culpa.
“Right now, I only know how to download each package from the server as *.zip file, extract out the *.xml file and display. If you know how to use PowerShell to get the list of packages *and* get a list of descriptions, versions, and icons, please let me know.”
One thing you can do is call the nuget API for whatever chocolatey feed you’re using. For example: (Feed url)/Packages() (i.e.: http://chocolatey.org/api/v2/Packages() )
It is subject to pagination, but it contains all the XML metadata you want, without having to download each package.
As you can see in https://chocolatey.org/install.ps1:
$url = ‘https://chocolatey.org/api/v2/Packages()?$filter=((Id%20eq%20%27chocolatey%27)%20and%20(not%20IsPrerelease))%20and%20IsLatestVersion’
[xml]$result = Download-String $url
$url = $result.feed.entry.content.src
This gets the xml data for the latest chocolatey package, but I’m sure you can do other creative filtering. If you’re hosting an internal feed, you can just take the feed url and add
I hope that was helpful do you. I was wondering how you would go about creating the wizard page that populates based on the current packages available in a given chocolatey repo.
I’m extremely new to MDT, but not powershell/chocolatey :P.
Hi i could well be doing this all wrong, but I can’t seem to find “ZTIChocolatey-Wrapper.ps1” in your link on codeplex, just “install-chocolatey.ps1”. Where am I going wrong? Cheers
Found it in here https://github.com/Esysc/MDTtools/blob/master/ZTIChocolatey-Wrapper.ps1. I assume its the same thing… It seems i’m missing a switch someplace as the TS is waiting for some input – found this in the log?
2017-04-18 14:59:04,747 [INFO ] – The package Silverlight wants to run ‘chocolateyInstall.ps1’.
2017-04-18 14:59:04,751 [INFO ] – Note: If you don’t run this script, the installation will fail.
2017-04-18 14:59:04,756 [INFO ] – Note: To confirm automatically next time, use ‘-y’ or consider:
2017-04-18 14:59:04,761 [INFO ] – choco feature enable -n allowGlobalConfirmation
2017-04-18 14:59:04,787 [INFO ] – Do you want to run the script?
2017-04-18 14:59:04,794 [INFO ] – 1) yes
2017-04-18 14:59:04,798 [INFO ] – 2) no
2017-04-18 14:59:04,803 [INFO ] – 3) print
any ideas?
Actually found at:
https://raw.githubusercontent.com/keithga/DeployShared/master/Templates/Distribution/Scripts/Extras/Install-Chocolatey.ps1
perfect thanks
Nice work! However ..
I imported your script (from https://raw.githubusercontent.com/keithga …) into my Scripts directory, created an MDT application that runs this command:
powershell.exe -NoProfile -ExecutionPolicy unrestricted “%ScriptRoot%\Install-Chocolatey.ps1” -verbose -Packages “vcredist2005”
, but when I execute this as part of a task sequence to deploy Windows 7, it asks me for confirmation:
Security Warning
Run only scripts that you trust. While scripts from the Internet can be useful,
this script can potentially harm your computer. Do you want to run
\\BCMDT1\MDTBuildLab$\Scripts\Install-Chocolatey.ps1?
[D] Do not run [R] Run once [S] Suspend [?] Help (default is “D”):
Why it asks me to confirm to run the script?
Yea, try the -y switch to approve.
well. I did!
Yet it requires me to interactively confirm running the script .
commandline is: powershell.exe -NoProfile -ExecutionPolicy unrestricted “%ScriptRoot%\Install-Chocolatey.ps1” -verbose -Packages “vcredist2005” -Y
screenshot http://amber.bonhoeffer.nl/content/images/20170612-task-sequence-chocolatey.png
No group policies are active at this point. Do you have any idea how to fix this?
I have updated the article body with the correct link to the new PowerShell script.
Thanks for your time. I did find the script “Install-Chocolatey.ps1” which was committed 7 months ago. Has there been any change?
It is strange that, when I copy the script from the deployment share to a local drive, i.e. %Temp% , it runs fine. However when I run the script straight from the deployment share , it asks me to confirm running it. Even while the executionpolicy was set to RemoteSigned , in both scopes CurrentUser and LocalMachine. I have run this by opening cmd shell while the task sequence was halting. Then I ran this commandscript:
Powershell.exe -ExecutionPolicy Unrestricted -Command “Get-ExecutionPolicy -List”
set SCRIPTROOT=\\bcmdt1\mdtbuildlab$\scripts
:: this asks the user to run …
powershell.exe -ExecutionPolicy Unrestricted -File “%SCRIPTROOT%\Install-Chocolatey.ps1” -Packages vcredist2005
copy %SCRIPTROOT%\Install-Chocolatey.ps1 %TEMP%\Install-Chocolatey.ps1
:: this just runs!
powershell.exe -ExecutionPolicy Unrestricted -File “%TEMP%\Install-Chocolatey.ps1” -Packages vcredist2005
I had to set Scriptroot env variable because this was not run as a sequenced task. Surely running an cmd-script defeats the whole ease of user of running the PowerShell-script from a command line task. If you know why this behavior exists, I would be very happy to hear about it..
… and you can see I am trying to run your script on Windows 7. In fact Windows 7 Enterprise x86 SP1 Dutch. I did try your script on a deployment of Windows 10 Pro x64 and it ran just fine … Important difference here of course: Windows 7 has PowerShell v2.0, Windows 10 has PowerShell v5
Be sure the script you downloaded hasn’t been marked as unsafe by IE.
The script isn’t blocked. I tried to install Windows Management Framework 5.1 prior to running the chocolatey install task, and had to install .NET Framework 4.6.2 first. Still no luck
Alright .. I searched a little further and found This stackoverflow post.
It turns out running scripts from the deploymentshare using the commandline
Powershell.exe -executionPolicy Unrestricted -File "...."
will sometimes trigger the security warning and the “Do you want to run this script?” question because the path is considered something from the bad internet. To fix this, use executionpolicy Bypass. So the recommended way to invoke the Install-Chocolatey.ps for example to install vcredist2005 is like this:
Powershell.exe -executionPolicy Bypass -File "%ScriptRoot%\Install-Chocolatey.ps1" -Verbose -Packages "vcredist2005" -y
I am apparently the first one to stumble across this..
Hi, good post, also I have another way to install apps in MDT and chocolatey here is the post
http://blogs.itpro.es/octaviordz/2016/06/04/integrando-chocolatey-a-mdt-2013-e-instalando-aplicaciones-de-forma-desatendida-en-windows-10/