Chocolatey.psm1

using namespace System.Management.Automation
#Region '.\Enum\Ensure.ps1' 0
enum Ensure
{
    Absent
    Present
}
#EndRegion '.\Enum\Ensure.ps1' 6
#Region '.\Classes\001.ChocolateyReason.ps1' 0
class ChocolateyReason
{
    [DscProperty(NotConfigurable)]
    [string] $Code

    [DscProperty(NotConfigurable)]
    [string] $Phrase
}
#EndRegion '.\Classes\001.ChocolateyReason.ps1' 9
#Region '.\Classes\002.ChocolateyPackage.ps1' 0
#using namespace System.Management.Automation

<#
    .SYNOPSIS
        The `ChocolateyPackage` DSC resource is used to install or remove chocolatey
        packages.
    .DESCRIPTION
        The ChocolateyPackage DSC Resource helps with chocolatey package management.
    .PARAMETER Name
        The name of the ChocolateyPackage to set in the desired state.
    .PARAMETER Version
        The version of the package to install. If not set, it will only ensure the package
        is present/absent.
        If set to latest, it will always make sure the latest version available on the source is
        the one installed.
        If set to a version it will try to compare and make sure the installed version is greater
        or equal than the one desired.
    .PARAMETER ChocolateyOptions
        Chocolatey parameters as per the Install or Update chocolateyPackage commands.
    .PARAMETER UpdateOnly
        Only update the package if present.
        When absent do not attempt to install.
    .PARAMETER Reasons
        Reason for compliance or non-compliance returned by the Get method.
    .EXAMPLE
        Invoke-DscResource -ModuleName Chocolatey -Name ChocolateyPackage -Method Get -Property @{
            Ensure = 'present'
            Name = 'localhost'
            UpdateOnly = $true
        }
 
        This example shows how to call the resource using Invoke-DscResource.
#>

[DscResource(RunAsCredential = 'Optional')]
class ChocolateyPackage
{
    [DscProperty(Mandatory)]
    [Ensure] $Ensure = 'Present'

    [DscProperty(Key)]
    [String] $Name

    [DscProperty()]
    [String] $Version

    [DscProperty()]
    [hashtable] $ChocolateyOptions

    [DscProperty()]
    [PSCredential] $Credential

    [DscProperty(NotConfigurable)]
    [bool] $UpdateOnly

    [DscProperty(NotConfigurable)]
    [ChocolateyReason[]] $Reasons

    [ChocolateyPackage] Get()
    {
        $currentState = [ChocolateyPackage]::new()
        $currentState.Name = $this.Name

        if ($false -eq (Test-ChocolateyInstall))
        {
            Write-Debug -Message 'Chocolatey is not installed.'
            $currentState.Ensure = 'Absent'

            $currentState.Reasons += @{
                code = 'ChocolateyPackage:ChocolateyPackage:ChocolateyNotInstalled'
                phrase = 'The Chocolatey software is not installed. We cannot check if a package is present using choco.'
            }

            return $currentState
        }

        try
        {
            $localPackage = Get-ChocolateyPackage -LocalOnly -Name $this.Name -Exact
        }
        catch
        {
            Write-Verbose -Message ('Exception Caught:' -f $_)
            $localPackage = $null
            $currentState.Reasons += @{
                code = 'ChocolateyPackage:ChocolateyPackage:ChocolateyError'
                phrase = ('Error: {0}.' -f $_)
            }
        }

        if ($null -eq $localPackage)
        {
            Write-Debug -Message ('Local Package ''{0}'' not found.' -f $this.Name)
            $currentState.Ensure = [Ensure]::Absent
        }
        else
        {
            Write-Debug -Message ('Local Package found: {0}' -f ($localPackage | ConvertTo-Json))
            $currentState.Ensure = [ensure]::Present
            $currentState.Version = $localPackage.Version
        }

        if ($this.Ensure -eq 'Absent' -and $currentState.Ensure -eq $this.Ensure)
        {
            Write-Debug -Message ('The package named ''{0}'' is absent as expected.' -f $this.Name)
            $currentState.Reasons += @{
                Code   = ('ChocolateyPackage:ChocolateyPackage:Compliant')
                Phrase = ('The Package ''{0}'' is not installed as desired.' -f $currentState.Name)
            }
        }
        elseif ([string]::IsNullOrEmpty($this.Version) -and $currentState.Ensure -eq $this.Ensure)
        {
            Write-Debug -Message ('The package named ''{0}'' is present as expected. No version required.' -f $this.Name)
            $currentState.Reasons += @{
                Code   = ('ChocolateyPackage:ChocolateyPackage:Compliant')
                Phrase = ('The Package ''{0}'' is installed (with version ''{1}'').' -f $currentState.Name, $currentState.Version)
            }
        }
        elseif (-not [string]::IsNullOrEmpty($this.Version) -and $this.Version -eq $localPackage.Version -and $currentState.Ensure -eq $this.Ensure)
        {
            Write-Debug -Message ('The package named ''{0}'' is present with expected version.' -f $this.Name)
            $currentState.Reasons += @{
                Code   = ('ChocolateyPackage:ChocolateyPackage:Compliant')
                Phrase = ('The Package ''{0}'' is installed with expected version ''{1}''.' -f $currentState.Name, $currentState.Version)
            }
        }
        elseif ($currentState.Ensure -ne $this.Ensure)
        {
            if ($this.Ensure -eq 'Absent')
            {
                $currentState.Reasons += @{
                    Code   = ('ChocolateyPackage:ChocolateyPackage:ShouldNotBeInstalled')
                    Phrase = ('The Package ''{0}'' is installed with version ''{1}'' but is NOT expected to be present.' -f $currentState.Name, $currentState.Version)
                }
            }
            else
            {
                $currentState.Reasons += @{
                    Code   = ('ChocolateyPackage:ChocolateyPackage:ShouldBeInstalled')
                    Phrase = ('The Package ''{0}'' is not installed but is expected to be present.' -f $currentState.Name)
                }
            }
        }
        else
        {
            Write-Debug -Message ('The package named ''{0}'' is ''Present'' with version ''{1}'' while we expect version ''{2}''.' -f $this.Name, $currentState.Version,$this.Version)
            if ('latest' -eq $this.Version)
            {
                Write-Debug -Message (' Grabbing the latest version of ''{0}'' from source.' -f $this.Name)
                $searchVersionParam = @{
                    Exact = $true
                    Name  = $this.Name
                }

                if ($this.ChocolateyOptions -and $this.ChocolateyOptions.ContainsKey('source'))
                {
                    Write-Debug -Message (' Searching in specified source ''{0}''.' -f $this.ChocolateyOptions['source'])
                    $searchVersionParam['source'] = $this.ChocolateyOptions['source']
                }

                Write-Debug -Message (' Searching with ''Get-ChocolateyPackage'' and parameters {0}' -f ($searchVersionParam | ConvertTo-Json -Depth 3))
                $refVersionPackage = Get-ChocolateyPackage @searchVersionParam

                if ($null -eq $refVersionPackage)
                {
                    Write-Debug -Message ('The package ''{0}'' could not be found on the source repository.' -f $this.Name)
                    $refVersion = $null
                    $currentState.Reasons += @{
                        Code   = ('ChocolateyPackage:ChocolateyPackage:LatestPackageNotFound')
                        Phrase = ('The Package ''{0}'' is installed with version ''{1}'' but couldn''t be found on the source.' -f $currentState.Name, $currentState.Version, $this.Version)
                    }
                }
                else
                {
                    $refVersion = $refVersionPackage.Version
                    Write-Debug -Message ('Latest version for ''{0}'' found in source is ''{1}''.' -f $this.Name, $refVersion)
                }
            }
            else
            {
                $refVersion = $this.Version
            }

            if ([string]::IsNullOrEmpty($refVersion))
            {
                # No need to check for version because the 'LatestPackageNotFound' on source...
            }
            elseif ((Compare-SemVerVersion -ReferenceVersion $refVersion -DifferenceVersion $currentState.version) -in @('=', '<'))
            {
                $currentState.Reasons += @{
                    Code   = ('ChocolateyPackage:ChocolateyPackage:Compliant')
                    Phrase = ('The Package ''{0}'' is installed with version ''{1}'' higher or equal than the expected ''{2}'' (''{3}'').' -f $currentState.Name, $currentState.Version, $this.Version, $refVersion)
                }
            }
            else
            {
                $currentState.Reasons += @{
                    Code   = ('ChocolateyPackage:ChocolateyPackage:BelowExpectedVersion')
                    Phrase = ('The Package ''{0}'' is installed with version ''{1}'' Lower than the expected ''{2}''.' -f $currentState.Name, $currentState.Version, $this.Version)
                }
            }
        }

        return $currentState
    }

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

        if ($currentState.Reasons.Code.Where({$_ -in @('BelowExpectedVersion','ShouldBeInstalled','ShouldNotBeInstalled')}))
        {
            return $false
        }
        else
        {
            return $true
        }
    }

    [void] Set()
    {
        [ChocolateyPackage] $currentState = $this.Get()
        $chocoCommand = Get-Command -Name 'Install-ChocolateyPackage'
        [hashtable] $chocoCommandParams = @{
            Name        = $this.Name
            Confirm     = $false
            ErrorAction = 'Stop'
        }

        switch -Regex ($currentState.Reasons.Code)
        {
            'BelowExpectedVersion$'
            {
                Write-Debug -Message ('Upgrading package ''{0}'' to version ''{1}''.' -f $this.Name, $this.Version)
                $chocoCommand =  Get-Command -Name 'Update-ChocolateyPackage' -Module 'Chocolatey'
            }

            'ShouldBeInstalled$'
            {
                $chocoCommand = Get-Command -Name 'Install-ChocolateyPackage' -Module 'Chocolatey'

                if ('latest' -eq $this.Version -or [string]::IsNullOrEmpty($this.Version))
                {
                    Write-Debug -Message ('Installing the ''latest'' version of ''{0}'' from the configured or specified source.' -f $this.Name)
                }
                else
                {
                    Write-Debug -Message ('Installing package ''{0}'' to version ''{1}''.' -f $this.Name, $this.Version)
                    $chocoCommandParams['Version'] = $this.Version
                }
            }

            'ShouldNotBeInstalled$'
            {
                $chocoCommand = Get-Command -Name 'Uninstall-ChocolateyPackage' -Module 'Chocolatey'
            }
        }

        if ($this.UpdateOnly -and $chocoCommand.Name -eq 'Install-ChocolateyPackage')
        {
            Write-Verbose -Message ('Skipping install of ''{0}'' because ''UpdateOnly'' is set.' -f $this.Name)
            return
        }

        if ($this.Credential)
        {
            $chocoCommandParams['Credential'] = $this.Credential
        }

        $this.ChocolateyOptions.keys.Where{$_ -notin $chocoCommandParams.Keys}.Foreach{
            if ($chocoCommand.Parameters.Keys -contains $_)
            {
                if ($this.ChocolateyOptions[$_] -in @('True','False'))
                {
                    $chocoCommandParams[$_] = [bool]::Parse($this.ChocolateyOptions[$_])
                }
                else
                {
                    $chocoCommandParams[$_] = $this.ChocolateyOptions[$_]
                }
            }
            else
            {
                Write-Verbose -Message (' Ignoring parameter ''{0}''. Not suported by ''{1}''.' -f $_, $chocoCommand.Name)
            }
        }

        Write-Verbose -Message (' Calling ''{0}'' with parameters {1}.' -f $chocoCommand.Name,($chocoCommandParams | ConvertTo-Json -Depth 3))
        &$($chocoCommand.Name) @ChocoCommandParams
    }
}
#EndRegion '.\Classes\002.ChocolateyPackage.ps1' 292
#Region '.\Classes\003.ChocolateySoftware.ps1' 0
#using namespace System.Management.Automation

<#
    .SYNOPSIS
        The `ChocolateySoftware` DSC resource is used to install or remove choco.exe.
    .DESCRIPTION
        Install Chocolatey Software either from a fixed URL where the chocolatey nupkg is stored,
        or from the url of a NuGet feed containing the Chocolatey Package.
        A version can be specified to lookup the Package feed for a specific version, and install it.
        A proxy URL and credential can be specified to fetch the Chocolatey package, or the proxy configuration
        can be ignored.
    .PARAMETER Ensure
        Indicate whether the Chocolatey Software should be installed or not on the system.
    .PARAMETER Version
        Version to install if you want to be specific, this is the way to Install a pre-release version, as when not specified,
        the latest non-prerelease version is looked up from the feed defined in PackageFeedUrl.
    .PARAMETER ChocolateyPackageUrl
        Exact URL of the chocolatey package. This can be an HTTP server, a network or local path.
        This must be the .nupkg package as downloadable from here: https://chocolatey.org/packages/chocolatey
    .PARAMETER PackageFeedUrl
        Url of the NuGet Feed API to use for looking up the latest version of Chocolatey (available on that feed).
        This is also used when searching for a specific version, doing a lookup via an Odata filter.
    .PARAMETER ChocoTempDir
        The temporary folder to extract the Chocolatey Binaries during install. This does not set the Chocolatey Cache dir.
    .PARAMETER IgnoreProxy
        Ensure the proxy is bypassed when downloading the Chocolatey Package from the URL.
    .PARAMETER ProxyCredential
        Credential to authenticate to the proxy, if not specified but the ProxyLocation is set, an attempt
        to use the Cached credential will be made.
    .PARAMETER ProxyLocation
        Proxy url to use when downloading the Chocolatey Package for installation.
    .EXAMPLE
        Invoke-DscResource -ModuleName Chocolatey -Name ChocolateySoftware -Method Get -Property @{
            Ensure = 'Present'
        }
 
        # This example shows how to call the resource using Invoke-DscResource.
#>

[DscResource()]
class ChocolateySoftware
{
    [DscProperty(Key)]
    [Ensure] $Ensure = 'Present'

    [DscProperty()]
    [String] $InstallationDirectory

    [DscProperty()] #WriteOnly
    [String] $ChocolateyPackageUrl

    [DscProperty()] #WriteOnly
    [String] $PackageFeedUrl

    [DscProperty()] #WriteOnly
    [string] $Version

    [DscProperty()] #WriteOnly
    [String] $ChocoTempDir

    [DscProperty()] #WriteOnly
    [string] $ProxyLocation

    [DscProperty()] #WriteOnly
    [bool]   $IgnoreProxy

    [DscProperty()] #WriteOnly
    [PSCredential] $ProxyCredential

    [DscProperty(NotConfigurable)]
    [ChocolateyReason[]] $Reasons

    [ChocolateySoftware] Get()
    {
        $currentState = [ChocolateySoftware]::new()
        $chocoExe = @(Get-Command -Name 'choco.exe' -ErrorAction 'Ignore')[0]

        if ($null -eq $chocoExe)
        {
            Write-Verbose -Message ('Path: {0}' -f $ENV:Path)
            $currentState.Ensure = 'Absent'
        }
        else
        {
            $currentState.Ensure = 'Present'
            $chocoBin = Split-Path -Path $chocoExe.Path -Parent
            $chocoInstallPath = Split-Path -Path $chocoBin -Parent
            $currentState.InstallationDirectory = $chocoInstallPath
        }

        if ($this.Ensure -eq 'Present' -and $currentState.Ensure -eq 'Absent')
        {
            Write-Debug -Message 'Choco not found while it should be installed.'
            $currentState.Reasons += @{
                code = 'ChocolateySoftware:ChocolateySoftware:ChocoShouldBeInstalled'
                phrase = 'The Chocolatey software is not installed but is expected to be.'
            }
        }
        elseif ($this.Ensure -eq 'Absent' -and $currentState.Ensure -eq $this.Ensure)
        {
            Write-Debug -Message 'Choco not found as expected.'
            $currentState.Reasons += @{
                code = 'ChocolateySoftware:ChocolateySoftware:Compliant'
                phrase = 'Chocolatey software is absent as expected.'
            }
        }
        elseif ($this.Ensure -eq 'Absent' -and $currentState.Ensure -eq 'Present')
        {
            Write-Debug -Message 'Choco found while it should be ''Absent''.'
            $currentState.Reasons += @{
                code = 'ChocolateySoftware:ChocolateySoftware:ChocoShouldBeRemoved'
                phrase = 'Chocolatey software is unexpectedly present and should be uninstalled.'
            }
        }
        else
        {
            Write-Verbose -Message 'Choco.exe is found as expected, let''s retrieve its Install Directory.'
            # Present as it should
            if ([string]::IsNullOrEmpty($this.InstallationDirectory) -or $this.InstallationDirectory -eq $currentState.InstallationDirectory)
            {
                $currentState.Reasons += @{
                    code = 'ChocolateySoftware:ChocolateySoftware:Compliant'
                    phrase = ('Choco.exe is correctly installed at ''{0}''.' -f $currentState.InstallationDirectory)
                }
            }
            else
            {
                $currentState.Reasons += @{
                    code = 'ChocolateySoftware:ChocolateySoftware:ChocoInstalledInWrongDirectory'
                    phrase = ('Choco.exe is **incorrectly** installed at ''{0}''. Unable to remediate.' -f $currentState.InstallationDirectory)
                }
            }
        }

        return $currentState
    }

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

        if ($currentState.Reasons.Code.Where{$_ -notmatch 'Compliant$'})
        {
            return $false
        }
        else
        {
            return $true
        }
    }

    [void] Set()
    {
        $currentState = $this.Get()

        if ($currentState.Reasons.code.Where{$_ -match 'ChocoShouldBeInstalled$'})
        {
            $properties = @(
                'ChocolateyPackageUrl'
                'PackageFeedUrl'
                'Version'
                'ChocoTempDir'
                'ProxyLocation'
                'InstallationDirectory'
                'IgnoreProxy'
                'InstallationDirectory'
                'ProxyCredential'
            )

            $installChocoSoftwareParam = @{}

            $properties.Where{-not [string]::IsNullOrEmpty($this.($_))}.Foreach{
                $installChocoSoftwareParam[$_] = $this.($_)
            }

            Write-Debug -Message ('Installing Chocolatey with parameters: {0}' -f ($installChocoSoftwareParam | ConvertTo-Json -Depth 2))
            Install-ChocolateySoftware @installChocoSoftwareParam
        }
        elseif ($currentState.Reasons.code.Where{$_ -match 'ChocoShouldBeRemoved$'})
        {
            if ( -not [string]::isNullOrEmpty($this.InstallationDirectory))
            {
                Write-Debug -Message ('Uninstall-Chocolatey -InstallationDir ''{0}''' -f $this.InstallationDirectory)
                $null = Uninstall-Chocolatey -InstallationDir $this.InstallationDirectory -Confirm:$false
            }
            else
            {
                $null = Uninstall-Chocolatey -Confirm:$false
            }
        }
        else
        {
            Write-Verbose -Message 'No ChocolateySoftware action taken.'
        }
    }
}
#EndRegion '.\Classes\003.ChocolateySoftware.ps1' 196
#Region '.\Classes\004.ChocolateySource.ps1' 0

<#
    .SYNOPSIS
        The `ChocolateySource` DSC resource is used to configure or remove source feeds for chocolatey.
 
    .DESCRIPTION
        Chocolatey will allow you to interact with sources.
        You can register a new source, whether internal or external with some source
        specific settings such as proxy.
 
    .PARAMETER Ensure
        Indicate whether the Chocolatey source should be installed or removed from the system.
 
    .PARAMETER Name
        Name - the name of the source. Required with some actions. Defaults to empty.
 
    .PARAMETER Source
        Source - The source. This can be a folder/file share or an http location.
        If it is a url, it will be a location you can go to in a browser and
        it returns OData with something that says Packages in the browser,
        similar to what you see when you go to https://chocolatey.org/api/v2/.
        Defaults to empty.
 
    .PARAMETER Disabled
        Allow the source to be registered but disabled.
 
    .PARAMETER BypassProxy
        Bypass Proxy - Should this source explicitly bypass any explicitly or
        system configured proxies? Defaults to false. Available in 0.10.4+.
 
    .PARAMETER SelfService
        Allow Self-Service - Should this source be allowed to be used with self-
        service? Requires business edition (v1.10.0+) with feature
        'useBackgroundServiceWithSelfServiceSourcesOnly' turned on. Defaults to
        false. Available in 0.10.4+.
 
    .PARAMETER Priority
        Priority - The priority order of this source as compared to other
        sources, lower is better. Defaults to 0 (no priority). All priorities
        above 0 will be evaluated first, then zero-based values will be
        evaluated in config file order. Available in 0.9.9.9+.
 
    .PARAMETER Credential
        Credential used with authenticated feeds. Defaults to empty.
 
    .EXAMPLE
        Invoke-DscResource -ModuleName Chocolatey -Name ChocolateySource -Method Get -Property @{
            Ensure = 'Present'
            Name = 'Chocolatey'
            Disable = $true
        }
 
        # This example shows how to call the resource using Invoke-DscResource.
#>

[DscResource()]
class ChocolateySource
{
    [DscProperty()]
    [Ensure] $Ensure = 'Present'

    [DscProperty(Key)]
    [string] $Name

    [DscProperty()]
    # If we want to make sure a source is disabled, we don't need to provide its
    # source location
    [string] $Source

    [DscProperty()]
    [Nullable[bool]] $Disabled

    [DscProperty()]
    [Nullable[bool]] $ByPassProxy

    [DscProperty()]
    [Nullable[bool]] $SelfService

    [DscProperty()]
    [Nullable[int]] $Priority

    [DscProperty()]
    [String] $Username

    [DscProperty()]
    [String] $Password

    [DscProperty()] # WriteOnly
    [pscredential] $Credential

    [DscProperty(NotConfigurable)]
    [ChocolateyReason[]] $Reasons


    [ChocolateySource] Get()
    {
        $currentState = [ChocolateySource]::New()
        $currentState.Name = $this.Name

        try
        {
            $localSource = Get-ChocolateySource -Name $this.Name
        }
        catch
        {
            Write-Verbose -Message ('Exception Caught:' -f $_)
            $localSource = $null
            $currentState.Reasons += @{
                code = 'ChocolateySource:ChocolateySource:ChocolateyError'
                phrase = ('Error: {0}.' -f $_)
            }
        }

        if ($localSource.Name -eq $this.Name)
        {
            $currentState.Ensure = 'Present'
        }
        else
        {
            $currentState.Ensure = 'Absent'
        }

        if ($this.Ensure -ne $currentState.Ensure)
        {
            if ($this.Ensure -eq 'Absent')
            {
                $currentState.Reasons += @{
                    code = 'ChocolateySource:ChocolateySource:ShouldBeAbsent'
                    phrase = ('The source ''{0}'' is ''Present'' but should be ''Absent''.' -f $this.Name)
                }
            }
            else
            {
                $currentState.Reasons += @{
                    code = 'ChocolateySource:ChocolateySource:ShouldBePresent'
                    phrase = ('The source ''{0}'' is ''Absent'' but should be ''Present''.' -f $this.Name)
                }
            }
        }
        else
        {
            $currentState.Reasons += @{
                code = 'ChocolateySource:ChocolateySource:EnsureCompliant'
                phrase = ('The source ''{0}'' is ''{1}'' as expected.' -f $this.Name, $this.Ensure)
            }
        }

        $currentState.Source = $localSource.Source
        $currentState.Disabled = $localSource.Disabled
        $currentState.ByPassProxy = $localSource.ByPassProxy
        $currentState.SelfService = $localSource.SelfService
        $currentState.Priority = $localSource.Priority
        $currentState.Username = $localSource.user
        $currentState.Password = $localSource.password

        if (-not [string]::isNullOrEmpty($this.Source) -and $currentState.Source -ne $this.Source)
        {
            $currentState.Reasons += [ChocolateyReason]@{
                code = 'ChocolateySource:ChocolateySource:IncorrectSource'
                phrase = ('The ChocolateySource for source named ''{0}'' is expected to be ''{1}'' and was ''{2}''.' -f $this.Name, $this.Source, $currentState.Source)
            }
        }
        elseif (-not [string]::isNullOrEmpty($this.Source) )
        {
            $currentState.Reasons += [ChocolateyReason]@{
                code = 'ChocolateySource:ChocolateySource:SourceCompliant'
                phrase = ('The ChocolateySource for source named ''{0}'' is ''{1}'' as expected.' -f $this.Name, $currentState.Source)
            }
        }


        if (-not [string]::isNullOrEmpty($this.Disabled) -and $currentState.Disabled -ne $this.Disabled)
        {
            $currentState.Reasons += [ChocolateyReason]@{
                code = 'ChocolateySource:ChocolateySource:DisabledNotExpected'
                phrase = ('The Chocolatey Source named ''{0}'' is expected to have disabled as ''{1}'' and was ''{2}''.' -f $this.Name, $this.Disabled, $currentState.Disabled)
            }
        }
        elseif (-not [string]::isNullOrEmpty($this.Disabled))
        {
            $currentState.Reasons += [ChocolateyReason]@{
                code = 'ChocolateySource:ChocolateySource:DisabledCompliant'
                phrase = ('The Chocolatey Source named ''{0}'' has disabled set to ''{1}'' as expected.' -f $this.Name, $this.Disabled, $currentState.Disabled)
            }
        }

        if (-not [string]::isNullOrEmpty($this.ByPassProxy) -and $currentState.ByPassProxy -ne $this.ByPassProxy)
        {
            $currentState.Reasons += [ChocolateyReason]@{
                code = 'ChocolateySource:ChocolateySource:ByPassProxyNotExpected'
                phrase = ('The Chocolatey ByPassProxy for source name ''{0}'' is expected to be ''{1}'' and was ''{2}''.' -f $this.Name, $this.ByPassProxy, $currentState.ByPassProxy)
            }
        }
        elseif (-not [string]::isNullOrEmpty($this.ByPassProxy))
        {
            $currentState.Reasons += [ChocolateyReason]@{
                code = 'ChocolateySource:ChocolateySource:ByPassProxyCompliant'
                phrase = ('The Chocolatey ByPassProxy for source name ''{0}'' is ''{1}'' as expected.' -f $this.Name, $currentState.ByPassProxy)
            }
        }

        if (-not [string]::isNullOrEmpty($this.selfService) -and $currentState.selfService -ne $this.selfService)
        {
            $currentState.Reasons += [ChocolateyReason]@{
                code = 'ChocolateySource:ChocolateySource:SelfServiceNotExpected'
                phrase = ('The Chocolatey SelfService for source name ''{0}'' is expected to be ''{1}'' and was ''{2}''.' -f $this.Name, $this.SelfService, $currentState.SelfService)
            }
        }
        elseif (-not [string]::isNullOrEmpty($this.selfService))
        {
            $currentState.Reasons += [ChocolateyReason]@{
                code = 'ChocolateySource:ChocolateySource:SelfServiceCompliant'
                phrase = ('The Chocolatey SelfService for source name ''{0}'' is ''{1}'' as expected.' -f $this.Name, $currentState.SelfService)
            }
        }

        if (-not [string]::isNullOrEmpty($this.priority) -and $currentState.priority -ne $this.priority)
        {
            $currentState.Reasons += [ChocolateyReason]@{
                code = 'ChocolateySource:ChocolateySource:PriorityIncorrect'
                phrase = ('The priority for source name ''{0}'' is expected to be ''{1}'' and was ''{2}''.' -f $this.Name, $this.priority, $currentState.priority)
            }
        }
        elseif (-not [string]::isNullOrEmpty($this.priority))
        {
            $currentState.Reasons += [ChocolateyReason]@{
                code = 'ChocolateySource:ChocolateySource:PriorityCompliant'
                phrase = ('The priority for source name ''{0}'' is ''{1}'' as expected.' -f $this.Name, $currentState.priority)
            }
        }

        if (-not [string]::isNullOrEmpty($this.Username) -and $currentState.Username -ne $this.Username)
        {
            $currentState.Reasons += [ChocolateyReason]@{
                code = 'ChocolateySource:ChocolateySource:UsernameNotExpected'
                phrase = ('The ChocolateySource for source name ''{0}'' is expected to have the user ''{1}'' and was ''{2}''.' -f $this.Name, $this.Username, $currentState.Username)
            }
        }
        elseif (-not [string]::isNullOrEmpty($this.Username)) # Username compliant
        {
            $currentState.Reasons += [ChocolateyReason]@{
                code = 'ChocolateySource:ChocolateySource:UsernameCompliant'
                phrase = ('The ChocolateySource username for source name ''{0}'' is ''{1}'' as expected.' -f $this.Name, $currentState.Username)
            }
        }

        return $currentState
    }

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

        if ($currentState.Reasons.code.Where({$_ -notmatch 'compliant$'}))
        {
            return $false
        }
        else
        {
            return $true
        }
    }

    [void] Set()
    {
        $currentState = $this.Get()

        switch -Regex ($currentState.Reasons.Code)
        {
            'ShouldBeAbsent$'
            {
                Unregister-ChocolateySource -Name $this.Name -Force
            }

            'ShouldBePresent$|IncorrectSource$|ByPassProxyNotExpected$|PriorityIncorrect$|UsernameNotExpected$'
            {
                #Register-ChocolateySource -Name $this.Name -Force
                $registerChocolateySourceParams = @{
                    Name = $this.Name
                    Source = $this.Source
                }

                if (-not [string]::isNullOrEmpty($this.Disabled))
                {
                    $registerChocolateySourceParams['Disabled'] = $this.Disabled
                }

                if (-not [string]::IsNullOrEmpty($this.ByPassProxy))
                {
                    $registerChocolateySourceParams['ByPassProxy'] = $this.ByPassProxy
                }

                if (-not [string]::IsNullOrEmpty($this.SelfService))
                {
                    $registerChocolateySourceParams['SelfService'] = $this.SelfService
                }

                if (-not [string]::IsNullOrEmpty($this.Priority))
                {
                    $registerChocolateySourceParams['Priority'] = $this.Priority
                }

                if (-not [string]::IsNullOrEmpty($this.Username))
                {
                    $registerChocolateySourceParams['KeyUser'] = $this.Username
                    throw 'NotImplementedYet'
                }

                if (-not [string]::isNullOrEmpty($this.Password))
                {
                    $registerChocolateySourceParams['Key'] = $this.Password
                }

                if (-not [string]::IsNullOrEmpty($this.Credential))
                {
                    $registerChocolateySourceParams['Credential'] = $this.Credential
                }

                Register-ChocolateySource @registerChocolateySourceParams
                return
            }

            'DisabledNotExpected$'
            {
                if ($currentState.Disabled)
                {
                    Enable-ChocolateySource -Name $this.Name
                }
                else
                {
                    Disable-ChocolateySource -Name $this.Name
                }
            }
        }
    }
}
#EndRegion '.\Classes\004.ChocolateySource.ps1' 336
#Region '.\Classes\005.ChocolateyFeature.ps1' 0

<#
    .SYNOPSIS
        The `ChocolateyFeature` DSC resource is used to enable or disable features.
 
    .DESCRIPTION
        Chocolatey configuration lets you enable or disabled features, but while some are
        set by defaults.
        This resources lets you enable or disable a feature, but also tells you if it's been
        set or just left as default.
 
    .PARAMETER Ensure
        Indicate whether the Chocolatey feature should be enabled or disabled on the system.
 
    .PARAMETER Name
        Name - the name of the feature.
 
    .EXAMPLE
        Invoke-DscResource -ModuleName Chocolatey -Name ChocolateyFeature -Method Get -Property @{
            Ensure = 'Absent'
            Name = 'showDownloadProgress'
        }
 
        # This example shows how to disable the feature showDownloadProgress using Invoke-DscResource.
#>

[DscResource()]
class ChocolateyFeature
{
    [DscProperty()]
    [Ensure] $Ensure = 'Present'

    [DscProperty(Key)]
    [string] $Name

    [DscProperty(NotConfigurable)]
    [ChocolateyReason[]] $Reasons

    [ChocolateyFeature] Get()
    {
        $currentState = [ChocolateyFeature]::new()
        $currentState.Name = $this.Name

        try
        {
            $feature = Get-ChocolateyFeature -Name $this.Name
            $currentState.Ensure = if ($feature.enabled -eq 'true')
            {
                'Present'
            }
            else
            {
                'Absent'
            }
        }
        catch
        {
            Write-Verbose -Message ('Exception Caught:' -f $_)
            $feature = $null
            $currentState.Ensure = 'Absent'
            $currentState.Reasons += @{
                code = 'ChocolateySource:ChocolateySource:ChocolateyError'
                phrase = ('Error: {0}.' -f $_)
            }
        }

        if ($null -eq $feature)
        {
            $currentState.Reasons += @{
                code = 'ChocolateyFeature:ChocolateyFeature:FeatureNotFound'
                phrase = ('The feature ''{0}'' was not found.' -f $this.Name)
            }
        }
        elseif ($currentState.Ensure -eq 'Present' -and $this.Ensure -eq 'Present')
        {
            $currentState.Reasons += @{
                code = 'ChocolateyFeature:ChocolateyFeature:FeaturePresentCompliant'
                phrase = ('The feature ''{0}'' is enabled as expected. Set Explicitly is {1}.' -f $this.Name, $feature.setExplicitly)
            }
        }
        elseif ($currentState.Ensure -eq 'Present'  -and $this.Ensure -eq 'Absent')
        {
            $currentState.Reasons += @{
                code = 'ChocolateyFeature:ChocolateyFeature:FeatureShouldBeDisabled'
                phrase = ('The feature ''{0}'' is enabled while it''s expected to be disabled. Set Explicitly is {1}.' -f $this.Name, $feature.setExplicitly)
            }
        }
        elseif ($currentState.Ensure -eq 'Absent' -and $this.Ensure -eq 'Absent')
        {
            $currentState.Reasons += @{
                code = 'ChocolateyFeature:ChocolateyFeature:FeatureAbsentCompliant'
                phrase = ('The feature ''{0}'' is disabled as expected. Set Explicitly is {1}.' -f $this.Name, $feature.setExplicitly)
            }
        }
        elseif ($currentState.Ensure -eq 'Absent' -and $this.Ensure -eq 'Present')
        {
            $currentState.Reasons += @{
                code = 'ChocolateyFeature:ChocolateyFeature:FeatureShouldBeEnabled'
                phrase = ('The feature ''{0}'' is disabled but we expected it enabled. Set Explicitly is {1}.' -f $this.Name, $feature.setExplicitly)
            }
        }

        return $currentState
    }

    [bool] Test()
    {
        $currentState = $this.Get()
        $currentState.Reasons.code.Where{
            $_ -notmatch 'Compliant$'
        }

        if ($currentState.count -eq 0)
        {
            return $true
        }
        else
        {
            return $false
        }
    }

    [void] Set()
    {
        $currentState = $this.Get()

        switch -Regex ($currentState.Reasons.code)
        {
            'FeatureShouldBeDisabled$'
            {
                # Disable the feature
                Disable-ChocolateyFeature -Name $this.Name -Confirm:$false
            }

            'FeatureShouldBeEnabled$'
            {
                # Enable the feature
                Enable-ChocolateyFeature -Name $this.Name -Confirm:$false
            }
        }
    }
}
#EndRegion '.\Classes\005.ChocolateyFeature.ps1' 142
#Region '.\Classes\006.ChocolateySetting.ps1' 0

<#
    .SYNOPSIS
        The `ChocolateySetting` DSC resource is used to set or unset Settings.
 
    .DESCRIPTION
        Chocolatey lets you set or unset general Settings.
        This resources lets you set or unset a Setting.
 
    .PARAMETER Ensure
        Indicate whether the Chocolatey Setting should be enabled or disabled on the system.
 
    .PARAMETER Name
        Name - the name of the Setting.
 
    .PARAMETER Value
        Value - the value of the Setting, if ensure is set to present.
        When Ensure is absent, the setting's value is cleared.
 
    .EXAMPLE
        Invoke-DscResource -ModuleName Chocolatey -Name ChocolateySetting -Method Get -Property @{
            Ensure = 'Present'
            Name = 'webRequestTimeoutSeconds'
            Value = '30'
        }
 
        # This example shows how to set the Setting webRequestTimeoutSeconds using Invoke-DscResource.
#>

[DscResource()]
class ChocolateySetting
{
    [DscProperty()]
    [Ensure] $Ensure = 'Present'

    [DscProperty(Key)]
    [string] $Name

    [DscProperty()]
    [string] $Value

    [DscProperty(NotConfigurable)]
    [ChocolateyReason[]] $Reasons

    [ChocolateySetting] Get()
    {
        $currentState = [ChocolateySetting]::new()
        $currentState.Name = $this.Name

        try
        {
            $setting = Get-ChocolateySetting -Name $this.Name
            $currentState.Value = $setting.Value
            if (-not [string]::IsNullOrEmpty($setting.Value))
            {
                $currentState.Ensure = 'Present'
            }
            else
            {
                $currentState.Ensure = 'Absent'
            }
        }
        catch
        {
            Write-Verbose -Message ('Exception Caught:' -f $_)
            $Setting = $null
            $currentState.Ensure = 'Absent'
            $currentState.Reasons += @{
                code = 'ChocolateySetting:ChocolateySetting:ChocolateyError'
                phrase = ('Error: {0}.' -f $_)
            }
        }

        if ($null -eq $Setting)
        {
            $currentState.Reasons += @{
                code = 'ChocolateySetting:ChocolateySetting:SettingNotFound'
                phrase = ('The Setting ''{0}'' was not found.' -f $this.Name)
            }
        }
        else
        {
            if ($this.Ensure -eq 'Present' -and $currentState.Value -eq $this.Value)
            {
                $currentState.Ensure = 'Present'
                $currentState.Reasons += @{
                    code = 'ChocolateySetting:ChocolateySetting:SettingCompliant'
                    phrase = ('The Setting ''{0}'' is enabled with value ''{1}'' as expected.' -f $this.Name, $setting.Value)
                }
            }
            elseif (-not [string]::isNullOrEmpty($Setting.value) -and $this.Ensure -eq 'Absent')
            {
                $currentState.Ensure = 'Present'
                $currentState.Reasons += @{
                    code = 'ChocolateySetting:ChocolateySetting:SettingShouldBeUnset'
                    phrase = ('The Setting ''{0}'' is Present while it''s expected to be unset (Absent). Currently set to ''{1}''.' -f $this.Name, $Setting.Value)
                }
            }
            elseif ([string]::isNullOrEmpty($Setting.value) -and $this.Ensure -eq 'Absent')
            {
                $currentState.Ensure = 'Absent'
                $currentState.Reasons += @{
                    code = 'ChocolateySetting:ChocolateySetting:SettingUnsetCompliant'
                    phrase = ('The Setting ''{0}'' is unset as expected.' -f $this.Name)
                }
            }
            elseif ([string]::isNullOrEmpty($Setting.value) -and $this.Ensure -eq 'Present')
            {
                $currentState.Ensure = 'Absent'
                $currentState.Reasons += @{
                    code = 'ChocolateySetting:ChocolateySetting:SettingShouldBeSet'
                    phrase = ('The Setting ''{0}'' should be set.' -f $this.Name)
                }
            }
            elseif ([string]::isNullOrEmpty($Setting.value) -and [string]::isNullOrEmpty($this.value) -and $this.Ensure -eq 'Present')
            {
                $currentState.Ensure = 'Absent'
                $currentState.Reasons += @{
                    code = 'ChocolateySetting:ChocolateySetting:SettingIncorrectlySet'
                    phrase = ('The Setting ''{0}'' should be set.' -f $this.Name)
                }
            }
            elseif ($this.Ensure -eq 'Present' -and $setting.Value -ne $this.Value)
            {
                $currentState.Ensure = 'Present'
                $currentState.Reasons += @{
                    code = 'ChocolateySetting:ChocolateySetting:SettingNotCorrect'
                    phrase = ('The Setting ''{0}'' should be set to ''{1}'' but is ''{2}''.' -f $this.Name, $this.Value, $setting.Value)
                }
            }
        }

        return $currentState
    }

    [bool] Test()
    {
        $currentState = $this.Get()
        $currentState.Reasons.code.Where{
            $_ -notmatch 'Compliant$'
        }

        if ($currentState.count -eq 0)
        {
            return $true
        }
        else
        {
            return $false
        }
    }

    [void] Set()
    {
        $currentState = $this.Get()

        switch ($currentState.Reasons.code)
        {
            'SettingShouldBeUnset'
            {
                # Unset the Setting
                Set-ChocolateySetting -Name $this.Name -Unset -Confirm:$false
            }

            'SettingShouldBeSet$|SettingNotCorrect$'
            {
                # Configure the Setting
                Set-ChocolateySetting -Name $this.Name -Value $this.Value -Confirm:$false
            }
        }
    }
}
#EndRegion '.\Classes\006.ChocolateySetting.ps1' 172
#Region '.\Classes\007.ChocolateyPin.ps1' 0

<#
    .SYNOPSIS
        The `ChocolateyPin` DSC resource is used to set or remove Pins.
 
    .DESCRIPTION
        Chocolatey lets you pin package versions so they don't get updated.
        This resources lets you set or remove a Pin.
 
    .PARAMETER Ensure
        Indicate whether the Chocolatey Pin should be enabled or disabled for this package.
 
    .PARAMETER Version
        Version of the Package to pin.
 
    .EXAMPLE
        Invoke-DscResource -ModuleName Chocolatey -Name ChocolateyPin -Method Get -Property @{
            Ensure = 'Present'
            Name = 'putty.portable'
            Version = '0.78'
        }
 
        # This example shows how to set the Pin webRequestTimeoutSeconds using Invoke-DscResource.
#>

[DscResource()]
class ChocolateyPin
{
    [DscProperty()]
    [Ensure] $Ensure = 'Present'

    [DscProperty(Key)]
    [string] $Name

    [DscProperty()]
    [string] $Version

    [DscProperty(NotConfigurable)]
    [ChocolateyReason[]] $Reasons

    [ChocolateyPin] Get()
    {
        $currentState = [ChocolateyPin]::new()
        $currentState.Name = $this.Name

        try
        {
            $pin = Get-ChocolateyPin -Name $this.Name
            $currentState.Version = $pin.Version
            if (-not [string]::IsNullOrEmpty($pin.Name))
            {
                $currentState.Ensure = 'Present'
            }
            else
            {
                $currentState.Ensure = 'Absent'
            }
        }
        catch
        {
            Write-Verbose -Message ('Exception Caught:' -f $_)
            $pin = $null
            $currentState.Ensure = 'Absent'
            $currentState.Reasons += @{
                code = 'ChocolateyPin:ChocolateyPin:ChocolateyError'
                phrase = ('Error: {0}.' -f $_)
            }
        }

        if ($null -eq $pin)
        {
            Write-Debug -Message ('No pin found for package {0}' -f $this.Name)

            if ($this.Ensure -eq 'Absent')
            {
                $currentState.Reasons += @{
                    code = 'ChocolateyPin:ChocolateyPin:PinAbsentCompliant'
                    phrase = ('The package ''{0}'' is not pinned, as expected.' -f $this.Name)
                }
            }
            else # expected Present
            {
                # Sould be set
                $currentState.Reasons += @{
                    code = 'ChocolateyPin:ChocolateyPin:PinShouldBeSet'
                    phrase = ('The package ''{0}'' wasn''t pinned but should be set. (To version ''{1}'').' -f $this.Name, $this.Version)
                }
            }
        }
        elseif ($this.Ensure -eq 'Absent')
        {
            Write-Debug -Message 'Present but expected Absent. Should be removed.'
            $currentState.Reasons += @{
                code = 'ChocolateyPin:ChocolateyPin:PinShouldBeRemoved'
                phrase = ('The package ''{0}'' is pinned to ''{1}'' but it souldn''t.' -f $this.Name, $pin.Version)
            }
        }
        elseif ($this.Ensure -eq 'Present' -and $pin.Version -ne $this.Version)
        {
            Write-Debug -Message ('The package is pinned, that''s expected, but version differs (Expected: {0}, Current: {1}).' -f $currentState.Version, $this.Version)
            if ([string]::IsNullOrEmpty($this.Version))  # Assumes $this.Version is NOT set (Package must be pinned, but to ANY version)
            {
                # Pin version not expected, so $pin.Version is whatever was pinned at the time
                $currentState.Reasons += @{
                    code = 'ChocolateyPin:ChocolateyPin:PinCompliant'
                    phrase = ('The package ''{0}'' is pinned to version ''{1}''. No desired version specified for the pin.' -f $this.Name, $pin.Version)
                }
            }
            else
            {
                # Pin version mismatch
                $currentState.Reasons += @{
                    code = 'ChocolateyPin:ChocolateyPin:PinVersionMismatch'
                    phrase = ('The package ''{0}'' should be pinned to ''{1}'' but is set to ''{2}''.' -f $this.Name, $this.Version, $pin.Version)
                }
            }
        }
        elseif ($this.Ensure -eq 'Present' -and $pin.Version -eq $this.Version)
        {
            Write-Debug -Message 'The Pin is set to the desired version (not null)'
            $currentState.Reasons += @{
                code = 'ChocolateyPin:ChocolateyPin:PinCompliant'
                phrase = ('The Pin ''{0}'' is enabled with value ''{1}'' as expected.' -f $this.Name, $pin.Version)
            }
        }

        return $currentState
    }

    [bool] Test()
    {
        $currentState = $this.Get()
        $currentState.Reasons.code.Where{
            $_ -notmatch 'Compliant$'
        }

        if ($currentState.count -eq 0)
        {
            return $true
        }
        else
        {
            return $false
        }
    }

    [void] Set()
    {
        $currentState = $this.Get()

        switch -Regex ($currentState.Reasons.code)
        {
            'PinShouldBeRemoved'
            {
                Write-Verbose -Message ('Removing the pin on package ''{0}''.' -f $this.Name)
                Remove-ChocolateyPin -Name $this.Name -Confirm:$false
            }

            'PinVersionMismatch$|PinShouldBeSet$'
            {
                Write-Verbose -Message ('Setting pin on package ''{0}'' asking for version ''{0}''.' -f $this.Name, $this.Version)
                Add-ChocolateyPin -Name $this.Name -Version $this.Version -Confirm:$false
            }
        }
    }
}
#EndRegion '.\Classes\007.ChocolateyPin.ps1' 166
#Region '.\private\Assert-ChocolateyIsElevated.ps1' 0
<#
.SYNOPSIS
    Make sure the current process is running elevated for Chocolatey.
 
.DESCRIPTION
    This command throws if the process is not running elevated.
    This is useful when running in a default value of a switch parameter
    to validate either that the running process is elevated, or that
    the user wants to run non elevated anyway by toggling the switch.
 
.EXAMPLE
    [Parameter(DontShow)]
    [switch]
    $RunNonElevated = $(Assert-ChocolateyIsElevated)
 
.NOTES
    This is only for commands that change the system and needs Elevated permissions.
#>

function Assert-ChocolateyIsElevated
{
    [CmdletBinding()]
    [OutputType([bool])]
    param
    (
        #
    )

    if ([Security.Principal.WindowsPrincipal]::New([Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))
    {
        Write-Verbose -Message 'This process is running elevated.'
    }
    else
    {
        throw 'This command must be ran elevated.'
    }
}
#EndRegion '.\private\Assert-ChocolateyIsElevated.ps1' 37
#Region '.\private\Compare-SemVerVersion.ps1' 0
<#
.SYNOPSIS
    Compares two versions and find whether they're equal, or one is newer than the other.
 
.DESCRIPTION
    The Compare-SemVerVersion allows the comparison of SemVer 2.0 versions (including prerelease identifiers)
    as documented on semver.org
    The result will be = if the versions are equivalent, > if the reference version takes precedence, or < if the
    difference version wins.
 
.PARAMETER ReferenceVersion
    The string version you would like to test.
 
.PARAMETER DifferenceVersion
    The other string version you would like to compare agains the reference.
 
.EXAMPLE
    Compare-SemVerVersion -ReferenceVersion '0.2.3.546-alpha.201+01012018' -DifferenceVersion '0.2.3.546-alpha.200'
    # >
    Compare-SemVerVersion -ReferenceVersion '0.2.3.546-alpha.201+01012018' -DifferenceVersion '0.2.3.546-alpha.202'
    # <
 
.EXAMPLE
    Compare-SemVerVersion -ReferenceVersion '0.2.3.546-alpha.201+01012018' -DifferenceVersion '0.2.3.546-alpha.201+01012015'
    # =
 
.NOTES
    Worth noting that the documentaion of SemVer versions should follow this logic (from semver.org)
    1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.
#>

function Compare-SemVerVersion
{
    [CmdletBinding()]
    [OutputType([string])]
    param (
        [Parameter(Mandatory=$true)]
        [System.String]
        $ReferenceVersion,

        [Parameter()]
        [System.String]
        $DifferenceVersion
    )

    $refVersion = Get-SemVerFromString -VersionString $ReferenceVersion -ErrorAction Stop
    $diffVersion = Get-SemVerFromString -VersionString $DifferenceVersion -ErrorAction Stop

    # Compare Version first
    if ($refVersion.Version -eq $diffVersion.Version)
    {
        if (!$refVersion.Prerelease -and $diffVersion.Prerelease)
        {
            '>'
        }
        elseif ($refVersion.Prerelease -and !$diffVersion.Prerelease)
        {
            '<'
        }
        elseif (!$diffVersion.Prerelease -and !$refVersion.Prerelease)
        {
            '='
        }
        elseif ($refVersion.Prerelease -eq $diffVersion.Prerelease)
        {
            '='
        }
        else
        {
            $resultSoFar = '='

            foreach ($index in 0..($refVersion.PrereleaseArray.count - 1))
            {
                $refId = ($refVersion.PrereleaseArray[$index] -as [uint64])
                $diffId = ($diffVersion.PrereleaseArray[$index] -as [uint64])
                if ($refId -and $diffId)
                {
                    if ($refid -gt $diffId)
                    {
                        return '>'
                    }
                    elseif ($refId -lt $diffId)
                    {
                        return '<'
                    }
                    else
                    {
                        Write-Debug "Ref identifier at index = $index are equals, moving onto next"
                    }
                }
                else
                {
                    $refId = [char[]]$refVersion.PrereleaseArray[$index]
                    $diffId = [char[]]$diffVersion.PrereleaseArray[$index]
                    foreach ($charIndex in 0..($refId.Count - 1))
                    {
                        if ([int]$refId[$charIndex] -gt [int]$diffId[$charIndex])
                        {
                            return '>'
                        }
                        elseif ([int]$refId[$charIndex] -lt [int]$diffId[$charIndex])
                        {
                            return '<'
                        }

                        if ($refId.count -eq $charIndex + 1 -and $refId.count -lt $diffId.count)
                        {
                            return '>'
                        }
                        elseif ($diffId.count -eq $index + 1 -and $refId.count -gt $diffId.count)
                        {
                            return '<'
                        }
                    }
                }

                if ($refVersion.PrereleaseArray.count -eq $index + 1 -and $refVersion.PrereleaseArray.count -lt $diffVersion.PrereleaseArray.count)
                {
                    return '<'
                }
                elseif ($diffVersion.PrereleaseArray.count -eq $index + 1 -and $refVersion.PrereleaseArray.count -gt $diffVersion.PrereleaseArray.count)
                {
                    return '>'
                }
            }
            return $resultSoFar
        }
    }
    elseif ($refVersion.Version -gt $diffVersion.Version)
    {
        '>'
    }
    else
    {
        '<'
    }
}
#EndRegion '.\private\Compare-SemVerVersion.ps1' 137
#Region '.\private\Get-ChocolateyDefaultArgument.ps1' 0

<#
.SYNOPSIS
Transforms parameters Key/value into choco.exe Parameters.
 
.DESCRIPTION
This private command allows to pass parameters and it returns
an array of parameters to be used with the choco.exe command.
No validation is done at this level, it should be handled
by the Commands leveraging this function.
 
.PARAMETER Name
Name of the element being targeted (can be source, feature, package and so on).
 
.PARAMETER Value
The value of the config setting. Required with some Actions.
Defaults to empty.
 
.PARAMETER Source
Source uri (whether local or remote)
 
.PARAMETER Disabled
Specify whethere the element targeted should be disabled or enabled (by default).
 
.PARAMETER BypassProxy
Bypass the proxy for fetching packages on a feed.
 
.PARAMETER SelfService
Specify if the source is, can or should be used for self service.
 
.PARAMETER NotBroken
Filter out the packages that are reported broken.
 
.PARAMETER AllVersions
List all version available.
 
.PARAMETER Priority
Priority of the feed, default to 0
 
.PARAMETER Credential
Credential to authenticate to the source feed.
 
.PARAMETER ProxyCredential
Credential for the Proxy.
 
.PARAMETER Force
Force the action being targeted.
 
.PARAMETER CacheLocation
Location where the download will be cached.
 
.PARAMETER InstallArguments
Arguments to pass to the Installer (Not Package args)
 
.PARAMETER InstallArgumentsSensitive
Arguments to pass to the Installer that should be obfuscated from log and output.
 
.PARAMETER PackageParameters
PackageParameters - Parameters to pass to the package, that should be handled by the ChocolateyInstall.ps1
 
.PARAMETER PackageParametersSensitive
Arguments to pass to the Package that should be obfuscated from log and output.
 
.PARAMETER OverrideArguments
Should install arguments be used exclusively without appending to current package passed arguments
 
.PARAMETER NotSilent
    Do not install this silently. Defaults to false.
 
.PARAMETER ApplyArgsToDependencies
    Apply Install Arguments To Dependencies - Should install arguments be
    applied to dependent packages? Defaults to false
 
.PARAMETER AllowDowngrade
    Should an attempt at downgrading be allowed? Defaults to false.
 
.PARAMETER IgnoreDependencies
    IgnoreDependencies - Ignore dependencies when installing package(s).
 
.PARAMETER ForceDependencies
    Force dependencies to be reinstalled when force
    installing package(s). Must be used in conjunction with --force.
    Defaults to false.
 
.PARAMETER SkipPowerShell
    Skip Powershell - Do not run chocolateyInstall.ps1. Defaults to false.
 
.PARAMETER IgnoreChecksum
    IgnoreChecksums - Ignore checksums provided by the package. Overrides
    the default feature 'checksumFiles' set to 'True'.
 
.PARAMETER AllowEmptyChecksum
    Allow Empty Checksums - Allow packages to have empty/missing checksums
    for downloaded resources from non-secure locations (HTTP, FTP). Use this
    switch is not recommended if using sources that download resources from
    the internet. Overrides the default feature 'allowEmptyChecksums' set to
    'False'. Available in 0.10.0+.
 
.PARAMETER ignorePackageCodes
    IgnorePackageExitCodes - Exit with a 0 for success and 1 for non-success,
    no matter what package scripts provide for exit codes. Overrides the
    default feature 'usePackageExitCodes' set to 'True'. Available in 0.-
    9.10+.
 
.PARAMETER UsePackageCodes
    UsePackageExitCodes - Package scripts can provide exit codes. Use those
    for choco's exit code when non-zero (this value can come from a
    dependency package). Chocolatey defines valid exit codes as 0, 1605,
    1614, 1641, 3010. Overrides the default feature 'usePackageExitCodes'
    set to 'True'. Available in 0.9.10+.
 
.PARAMETER StopOnFirstFailure
    Stop On First Package Failure - stop running install, upgrade or
    uninstall on first package failure instead of continuing with others.
    Overrides the default feature 'stopOnFirstPackageFailure' set to 'False-
    '. Available in 0.10.4+.
 
.PARAMETER SkipCache
    Skip Download Cache - Use the original download even if a private CDN
    cache is available for a package. Overrides the default feature
    'downloadCache' set to 'True'. Available in 0.9.10+. [Licensed editions](https://chocolatey.org/compare)
    only. See https://chocolatey.org/docs/features-private-cdn
 
.PARAMETER UseDownloadCache
    Use Download Cache - Use private CDN cache if available for a package.
    Overrides the default feature 'downloadCache' set to 'True'. Available
    in 0.9.10+. [Licensed editions](https://chocolatey.org/compare) only. See https://chocolate-
    y.org/docs/features-private-cdn
 
.PARAMETER SkipVirusCheck
    Skip Virus Check - Skip the virus check for downloaded files on this run.
    Overrides the default feature 'virusCheck' set to 'True'. Available
    in 0.9.10+. [Licensed editions](https://chocolatey.org/compare) only.
    See https://chocolatey.org/docs/features-virus-check
 
.PARAMETER VirusCheck
    Virus Check - check downloaded files for viruses. Overrides the default
    feature 'virusCheck' set to 'True'. Available in 0.9.10+. Licensed
    editions only. See https://chocolatey.org/docs/features-virus-check
 
.PARAMETER VirusPositive
    Virus Check Minimum Scan Result Positives - the minimum number of scan
    result positives required to flag a package. Used when virusScannerType
    is VirusTotal. Overrides the default configuration value
    'virusCheckMinimumPositives' set to '5'. Available in 0.9.10+. Licensed
    editions only. See https://chocolatey.org/docs/features-virus-check
 
.PARAMETER OrderByPopularity
    Order the community packages (chocolatey.org) by popularity.
 
.PARAMETER Version
    Version - A specific version to install. Defaults to unspecified.
 
.PARAMETER LocalOnly
    LocalOnly - Only search against local machine items.
 
.PARAMETER IdOnly
    Id Only - Only return Package Ids in the list results. Available in 0.10.6+.
 
.PARAMETER Prerelease
    Prerelease - Include Prereleases? Defaults to false.
 
.PARAMETER ApprovedOnly
    ApprovedOnly - Only return approved packages - this option will filter
    out results not from the [community repository](https://chocolatey.org/packages). Available in 0.9.10+.
 
.PARAMETER IncludePrograms
    IncludePrograms - Used in conjunction with LocalOnly, filters out apps
    chocolatey has listed as packages and includes those in the list.
    Defaults to false.
 
.PARAMETER ByIdOnly
    ByIdOnly - Only return packages where the id contains the search filter.
    Available in 0.9.10+.
 
.PARAMETER IdStartsWith
    IdStartsWith - Only return packages where the id starts with the search
    filter. Available in 0.9.10+.
 
.PARAMETER Exact
    Exact - Only return packages with this exact name. Available in 0.9.10+.
 
.PARAMETER x86
    Force the x86 packages on x64 machines.
 
.PARAMETER AcceptLicense
    AcceptLicense - Accept license dialogs automatically.
    Reserved for future use.
 
.PARAMETER Timeout
    CommandExecutionTimeout (in seconds) - The time to allow a command to
    finish before timing out. Overrides the default execution timeout in the
    configuration of 2700 seconds. '0' for infinite starting in 0.10.4.
 
.PARAMETER UseRememberedArguments
    Use Remembered Options for Upgrade - use the arguments and options used
    during install for upgrade. Does not override arguments being passed at
    runtime. Overrides the default feature
    'useRememberedArgumentsForUpgrades' set to 'False'. Available in 0.10.4+.
 
.PARAMETER IgnoreRememberedArguments
    Ignore Remembered Options for Upgrade - ignore the arguments and options
    used during install for upgrade. Overrides the default feature
    'useRememberedArgumentsForUpgrades' set to 'False'. Available in 0.10.4+.
 
.PARAMETER ExcludePrerelease
    Exclude Prerelease - Should prerelease be ignored for upgrades? Will be
    ignored if you pass `--pre`. Available in 0.10.4+.
 
.PARAMETER AutoUninstaller
    UseAutoUninstaller - Use auto uninstaller service when uninstalling.
    Overrides the default feature 'autoUninstaller' set to 'True'. Available
    in 0.9.10+.
 
.PARAMETER SkipAutoUninstaller
    SkipAutoUninstaller - Skip auto uninstaller service when uninstalling.
    Overrides the default feature 'autoUninstaller' set to 'True'. Available
    in 0.9.10+.
 
.PARAMETER FailOnAutouninstaller
    FailOnAutoUninstaller - Fail the package uninstall if the auto
    uninstaller reports and error. Overrides the default feature
    'failOnAutoUninstaller' set to 'False'. Available in 0.9.10+.
 
.PARAMETER IgnoreAutoUninstallerFailure
    Ignore Auto Uninstaller Failure - Do not fail the package if auto
    uninstaller reports an error. Overrides the default feature
    'failOnAutoUninstaller' set to 'False'. Available in 0.9.10+.
 
.PARAMETER KeyUser
    User - used with authenticated feeds. Defaults to empty.
 
.PARAMETER Key
    Password - the user's password to the source. Encrypted in chocolatey.config file.
 
.EXAMPLE
    Get-ChocolateyDefaultArguments @PSBoundparameters
#>

function Get-ChocolateyDefaultArgument
{
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'None')]
    [OutputType([collections.generic.list[string]])]
    param
    (
        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [System.String]
        $Name,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        $Source,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $Disabled,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        $Value,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $BypassProxy,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $SelfService,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $NotBroken,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $AllVersions,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [int]
        $Priority = 0,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [PSCredential]
        $Credential,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [PSCredential]
        $ProxyCredential,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $Force,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [System.String]
        $CacheLocation,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [String]
        $InstallArguments,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [String]
        $InstallArgumentsSensitive,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [String]
        $PackageParameters,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [String]
        $PackageParametersSensitive,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $OverrideArguments,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $NotSilent,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $ApplyArgsToDependencies,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $AllowDowngrade,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $IgnoreDependencies,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $ForceDependencies,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $SkipPowerShell,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $IgnoreChecksum,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $AllowEmptyChecksum,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $ignorePackageCodes,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $UsePackageCodes,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $StopOnFirstFailure,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $SkipCache,


        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $UseDownloadCache,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $SkipVirusCheck,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $VirusCheck,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [int]
        $VirusPositive,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [Switch]
        $OrderByPopularity,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [System.String]
        $Version,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $LocalOnly,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $IdOnly,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $Prerelease,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $ApprovedOnly,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $IncludePrograms,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $ByIdOnly,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $IdStartsWith,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $Exact,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $x86,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $AcceptLicense,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [int]
        $Timeout,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $UseRememberedArguments,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $IgnoreRememberedArguments,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $ExcludePrerelease,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $AutoUninstaller,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $SkipAutoUninstaller,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $FailOnAutouninstaller,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $IgnoreAutoUninstallerFailure,

        [Parameter()]
        #To be used when Password is too long (>240 char) like a key
        [string]
        $KeyUser,

        [Parameter()]
        [string]
        $Key
    )

    process
    {
        [collections.generic.list[string]] $ChocoArguments = [collections.generic.list[string]]::new()
        $Arguments = switch ($PSBoundParameters.Keys)
        {
            'Value'
            {
                "--value=`"$value`""
            }
            'Priority'
            {
                if ( $Priority -gt 0)
                {
                    "--priority=$priority"
                }
            }
            'SelfService'
            {
                "--allow-self-service"
            }
            'Name'
            {
                "--name=`"$Name`""
            }
            'Source'
            {
                "-s`"$Source`""
            }
            'ByPassProxy'
            {
                "--bypass-proxy"
            }
            'CacheLocation'
            {
                "--cache-location=`"$CacheLocation`""
            }
            'WhatIf'
            {
                "--whatif"
            }
            'cert'
            {
                "--cert=`"$Cert`""
            }
            'Force'
            {
                '--yes'; '--force'
            }
            'AcceptLicense'
            {
                '--accept-license'
            }
            'Verbose'
            {
                '--verbose'
            }
            'Debug'
            {
                '--debug'
            }
            'NoProgress'
            {
                '--no-progress'
            }
            'Credential'
            {
                if ($Credential.Username)
                {
                    "--user=`"$($Credential.Username)`""
                }
                if ($Credential.GetNetworkCredential().Password)
                {
                    "--password=`"$($Credential.GetNetworkCredential().Password)`""
                }
            }
            'KeyUser'
            {
                "--user=`"$KeyUser`""
            }
            'Key'
            {
                "--password=`"$Key`""
            }
            'Timeout'
            {
                "--execution-timeout=$Timeout"
            }
            'AllowUnofficalBuild'
            {
                "--allow-unofficial-build"
            }
            'FailOnSTDErr'
            {
                '--fail-on-stderr'
            }
            'Proxy'
            {
                "--Proxy=`"$Proxy`""
            }
            'ProxyCredential'
            {
                if ($ProxyCredential.Username)
                {
                    "--proxy-user=`"$($ProxyCredential.Username)`""
                }
                if ($ProxyCredential.GetNetworkCredential().Password)
                {
                    "--proxy-password=`"$($ProxyCredential.GetNetworkCredential().Password)`""
                }
            }
            'ProxyBypassList'
            {
                "--proxy-bypass-list=`"$($ProxyBypassList -join ',')`""
            }
            'ProxyBypassLocal'
            {
                "--proxy-bypass-on-local"
            }

            #List / Search Parameters
            'ByTagOnly'
            {
                '--by-tag-only'
            }
            'ByIdOnly'
            {
                '--by-id-only'
            }
            'LocalOnly'
            {
                '--local-only'
            }
            'IdStartsWith'
            {
                '--id-starts-with'
            }
            'ApprovedOnly'
            {
                '--approved-only'
            }
            'OrderByPopularity'
            {
                '--order-by-popularity'
            }
            'NotBroken'
            {
                '--not-broken'
            }
            'prerelease'
            {
                '--prerelease'
            }
            'IncludePrograms'
            {
                '--include-programs'
            }
            'AllVersions'
            {
                '--all-versions'
            }
            'Version'
            {
                "--version=`"$version`""
            }
            'exact'
            {
                "--exact"
            }

            #Install Parameters
            'x86'
            {
                "--x86"
            }
            'OverrideArguments'
            {
                '--override-arguments'
            }
            'NotSilent'
            {
                '--not-silent'
            }
            'ApplyArgsToDependencies'
            {
                '--apply-install-arguments-to-dependencies'
            }
            'AllowDowngrade'
            {
                '--allow-downgrade'
            }

            'ignoredependencies'
            {
                '--ignore-dependencies'
            }
            'ForceDependencies'
            {
                '--force-dependencies'
            }
            'SkipPowerShell'
            {
                '--skip-powershell'
            }
            'IgnoreChecksum'
            {
                '--ignore-checksum'
            }
            'allowemptychecksum'
            {
                '--allow-empty-checksum'
            }
            'AllowEmptyChecksumSecure'
            {
                '--allow-empty-checksums-secure'
            }
            'RequireChecksum'
            {
                '--requirechecksum'
            }
            'Checksum'
            {
                "--download-checksum=`"$Checksum`""
            }
            'Checksum64'
            {
                "--download-checksum-x64=`"$CheckSum64`""
            }
            'ChecksumType'
            {
                "--download-checksum-type=`"$ChecksumType`""
            }
            'checksumtype64'
            {
                "--download-checksum-type-x64=`"$Checksumtype64`""
            }
            'ignorepackagecodes'
            {
                '--ignore-package-exit-codes'
            }
            'UsePackageExitCodes'
            {
                '--use-package-exit-codes'
            }
            'StopOnFirstFailure'
            {
                '--stop-on-first-failure'
            }
            'SkipCache'
            {
                '--skip-download-cache'
            }
            'UseDownloadCache'
            {
                '--use-download-cache'
            }
            'SkipVirusCheck'
            {
                '--skip-virus-check'
            }
            'VirusCheck'
            {
                '--virus-check'
            }
            'VirusPositive'
            {
                "--virus-positives-minimum=`"$VirusPositive`""
            }
            'InstallArguments'
            {
                "--install-arguments=`"$InstallArguments`""
            }
            'InstallArgumentsSensitive'
            {
                "--install-arguments-sensitive=`"$InstallArgumentsSensitive`""
            }
            'PackageParameters'
            {
                "--package-parameters=`"$PackageParameters`""
            }
            'PackageParametersSensitive'
            {
                "--package-parameters-sensitive=`"$PackageParametersSensitive`""
            }
            'MaxDownloadRate'
            {
                "--maximum-download-bits-per-second=$MaxDownloadRate"
            }
            'IgnoreRememberedArguments'
            {
                '--ignore-remembered-arguments'
            }
            'UseRememberedArguments'
            {
                '--use-remembered-options'
            }
            'ExcludePrerelease'
            {
                '--exclude-pre'
            }

            #uninstall package params
            'AutoUninstaller'
            {
                '--use-autouninstaller'
            }
            'SkipAutoUninstaller'
            {
                '--skip-autouninstaller'
            }
            'FailOnAutouninstaller'
            {
                '--fail-on-autouninstaller'
            }
            'IgnoreAutoUninstallerFailure'
            {
                '--ignore-autouninstaller-failure'
            }
        }


        if ($PSCmdlet.ShouldProcess('Returning Choco arguments','return'))
        {
            $Arguments.Foreach{
                $null = $ChocoArguments.Add($_)
            }

            $null = $ChocoArguments.Add('--no-progress')
            $null = $ChocoArguments.Add('--limit-output')
            return $ChocoArguments
        }
    }
}
#EndRegion '.\private\Get-ChocolateyDefaultArgument.ps1' 805
#Region '.\private\Get-ChocolateyInstallPath.ps1' 0

<#
.SYNOPSIS
Gets environment variable ChocolateyInstall from Machine scope.
 
.DESCRIPTION
This command gets the machine-scoped environment variable 'ChocolateyInstall',
and make sure it's set if the folder is present but variable is not.
If the variable is not set and the choclatey folder can't be found,
the command will write to the error stream.
 
.EXAMPLE
Get-ChocolateyInstallPath -ErrorAction 'Stop'
 
#>

function Get-ChocolateyInstallPath
{
    [CmdletBinding()]
    [OutputType([string])]
    param
    (
        #
    )

    $chocoInstallPath = [Environment]::GetEnvironmentVariable('ChocolateyInstall', 'Machine')
    if ([string]::IsNullOrEmpty($chocoPath) -and (Test-Path -Path (Join-Path -Path $env:ProgramData -ChildPath 'Chocolatey')))
    {
        $chocoInstallPath = Join-Path -Path $env:ProgramData -ChildPath 'Chocolatey'
        [Environment]::SetEnvironmentVariable('ChocolateyInstall', $chocoInstallPath, 'Machine')
    }
    elseif (-not [string]::IsNullOrEmpty($chocoInstallPath))
    {
        Write-Debug -Message ('ChocolateyInstall path Machine environmen variable already set to ''{0}''.' -f $chocoInstallPath)
    }
    else
    {
        Write-Error -Message 'The chocolatey install Machine environment variable couldn''t be found.'
    }

    return $chocoInstallPath
}
#EndRegion '.\private\Get-ChocolateyInstallPath.ps1' 42
#Region '.\private\Get-Downloader.ps1' 0
<#
.SYNOPSIS
    Returns a Downloader object (System.Net.WebClient) set up.
 
.DESCRIPTION
    Returns a Downloader object configured with Proxy and Credential.
    This is used during the Chocolatey software Install Process,
    to retrieve metadata and to download the file.
 
.PARAMETER url
    Url to execute the request against.
 
.PARAMETER ProxyLocation
    Url of the Proxy to use for executing request.
 
.PARAMETER ProxyCredential
    Credential to be used by the proxy. By default it will try to use the cached credential.
 
.PARAMETER IgnoreProxy
    Bypass the proxy for this request.
 
.EXAMPLE
    Get-Downloader -Url https://chocolatey.org/api/v2
#>

function Get-Downloader
{
    [CmdletBinding()]
    [OutputType([System.Net.WebClient])]
    param
    (
        [Parameter(Mandatory = $true)]
        [System.String]
        $url,

        [Parameter()]
        [uri]
        $ProxyLocation,

        [Parameter()]
        [pscredential]
        $ProxyCredential,

        [Parameter()]
        # To bypass the use of any proxy, please set IgnoreProxy
        [switch]
        $IgnoreProxy
    )

    $downloader = [System.Net.WebClient]::new()
    $defaultCreds = [System.Net.CredentialCache]::DefaultCredentials

    if ($null -ne $defaultCreds)
    {
        $downloader.Credentials = $defaultCreds
    }

    if ($null -ne $ignoreProxy -and $ignoreProxy -eq 'true')
    {
        Write-Debug "Explicitly bypassing proxy"
        $downloader.Proxy = [System.Net.GlobalProxySelection]::GetEmptyWebProxy()
    }
    else
    {
        # check if a proxy is required
        if ($ProxyLocation -and ![string]::IsNullOrEmpty($ProxyLocation))
        {
            $proxy = New-Object System.Net.WebProxy($ProxyLocation, $true)
            if ($null -ne $ProxyCredential)
            {
                $proxy.Credentials = $ProxyCredential
            }

            Write-Debug "Using explicit proxy server '$ProxyLocation'."
            $downloader.Proxy = $proxy
        }
        elseif (-not $downloader.Proxy.IsBypassed($url))
        {
            # system proxy (pass through)
            $creds = $defaultCreds
            if ($null -eq $creds)
            {
                Write-Debug "Default credentials were null. Attempting backup method"
                throw "Could not download required file from $url"
            }

            $proxyaddress = $downloader.Proxy.GetProxy($url).Authority
            Write-Debug "Using system proxy server '$proxyaddress'."
            $proxy = New-Object System.Net.WebProxy($proxyaddress)
            $proxy.Credentials = $creds
            $downloader.Proxy = $proxy
        }
    }

    return $downloader
}
#EndRegion '.\private\Get-Downloader.ps1' 96
#Region '.\private\Get-RemoteFile.ps1' 0
<#
.SYNOPSIS
    Download a file from url using specified proxy settings.
 
.DESCRIPTION
    Helper function to Download a file from a given url
    using specified proxy settings.
 
.PARAMETER url
    URL of the file to download
 
.PARAMETER file
    File path and name to save the downloaded file to.
 
.PARAMETER ProxyLocation
    Proxy uri to use for the download.
 
.PARAMETER ProxyCredential
    Credential to use for authenticating to the proxy.
    By default it will try to load cached credentials.
 
.PARAMETER IgnoreProxy
    Bypass the proxy for this request.
 
.EXAMPLE
    Get-RemoteFile -Url https://chocolatey.org/api/v2/0.10.8/ -file C:\chocolatey.zip
 
#>

function Get-RemoteFile
{
    [CmdletBinding()]
    param (
        [Parameter()]
        [System.String]
        $url,

        [Parameter()]
        [System.String]
        $file,

        [Parameter()]
        [uri]
        $ProxyLocation,

        [Parameter()]
        [pscredential]
        $ProxyCredential,

        [Parameter()]
        # To bypass the use of any proxy, please set IgnoreProxy
        [switch]
        $IgnoreProxy
    )

    Write-Debug "Downloading $url to $file"
    $downloaderParams = @{}
    $KeysForDownloader = $PSBoundParameters.keys | Where-Object { $_ -notin @('file') }
    foreach ($key in $KeysForDownloader )
    {
        Write-Debug "`tWith $key :: $($PSBoundParameters[$key])"
        $null = $downloaderParams.Add($key , $PSBoundParameters[$key])
    }

    $downloader = Get-Downloader @downloaderParams
    $downloader.DownloadFile($url, $file)
}
#EndRegion '.\private\Get-RemoteFile.ps1' 67
#Region '.\private\Get-RemoteString.ps1' 0
<#
.SYNOPSIS
    Download the content from url using specified proxy settings.
 
.DESCRIPTION
    Helper function to Download the content from a url
    using specified proxy settings.
 
.PARAMETER url
    URL of the file to download.
 
.PARAMETER file
    File path and name to save the downloaded file to.
 
.PARAMETER ProxyLocation
    Proxy uri to use for the download.
 
.PARAMETER ProxyCredential
    Credential to use for authenticating to the proxy.
    By default it will try to load cached credentials.
 
.PARAMETER IgnoreProxy
    Bypass the proxy for this request.
 
.EXAMPLE
    Get-RemoteString -Url https://chocolatey.org/install.ps1
#>

function Get-RemoteString
{
    [CmdletBinding()]
    param
    (
        [Parameter()]
        [System.String]
        $url,

        [Parameter()]
        [uri]
        $ProxyLocation,

        [Parameter()]
        [pscredential]
        $ProxyCredential,

        [Parameter()]
        # To bypass the use of any proxy, please set IgnoreProxy
        [switch]
        $IgnoreProxy
    )

    Write-Debug "Downloading string from $url"
    $downloaderParams = @{}
    $KeysForDownloader = $PSBoundParameters.keys | Where-Object { $_ -notin @() }
    foreach ($key in $KeysForDownloader )
    {
        Write-Debug -Message "`tWith $key :: $($PSBoundParameters[$key])"
        $null = $downloaderParams.Add($key, $PSBoundParameters[$key])
    }

    $downloader = Get-Downloader @downloaderParams
    return $downloader.DownloadString($url)
}
#EndRegion '.\private\Get-RemoteString.ps1' 63
#Region '.\private\Get-SemVerFromString.ps1' 0
function Get-SemVerFromString
{
    <#
    .SYNOPSIS
        Private function to parse a string to a SemVer 2.0 custom object, but with added Revision number common to .Net world (and Choco Packages)
 
    .DESCRIPTION
        This function parses the string of a version into an object composed of a [System.Version] object (Major, Minor, Patch, Revision)
        plus the pre-release identifiers and Build Metadata. The PreRelease metadata is also made available as an array to ease the
        version comparison.
 
    .PARAMETER VersionString
        String representation of the Version to Parse.
 
    .EXAMPLE
        Get-SemVerFromString -VersionString '1.6.24.256-rc1+01012018'
 
    .EXAMPLE
        Get-SemVerFromString -VersionString '1.6-alpha.13.24.15'
 
    .NOTES
        The function returns a PSObject of PSTypeName Package.Version
    #>

    [CmdletBinding()]
    [OutputType([PSobject])]

    param (
        [Parameter()]
        [System.String]
        $VersionString
    )

    # Based on SemVer 2.0 but adding Revision (common in .Net/NuGet/Chocolatey packages) https://semver.org
    if ($VersionString -notmatch '-')
    {
        [System.Version]$version, $BuildMetadata = $VersionString -split '\+', 2
    }
    else
    {
        [System.Version]$version, [System.String]$Tag = $VersionString -split '-', 2
        $PreRelease, $BuildMetadata = $Tag -split '\+', 2
    }

    $PreReleaseArray = $PreRelease -split '\.'

    [psobject]@{
        PSTypeName      = 'Package.Version'
        Version         = $version
        Prerelease      = $PreRelease
        Metadata        = $BuildMetadata
        PrereleaseArray = $PreReleaseArray
    }
}
#EndRegion '.\private\Get-SemVerFromString.ps1' 54
#Region '.\private\Repair-PowerShellOutputRedirectionBug.ps1' 0
<#
.SYNOPSIS
    Fix for PS2/3
 
.DESCRIPTION
    PowerShell v2/3 caches the output stream. Then it throws errors due
    to the FileStream not being what is expected. Fixes "The OS handle's
    position is not what FileStream expected. Do not use a handle
    simultaneously in one FileStream and in Win32 code or another
    FileStream."
 
.EXAMPLE
    Repair-PowerShellOutputRedirectionBug #Only for PSVersion below PS4
#>

function Repair-PowerShellOutputRedirectionBug
{
    [CmdletBinding()]
    param (

    )

    if ($PSVersionTable.PSVersion.Major -lt 4)
    {
        return
    }

    try
    {
        # http://www.leeholmes.com/blog/2008/07/30/workaround-the-os-handles-position-is-not-what-filestream-expected/ plus comments
        $bindingFlags = [Reflection.BindingFlags] "Instance,NonPublic,GetField"
        $objectRef = $host.GetType().GetField("externalHostRef", $bindingFlags).GetValue($host)
        $bindingFlags = [Reflection.BindingFlags] "Instance,NonPublic,GetProperty"
        $consoleHost = $objectRef.GetType().GetProperty("Value", $bindingFlags).GetValue($objectRef, @())
        [void] $consoleHost.GetType().GetProperty("IsStandardOutputRedirected", $bindingFlags).GetValue($consoleHost, @())
        $bindingFlags = [Reflection.BindingFlags] "Instance,NonPublic,GetField"
        $field = $consoleHost.GetType().GetField("standardOutputWriter", $bindingFlags)
        $field.SetValue($consoleHost, [Console]::Out)
        [void] $consoleHost.GetType().GetProperty("IsStandardErrorRedirected", $bindingFlags).GetValue($consoleHost, @())
        $field2 = $consoleHost.GetType().GetField("standardErrorWriter", $bindingFlags)
        $field2.SetValue($consoleHost, [Console]::Error)
    }
    catch
    {
        Write-Warning "Unable to apply redirection fix."
    }
}
#EndRegion '.\private\Repair-PowerShellOutputRedirectionBug.ps1' 47
#Region '.\public\Add-ChocolateyPin.ps1' 0

<#
.SYNOPSIS
    Add a Pin to a Chocolatey Package
 
.DESCRIPTION
    Allows you to pin a Chocolatey Package like choco pin add -n=packagename
 
.PARAMETER Name
    Name of the Chocolatey Package to pin.
    The Package must be installed beforehand.
 
.PARAMETER Version
    This allows to pin a specific Version of a Chocolatey Package.
    The Package with the Version to pin must be installed beforehand.
 
.PARAMETER RunNonElevated
    Throws if the process is not running elevated. use -RunNonElevated if you really want to run
    even if the current shell is not elevated.
 
.EXAMPLE
    Add-ChocolateyPin -Name 'PackageName'
 
.EXAMPLE
    Add-ChocolateyPin -Name 'PackageName' -Version '1.0.0'
 
.NOTES
    https://chocolatey.org/docs/commands-pin
#>

function Add-ChocolateyPin
{
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    [OutputType([void])]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Package')]
        [System.String]
        $Name,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [System.String]
        $Version,

        [Parameter(DontShow)]
        [switch]
        $RunNonElevated = $(Assert-ChocolateyIsElevated)
    )

    begin
    {
        if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
        {
            throw "Chocolatey Software not found."
        }
    }

    process
    {
        if (-not (Get-ChocolateyPackage -Name $Name -Exact))
        {
            throw ('Chocolatey Package ''{0}'' cannot be found.' -f $Name)
        }

        $ChocoArguments = @('pin', 'add')
        $ChocoArguments += Get-ChocolateyDefaultArgument @PSBoundParameters
        Write-Verbose -Message ('choco {0}' -f ($ChocoArguments -join ' '))

        if ($PSCmdlet.ShouldProcess("$Name $Version", "Add Pin"))
        {
            $output = &$chocoCmd $ChocoArguments

            # LASTEXITCODE is always 0 unless point an existing version (0 when remove but already removed)
            if ($LASTEXITCODE -ne 0)
            {
                throw ("Error when trying to add Pin for Package '{0}'.`r`n {1}" -f "$Name $Version", ($output -join "`r`n"))
            }
            else
            {
                $output | ForEach-Object -Process {
                    Write-Verbose -Message ('{0}' -f $_)
                }
            }
        }
    }
}
#EndRegion '.\public\Add-ChocolateyPin.ps1' 87
#Region '.\public\Disable-ChocolateyFeature.ps1' 0

<#
.SYNOPSIS
    Disable a Chocolatey Feature
 
.DESCRIPTION
    Allows you to disable a Chocolatey Feature usually accessed by choco feature disable -n=bob
 
.PARAMETER Name
    Name of the Chocolatey Feature to disable. Some are only available in the Chocolatey for business version.
 
.PARAMETER RunNonElevated
    Throws if the process is not running elevated. use -RunNonElevated if you really want to run
    even if the current shell is not elevated.
 
.EXAMPLE
    Disable-ChocolateyFeature -Name 'Bob'
 
.NOTES
    https://github.com/chocolatey/choco/wiki/CommandsFeature
#>

function Disable-ChocolateyFeature
{
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')]
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')]
    [OutputType([void])]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Feature')]
        [System.String]
        $Name,

        [Parameter(DontShow)]
        [switch]
        $RunNonElevated = $(Assert-ChocolateyIsElevated)
    )

    process
    {
        if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
        {
            throw "Chocolatey Software not found."
        }

        if (-not (Get-ChocolateyFeature -Name $Name))
        {
            throw "Chocolatey Feature $Name cannot be found."
        }

        $ChocoArguments = @('feature', 'disable')
        $ChocoArguments += Get-ChocolateyDefaultArgument @PSBoundParameters
        Write-Verbose -Message ('choco {0}' -f ($ChocoArguments -join ' '))

        if ($PSCmdlet.ShouldProcess($Env:COMPUTERNAME, "$chocoCmd $($ChocoArguments -join ' ')"))
        {
            &$chocoCmd $ChocoArguments | ForEach-Object -Process {
                Write-Verbose -Message ('{0}' -f $_)
            }
        }
    }
}
#EndRegion '.\public\Disable-ChocolateyFeature.ps1' 63
#Region '.\public\Disable-ChocolateySource.ps1' 0

<#
.SYNOPSIS
    Disable a Source set in the Chocolatey Config
 
.DESCRIPTION
    Lets you disable an existing source.
    The equivalent Choco command is Choco source disable -n=sourcename
 
.PARAMETER Name
    Name of the Chocolatey source to Disable
 
.PARAMETER RunNonElevated
    Throws if the process is not running elevated. use -RunNonElevated if you really want to run
    even if the current shell is not elevated.
 
.EXAMPLE
    Disable-ChocolateySource -Name chocolatey
 
.NOTES
    https://github.com/chocolatey/choco/wiki/CommandsSource
#>

function Disable-ChocolateySource
{
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')]
    [CmdletBinding()]
    [OutputType([void])]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [System.String]
        $Name,

        [Parameter(DontShow)]
        [switch]
        $RunNonElevated = $(Assert-ChocolateyIsElevated)
    )

    process
    {
        if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
        {
            throw "Chocolatey Software not found."
        }

        if (-not (Get-ChocolateySource -Name $Name))
        {
            throw "Chocolatey Source $Name cannot be found. You can Register it using Register-ChocolateySource."
        }

        $ChocoArguments = @('source', 'disable')
        $ChocoArguments += Get-ChocolateyDefaultArgument @PSBoundParameters
        Write-Verbose -Message ('choco {0}' -f ($ChocoArguments -join ' '))

        &$chocoCmd $ChocoArguments | ForEach-Object -Process {
            Write-Verbose -Message ('{0}' -f $_)
        }
    }
}
#EndRegion '.\public\Disable-ChocolateySource.ps1' 60
#Region '.\public\Enable-ChocolateyFeature.ps1' 0

<#
.SYNOPSIS
    Disable a Chocolatey Feature
 
.DESCRIPTION
    Allows you to enable a Chocolatey Feature usually accessed by choco feature enable -n=bob
 
.PARAMETER Name
    Name of the Chocolatey Feature to disable
 
.PARAMETER RunNonElevated
    Throws if the process is not running elevated. use -RunNonElevated if you really want to run
    even if the current shell is not elevated.
 
.EXAMPLE
    Enable-ChocolateyFeature -Name 'MyChocoFeatureName'
 
.NOTES
    https://github.com/chocolatey/choco/wiki/CommandsFeature
#>

function Enable-ChocolateyFeature
{
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')]
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')]
    [OutputType([void])]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Feature')]
        [System.String]
        $Name,

        [Parameter(DontShow)]
        [switch]
        $RunNonElevated = $(Assert-ChocolateyIsElevated)
    )

    process
    {
        if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
        {
            throw "Chocolatey Software not found."
        }

        if (!(Get-ChocolateyFeature -Name $Name))
        {
            throw "Chocolatey Feature $Name cannot be found."
        }

        $chocoArguments = @('feature', 'enable')

        $chocoArguments += Get-ChocolateyDefaultArgument @PSBoundParameters
        Write-Verbose -Message ('choco {0}' -f ($chocoArguments -join ' '))

        if ($PSCmdlet.ShouldProcess($Env:COMPUTERNAME, "$chocoCmd $($chocoArguments -join ' ')"))
        {
            &$chocoCmd $chocoArguments | ForEach-Object -Process {
                Write-Verbose -Message ('{0}' -f $_)
            }
        }
    }
}
#EndRegion '.\public\Enable-ChocolateyFeature.ps1' 64
#Region '.\public\Enable-ChocolateySource.ps1' 0

<#
.SYNOPSIS
    Enable a Source set in the Chocolatey Config
 
.DESCRIPTION
    Lets you Enable an existing source from the Chocolatey Config.
    The equivalent Choco command is Choco source enable -n=sourcename
 
.PARAMETER Name
    Name of the Chocolatey source to Disable
 
.PARAMETER RunNonElevated
    Throws if the process is not running elevated. use -RunNonElevated if you really want to run
    even if the current shell is not elevated.
 
.EXAMPLE
    Enable-ChocolateySource -Name 'chocolatey'
 
.NOTES
    https://github.com/chocolatey/choco/wiki/CommandsSource
#>

function Enable-ChocolateySource
{
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')]
    [CmdletBinding()]
    [OutputType([void])]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [System.String]
        $Name,

        [Parameter(DontShow)]
        [switch]
        $RunNonElevated = $(Assert-ChocolateyIsElevated)
    )

    process
    {
        if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
        {
            throw "Chocolatey Software not found."
        }

        if (-not (Get-ChocolateySource -id $Name))
        {
            throw "Chocolatey Source $Name cannot be found. You can Register it using Register-ChocolateySource."
        }

        $ChocoArguments = @('source', 'enable')
        $ChocoArguments += Get-ChocolateyDefaultArgument @PSBoundParameters
        Write-Verbose "choco $($ChocoArguments -join ' ')"

        &$chocoCmd $ChocoArguments | ForEach-Object -Process {
            Write-Verbose -Message ('{0}' -f $_)
        }
    }
}
#EndRegion '.\public\Enable-ChocolateySource.ps1' 60
#Region '.\public\Get-ChocolateyFeature.ps1' 0

<#
.SYNOPSIS
    Gets the Features set in the Configuration file.
 
.DESCRIPTION
    This command looks up in the Chocolatey Config file, and returns
    the Features available from there.
    Some feature may be available but now show up with this command.
 
.PARAMETER Feature
    Name of the Feature when retrieving a single Feature. It defaults to returning
    all feature available in the config file.
 
.EXAMPLE
    Get-ChocolateyFeature -Name MyFeatureName
 
.NOTES
    https://github.com/chocolatey/choco/wiki/CommandsFeature
#>

function Get-ChocolateyFeature
{
    [CmdletBinding()]
    param (
        [Parameter(
            ValueFromPipeline
            , ValueFromPipelineByPropertyName
        )]
        [Alias('Name')]
        [ValidateNotNullOrEmpty()]
        [string[]]
        $Feature = '*'
    )
    begin
    {
        if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
        {
            throw "Chocolatey Software not found."
        }

        $ChocoConfigPath = join-path $chocoCmd.Path ..\..\config\chocolatey.config -Resolve
        $ChocoXml = [xml]::new()
        $ChocoXml.Load($ChocoConfigPath)
    }

    process
    {
        if (!$ChocoXml)
        {
            throw "Error with Chocolatey config."
        }

        foreach ($Name in $Feature)
        {
            if ($Name -ne '*')
            {
                Write-Verbose ('Searching for Feature named ${0}' -f [Security.SecurityElement]::Escape($Name))
                $FeatureNodes = $ChocoXml.SelectNodes("//feature[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$([Security.SecurityElement]::Escape($Name.ToLower()))']")
            }
            else
            {
                Write-Verbose 'Returning all Sources configured.'
                $FeatureNodes = $ChocoXml.chocolatey.features.childNodes
            }

            foreach ($FeatureNode in $FeatureNodes)
            {
                $FeatureObject = [PSCustomObject]@{
                    PSTypeName = 'Chocolatey.Feature'
                }
                foreach ($property in $FeatureNode.Attributes.name)
                {
                    $FeaturePropertyParam = @{
                        MemberType = 'NoteProperty'
                        Name       = $property
                        Value      = $FeatureNode.($property).ToString()
                    }
                    $FeatureObject | Add-Member @FeaturePropertyParam
                }
                Write-Output $FeatureObject
            }
        }
    }
}
#EndRegion '.\public\Get-ChocolateyFeature.ps1' 85
#Region '.\public\Get-ChocolateyPackage.ps1' 0

<#
.SYNOPSIS
    List the packages from a source or installed on the local machine.
 
.DESCRIPTION
    This command can list the packages available on the configured source or a specified one.
    You can also retrieve the list of package installed locally.
    Finally, you can also use this command to search for a specific package, and specific version.
 
.PARAMETER Name
    Name or part of the name of the Package to search for, whether locally or from source(s).
 
.PARAMETER Version
    Version of the package you're looking for.
 
.PARAMETER LocalOnly
    Restrict the search to the installed package.
 
.PARAMETER IdOnly
    Id Only - Only return Package Ids in the list results. Available in 0.1-0.6+.
 
.PARAMETER Prerelease
    Prerelease - Include Prereleases? Defaults to false
 
.PARAMETER ApprovedOnly
    ApprovedOnly - Only return approved packages - this option will filter
    out results not from the community repository (https://chocolatey.org/packages). Available in 0.9.10+
 
.PARAMETER ByIdOnly
    ByIdOnly - Only return packages where the id contains the search filter.
    Available in 0.9.10+.
 
.PARAMETER IdStartsWith
    IdStartsWith - Only return packages where the id starts with the search
    filter. Available in 0.9.10+.
 
.PARAMETER NoProgress
    Do Not Show Progress - Do not show download progress percentages.
 
.PARAMETER Exact
    Exact - Only return packages with this exact name. Available in 0.9.10+.
 
.PARAMETER Source
    Source - Source location for install. Can use special 'webpi' or 'windowsfeatures' sources. Defaults to sources.
 
.PARAMETER Credential
    Credential used with authenticated feeds. Defaults to empty.
 
.PARAMETER CacheLocation
    CacheLocation - Location for download cache, defaults to %TEMP% or value in chocolatey.config file.
 
.EXAMPLE
    Get-ChocolateyPackage -LocalOnly chocolatey
 
.NOTES
    https://github.com/chocolatey/choco/wiki/CommandsList
#>

function Get-ChocolateyPackage
{
    [CmdletBinding()]
    param
    (
        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [String]
        $Name,

        [Parameter(
            , ValueFromPipelineByPropertyName
        )]
        [ValidateNotNullOrEmpty()]
        [System.String]
        $Version,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $LocalOnly,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $IdOnly,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $Prerelease,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $ApprovedOnly,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $ByIdOnly,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [Switch]
        $IdStartsWith,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $NoProgress,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $Exact,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        $Source,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [PSCredential]
        $Credential,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [System.String]
        $CacheLocation
    )

    process
    {
        if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
        {
            throw "Chocolatey Software not found."
        }

        $ChocoArguments = @('list', '-r')
        $paramKeys = [Array]::CreateInstance([string], $PSboundparameters.Keys.count)
        $PSboundparameters.Keys.CopyTo($paramKeys, 0)
        switch ($paramKeys)
        {
            'verbose'
            {
                $null = $PSBoundParameters.remove('Verbose')
            }
            'debug'
            {
                $null = $PSBoundParameters.remove('debug')
            }
            'Name'
            {
                $null = $PSBoundParameters.remove('Name')
            }
            'Exact'
            {
                $null = $PSBoundParameters.remove('Exact')
            }
        }

        $ChocoArguments += Get-ChocolateyDefaultArgument @PSBoundParameters
        Write-Verbose "choco $($ChocoArguments -join ' ')"

        if ($ChocoArguments -contains '--verbose')
        {
            $ChocoArguments = [System.Collections.ArrayList]$ChocoArguments
            $ChocoArguments.remove('--verbose')
        }

        if ( $LocalOnly -and
            !$PSboundparameters.containsKey('Version') -and
            (($Name -and $Exact) -or ([string]::IsNullOrEmpty($Name)))
        )
        {
            $chocoInstallPath = Get-ChocolateyInstallPath -ErrorAction 'SilentlyContinue'
            if ([string]::IsNullOrEmpty($chocoInstallPath))
            {
                Write-Verbose -Message 'Chocolatey Software is not installed on this system.'
                return
            }

            $cachePath = [io.path]::Combine($chocoInstallPath, 'cache', 'GetChocolateyPackageCache.xml')
            try
            {
                if (-not (Test-Path -Path $CacheFolder))
                {
                    $null = New-Item -Type Directory -Path $CacheFolder -Force -ErrorAction Stop
                }
                if (Test-Path -Path $CachePath)
                {
                    $CachedFile = Get-Item $CachePath
                }

                [io.file]::OpenWrite($CachePath).close()
                $CacheAvailable = $true
            }
            catch
            {
                Write-Debug "Unable to write to cache $CachePath, caching unavailable."
                $CacheAvailable = $false
            }

            if ( $CacheAvailable -and $CachedFile -and
                $CachedFile.LastWriteTime -gt ([datetime]::Now.AddSeconds(-60))
            )
            {
                Write-Debug "Retrieving from cache at $CachePath."
                $UnfilteredResults = @(Import-Clixml -Path $CachePath)
                Write-Debug "Loaded $($UnfilteredResults.count) from cache."
            }
            else
            {
                Write-Debug "Running command (before caching)."
                $ChocoListOutput = &$chocoCmd $ChocoArguments
                Write-Debug "$chocoCmd $($ChocoArguments -join ' ')"
                $UnfilteredResults = $ChocoListOutput | ConvertFrom-Csv -Delimiter '|' -Header 'Name', 'Version'
                $CacheFile = [io.fileInfo]$CachePath

                if ($CacheAvailable)
                {
                    try
                    {
                        $null = $UnfilteredResults | Export-Clixml -Path $CacheFile -Force -ErrorAction 'Stop'
                        Write-Debug "Unfiltered list cached at $CacheFile."
                    }
                    catch
                    {
                        Write-Debug "Error Creating the cache at $CacheFile."
                    }
                }
            }

            $UnfilteredResults | Where-Object {
                $( if ($Name)
                    {
                        $_.Name -eq $Name
                    }
                    else
                    {
                        $true
                    })
            }
        }
        else
        {
            Write-Debug "Running from command without caching."
            $ChocoListOutput = &$chocoCmd $ChocoArguments $Name $( if ($Exact)
                {
                    '--exact'
                } )
            $ChocoListOutput | ConvertFrom-Csv -Delimiter '|' -Header 'Name', 'Version'
        }
    }
}
#EndRegion '.\public\Get-ChocolateyPackage.ps1' 244
#Region '.\public\Get-ChocolateyPin.ps1' 0

<#
.SYNOPSIS
    Gets the pinned Chocolatey Packages.
 
.DESCRIPTION
    This command gets the pinned Chocolatey Packages, and returns
    the Settings available from there.
 
.PARAMETER Name
    Name of the Packages when retrieving a single one or a specific list.
    It defaults to returning all Packages available in the config file.
 
.EXAMPLE
    Get-ChocolateyPin -Name packageName
 
.NOTES
    https://chocolatey.org/docs/commands-pin
#>


function Get-ChocolateyPin
{
    [CmdletBinding()]
    param
    (
        [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [System.String]
        $Name = '*'
    )

    process
    {
        if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
        {
            throw "Chocolatey Software not found."
        }

        if ($Name -ne '*' -and -not (Get-ChocolateyPackage -Name $Name))
        {
            throw "Chocolatey Package $Name cannot be found."
        }

        # Prepare the arguments for `choco pin list -r`
        $ChocoArguments = @('pin', 'list', '-r')

        Write-Verbose -Message "choco $($ChocoArguments -join ' ')"

        # Stop here if the list is empty
        if (-Not ($ChocoPinListOutput = &$chocoCmd $ChocoArguments))
        {
            return
        }
        else
        {
            Write-Verbose ("Found {0} Packages" -f $ChocoPinListOutput.count)
            # Convert the list to objects
            $ChocoPinListOutput = $ChocoPinListOutput | ConvertFrom-Csv -Delimiter '|' -Header 'Name', 'Version'
        }

        if ($Name -ne '*')
        {
            Write-Verbose -Message 'Filtering pinned Packages'
            $ChocoPinListOutput = $ChocoPinListOutput | Where-Object { $_.Name -in $Name }
        }
        else
        {
            Write-Verbose -Message 'Returning all pinned Packages'
        }

        foreach ($Pin in $ChocoPinListOutput)
        {
            [PSCustomObject]@{
                PSTypeName = 'Chocolatey.Pin'
                Name       = $Pin.Name
                Version    = $Pin.Version
            }
        }
    }
}
#EndRegion '.\public\Get-ChocolateyPin.ps1' 80
#Region '.\public\Get-ChocolateySetting.ps1' 0

<#
.SYNOPSIS
    Gets the Settings set in the Configuration file.
 
.DESCRIPTION
    This command looks up in the Chocolatey Config file, and returns
    the Settings available from there.
 
.PARAMETER Setting
    Name of the Setting when retrieving a single one or a specific list.
    It defaults to returning all Settings available in the config file.
 
.EXAMPLE
    Get-ChocolateySetting -Name CacheLocation
 
.NOTES
    https://github.com/chocolatey/choco/wiki/CommandsConfig
#>

function Get-ChocolateySetting
{
    [CmdletBinding()]
    param
    (
        [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Name')]
        [ValidateNotNullOrEmpty()]
        [string[]]
        $Setting = '*'
    )

    begin
    {
        if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
        {
            throw "Chocolatey Software not found."
        }

        $ChocoConfigPath = Join-Path -Path $chocoCmd.Path -ChildPath '..\..\config\chocolatey.config' -Resolve
        $chocoXml = [xml]::new()
        $chocoXml.Load($ChocoConfigPath)
    }

    process
    {
        if (-not $chocoXml)
        {
            throw "Error with Chocolatey config."
        }

        foreach ($Name in $Setting)
        {
            if ($Name -ne '*')
            {
                Write-Verbose ("Searching for Setting named {0}" -f [Security.SecurityElement]::Escape($Name))
                $SettingNodes = $chocoXml.SelectNodes("//add[translate(@key,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$([Security.SecurityElement]::Escape($Name.ToLower()))']")
            }
            else
            {
                Write-Verbose 'Returning all Sources configured.'
                $SettingNodes = $chocoXml.chocolatey.config.childNodes
            }

            foreach ($SettingNode in $SettingNodes)
            {
                $SettingObject = [ordered]@{
                    PSTypeName = 'Chocolatey.Setting'
                }

                foreach ($property in $SettingNode.Attributes.name)
                {
                    $settingObject[$property] = '{0}' -f $SettingNode.($property)
                }

                [PSCustomObject]$SettingObject
            }
        }
    }
}
#EndRegion '.\public\Get-ChocolateySetting.ps1' 80
#Region '.\public\Get-ChocolateySource.ps1' 0

<#
.SYNOPSIS
    List the source from Configuration file.
 
.DESCRIPTION
    Allows you to list the configured source from the Chocolatey Configuration file.
    When it comes to the source location, this can be a folder/file share
    or an http location. If it is a url, it will be a location you can go
    to in a browser and it returns OData with something that says Packages
    in the browser, similar to what you see when you go
    to https://chocolatey.org/api/v2/.
 
.PARAMETER Name
    Retrieve specific source details from configuration file.
 
.EXAMPLE
    Get-ChocolateySource -Name Chocolatey
 
.NOTES
    https://github.com/chocolatey/choco/wiki/CommandsSource
#>

function Get-ChocolateySource
{
    [CmdletBinding()]
    param (
        [Parameter(
            ValueFromPipeline
            , ValueFromPipelineByPropertyName
        )]
        [Alias('id')]
        [ValidateNotNullOrEmpty()]
        [string[]]
        $Name = '*'
    )
    begin
    {
        if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
        {
            throw "Chocolatey Software not found."
        }
        $ChocoConfigPath = join-path $chocoCmd.Path ..\..\config\chocolatey.config -Resolve
        $ChocoXml = [xml]::new()
        $ChocoXml.Load($ChocoConfigPath)
    }

    process
    {
        if (!$ChocoXml)
        {
            throw "Error with Chocolatey config."
        }

        foreach ($id in $Name)
        {
            if ($id -ne '*')
            {
                Write-Verbose ('Searching for Source with id ${0}' -f [Security.SecurityElement]::Escape($id))
                $sourceNodes = $ChocoXml.SelectNodes("//source[translate(@id,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$([Security.SecurityElement]::Escape($id.ToLower()))']")
            }
            else
            {
                Write-Verbose 'Returning all Sources configured.'
                $sourceNodes = $ChocoXml.chocolatey.sources.childNodes
            }

            foreach ($source in $sourceNodes)
            {
                Write-Output (
                    [PSCustomObject]@{
                        PSTypeName  = 'Chocolatey.Source'
                        Name        = $source.id
                        Source      = $source.value
                        disabled    = [bool]::Parse($source.disabled)
                        bypassProxy = [bool]::Parse($source.bypassProxy)
                        selfService = [bool]::Parse($source.selfService)
                        priority    = [int]$source.priority
                        username    = $source.user
                        password    = $source.password
                    })
            }
        }
    }
}
#EndRegion '.\public\Get-ChocolateySource.ps1' 85
#Region '.\public\Get-ChocolateyVersion.ps1' 0

<#
.SYNOPSIS
    Retrieve the version of the Chocolatey available in $Env:Path
 
.DESCRIPTION
    Get the version of the Chocolatey currently installed.
 
.EXAMPLE
    Get-ChocolateyVersion #This command does not accept parameter
 
.NOTES
    This does not specify the SKU (C4B or Community)
#>

function Get-ChocolateyVersion
{
    [CmdletBinding()]
    [OutputType([version])]
    param (
    )

    if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
    {
        throw "Chocolatey Software not found."
    }

    $ChocoArguments = @('-v')
    Write-Verbose "choco $($ChocoArguments -join ' ')"

    $CHOCO_OLD_MESSAGE = "Please run chocolatey /? or chocolatey help - chocolatey v"
    $versionOutput = (&$chocoCmd $ChocoArguments) -replace ([regex]::escape($CHOCO_OLD_MESSAGE))
    #remove other text to keep only the last line which should have the version
    $versionOutput = ($versionOutput -split '\r\n|\n|\r')[-1]
    Write-Verbose $versionOutput
    [version]($versionOutput)
}
#EndRegion '.\public\Get-ChocolateyVersion.ps1' 37
#Region '.\public\Install-ChocolateyPackage.ps1' 0

<#
.SYNOPSIS
    Installs a Chocolatey package or a list of packages (sometimes specified as a packages.config).
 
.DESCRIPTION
    Once the Chocolatey Software has been installed (see Install-ChocolateySoftware) this command
    allows you to install Software packaged for Chocolatey.
 
.PARAMETER Name
    Package Name to install, either from a configured source, a specified one such as a folder,
    or the current directory '.'
 
.PARAMETER Version
    Version - A specific version to install. Defaults to unspecified.
 
.PARAMETER Source
    Source - The source to find the package(s) to install. Special sources
    include: ruby, webpi, cygwin, windowsfeatures, and python. To specify
    more than one source, pass it with a semi-colon separating the values (-
    e.g. "'source1;source2'"). Defaults to default feeds.
 
.PARAMETER Credential
    Credential used with authenticated feeds. Defaults to empty.
 
.PARAMETER Force
    Force - force the behavior. Do not use force during normal operation -
    it subverts some of the smart behavior for commands.
 
.PARAMETER CacheLocation
    CacheLocation - Location for download cache, defaults to %TEMP% or value
    in chocolatey.config file.
 
.PARAMETER NoProgress
    Do Not Show Progress - Do not show download progress percentages.
    Available in 0.10.4+.
 
.PARAMETER AcceptLicense
    AcceptLicense - Accept license dialogs automatically. Reserved for future use.
 
.PARAMETER Timeout
    CommandExecutionTimeout (in seconds) - The time to allow a command to
    finish before timing out. Overrides the default execution timeout in the
    configuration of 2700 seconds. '0' for infinite starting in 0.10.4.
 
.PARAMETER x86
    ForceX86 - Force x86 (32bit) installation on 64 bit systems. Defaults to false.
 
.PARAMETER InstallArguments
    InstallArguments - Install Arguments to pass to the native installer in
    the package. Defaults to unspecified.
 
.PARAMETER InstallArgumentsSensitive
    InstallArgumentsSensitive - Install Arguments to pass to the native
    installer in the package that are sensitive and you do not want logged.
    Defaults to unspecified. Available in 0.10.1+. [Licensed editions](https://chocolatey.org/compare) only.
 
.PARAMETER PackageParameters
    PackageParameters - Parameters to pass to the package, that should be handled by the ChocolateyInstall.ps1
 
.PARAMETER PackageParametersSensitive
    PackageParametersSensitive - Package Parameters to pass the package that
    are sensitive and you do not want logged. Defaults to unspecified.
    Available in 0.10.1+. [Licensed editions](https://chocolatey.org/compare) only.
 
.PARAMETER OverrideArguments
    OverrideArguments - Should install arguments be used exclusively without
    appending to current package passed arguments? Defaults to false.
 
.PARAMETER NotSilent
    NotSilent - Do not install this silently. Defaults to false.
 
.PARAMETER ApplyArgsToDependencies
    Apply Install Arguments To Dependencies - Should install arguments be
    applied to dependent packages? Defaults to false.
 
.PARAMETER AllowDowngrade
    AllowDowngrade - Should an attempt at downgrading be allowed? Defaults to false.
 
.PARAMETER IgnoreDependencies
    IgnoreDependencies - Ignore dependencies when installing package(s).
    Defaults to false.
 
.PARAMETER ForceDependencies
    ForceDependencies - Force dependencies to be reinstalled when force
    installing package(s). Must be used in conjunction with --force.
    Defaults to false.
 
.PARAMETER SkipPowerShell
    Skip Powershell - Do not run chocolateyInstall.ps1. Defaults to false.
 
.PARAMETER IgnoreChecksum
    IgnoreChecksums - Ignore checksums provided by the package. Overrides
    the default feature 'checksumFiles' set to 'True'. Available in 0.9.9.9+.
 
.PARAMETER AllowEmptyChecksum
    Allow Empty Checksums - Allow packages to have empty/missing checksums
    for downloaded resources from non-secure locations (HTTP, FTP). Use this
    switch is not recommended if using sources that download resources from
    the internet. Overrides the default feature 'allowEmptyChecksums' set to
    'False'. Available in 0.10.0+.
 
.PARAMETER ignorePackageCodes
    IgnorePackageExitCodes - Exit with a 0 for success and 1 for non-success,
    no matter what package scripts provide for exit codes. Overrides the
    default feature 'usePackageExitCodes' set to 'True'. Available in 0.-9.10+.
 
.PARAMETER UsePackageCodes
    UsePackageExitCodes - Package scripts can provide exit codes. Use those
    for choco's exit code when non-zero (this value can come from a
    dependency package). Chocolatey defines valid exit codes as 0, 1605,
    1614, 1641, 3010. Overrides the default feature 'usePackageExitCodes'
    set to 'True'. Available in 0.9.10+.
 
.PARAMETER StopOnFirstFailure
    Stop On First Package Failure - stop running install, upgrade or
    uninstall on first package failure instead of continuing with others.
    Overrides the default feature 'stopOnFirstPackageFailure' set to 'False'. Available in 0.10.4+.
 
.PARAMETER SkipCache
    Skip Download Cache - Use the original download even if a private CDN
    cache is available for a package. Overrides the default feature
    'downloadCache' set to 'True'. Available in 0.9.10+. [Licensed editions](https://chocolatey.org/compare)
    only. See https://chocolatey.org/docs/features-private-cdn
 
.PARAMETER UseDownloadCache
    Use Download Cache - Use private CDN cache if available for a package.
    Overrides the default feature 'downloadCache' set to 'True'. Available
    in 0.9.10+. [Licensed editions](https://chocolatey.org/compare) only. See https://chocolate-
    y.org/docs/features-private-cdn
 
.PARAMETER SkipVirusCheck
    Skip Virus Check - Skip the virus check for downloaded files on this run.
    Overrides the default feature 'virusCheck' set to 'True'. Available
    in 0.9.10+. [Licensed editions](https://chocolatey.org/compare) only.
    See https://chocolatey.org/docs/features-virus-check
 
.PARAMETER VirusCheck
    Virus Check - check downloaded files for viruses. Overrides the default
    feature 'virusCheck' set to 'True'. Available in 0.9.10+.
    Licensed editions only. See https://chocolatey.org/docs/features-virus-check
 
.PARAMETER VirusPositive
    Virus Check Minimum Scan Result Positives - the minimum number of scan
    result positives required to flag a package. Used when virusScannerType
    is VirusTotal. Overrides the default configuration value
    'virusCheckMinimumPositives' set to '5'. Available in 0.9.10+. Licensed
    editions only. See https://chocolatey.org/docs/features-virus-check
 
.PARAMETER RunNonElevated
    Throws if the process is not running elevated. use -RunNonElevated if you really want to run
    even if the current shell is not elevated.
 
.EXAMPLE
    Install-ChocolateyPackage -Name Chocolatey -Version 0.10.8
 
.NOTES
    https://github.com/chocolatey/choco/wiki/CommandsInstall
#>

function Install-ChocolateyPackage
{
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')]
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [System.String[]]
        $Name,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [System.String]
        $Version,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        $Source,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [PSCredential]
        $Credential,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $Force,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [System.String]
        $CacheLocation,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $NoProgress,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $AcceptLicense,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [int]
        $Timeout,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $x86,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [System.String]
        $InstallArguments,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [System.String]
        $InstallArgumentsSensitive,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [System.String]
        $PackageParameters,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [System.String]
        $PackageParametersSensitive,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $OverrideArguments,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $NotSilent,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $ApplyArgsToDependencies,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $AllowDowngrade,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $IgnoreDependencies,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $ForceDependencies,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $SkipPowerShell,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $IgnoreChecksum,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $AllowEmptyChecksum,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $ignorePackageCodes,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $UsePackageCodes,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $StopOnFirstFailure,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $SkipCache,


        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $UseDownloadCache,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $SkipVirusCheck,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $VirusCheck,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [int]
        $VirusPositive,

        [Parameter(DontShow)]
        [switch]
        $RunNonElevated = $(Assert-ChocolateyIsElevated)
    )

    begin
    {
        $null = $PSboundParameters.remove('Name')
        if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
        {
            throw "Chocolatey Software not found."
        }

        $chocoInstallPath = Get-ChocolateyInstallPath -ErrorAction 'Stop'
        $cachePath = [io.path]::Combine($chocoInstallPath, 'cache', 'GetChocolateyPackageCache.xml')
        if ((Test-Path -Path $cachePath))
        {
            Write-Debug -Message 'Removing cache begin of Install-ChocolateyPackage'
            $null = Remove-Item -Path $cachePath -ErrorAction SilentlyContinue -Force -Confirm:$false
            Write-Debug -Message 'Removed'
        }
    }

    process
    {
        foreach ($PackageName in $Name)
        {
            $ChocoArguments = @('install', $PackageName)

            $ChocoArguments += Get-ChocolateyDefaultArgument @PSBoundParameters
            Write-Verbose "choco $($ChocoArguments -join ' ')"

            if ($PSCmdlet.ShouldProcess($PackageName, "Install"))
            {
                #Impact confirmed, go choco go!
                $ChocoArguments += '-y'
                &$chocoCmd $ChocoArguments
            }
        }
    }
}
#EndRegion '.\public\Install-ChocolateyPackage.ps1' 333
#Region '.\public\Install-ChocolateySoftware.ps1' 0
# =====================================================================
# Copyright 2017 Chocolatey Software, Inc, and the
# original authors/contributors from ChocolateyGallery
# Copyright 2011 - 2017 RealDimensions Software, LLC, and the
# original authors/contributors from ChocolateyGallery
# at https://github.com/chocolatey/chocolatey.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# =====================================================================

<#
.SYNOPSIS
    Install the Chocolatey Software from a URL to download the binary from.
 
.DESCRIPTION
    Install Chocolatey Software either from a fixed URL where the chocolatey nupkg is stored,
    or from the url of a NuGet feed containing the Chocolatey Package.
    A version can be specified to lookup the Package feed for a specific version, and install it.
    A proxy URL and credential can be specified to fetch the Chocolatey package, or the proxy configuration
    can be ignored.
 
.PARAMETER ChocolateyPackageUrl
    Exact URL of the chocolatey package. This can be an HTTP server, a network or local path.
    This must be the .nupkg package as downloadable from here: https://chocolatey.org/packages/chocolatey
 
.PARAMETER PackageFeedUrl
    Url of the NuGet Feed API to use for looking up the latest version of Chocolatey (available on that feed).
    This is also used when searching for a specific version, doing a lookup via an Odata filter.
 
.PARAMETER Version
    Version to install if you want to be specific, this is the way to Install a pre-release version, as when not specified,
    the latest non-prerelease version is looked up from the feed defined in PackageFeedUrl.
 
.PARAMETER ChocoTempDir
    The temporary folder to extract the Chocolatey Binaries during install. This does not set the Chocolatey Cache dir.
 
.PARAMETER ProxyLocation
    Proxy url to use when downloading the Chocolatey Package for installation.
 
.PARAMETER ProxyCredential
    Credential to authenticate to the proxy, if not specified but the ProxyLocation is set, an attempt
    to use the Cached credential will be made.
 
.PARAMETER IgnoreProxy
    Ensure the proxy is bypassed when downloading the Chocolatey Package from the URL.
 
.PARAMETER InstallationDirectory
    Set the Installation Directory for Chocolatey, by creating the Environment Variable. This will persist after the installation.
 
.PARAMETER RunNonElevated
    Throws if the process is not running elevated. use -RunNonElevated if you really want to run
    even if the current shell is not elevated.
 
.EXAMPLE
    Install latest chocolatey software from the Community repository (non pre-release version)
    Install-ChocolateySoftware
 
.EXAMPLE
    # Install latest chocolatey software from a custom internal feed
    Install-ChocolateySoftware -PackageFeedUrl https://proget.mycorp.local/nuget/Choco
 
.NOTES
    Please raise issues at https://github.com/gaelcolas/Chocolatey/issues
#>

function Install-ChocolateySoftware
{
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')]
    [CmdletBinding(DefaultParameterSetName = 'FromFeedUrl')]
    param
    (
        [Parameter(ParameterSetName = 'FromPackageUrl')]
        [uri]
        $ChocolateyPackageUrl,

        [Parameter(ParameterSetName = 'FromFeedUrl')]
        [uri]
        $PackageFeedUrl = 'https://chocolatey.org/api/v2',

        [Parameter()]
        [System.String]
        $Version,

        [Parameter()]
        [System.String]
        $ChocoTempDir,

        [Parameter()]
        [uri]
        $ProxyLocation,

        [Parameter()]
        [pscredential]
        $ProxyCredential,

        [Parameter()]
        [switch]
        $IgnoreProxy,

        [Parameter()]
        [System.String]
        $InstallationDirectory,

        [Parameter(DontShow)]
        [switch]
        $RunNonElevated = $(Assert-ChocolateyIsElevated)
    )

    if ($PSVersionTable.PSVersion.Major -lt 4)
    {
        Repair-PowerShellOutputRedirectionBug
    }

    # Attempt to set highest encryption available for SecurityProtocol.
    # PowerShell will not set this by default (until maybe .NET 4.6.x). This
    # will typically produce a message for PowerShell v2 (just an info
    # message though)
    try
    {
        # Set TLS 1.2 (3072), then TLS 1.1 (768), then TLS 1.0 (192), finally SSL 3.0 (48)
        # Use integers because the enumeration values for TLS 1.2 and TLS 1.1 won't
        # exist in .NET 4.0, even though they are addressable if .NET 4.5+ is
        # installed (.NET 4.5 is an in-place upgrade).
        [System.Net.ServicePointManager]::SecurityProtocol = 3072 -bor 768 -bor 192
    }
    catch
    {
        Write-Warning -Message 'Unable to set PowerShell to use TLS 1.2 and TLS 1.1 due to old .NET Framework installed. If you see underlying connection closed or trust errors, you may need to do one or more of the following: (1) upgrade to .NET Framework 4.5+ and PowerShell v3, (2) specify internal Chocolatey package location (set $env:chocolateyDownloadUrl prior to install or host the package internally), (3) use the Download + PowerShell method of install. See https://chocolatey.org/install for all install options.'
    }

    switch ($PSCmdlet.ParameterSetName)
    {
        'FromFeedUrl'
        {
            if ($PackageFeedUrl -and -not [string]::IsNullOrEmpty($Version))
            {
                Write-Verbose -Message "Downloading specific version of Chocolatey: $Version"
                $url = "$PackageFeedUrl/package/chocolatey/$Version"
            }
            else
            {
                if (-not [string]::IsNullOrEmpty($PackageFeedUrl))
                {
                    $url = $PackageFeedUrl
                }
                else
                {
                    $url = 'https://chocolatey.org/api/v2'
                }

                Write-Verbose "Getting latest version of the Chocolatey package for download."
                $url = "$url/Packages()?`$filter=((Id%20eq%20%27chocolatey%27)%20and%20(not%20IsPrerelease))%20and%20IsLatestVersion"
                Write-Debug -Message ('Retrieving Binary URL from Package Metadata: {0}' -f $url)

                $GetRemoteStringParams = @{
                    url = $url
                }

                [string[]]$getRemoteStringParamsName = (Get-Command -Name Get-RemoteString).parameters.keys
                $KeysForRemoteString = $PSBoundParameters.keys | Where-Object { $_ -in $GetRemoteStringParamsName }
                foreach ($key in $KeysForRemoteString )
                {
                    Write-Debug -Message "`tWith $key :: $($PSBoundParameters[$key])"
                    $GetRemoteStringParams[$key] =$PSBoundParameters[$key]
                }

                [xml]$result = Get-RemoteString @GetRemoteStringParams
                Write-Debug "New URL for nupkg: $url"
                $url = $result.feed.entry.content.src
            }
        }

        'FromPackageUrl'
        {
            #ignores version
            Write-Verbose -Message "Downloading Chocolatey from : $ChocolateyPackageUrl"
            $url = $ChocolateyPackageUrl
        }
    }

    if ([string]::IsNullOrEmpty($env:TEMP))
    {
        $env:TEMP = Join-Path $Env:SYSTEMDRIVE 'temp'
    }

    $tempDir = [io.path]::Combine($Env:TEMP, 'chocolatey', 'chocInstall')
    if (-not [System.IO.Directory]::Exists($tempDir))
    {
        $null = New-Item -path $tempDir -ItemType Directory
    }

    $file = Join-Path -Path $tempDir -ChildPath "chocolatey.zip"
    # Download the Chocolatey package
    Write-Verbose -Message "Getting Chocolatey from $url."
    $GetRemoteFileParams = @{
        url  = $url
        file = $file
    }

    $GetRemoteFileParamsName = (get-command Get-RemoteFile).parameters.keys
    $KeysForRemoteFile = $PSBoundParameters.keys | Where-Object { $_ -in $GetRemoteFileParamsName }
    foreach ($key in $KeysForRemoteFile )
    {
        Write-Debug "`tWith $key :: $($PSBoundParameters[$key])"
        $null = $GetRemoteFileParams.Add($key , $PSBoundParameters[$key])
    }

    $null = Get-RemoteFile @GetRemoteFileParams

    # unzip the package
    Write-Verbose "Extracting $file to $tempDir..."

    if ($PSVersionTable.PSVersion.Major -ge 5)
    {
        Expand-Archive -Path "$file" -DestinationPath "$tempDir" -Force
    }
    else
    {
        try
        {
            $shellApplication = new-object -com shell.application
            $zipPackage = $shellApplication.NameSpace($file)
            $destinationFolder = $shellApplication.NameSpace($tempDir)
            $destinationFolder.CopyHere($zipPackage.Items(), 0x10)
        }
        catch
        {
            throw "Unable to unzip package using built-in compression. Error: `n $_"
        }
    }

    # Call chocolatey install
    Write-Verbose -Message "Installing chocolatey on this machine."
    $TempTools = [io.path]::combine($tempDir, 'tools')
    # To be able to mock
    $chocInstallPS1 = Join-Path -Path $TempTools -ChildPath 'chocolateyInstall.ps1'

    if ($InstallationDirectory)
    {
        [Environment]::SetEnvironmentVariable('ChocolateyInstall', $InstallationDirectory, 'Machine')
    }

    & $chocInstallPS1 | Write-Debug
    Write-Verbose -Message 'Ensuring chocolatey commands are on the path.'
    [string] $chocoPath = ''

    if ($chocoPath = [Environment]::GetEnvironmentVariable('ChocolateyInstall','Machine'))
    {
        Write-Debug -Message ('The Machine Environment variable is already set to: ''{0}''.' -f $chocoPath)
    }
    else
    {
        # Checking if it was installed in AllUserProfile/Chocolatey (was default many years ago)
        $chocoPath = Join-Path -Path $env:ALLUSERSPROFILE -ChildPath 'Chocolatey'
        if (-not (Test-Path -Path $chocoPath))
        {
            # The AllUserProfile/Chocolatey folder does not exit, let's install in correct default location
            $chocoPath = Join-Path -Path $env:ProgramData -ChildPath 'Chocolatey'
        }

        # Set the Machine-scoped 'ChocolateyInstall' environement variable
        Write-Debug -Message ('Setting the Machine & Process Environment variable to: ''{0}''.' -f $chocoPath)
        [Environment]::SetEnvironmentVariable('ChocolateyInstall', $chocoPath, 'Machine')
        [Environment]::SetEnvironmentVariable('ChocolateyInstall', $chocoPath, 'Process')
    }

    $chocoExePath = Join-Path -Path $chocoPath -ChildPath 'bin'

    if (@($env:Path.ToLower() -split [io.path]::PathSeparator) -notcontains $chocoExePath.ToLower())
    {
        # we can't see the choco bin folder in $env:Path, trying to load from Machine.
        $env:Path = [Environment]::GetEnvironmentVariable('Path', 'Machine')
    }

    Write-Verbose -Message 'Ensuring chocolatey.nupkg is in the lib folder'
    $chocoPkgDir = Join-Path -Path $chocoPath -ChildPath 'lib\chocolatey'
    $nupkg = Join-Path -Path $chocoPkgDir -ChildPath 'chocolatey.nupkg'
    $null = [System.IO.Directory]::CreateDirectory($chocoPkgDir)
    Copy-Item -Path $file -Destination $nupkg -Force -ErrorAction 'SilentlyContinue'

    if ($ChocoVersion = & "$chocoPath\choco.exe" @('-v'))
    {
        Write-Verbose ('Installed Chocolatey Version: {0}'-f $ChocoVersion)
    }
}
#EndRegion '.\public\Install-ChocolateySoftware.ps1' 295
#Region '.\public\Register-ChocolateySource.ps1' 0

<#
.SYNOPSIS
    Register a new Chocolatey source or edit an existing one.
 
.DESCRIPTION
    Chocolatey will allow you to interact with sources.
    You can register a new source, whether internal or external with some source
    specific settings such as proxy.
 
.PARAMETER Name
    Name - the name of the source. Required with some actions. Defaults to empty.
 
.PARAMETER Source
    Source - The source. This can be a folder/file share or an http location.
    If it is a url, it will be a location you can go to in a browser and
    it returns OData with something that says Packages in the browser,
    similar to what you see when you go to https://chocolatey.org/api/v2/.
    Defaults to empty.
 
.PARAMETER Disabled
    Allow the source to be registered but disabled.
 
.PARAMETER BypassProxy
    Bypass Proxy - Should this source explicitly bypass any explicitly or
    system configured proxies? Defaults to false. Available in 0.10.4+.
 
.PARAMETER SelfService
    Allow Self-Service - Should this source be allowed to be used with self-
    service? Requires business edition (v1.10.0+) with feature
    'useBackgroundServiceWithSelfServiceSourcesOnly' turned on. Defaults to
    false. Available in 0.10.4+.
 
.PARAMETER Priority
    Priority - The priority order of this source as compared to other
    sources, lower is better. Defaults to 0 (no priority). All priorities
    above 0 will be evaluated first, then zero-based values will be
    evaluated in config file order. Available in 0.9.9.9+.
 
.PARAMETER Credential
    Credential used with authenticated feeds. Defaults to empty.
 
.PARAMETER Force
    Force - force the behavior. Do not use force during normal operation -
    it subverts some of the smart behavior for commands.
 
.PARAMETER CacheLocation
    CacheLocation - Location for download cache, defaults to %TEMP% or value
    in chocolatey.config file.
 
.PARAMETER NoProgress
    Do Not Show Progress - Do not show download progress percentages.
    Available in 0.10.4+.
 
.PARAMETER KeyUser
    API Key User for the source being registered.
 
.PARAMETER Key
    API key for the source (too long in C4B to be passed as credentials)
 
.PARAMETER RunNonElevated
    Throws if the process is not running elevated. use -RunNonElevated if you really want to run
    even if the current shell is not elevated.
 
.EXAMPLE
    Register-ChocolateySource -Name MyNuget -Source https://proget/nuget/choco
 
.NOTES
    https://github.com/chocolatey/choco/wiki/CommandsSource
#>

function Register-ChocolateySource
{
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')]
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [System.String]
        $Name,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        $Source,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $Disabled = $false,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $BypassProxy = $false,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $SelfService = $false,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [int]
        $Priority = 0,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [PSCredential]
        $Credential,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $Force,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [System.String]
        $CacheLocation,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [switch]
        $NoProgress,

        [Parameter()]
        #To be used when Password is too long (>240 char) like a key
        $KeyUser,

        [Parameter()]
        $Key,

        [Parameter(DontShow)]
        [switch]
        $RunNonElevated = $(Assert-ChocolateyIsElevated)
    )

    process
    {
        if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
        {
            throw "Chocolatey Software not found."
        }

        if (-not $PSBoundParameters.containskey('Disabled'))
        {
            $null = $PSBoundParameters.add('Disabled', $Disabled)
        }

        if (-not $PSBoundParameters.containskey('SelfService'))
        {
            $null = $PSBoundParameters.add('SelfService', $SelfService)
        }

        if (-not $PSBoundParameters.containskey('BypassProxy'))
        {
            $null = $PSBoundParameters.add('BypassProxy', $BypassProxy)
        }

        $ChocoArguments = @('source', 'add')
        $ChocoArguments += Get-ChocolateyDefaultArgument @PSBoundParameters
        Write-Verbose "choco $($ChocoArguments -join ' ')"

        &$chocoCmd $ChocoArguments | ForEach-Object -Process {
            Write-Verbose -Message $_
        }

        if ($Disabled)
        {
            &$chocoCmd @('source', 'disable', "-n=`"$Name`"", '--limit-output') | ForEach-Object -Process {
                Write-Verbose -Message $_
            }
        }
    }
}
#EndRegion '.\public\Register-ChocolateySource.ps1' 166
#Region '.\public\Remove-ChocolateyPin.ps1' 0

<#
.SYNOPSIS
    Remove a Pin from a Chocolatey Package
 
.DESCRIPTION
    Allows you to remove a pinned Chocolatey Package like choco pin remove -n=packagename
 
.PARAMETER Name
    Name of the Chocolatey Package to remove the pin.
 
.PARAMETER RunNonElevated
    Throws if the process is not running elevated. use -RunNonElevated if you really want to run
    even if the current shell is not elevated.
 
.EXAMPLE
    Remove-ChocolateyPin -Name 'PackageName'
 
.NOTES
    https://chocolatey.org/docs/commands-pin
#>

function Remove-ChocolateyPin
{
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    [OutputType([void])]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Package')]
        [System.String]
        $Name,

        [Parameter(DontShow)]
        [switch]
        $RunNonElevated = $(Assert-ChocolateyIsElevated)
    )

    process
    {
        if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
        {
            throw "Chocolatey Software not found."
        }

        if (-not (Get-ChocolateyPackage -Name $Name))
        {
            throw "The Pin for Chocolatey Package $Name cannot be found."
        }

        $chocoArguments = @('pin', 'remove', '-r')
        $chocoArguments += Get-ChocolateyDefaultArgument @PSBoundParameters
        Write-Verbose -Message "choco $($chocoArguments -join ' ')"

        if ($PSCmdlet.ShouldProcess("$Name", "Remove Pin"))
        {
            $output = &$chocoCmd $chocoArguments

            # LASTEXITCODE is always 0 unless point an existing version (0 when remove but already removed)
            if ($LASTEXITCODE -ne 0)
            {
                throw ("Error when trying to remove Pin for {0}.`r`n {1}" -f "$Name", ($output -join "`r`n"))
            }
            else
            {
                $output | ForEach-Object -Process {
                    Write-Verbose -Message ('{0}' -f $_)
                }
            }
        }
    }
}
#EndRegion '.\public\Remove-ChocolateyPin.ps1' 72
#Region '.\public\Set-ChocolateySetting.ps1' 0

<#
.SYNOPSIS
    Set or unset a Chocolatey Setting
 
.DESCRIPTION
    Allows you to set or unset the value of a Chocolatey setting usually accessed by choco config set -n=bob value
 
.PARAMETER Name
    Name (or setting) of the Chocolatey setting to modify
 
.PARAMETER Value
    Value to be given on the setting. This is not available when the switch -Unset is used.
 
.PARAMETER Unset
    Unset the setting, returning to the Chocolatey defaults.
 
.PARAMETER RunNonElevated
    Throws if the process is not running elevated. use -RunNonElevated if you really want to run
    even if the current shell is not elevated.
 
.EXAMPLE
    Set-ChocolateySetting -Name 'cacheLocation' -value 'C:\Temp\Choco'
 
.NOTES
    https://github.com/chocolatey/choco/wiki/CommandsConfig
#>

function Set-ChocolateySetting
{
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')]
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')]
    [OutputType([Void])]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Setting')]
        [System.String]
        $Name,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Set')]
        [AllowEmptyString()]
        [System.String]
        $Value,

        [Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Unset')]
        [switch]
        $Unset,

        [Parameter(DontShow)]
        [switch]
        $RunNonElevated = $(Assert-ChocolateyIsElevated)
    )

    process
    {
        if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
        {
            throw "Chocolatey Software not found."
        }

        $ChocoArguments = @('config')
        #Removing PSBoundParameters that could impact Chocolatey's "choco config set" command
        foreach ($key in @([System.Management.Automation.Cmdlet]::CommonParameters + [System.Management.Automation.Cmdlet]::OptionalCommonParameters))
        {
            if ($PSBoundParameters.ContainsKey($key))
            {
                $null = $PSBoundParameters.remove($key)
            }
        }

        if ($Unset -or [string]::IsNullOrEmpty($Value))
        {
            if ($PSBoundParameters.ContainsKey('value'))
            {
                $null = $PSBoundParameters.Remove('Value')
            }

            $null = $PSBoundParameters.remove('unset')
            $ChocoArguments += 'unset'
        }
        else
        {
            $PSBoundParameters['Value'] = $ExecutionContext.InvokeCommand.ExpandString($Value).TrimEnd(@('/', '\'))
            $ChocoArguments += 'set'
        }

        $ChocoArguments += Get-ChocolateyDefaultArgument @PSBoundParameters
        Write-Verbose -Message ('choco {0}' -f ($ChocoArguments -join ' '))

        if ($PSCmdlet.ShouldProcess($Env:COMPUTERNAME, "$chocoCmd $($ChocoArguments -join ' ')"))
        {
            &$chocoCmd $ChocoArguments | ForEach-Object -Process {
                Write-Verbose -Message ('{0}' -f $_)
            }
        }
    }
}
#EndRegion '.\public\Set-ChocolateySetting.ps1' 98
#Region '.\public\Test-ChocolateyFeature.ps1' 0

<#
.SYNOPSIS
    Test Whether a feature is disabled, enabled or not found
 
.DESCRIPTION
    Some feature might not be available in your version or SKU.
    This command allows you to test the state of that feature.
 
.PARAMETER Name
    Name of the feature to verify
 
.PARAMETER Disabled
    Test if the feature is disabled, the default is to test if the feature is enabled.
 
.EXAMPLE
    Test-ChocolateyFeature -Name FeatureName -Disabled
 
.NOTES
    https://github.com/chocolatey/choco/wiki/CommandsFeature
#>

function Test-ChocolateyFeature
{
    [CmdletBinding()]
    [outputType([Bool])]
    param (
        [Parameter(
            Mandatory = $true
            , ValueFromPipelineByPropertyName
        )]
        [Alias('Feature')]
        [System.String]
        $Name,

        [Parameter(
            ValueFromPipelineByPropertyName
        )]
        [Switch]
        $Disabled
    )

    process
    {
        if (-not (Get-Command 'choco.exe' -CommandType Application -ErrorAction SilentlyContinue))
        {
            throw "Chocolatey Software not found."
        }

        if (!($Feature = Get-ChocolateyFeature -Name $Name))
        {
            Write-Warning "Chocolatey Feature $Name cannot be found."
            return $false
        }
        $Feature | Write-Verbose
        if ($Feature.enabled -eq !$Disabled.ToBool())
        {
            Write-Verbose ("The Chocolatey Feature {0} is set to {1} as expected." -f $Name, (@('Disabled', 'Enabled')[([int]$Disabled.ToBool())]))
            return $true
        }
        else
        {
            Write-Verbose ("The Chocolatey Feature {0} is NOT set to {1} as expected." -f $Name, (@('Disabled', 'Enabled')[([int]$Disabled.ToBool())]))
            return $False
        }
    }
}
#EndRegion '.\public\Test-ChocolateyFeature.ps1' 67
#Region '.\public\Test-ChocolateyInstall.ps1' 0

<#
.SYNOPSIS
    Test if the Chocolatey Software is installed.
 
.DESCRIPTION
    To test whether the Chocolatey Software is installed, it first look for the Command choco.exe.
    It then check if it's installed in the InstallDir path, if provided.
 
.PARAMETER InstallDir
    To ensure the software is installed in the given directory. If not specified,
    it will only test if the commadn choco.exe is available.
 
.EXAMPLE
    Test-ChocolateyInstall #Test whether the Chocolatey Software is installed
 
.NOTES
General notes
#>

function Test-ChocolateyInstall
{
    [CmdletBinding()]
    [OutputType([bool])]
    param (
        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [System.String]
        $InstallDir
    )

    Write-Verbose "Loading machine Path Environment variable into session."
    $envPath = [Environment]::GetEnvironmentVariable('Path', 'Machine')
    [Environment]::SetEnvironmentVariable($envPath, 'Process')

    if ($InstallDir)
    {
        $InstallDir = (Resolve-Path $InstallDir -ErrorAction Stop).Path
    }

    if (-not ($chocoCmd = @(Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue')[0]))
    {
        if (
            -not $InstallDir -or
            $chocoCmd.Path -match [regex]::Escape($InstallDir)
        )
        {
            Write-Verbose ('Chocolatey Software found in {0}' -f $chocoCmd.Path)
            return $true
        }
        else
        {
            Write-Verbose (
                'Chocolatey Software not installed in {0}`n but in {1}' -f $InstallDir, $chocoCmd.Path
            )
            return $false
        }
    }
    else
    {
        Write-Verbose -Message 'Chocolatey Software not found.'
        return $false
    }
}
#EndRegion '.\public\Test-ChocolateyInstall.ps1' 64
#Region '.\public\Test-ChocolateyPackageIsInstalled.ps1' 0

<#
.SYNOPSIS
    Verify if a Chocolatey Package is installed locally
 
.DESCRIPTION
    Search and compare the Installed PackageName locally, and compare the provided property.
    The command return an object with the detailed properties, and a comparison between the installed version
    and the expected version.
 
.PARAMETER Name
    Exact name of the package to be testing against.
 
.PARAMETER Version
    Version expected of the package, or latest to compare against the latest version from a source.
 
.PARAMETER Source
    Source to compare the latest version against. It will retrieve the
 
.PARAMETER Credential
    Credential used with authenticated feeds. Defaults to empty.
 
.PARAMETER CacheLocation
    CacheLocation - Location for download cache, defaults to %TEMP% or value
    in chocolatey.config file.
 
.PARAMETER UpdateOnly
    Test if the package needs to be installed if absent.
    In Update Only mode, a package of lower version needs to be updated, but a package absent
    won't be installed.
 
.EXAMPLE
    Test-ChocolateyPackageIsInstalled -Name Chocolatey -Source https://chocolatey.org/api/v2
 
.NOTES
    https://github.com/chocolatey/choco/wiki/CommandsList
#>

function Test-ChocolateyPackageIsInstalled
{
    [CmdletBinding()]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "")]
    param (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [System.String]
        $Name,

        [Parameter(
            ValueFromPipelineByPropertyName
        )]
        [ValidateNotNullOrEmpty()]
        [System.String]
        $Version,

        [Parameter(
            ValueFromPipelineByPropertyName
        )]
        $Source,

        [Parameter(
            ValueFromPipelineByPropertyName
        )]
        [PSCredential]
        $Credential,

        [Parameter(
            ValueFromPipelineByPropertyName
        )]
        [System.String]
        $CacheLocation,

        [Parameter(
            ValueFromPipelineByPropertyName
        )]
        [switch]
        $UpdateOnly

    )

    process
    {
        if (-not (Get-Command 'choco.exe' -CommandType Application -ErrorAction SilentlyContinue))
        {
            throw "Chocolatey Software not found."
        }

        #if version latest verify against sources
        if (! ($InstalledPackages = @(Get-ChocolateyPackage -LocalOnly -Name $Name -Exact)) )
        {
            Write-Verbose "Could not find Package $Name."
        }

        $SearchPackageParams = $PSBoundParameters
        $null = $SearchPackageParams.Remove('version')
        $null = $SearchPackageParams.Remove('UpdateOnly')

        if ($Version -eq 'latest')
        {
            $ReferenceObject = Get-ChocolateyPackage @SearchPackageParams -Exact
            if (!$ReferenceObject)
            {
                throw "Latest version of Package $name not found. Verify that the sources are reachable and package exists."
            }
        }
        else
        {
            $ReferenceObject = [PSCustomObject]@{
                Name = $Name
            }
            if ($Version)
            {
                $ReferenceObject | Add-Member -MemberType NoteProperty -Name version -value $Version
            }
        }

        $PackageFound = $false
        $MatchingPackages = $InstalledPackages | Where-Object {
            Write-Debug "Testing $($_.Name) against $($ReferenceObject.Name)"
            if ($_.Name -eq $ReferenceObject.Name)
            {
                $PackageFound = $True
                Write-Debug "Package Found"

                if (!$Version)
                {
                    return $true
                }
                elseif ((Compare-SemVerVersion $_.version $ReferenceObject.version) -in @('=', '>'))
                {
                    return $true
                }
                else
                {
                    return $false
                }
            }
        }

        if ($MatchingPackages)
        {
            Write-Verbose ("'{0}' packages match the given properties." -f $MatchingPackages.Count)
            $VersionGreaterOrEqual = $true
        }
        elseif ($PackageFound -and $UpdateOnly)
        {
            Write-Verbose "This package is installed with a lower version than specified."
            $VersionGreaterOrEqual = $false
        }
        elseif (!$PackageFound -and $UpdateOnly)
        {
            Write-Verbose "No packages match the selection, but no need to Install."
            $VersionGreaterOrEqual = $true
        }
        else
        {
            Write-Verbose "No packages match the selection and need Installing."
            $VersionGreaterOrEqual = $False
        }

        Write-Output (
            [PSCustomObject]@{
                PackagePresent        = $PackageFound
                VersionGreaterOrEqual = $VersionGreaterOrEqual
            })
    }
}
#EndRegion '.\public\Test-ChocolateyPackageIsInstalled.ps1' 167
#Region '.\public\Test-ChocolateyPin.ps1' 0

<#
.SYNOPSIS
    Test whether a package is set, enabled or not found
 
.DESCRIPTION
    This command allows you to test the values of a pinned package.
 
.PARAMETER Name
    Name of the Package to verify
 
.PARAMETER Version
    Test if the Package version provided matches with the one set on the config file.
 
.EXAMPLE
    Test-ChocolateyPin -Name PackageName -Version ''
 
.NOTES
    https://chocolatey.org/docs/commands-pin
#>

function Test-ChocolateyPin
{
    [CmdletBinding()]
    [OutputType([Bool])]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [string]
        $Name,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [string]
        $Version
    )

    process
    {
        if (-not (Get-Command 'choco.exe' -CommandType 'Application' -ErrorAction 'SilentlyContinue'))
        {
            throw 'Chocolatey Software not found.'
        }

        if (-not ($pin = Get-ChocolateyPin -Name $Name))
        {
            Write-Verbose -Message ('The Pin for the Chocolatey Package ''{0}'' cannot be found.' -f $Name)
            return $false
        }

        if ([string]$pin.Version -eq $Version)
        {
            Write-Verbose -Message ('The Pin for the Chocolatey Package ''{0}'' is set to ''{1}'' as expected.' -f $Name, $pin.Version)
            return $true
        }
        else
        {
            Write-Verbose ('The Pin for the Chocolatey Package ''{0}'' is NOT set to ''{1}'' but to ''{2}''.' -f $Name, $Version, $pin.Version)
            return $false
        }
    }
}
#EndRegion '.\public\Test-ChocolateyPin.ps1' 61
#Region '.\public\Test-ChocolateySetting.ps1' 0

<#
.SYNOPSIS
    Test Whether a setting is set, enabled or not found
 
.DESCRIPTION
    Some settings might not be available in your version or SKU.
    This command allows you to test the values of a named setting.
 
.PARAMETER Name
    Name of the Setting to verify
 
.PARAMETER Value
    Test if the Setting value provided matches with the one set on the config file.
 
.PARAMETER Unset
    Test if the Setting is disabled, the default is to test if the feature is enabled.
 
.EXAMPLE
    Test-ChocolateySetting -Name SettingName -value ''
 
.NOTES
    https://github.com/chocolatey/choco/wiki/CommandsConfig
#>

function Test-ChocolateySetting
{
    [CmdletBinding(DefaultParameterSetName = 'Set')]
    [OutputType([Bool])]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('Setting')]
        [System.String]
        $Name,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Set')]
        [AllowEmptyString()]
        [AllowNull()]
        [System.String]
        $Value,

        [Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Unset')]
        [switch]
        $Unset
    )

    process
    {
        if (-not (Get-Command 'choco.exe' -CommandType Application -ErrorAction SilentlyContinue))
        {
            throw "Chocolatey Software not found."
        }

        if (-not ($setting = Get-ChocolateySetting -Name $Name))
        {
            Write-Warning "Chocolatey Setting $Name cannot be found."
            return $false
        }

        Write-Verbose -Message ('Setting ''{0}'' set to ''{1}''.' -f $setting.Name, $setting.Value)

        if ($Unset)
        {
            $value = ''
        }
        else
        {
            $value = $ExecutionContext.InvokeCommand.ExpandString($value).TrimEnd(@('/', '\'))
        }

        if ([string]$Setting.value -eq $Value)
        {
            Write-Verbose -Message ("The Chocolatey Setting {0} is set to '{1}' as expected." -f $Name, $value)
            return $true
        }
        else
        {
            Write-Verbose -Message ("The Chocolatey Setting {0} is NOT set to '{1}' as expected:{2}" -f $Name, $Setting.value, $value)
            return $false
        }
    }
}
#EndRegion '.\public\Test-Chocolat