Update-OneGet: Install OneGet on PS 3.0+
- Details
- Written by June Blender
- Last Updated: 13 April 2016
- Created: 14 November 2014
- Hits: 12095
One of the coolest new features in the Windows PowerShell 5.0 preview is the OneGet module. Windows PowerShell program manager, Dan Harman, describes OneGet as a “package manager manager,” but for most of us, it represents a simple, repeatable, and reliable way to install, update, and uninstall a variety of available programs from a variety of sources.
For example, if you want to install MarkDownPad2, a very simple and highly regarded HTML mark-up (or down) editor, you run a command like this:
Find-Package MarkDown2 | Install-Package
Yes. It’s just that easy. Really. And, if you need to uninstall it.
Get-Package MarkDown2 | Uninstall-Package
There are two versions of OneGet floating around:
- The official version of the OneGet module is included in the Windows Management Framework 5.0.
- The experimental version of the OneGet module is an open-source project on GitHub run by Garrett Serack, (@fearthecowboy) a lead developer of open source projects at Microsoft.
The official version of OneGet is now available only in the Windows PowerShell 5.0 preview, which supports Windows 8.1, Windows Server 2012 R2, and later. I don’t know if they plan to make the official version available for earlier versions of Windows or Windows PowerShell.
But, according to Garrett, the experimental version is designed to work on Windows PowerShell 3.0 and later, which supports Windows 7 SP1, Windows Server 2008 SP2, Windows Server 2008 R2 SP1, and later.
So, I wrote a little script, Update-OneGet.ps1 (attached below) that downloads the latest experimental version of the OneGet module, unblocks it (so you can run it with the RemoteSigned execution policy), unzips it, and saves it in a directory that you specify.
The Warnings
Now, the predictable warnings. Caveat emptor, especially when the download is free.
- You shouldn’t run any unofficial software on a production system or on any system with sensitive data or guaranteed up-time.
- Before running any open-source code on any system, review the code and make sure that it’s safe, or consult people who can verify that it’s safe.
- By design, open-source code is a work in progress. The version that you download this morning might work a bit differently than the version that you download in the afternoon.
And one less predictable one:
- Dan Harman mentioned in his talk that the official Uninstall-Package cmdlet might not completely uninstall a program. You might need to run an MSI to completely uninstall it.
Get the Experimental OneGet
I wrote a little script that downloads, unblocks, unzips, and installs the experimental version of the OneGet module on your system. It’s designed to be run repeatedly (hence the Update verb), so it always deletes everything in the directory and installs a new copy.
You can run it on Windows PowerShell 3.0 and later and you don’t need to have a GitHub user account. (If you have a GitHub account, you don’t need to log in, because the script doesn’t use it.)
The script has a Path parameter that takes the path to a directory. Update-OneGet installs the module in that directory.
Caution: Do not install the experimental version of OneGet in $pshome\Modules. If you do, it might prevent you from installing, uninstalling or updating the official version of the module.
To be safe, especially on systems that have both the official and experimental versions of the OneGet module, install the experimental version in a directory that will not be auto-loaded; that is, a directory that is not listed in your $env:PSModulepath variable. For example:
$home\Documents\Test\OneGetExperimental
-or-
C:\ps-test\OneGetExperimental
If you do not and will not have the official version, and you want the module to import automatically, you can provide the path to your current-user module directory, such as your $home\Documents\WindowsPowerShell\Modules\OneGetExperimental directory.
In case you’re wondering, the Path value doesn’t affect the module name. The module name is actually determined by the name of the module manifest file, so both the official and experimental versions are “OneGet” in Windows PowerShell.
The script also has an Import switch parameter that imports the module into the session after it’s installed. It’s optional, of course.
To get help for the script, use Get-Help with the path and file name of the script. For example:
Get-Help .\Update-OneGet.ps1
Importing OneGet (the experimental version)
After you install the OneGet module, you need to import it.
If you installed OneGet in your current-user modules directory, or any directory that is listed in $env:PSModulePath, Windows PowerShell imports it automatically when you use a cmdlet in the module, such as Find-Package, or use Get-Command or Get-Help on a module cmdlet without wildcards.
If you installed the module in a different directory, you can import it by using the path to the OneGet module manifest. Here’s how:
Import-Module <Path>\OneGet.psd1
If you are running Windows PowerShell 5.0 preview, you’ll have both the official and experimental versions of the module. When you have commands in your session with the same name, the commands that run are the ones added to the session last (most recently) For details, see about_Command_Precedence. And, because the modules have the same name, qualifying the cmdlet name with the module name (<Module>\Cmdlet) doesn’t help.
To avoid this confusion, when you want to use a command in the experimental version of the OneGet module, explicitly remove any accidentally auto-loaded versions of OneGet from the session and import the version that you want.
function Import-OneGetEx { if (Get-Module OneGet) { Remove-Module OneGet } Import-Module <Path>\OneGet.psd1 }
About OneGet
Today, there is no official help for the cmdlets in the OneGet module, but the Microsoft writers are working hard on it, and it should be available soon, both for the official and experimental modules.
In the meantime, I recommend Dan Harman’s terrific talk at the PowerShell Summit 2014 in Europe: Dan Harman – PowerShell Repositories Unleashed. In this talk, Dan introduces OneGet and its favorite child, PowerShellGet, and then delves into how to create a package provider that connects the OneGet framework to a particular package manager repositories.
Script: Update-OneGet.ps1
With special thanks to Windows PowerShell MVP Doug Finke (@dfinke) for reviewing the code.
You can copy the Update-OneGet.ps1 script code here or download a ZIP file of the Update-OneGet.ps1 script from the SAPIEN Downloads site.
To download, sign in, in the left nav, click Sample Scripts, click Update-OneGet.ps1.zip, and in the top right corner, click Download.
<# .NOTES =========================================================================== Created with: PowerShell Studio 2014, Version 4.1.74 Created on: 11/10/2014 4:06 PM Company: SAPIEN Technologies, Inc. Contact: June Blender, This email address is being protected from spambots. You need JavaScript enabled to view it., @juneb_get_help Filename: Update-OneGet.ps1 =========================================================================== .SYNOPSIS Downloads, installs, and imports the latest OneGet module from GitHub. .DESCRIPTION Update-OneGet.ps1 downloads, installs, and (optionally) imports the latest experimental version of the OneGet module from http://OneGet.org, which is linked to the OneGet project in GitHub. The script downloads the OneGet.zip file from OneGet.org and saves it in your downloads folder, $home\Downloads. It unblocks the file, unzips it, and installs it in the directory specified by the Path parameter. If you include the optional Import parameter, the script imports the module into the current session. After running the script, to import the experimental version of OneGet into any session, use the following command: Import-Module <path>\OneGet.psd1 This script runs on Windows PowerShell 3.0 and later. .PARAMETER Path Specifies a directory where the script installs the module. This parameter is required. Enter the path to a directory. Do not include a .zip file name extension. If the directory does not exist, the script creates it. If the directory exists, the script deletes the directory contents before installing the module. This lets you reuse the directory when updating. To prevent errors, specify a subdirectory of your Documents directory or a test directory. CAUTION: Do not specify a path in $pshome\Modules. Installing the experimental build of OneGet in this directory might prevent you from installing, uninstalling, or updating the official OneGet module from Microsoft. .PARAMETER Import Imports the module into the current session after installing it. .EXAMPLE .\Update-OneGet.ps1 -Path $home\Documents\Test\OneGet This command installs the newest OneGet module in the $home\Documents\Test\OneGet directory. To import it: Import-Module $home\Documents\Test\OneGet.psd1 .EXAMPLE .\Update-OneGet.ps1 -Path $home\Documents\Test\OneGet -Import This command installs the newest OneGet module in the $home\Documents\Test\OneGet directory and imports it into the current session. .EXAMPLE .\Update-OneGet.ps1 -Path $home\Documents\WindowsPowerShellModules\OneGet This command installs the newest OneGet module in the your current-user Modules directory. Windows PowerShell imports it automatically when you use a command in the module, such as Find-Package. .OUTPUTS System.Management.Automation.PSCustomObject, System.Management.Automation.PSModuleInfo If you use the Import parameter, Update-OneGet returns a module object. Otherwise, it returns a custom object with the Path and LastWriteTime of the OneGet module manifest, OneGet.psd1 #> #Requires -Version 3 Param ( [Parameter(Mandatory = $true)] [ValidateScript({$_ -notlike "*.zip" -and $_ -notlike "$pshome*" -and $_ -notlike "*System32*"})] [System.String] $Path, [Parameter(Mandatory=$false)] [Switch] $Import ) #***************************# # Helper Functions # #***************************# # Use this function on systems that do not have # the Extract-Archive cmdlet (PS 5.0) # function Unzip-OneGetZip { $shell = New-Object -ComObject shell.application $zip = $shell.NameSpace("$home\Downloads\OneGet.zip") foreach ($item in $zip.items()) { $shell.Namespace($script:Path).Copyhere($item) } } #***************************# # Main # #***************************# # Remove current OneGet from session if (Get-Module -Name OneGet) {Remove-Module OneGet} # Create the $Path path if (!(Test-Path $Path)) { try { mkdir $Path | Out-Null } catch { throw "Did not find and cannot create the $Path directory." } } else { dir $Path | Remove-Item -Recurse } #Download the Zip file to $home\Downloads try { Invoke-WebRequest -Uri http://oneget.org/oneget.zip -OutFile $home\Downloads\OneGet.zip } catch { throw "Cannot download OneGet zip file from http://oneget.org" } if (!($zip = Get-Item -Path $home\Downloads\OneGet.zip)) { throw "Cannot find OneGet zip file in $home\Downloads" } else { $zip | Unblock-File if (Get-Command Expand-Archive -ErrorAction SilentlyContinue) { $zip | Expand-Archive -DestinationPath $Path } else { Unzip-OneGetZip } if (!(Test-Path $Path\OneGet.psd1)) { throw "Cannot find OneGet.psd1 in $Path" } if ($Import) { Import-Module $Path\OneGet.psd1 if ((Get-Module OneGet).ModuleBase -ne $Path) { throw "Failed to import the new OneGet module from $Path." } else { Get-Module OneGet } } else { [PSCustomObject]@{Path = "$Path\OneGet.psd1"; Date = (dir $Path\OneGet.psd1).LastWriteTime} } }
June Blender is a technology evangelist at SAPIEN Technologies, Inc. You can reach her at This email address is being protected from spambots. You need JavaScript enabled to view it. or follow her on Twitter at @juneb_get_help.
For licensed customers, use the forum associated with your product in our Product Support Forums for Registered Customers.
For users of trial versions, please post in our Former and Future Customers - Questions forum.