Showing posts with label OneGet. Show all posts
Showing posts with label OneGet. Show all posts

Sunday, September 20, 2015

PowerShell Gallery - Create a module for the community

With PowerShellGet, the new package manager for PowerShell, you can easily perform discovery and installation of software packages, PowerShell modules etc. in a unified way. What makes it more attractive is the ease to contribute your modules to the community so that it’s discoverable and used by users who want to.
All you need is a Microsoft account and login to the PowerShell Gallery to download your API key to publish your module. Let’s see the step by step process for the same.
  • Login to the PowerShell gallery at https://www.powershellgallery.com
  • Once you have signed in, navigate to the account page to download the API Key (https://www.powershellgallery.com/account )
  • Once you have the account key, you can use the Publish-Module command to publish your modules to the gallery.
  • For e.g. I have a module to install Visual Studio 2015 on my machine.
  • First we need to ensure that the module is available in our module path
get-module -ListAvailable
  • Now we can use the Publish-Module command as given below.
 Publish-Module -Name VisualStudio2015 -NuGetApiKey $ApiKey -Verbose


  • That’s it, it’s that simple to contribute!!!


Sunday, August 16, 2015

Software package management using PowerShell OneGet, DSC, Chef and Chocolatey

Converting your software shared repositories to a managed approach with the use of a package management system that automates the process of installing, upgrading, configuration and removal of software packages in a consistent manner is a challenging task for IT.

The idea is to distribute software installation packages that contains additional metadata like, name, version, purpose, vendor, checksum etc. that will be used in an effective manner to manage dependencies and other details that are needed for the software to run properly. Having a package management system like this, will make easier to find, install, and remove software packages in a consistent manner.

In a windows infrastructure, you can make use of the tools like chocolatey, PowerShell package management and chef to automate and create an effective package management infrastructure that converts your infrastructure as code and thus maintaining an efficient process of software installations in your company.

Without much effort you can easily setup a chocolatey repository for your packages in Azure, and then later configure this as a source in PowerShell OneGet to install packages from this source. Later you can combine this with DSC or Chef to automatically install the packages and maintain the servers in a desired state based on the configuration.

A detailed tutorial on this series can be found at the posts from the links given below:




Using DSC, OneGet and chef to install chocolatey packages

Continuing from the previous sets of posts, we'll see how to make use of the packages available in our chocolatey repository and install them using Chef.

Installation of packages from a Chocolatey source during a chef client run can be achieved in a number of ways. We can make use of the Chocolatey cookbook that is available as part of the chef community cookbooks. If you want to make use of DSC to download and install packages, then you can use a resource to install packages using OneGet on the machine.

In this part of the series, I’ll show how we can use DSC to install packages from the OneGet source.
The first step is to ensure that WMF 5.0 is installed on the server. We can make use of the chocolatey cookbook to install PowerShell 5.0 on the server as given below.

This will ensure that the required PowerShell version is installed on the server.

Once we have WMF 5.0 installed, then we can use DSC to install packages on the server.
For installing and uninstalling packages, I’ve created a DSC resource. The resource code is as given below.

enum Ensure
{
    Absent
    Present
}

[DscResource()]
class xPackageManagement
{
    [DsCProperty(Key)]
    [System.String] $Name

    [DsCProperty(Mandatory)]
    [Ensure] $Ensure

    [DsCProperty()]
    [System.String] $Version

    [DsCProperty()]
    [System.String] $Source

    [DsCProperty(NotConfigurable)]
    [Boolean] $IsValid

    [xPackageManagement] Get()
    {       
        $this.IsValid = $false
        if(-not ([string]::IsNullOrWhiteSpace($this.Version)))
        {
            $package = Get-Package |? {($_.Name -eq $this.Name) -and ($_.Version -eq $this.Version)}
        }
        else
        {
            $package = Get-Package |? {$_.Name -eq $this.Name}
        }

        if($this.Ensure -eq [Ensure]::Present)
        {
            if($package -ne $null)
            {
                $this.IsValid = $true
            }
        }
        else
        {
            if($package -eq $null)
            {
                $this.IsValid = $true
            }
        }
        return $this  
    }

    [void] Set()
    {                  
      
        if($this.Ensure -eq [Ensure]::Present)
        {      
            if(-not ([String]::IsNullOrWhiteSpace($this.Source)))
            {
                if(-not ([string]::IsNullOrWhiteSpace($this.Version)))
                {
                    Install-Package -Name $this.Name -RequiredVersion $this.Version -Source $this.Source
                }
                else
                {
                    Install-Package -Name $this.Name -Source $this.Source
                }
            }
            else
            {
                if(-not ([string]::IsNullOrWhiteSpace($this.Version)))
                {
                    Install-Package -Name $this.Name -RequiredVersion $this.Version
                }
                else
                {
                    Install-Package -Name $this.Name
                }
            }
        }
        else
        {
            if(-not ([string]::IsNullOrWhiteSpace($this.Version)))
            {
                Get-Package |? {($_.Name -eq $this.Name) -and ($_.Version -eq $this.Version)} | Uninstall-Package -Force
            }
            else
            {
                Get-Package |? {$_.Name -eq $this.Name} | Uninstall-Package -Force
            }           
        }
    }

    [bool] Test()
    {
        $result = $this.Get()

        if($this.Ensure -eq [Ensure]::Present)
        {      
            if($result.IsValid)
            {
                if(-not ([String]::IsNullOrWhiteSpace($this.Version)))
                {
                    Write-Verbose "The pacakge $($this.Name) with version $($this.Version) already exists"    
                    return $true
                }
                else
                {
                    Write-Verbose "The pacakge $($this.Name) already exists"    
                    return $true
                }
            }
            else
            {
                if(-not ([String]::IsNullOrWhiteSpace($this.Version)))
                {
                    Write-Verbose "The pacakge $($this.Name) with version $($this.Version) does not exists. This will be installed"    
                    return $false
                }
                else
                {
                    Write-Verbose "The pacakge $($this.Name) does not exists. This will be installed"    
                    return $false
                }                    
            }
        }
        else
        {
            if($result.IsValid)
            {
                Write-Verbose "The pacakge $($this.Name) does not exists"    
                return $true
            }
            else
            {
                if(-not ([String]::IsNullOrWhiteSpace($this.Version)))
                {
                    Write-Verbose "The pacakge $($this.Name) with version $($this.Version) exists. This will be uninstalled"    
                    return $false
                }
                else
                {
                    Write-Verbose "The pacakge $($this.Name) exists. This will be uninstalled"    
                    return $false
                }                 
            }
        }
    }
}

You can also download the code from the GitHub repository https://github.com/prajeeshprathap/DSCResources

Before calling this resource, we need to first register the new package source that contains our packages. We'll make use of DSC here also.

enum Ensure
{
    Absent
    Present
}

[DscResource()]
class xChocolateySource
{
    [DsCProperty(Key)]
    [System.String] $Name

    [DsCProperty(Mandatory)]
    [System.String] $Location

    [DsCProperty(Mandatory)]
    [Ensure] $Ensure

    [DsCProperty(NotConfigurable)]
    [Boolean] $IsValid

    [xChocolateySource] Get()
    {      
        $this.IsValid = $false
        $packagesource = Get-PackageSource -ProviderName chocolatey -Name $this.Name       

        if($this.Ensure -eq [Ensure]::Present)
        {
            if($packagesource -ne $null)
            {
                $this.IsValid = $true
            }
        }
        else
        {
            if($packagesource -eq $null)
            {
                $this.IsValid = $true
            }
        }
        return $this 
    }

    [void] Set()
    {                 
     
        if($this.Ensure -eq [Ensure]::Present)
        {    
            Register-PackageSource -ProviderName Chocolatey -Name $this.Name -Location $this.Location -Force -Confirm:$true           
        }
        else
        {
            Unregister-PackageSource -Source $this.Name -ProviderName Chocolatey -Force         
        }
    }

    [bool] Test()
    {
        $result = $this.Get()

        if($this.Ensure -eq [Ensure]::Present)
        {     
            if($result.IsValid)
            {
                Write-Verbose "The pacakge source $($this.Name) already exists"   
                return $true               
            }
            else
            {
                Write-Verbose "The pacakge source $($this.Name) does not exist. This will be created"   
                return $false                  
            }
        }
        else
        {
            if($result.IsValid)
            {
                Write-Verbose "The pacakge source $($this.Name) does not exists"   
                return $true
            }
            else
            {
                Write-Verbose "The pacakge source $($this.Name) exists. This will be be removed"   
                return $false                
            }
        }
    }
}

Next we’ll create a cookbook and use this resource in the cookbook to install the packages.

Knife cookbook create packagemanagement

Edit the default.rd file to invoke the created resources


After adding the resources, we can now upload the package to the server and add it to the run list

Knife cookbook upload packagemanagement




Next chef run will execute the resource and install the package from the source.


Sunday, August 2, 2015

Setup your Chocolatey repository in Azure - Part 3

PackageManagement (previously referred as OneGet) is a new feature introduced in PowerShell 5.0 to discover and install software packages from around the web. It is a manager or multiplexor of existing package managers (also called package providers) that unifies Windows package management with a single Windows PowerShell interface. With PackageManagement, you can do the following.

Manage a list of software repositories in which packages can be searched, acquired, and installed
Discover software packages you need

Seamlessly install, uninstall, and inventory packages from one or more software repositories
To see the commands supported by PackageManagement, use the Get-Command as given below.


PS C:\> Get-Command -Module PackageManagement | ft -Property Name, Version, Source

Name                     Version Source          
----                     ------- ------          
Find-Package             1.0.0.0 PackageManagement
Get-Package              1.0.0.0 PackageManagement
Get-PackageProvider      1.0.0.0 PackageManagement
Get-PackageSource        1.0.0.0 PackageManagement
Install-Package          1.0.0.0 PackageManagement
Register-PackageSource   1.0.0.0 PackageManagement
Save-Package             1.0.0.0 PackageManagement
Set-PackageSource        1.0.0.0 PackageManagement
Uninstall-Package        1.0.0.0 PackageManagement
Unregister-PackageSource 1.0.0.0 PackageManagement


By default a set of providers with sources are configured in PackageManagement. You can use the Get-PackageSource cmdlet to see the available sources.


PS C:\> Get-PackageProvider | select name

Name     
----     
msu      
Programs 
msi      
PSModule 
Chocolatey
NuGet     



PS C:\> Get-PackageSource -ProviderName Chocolatey | ft ProviderName, IsTrusted, IsRegistered, Location

ProviderName IsTrusted IsRegistered Location                    
------------ --------- ------------ --------                    
Chocolatey       False         True http://chocolatey.org/api/v2/


Each PackageManagement provider may have one or multiple software sources, or repositories. The Get-PackageSource cmdlet can be used to discover what repositories are associated with a provider. For e.g. to see the sources associated with the Chocolatey provider use the cmdlet as given below. The Register-PackageSource cmdlet can be used to add a new source to the existing provider. We'll use this cmdlet to register the Chocolatey source we created in the previous post to the PackageManagement provider as given below.



PS C:\> Register-PackageSource –provider Chocolatey –name AzureChoco –location http://prajeeshchoco.azurewebsites.net/nuget

Name                             ProviderName     IsTrusted  IsRegistered IsValidated  Location                                                        
----                             ------------     ---------  ------------ -----------  --------                                                         
AzureChoco                       Chocolatey       False      True         True         http://prajeeshchoco.azurewebsites.net/nuget                    



PS C:\> Get-PackageSource -ProviderName Chocolatey | ft ProviderName, IsTrusted, IsRegistered, Location

ProviderName IsTrusted IsRegistered Location                                   
------------ --------- ------------ --------                                   
Chocolatey       False         True http://chocolatey.org/api/v2/              
Chocolatey       False         True http://prajeeshchoco.azurewebsites.net/nuget  



We’ve successfully registered our Chocolatey repository to the source, we can now find and install packages using the PackageManagement as  given.


PS C:\> Find-Package -Source AzureChoco | ft Name, Version, source

Name Version Source   
---- ------- ------   
Foxe 1.2.0   AzureChoco