Star InactiveStar InactiveStar InactiveStar InactiveStar Inactive
 

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 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.

If you have questions about our products, please post in our support forum.
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.
Copyright © 2024 SAPIEN Technologies, Inc.