PSChocoConfig.psm1

function Add-ChocoSource {
    <#
    .SYNOPSIS
    Adds a new source to chocolatey
     
    .DESCRIPTION
    Adds a new source with the given name and settings to chocolatey
     
    .PARAMETER Name
    The friendly name of the source
     
    .PARAMETER Source
    The URL or filepath of the source
     
    .PARAMETER Username
    The username used to authenticate to the source
     
    .PARAMETER Password
    The password used to authenticate to the source
     
    .PARAMETER Certificate
    The path to the certificate to use with the source if required
     
    .PARAMETER CertificatePassword
    The certificate's private key
     
    .PARAMETER AllowSelfService
    Enable self-service mode for the source
     
    .PARAMETER BypassProxy
    Bypass any proxy configuration for the specified source
     
    .PARAMETER AdminOnly
    Allow only local administrator group members to use the specified source
     
    .PARAMETER Priority
    The priority to give to the specified source
     
    .EXAMPLE
    Add-ChocoSource -Name bob -s https://reposserver/repository/choco
 
    .EXAMPLE
    Add-ChocoSource -Name bob -s \\fileserver\chocopackages
 
    .EXAMPLE
    Add-ChocoSource -Name bill -s https://repositoryserver/repository/choco -Username frank -Password frank1234
     
    .EXAMPLE
    Add-ChocoSource -Name bob -s https://repositoryserver/repository/choco -AllowSelfService
     
    .NOTES
    General notes
    #>

    
    [cmdletBinding(ConfirmImpact="High",SupportsShouldProcess,HelpUri="https://github.com/steviecoaster/PSChocoConfig/wiki/Add-ChocoSource",DefaultParameterSetName="Source")]
    Param(
        [Parameter(Mandatory,Position=0,ParameterSetName="Source")]
        [Alias("FriendlyName")]
        [String]
        $Name,

        [Parameter(Mandatory,Position=1,ParameterSetName="Source")]
        [String]
        $Source,

        [Parameter(Mandatory,Position=2,ParameterSetName="Credential")]
        [String]
        $Username,

        [Parameter(Mandatory,Position=3,ParameterSetName="Credential")]
        [String]
        $Password,

        [Parameter(Mandatory,Position=4,ParameterSetName="Certificate")]
        [ValidateScript({Test-Path $_})]
        [String]
        $Certificate,
        
        [Parameter(Mandatory,Position=5,ParameterSetName="Certificate")]
        [String]
        $CertificatePassword,

        [Parameter(Position=6)]
        [switch]
        $AllowSelfService,

        [Parameter(Position=7)]
        [switch]
        $BypassProxy,

        [Parameter(Position=8)]
        [switch]
        $AdminOnly,

        [Parameter(Position=9)]
        [int]
        $Priority
    )

    process {

        $collection = [System.Collections.Generic.List[string]]::New()

        switch($PSBoundParameters.Keys){

           'Name' {$collection.add("--name=$Name")} 
           'Source' {$collection.add("--source=$Source")}
           'Username' {$collection.add("--user='$Username'")}
           'Password' {$collection.add("--password='$Password'")}
           'Certificate' {$collection.add("--cert='$Certifacate'")}
           'CertificatePassword' {$collection.add("--certifactepassword='$CertifactePassword'")}
           'AllowSelfService' {$collection.add("--allowselfservice")}
           'BypassProxy' {$collection.add("--bypassproxy")}
           'AdminOnly' {$collection.add("--adminonly")}
           'Priority' { $collection.add("--priority=$Priority")}
        }

        $args = $collection -join ' '

        If($PSCmdlet.ShouldProcess($args,"Adding source $Name")){
            
            $choco = Start-Process choco -ArgumentList 'source','add',$args -PassThru -Wait

            If($choco.ExitCode -ne 0){

                Write-Error "An issue occured: $($_.Exception.Message)"
                
            }

            Else {

                Write-Verbose -Message "Added source: $Name"
            
            }
        }
    }

}
function Clear-ChocoConfig {
    <#
        .SYNOPSIS
        Unsets the chosen configuration item
 
        .DESCRIPTION
        This command wraps 'choco config' to make setting configuration items easier. Dynamically generates names from configuration file.
 
        .PARAMETER Name
 
        The name of the configuration item to change
 
        .EXAMPLE
        Clear-ChocoConfig -Name proxy
 
        Sets the proxy configuration setting to a blank default value
    #>

    [cmdletBinding(SupportsShouldProcess,ConfirmImpact="High",HelpUri="https://github.com/steviecoaster/PSChocoConfig/wiki/Clear-ChocoConfig")]
    Param (
        [Parameter(Mandatory,Position=0)]
        [ArgumentCompleter({
            param($Command,$Parameter,$WordTocomplete,$CommandAst,$FakeBoundParams)
            $results = Get-ChocoConfig | Select -ExpandProperty key

            If($WordTocomplete){

                $results.Where{ $_ -match "^$WordTocomplete"}
                
            }

            Else {

                $results

            }
        })]
        [String]

        $Name

    )

    process {

        If($PSCmdlet.ShouldProcess("$Name","Removing value: $Value")){
        
            $choco = choco config unset --name="'$Name'"
            Write-Host "$($choco[-1])"-ForegroundColor Yellow
        
        }
    }

}
function Disable-ChocoSource {
    <#
    .SYNOPSIS
    Disables the specified choco source
     
    .DESCRIPTION
    Sets the disabled property of the specified source to true.
     
    .PARAMETER Source
    The friendly name of the source to disable.
     
    .EXAMPLE
    Disable-ChocoSource -Source bob
    #>

    
    [cmdletBinding(ConfirmImpact="High",SupportsShouldProcess,HelpUri="https://github.com/steviecoaster/PSChocoConfig/wiki/Disable-ChocoSource")]
    Param(
        [Parameter(Mandatory,Position=0)]
        [String]
        $Source
    )

    process{

        If($PSCmdlet.ShouldProcess("$Source","Setting value: Disabled")){
            
            $StartInfo = [System.Diagnostics.ProcessStartInfo]::new()
            $source = 'dumb'
            $args = @('source','disable',"-n=$source")
            $StartInfo.CreateNoWindow = $true
            $StartInfo.UseShellExecute = $false
            $StartInfo.RedirectStandardOutput = $true
            $StartInfo.RedirectStandardError = $true
            $StartInfo.FileName = 'choco'
            $StartInfo.Arguments = $args

            $process = [System.Diagnostics.Process]::new()
            $process.StartInfo = $StartInfo
            [void]$process.Start()

            $output = $process.StandardOutput.ReadToEnd()
            $process.WaitForExit()

            Write-Verbose $output
            
           
    
        }

    }

}
function Enable-ChocoSource {
    <#
    .SYNOPSIS
    Enables the specified choco source
     
    .DESCRIPTION
    Sets the disabled property of the specified source to false
     
    .PARAMETER Source
    The friendly name of the source to enable
     
    .EXAMPLE
    Enable-ChocoSource -Source bob
    #>

    
    [cmdletBinding(ConfirmImpact="High",SupportsShouldProcess,HelpUri="https://github.com/steviecoaster/PSChocoConfig/wiki/Enable-ChocoSource")]
    Param(
        [Parameter(Mandatory,Position=0)]
        [String]
        $Source
    )

    process{

        If($PSCmdlet.ShouldProcess("$Source","Setting value: Enabled")){
            
            $StartInfo = [System.Diagnostics.ProcessStartInfo]::new()
            $source = 'dumb'
            $args = @('source','enable',"-n=$source")
            $StartInfo.CreateNoWindow = $true
            $StartInfo.UseShellExecute = $false
            $StartInfo.RedirectStandardOutput = $true
            $StartInfo.RedirectStandardError = $true
            $StartInfo.FileName = 'choco'
            $StartInfo.Arguments = $args

            $process = [System.Diagnostics.Process]::new()
            $process.StartInfo = $StartInfo
            [void]$process.Start()

            $output = $process.StandardOutput.ReadToEnd()
            $process.WaitForExit()

            Write-Verbose $output
        }

    }

}
function Get-ChocoConfig {
    <#
        .SYNOPSIS
        Converts choco's configuration file into a powershell object
         
        .PARAMETER ChocolateyConfig
        The chocolatey config to load. Defaults to $Env:ChocolateyInstall\config\chocolatey.config
         
        .PARAMETER ConfigurationItem
        Return only specified Configuration Item(s).
         
        .EXAMPLE
        Get-ChocoConfig
         
        .EXAMPLE
        Get-ChocoConfig -ConfigurationItem proxy
         
    #>

    [cmdletBinding(HelpUri="https://github.com/steviecoaster/PSChocoConfig/wiki/Get-ChocoConfig")]
    Param(
        [Parameter(ValueFromPipeline,Position=0)]
        [string]
        [ValidateScript({Test-Path $_})]
        $ChocolateyConfig = "$env:ChocolateyInstall\config\chocolatey.config",

        [Parameter(Position=1)]
        [String[]]
        $ConfigurationItem
    
    )

    process {
        
        [xml]$Config = Get-Content $ChocolateyConfig
        
        if($ConfigurationItem){
            Foreach($c in $ConfigurationItem){

                $config.chocolatey.config.add | Where-Object { $_.Key -eq $c }
            
            }

        }

        else{

            $config.chocolatey.config.add

        }
    }

}
function Get-ChocoFeature {
    <#
        .SYNOPSIS
        Retrieve feature settings from chocolatey config file
 
        .PARAMETER ChocolateyConfig
        The config file to load. Defaults to $env:ChocolateyInstall\config\chocolatey.config
 
        .PARAMETER Feature
        The feature(s) you with to query for information
 
        .EXAMPLE
        Get-ChocoFeature
 
        Returns all features and their values
 
        .EXAMPLE
        Get-ChocoFeature -Feature useBackgroundService
 
        Retrieves current setting of useBackgroundService feature
    #>

    [cmdletBinding(HelpUri="https://github.com/steviecoaster/PSChocoConfig/wiki/Get-ChocoFeature")]
    Param(
        [Parameter(ValueFromPipeline,Position=0)]
        [String]
        [ValidateScript({Test-Path $_})]
        $ChocolateyConfig = "$env:ChocolateyInstall\config\chocolatey.config",

        [Parameter(Position=1)]
        [String[]]
        $Feature
    )

    process {

        [xml]$config = Get-Content $ChocolateyConfig
        
        if($Feature){

            Foreach($f in $Feature) {

                $config.chocolatey.features.feature | Where-Object { $_.Name -eq $f } 

            }

        }

        else{

            $config.chocolatey.features.feature

        }

    }

}
function Get-ChocoSource {
    <#
    .SYNOPSIS
    List currently configured choco sources
     
    .DESCRIPTION
    Reads the chocolatey config file and returns a list of currently configured choco sources
     
    .PARAMETER ChocolateyConfig
    The path the config file to read from
     
    .PARAMETER Source
    The friendly name of the source to retrieve
     
    .EXAMPLE
    Get-ChocoSource
 
    Returns all currently configured choco sources
     
    .EXAMPLE
    Get-ChocoSource -Source internal
     
    Returns details about the choco source named "internal".
 
    #>

    
    [cmdletBinding(HelpUri="https://github.com/steviecoaster/PSChocoConfig/wiki/Get-ChocoSource")]
    Param(
        
        [Parameter(ValueFromPipeline,Position=0)]
        [string]
        [ValidateScript({Test-Path $_})]
        $ChocolateyConfig = "$env:ChocolateyInstall\config\chocolatey.config",

        [Parameter()]
        [string[]]
        $Source

    )

    process {

        [xml]$config = Get-Content $ChocolateyConfig

        if($Source){
            Foreach($s in $Source){

                $config.chocolatey.sources.source | Where-Object { $_.id -eq $s }
            
            }

        }

        else{

            $config.chocolatey.sources.source

        }
        
    }

}
function Remove-ChocoSource {
    <#
    .SYNOPSIS
    Removes the specified choco source
     
    .DESCRIPTION
    Removes the specified choco source
     
    .PARAMETER Source
    The friendly name of the source to remove
     
    .EXAMPLE
    Remove-ChocoSource -Source bob
    #>

    
    [cmdletBinding(ConfirmImpact="High",SupportsShouldProcess,HelpUri="https://github.com/steviecoaster/PSChocoConfig/wiki/Remove-ChocoSource")]
    Param(
        [Parameter(Mandatory,Position=0)]
        [String]
        $Source
    )

    process{

        If($PSCmdlet.ShouldProcess("$Source","Setting value: Enabled")){
            
            $StartInfo = [System.Diagnostics.ProcessStartInfo]::new()
            $source = 'dumb'
            $args = @('source','remove',"-n=$source")
            $StartInfo.CreateNoWindow = $true
            $StartInfo.UseShellExecute = $false
            $StartInfo.RedirectStandardOutput = $true
            $StartInfo.RedirectStandardError = $true
            $StartInfo.FileName = 'choco'
            $StartInfo.Arguments = $args

            $process = [System.Diagnostics.Process]::new()
            $process.StartInfo = $StartInfo
            [void]$process.Start()

            $output = $process.StandardOutput.ReadToEnd()
            $process.WaitForExit()

            Write-Verbose $output
    
        }

    }

}
function Set-ChocoConfig {
    <#
        .SYNOPSIS
        Sets the specified configuration item to the provided value
 
        .DESCRIPTION
        Wraps 'choco config' to make setting configuration values easier. Dynamically generates name values from chocolatey config file.
 
        .PARAMETER Value
        The value to set of the Name of the configuration item.
 
        .PARAMETER Name
        Name of the configuration item. Dynamically generated from the configuration file for tab-completion.
 
        .EXAMPLE
 
        Set-ChocoConfig -Name proxy -Value 'https://awesome.proxy.local'
    #>

    [cmdletBinding(SupportsShouldProcess,ConfirmImpact="High",HelpUri="https://github.com/steviecoaster/PSChocoConfig/wiki/Set-ChocoConfig")]
    Param (

        [Parameter(Mandatory,Position=0,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [ArgumentCompleter({
            param($Command,$Parameter,$WordTocomplete,$CommandAst,$FakeBoundParams)
            $results = Get-ChocoConfig | Select -ExpandProperty key

            If($WordTocomplete){

                $results.Where{ $_ -match "^$WordTocomplete"}
                
            }

            Else {

                $results

            }
        })]
        [String]
        $Name,

        [Parameter(Mandatory,Position=1)]
        [AllowEmptyString()]
        [String]
        $Value
    )

    

    process {

        If($PSCmdlet.ShouldProcess("$Name","Setting value: $Value")){
        
            $choco = choco config set --name="'$Name'" --value="'$Value'"
            Write-Host "$($choco[-1])"-ForegroundColor Yellow
        
        }
    }

}
function Set-ChocoFeature {
     <#
        .SYNOPSIS
        Sets the specified feature to the provided state.
 
        .DESCRIPTION
        Wraps 'choco config' to make setting configuration values easier. Dynamically generates name values from chocolatey config file.
 
        .PARAMETER Value
        The value to set of the Name of the configuration item.
 
        .PARAMETER Name
        Name of the feature. Dynamically generated from the configuration file for tab-completion.
    #>

    [cmdletBinding(SupportsShouldProcess,ConfirmImpact="High",HelpUri="https://github.com/steviecoaster/PSChocoConfig/wiki/Set-ChocoFeature")]
    Param (
        
        [Parameter(Mandatory,Position=0,ValueFromPipelineByPropertyName,ValueFromPipeline)]
        [ArgumentCompleter({
            param($Command,$Parameter,$WordTocomplete,$CommandAst,$FakeBoundParams)
            $results = Get-Chocofeature | Select -ExpandProperty Name

            If($WordTocomplete){

                $results.Where{ $_ -match "^$WordTocomplete"}
                
            }

            Else {

                $results

            }
        })]
        [String]
        $Name,

        [Parameter(Mandatory,Position=1)]
        [String]
        [ValidateSet('Enabled','Disabled')]
        $State
    )

    process {

        Switch($State){

            'Enabled' { $command = "enable" }
            'Disabled' { $command = "disable" }

        }

        If($PSCmdlet.ShouldProcess("Ensuring feature $Name is set to $State")){
        
            $choco = choco feature $command --name="'$Name'"
            Write-Host "$($choco[-1])"-ForegroundColor Yellow
        
        }
    }

}