2014/04/07

PowerShell - Playing with the new OneGet module (v5 preview)

One very cool thing in the last Windows Management Framework V5 Preview release is the new module OneGet which allow us to manage a list of software repositories, search/acquire/install/uninstall package(s).

This has been present in the Linux world for a very long time, for example with APT-GET (Debian). This new feature is basically a global silent installer for applications and tools. We should also be able to do configuration tasks and anything that you can do with PowerShell. The power you hold with a module like OneGet is only limited by your imagination! :-)

Note that this is a preview, there is no documentation yet, the features and behavior are likely to change before the final release.

OneGet Module ?

OneGet is a new way to discover and install software packages from around the web. With OneGet, you can:
  • Manage a list of software repositories in which packages can be searched, acquired, and installed
  • Search and filter your repositories to find the packages you need
  • Seamlessly install and uninstall packages from one or more repositories with a single PowerShell command


Cmdlets

Here is a list of the Cmdlets coming with this new module
Get-Command -Module OneGet

CommandType     Name                                               Source
-----------     ----                                               ------
Cmdlet          Add-PackageSource                                  OneGet
Cmdlet          Find-Package                                       OneGet
Cmdlet          Get-Package                                        OneGet
Cmdlet          Get-PackageSource                                  OneGet
Cmdlet          Install-Package                                    OneGet
Cmdlet          Remove-PackageSource                               OneGet
Cmdlet          Uninstall-Package                                  OneGet


For now, there is not much information in the help but the naming convention is explicit and we can easily understand the role of each of those:

Cmdlet Definition
Add-PackageSource Add a new Software Repository
Find-Package Search a package from one or more repositories
Get-Package Get the package installed locally
Get-PackageSource Get the Software Repositories
Install-Package Install a Package
Remove-PackageSource Remove a Package Source
Uninstall-Package Uninstall a Package


No help or examples for now (Find-Package Cmdlet)


Additional Cmdlet Get-PackageProvider ?

Note that we can also expect a new cmdlet called Get-PackageProvider in the final version from what we see in the manifest.





Workflow

From my understanding this is how the OneGet module interact with the package manager like Chocolatey.

  1. Load OneGet module in PowerShell. OneGet is the common interface for interacting with any Package Manager (Plugins).
  2. Then use a Provider for each Package Manager that plugs into OneGet. (Providers do all of the actual work, fetching content from the repositories and doing the actual installation.)
  3. The package manager will then query its software repository to retrieve the package. In this example Chocolatey use it's own set of Cmdlets (see below in this post)
  4. The package manager then download a configuration file OR get the URI where it will find the instruction to install the package. In the case of Chocolatey, a configuration file is downloaded from the repository and saved locally in C:\Chocolatey\lib\<APPNAME>\Tools,
  5. The Provider will then execute the configuration file and download the actual software (+ its dependencies) from a repository, and obviously install it.... silently :-)








Chocolatey Cmdlets
If we look at the files in the module directory, Chocolatey comes with its own set of Cmdlets. (Available on the Chocolatey GitHub repo)
C:\Windows\System32\WindowsPowerShell\v1.0\Modules\OneGet

Chocolatey Provider Cmdlets Helpers (Helpers.psm1)

Chocolatey Cmdlets (Chocolatey.psd1)

Using the module


Get the packages already installed

Since I've been using chocolatey for a while, Using Get-Package, OneGet is able to retrieve the all the package I installed on this PC.






Find and install a new package

Now if I want to install a package, that's very easy: Install-Package
We first search for the package


# We first query our provider for a package called putty
Find-Package -Name putty | fl *
# Then we install the package
Find-Package -Name putty | Install-Package -Verbose



PowerShell is download the configuration file the repository and execute it
Then Posh/OneGet is downloading the package (note the package it's not actually located on the chocolatey website)

The file are download and unzipped in C:\Chocolatey\lib directory by default.


ChocolateyInstall.ps1 content:
Install-ChocolateyZipPackage 'putty' 'http://the.earth.li/~sgtatham/putty/latest/x86/putty.zip'  "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"


Also note there is some interesting parameters in the Install-Package cmdlet:

  • InstallationOptions [hashtable]
  • InstallArguments [String]







Find and install one/multiple package(s) using Out-GridView

+Jeffrey Snover also shared a very smart line on twitter on how to use a small "GUI" to Select one or multiple packages you want to install:

# Using Out-GridView -PassThru to select the Packages
Find-Package | Out-Gridview -PassThru | Install-Package -Verbose

The other cool thing with Out-GridView is that you can also filter on multiple property





Uninstalling a package

# Get the package putty installed locally
Get-Package putty
# Get and Uninstall putty
Get-Package putty | Uninstall-Package -Verbose




Thanks for reading! If you have any questions, leave a comment or send me an email at fxcat@lazywinadmin.com. I invite you to follow me on Twitter @lazywinadm / Google+ / LinkedIn. You can also follow the LazyWinAdmin Blog on Facebook Page and Google+ Page.

12 comments:

  1. I created Helper Function for #PowerShell #OneGet to find and open Project Web site from packages found by Find-Package Cmdlet
    http://t.co/kmiBVBXVyG

    ReplyDelete
  2. I'm trying to use this to strip off the first 3 digits in a phone number report I have to do, so I need to query AD, get all user names & phone numbers, then strip off/delete the 1st 3 digits, and then export and email the csv. Any idea's how to do that reliably?

    ReplyDelete
  3. Thanks, that's great! My only problem is I should have mentioned I don't have an AD Web proxy so I have to use the Quest Cmdlets, can I do this using them?

    ReplyDelete
  4. Hi Marie, the script I shared with you use ADSI, so you dont need any module or snapin like Quest Cmdlets. It should just work fine

    Exporting the output can just be done using Export-CSV -path exported_users.csv

    Example:
    Get-DomainUser -DisplayName "*" | Export-CSV -path c:\exported_users.csv

    ReplyDelete
  5. Thank you Francois! I did not realize at first this was using ADSI, we have a 2003 domain and I don't have an AD Web service running and that leaves me struggling often, hence why I rely on the Quest AD Module.

    I do get the Username "SAMAccountName", Description, Display Name, and Telephone Number. The number outputs without the 1st three digits as I asked how to do, but I am left with the number as "-123-4567". How can I remove that leading "-" symbol?

    I then get this error and I think it's because I am searching the entire domain, how can I limit this to a single OU?

    Exception calling "Substring" with "1" argument(s): "startIndex cannot be larger than length of string.

    Parameter name: startIndex"

    At C:\scripts\list.ps1:6 char:9

    + New-Object -TypeName PSObject -Property @{

    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException

    + FullyQualifiedErrorId : ArgumentOutOfRangeException

    ReplyDelete
  6. Hi Francois, is there any way to do what I want that's not going to be a big challenge?

    I've spend a few days banging my head off the wall and can't figure this out

    ReplyDelete
  7. Hi Marie,

    You just need to change the substring value.

    see here, this should do it

    https://gist.github.com/lazywinadmin/38f8fe06e420d95acffa

    ReplyDelete
  8. Thank you again so much! Can I change the search parameter to only a specific OU and sub-OUs?

    ReplyDelete
  9. I found some ways to filter and query only an OU, but nothing is working right if I try to narrow the search scope.

    ReplyDelete
  10. Hi Marie,

    This should do it

    https://gist.github.com/lazywinadmin/b827b2a94e8089aa1520

    ReplyDelete
  11. Thanks for this complete introduction FX ! :) (I am surprised actually to see function such as "write-host" located in the Chocolatey module ^^)

    ReplyDelete