PSGetInternal.psm1

$script:ModuleRoot = $PSScriptRoot

function Get-RepoCredential {
    <#
    .SYNOPSIS
    Function to get the credential file.
     
    .DESCRIPTION
    Function to get the credential file.
     
    .EXAMPLE
    PS C:\> Get-RepoCredential
 
    Function to get the credential file from the configuration path of the module.
    #>

    [OutputType([pscredential])]
    [CmdletBinding()]
    param()

    $credFilePath = Join-Path $Script:ConfigPath "RepoCred.clixml"

    Import-Clixml $credFilePath
}

function Find-GIModule {
    <#
    .SYNOPSIS
    Will search all modules in configured Company-Internal repository.
     
    .DESCRIPTION
    Will search all modules in configured Company-Internal repository.
     
    .PARAMETER Name
    Name of the module.
     
    .PARAMETER Credential
    Credential to get access to the configured Company-Internal repository.
     
    .EXAMPLE
    PS C:\> Find-GIModule
 
    Will list all modules in the configured Company-Internal repository.
 
    .EXAMPLE
    PS C:\> Find-GIModule -Name "Company-Module"
 
    Will search the module "Company-Module" in the configured Company-Internal repository.
    #>

    [CmdletBinding()]
    Param (
        [string]
        $Name = "*",

        [pscredential]
        $Credential = (Get-RepoCredential)
    )
    begin{
        if(-not $Script:Config){
            throw "Internal PSGallery not configured! Use Set-GIRepository to set up an internal Repository."
        }
    }
    process {
        Find-Module -Repository $Script:Config.Name -Name $Name -Credential $Credential
    }
}

function Install-GIModule {
    <#
    .SYNOPSIS
    Install a module from configured Company-Internal repository.
     
    .DESCRIPTION
    Install a module from configured Company-Internal repository.
     
    .PARAMETER Name
    Name of the module.
     
    .PARAMETER Credential
    Credential to get access to the configured Company-Internal repository.
     
    .EXAMPLE
    PS C:\> Install-GIModule -Name "Company-Module"
 
    Will install the module "Company-Module" from the configured Company-Internal repository.
    #>

    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true)]
        [string]
        $Name,

        [pscredential]
        $Credential = (Get-RepoCredential),

        [swtich]
        $Force,

        [switch]
        $AllowClobber,

        [swtich]
        $AllowPrerelease,

        [string]
        $MinimumVersion,

        [string]
        $MaximumVersion,

        [string]
        $RequiredVersion,

        [ValidateSet('AllUsers', 'CurrentUser')]
        [string]
        $Scope = 'CurrentUser'
    )
    begin{
        if(-not $Script:Config){
            throw "Internal PSGallery not configured! Use Set-GIRepository to set up an internal Repository."
        }
        
        $param = @{
            Repository = $Script:Config.Name
            Name = $Name
            Credential = $Credential
            Scope = $Scope
        }
        if($Force){$param.Force = $Force}
        if($AllowClobber){$param.AllowClobber = $AllowClobber}
        if($AllowPrerelease){$param.AllowPrerelease = $AllowPrerelease}
        if($MinimumVersion){$param.MinimumVersion = $MinimumVersion}
        if($MaximumVersion){$param.MaximumVersion = $MaximumVersion}
        if($RequiredVersion){$param.RequiredVersion = $RequiredVersion}
    }
    process {
        Install-Module @param
    }
}

function Save-GIModule {
    <#
    .SYNOPSIS
    Save a module from configured Company-Internal repository to a specific path.
     
    .DESCRIPTION
    Save a module from configured Company-Internal repository to a specific path.
     
    .PARAMETER Name
    Name of the module.
     
    .PARAMETER Path
    Path where the module should be saved.
     
    .PARAMETER Credential
    Credential to get access to the configured Company-Internal repository.
     
    .EXAMPLE
    PS C:\> Save-GIModule -Name "Company-Module" -Path .
 
    Will save the module "Company-Module" from the configured Company-Internal repository to the current path.
    #>

    [CmdletBinding()]
    Param (
        [Parameter(Mandatory)]
        [string]
        $Name,

        [Parameter(Mandatory)]
        [string]
        $Path,

        [pscredential]
        $Credential = (Get-RepoCredential)
    )
    process {
        Save-Module -Repository $Script:Config.Name -Name $Name -Credential $Credential -Path $Path
    }
}

function Set-GIRepository {
    <#
    .SYNOPSIS
    This function will register a repository and create config and credential file.
     
    .DESCRIPTION
    This function will register a repository and create config and credential file.
     
    .PARAMETER Name
    Name of repository which should be registered.
     
    .PARAMETER SourceLocation
    URL of the repository, which should be registered.
     
    .PARAMETER Credential
    Credentials to get access to Company-Internal repository.
     
    .PARAMETER InstallationPolicy
    Parameter to trust or untrust the source of the repository.
     
    .EXAMPLE
    PS C:\> Set-GIRepository -Name "Contoso-Repository" -SourceLocation "https://pkgs.dev.azure.com/contosoINF/_packaging/InfernalAccounting/nuget/v2" -InstallationPolicy Trusted -Credential $cred
     
    Will register the trusted repository "Contoso-Repository" with SourceLocation "https://pkgs.dev.azure.com/contosoINF/_packaging/InfernalAccounting/nuget/v2".
    And will generate a config and credential file.
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions','')]
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory)]
        [string]
        $Name,

        [Parameter(Mandatory)]
        [uri]
        $SourceLocation,

        [Parameter(Mandatory)]
        [pscredential]
        $Credential,

        [ValidateSet('Trusted', 'Untrusted')]
        [string]
        $InstallationPolicy
    )
    process {
        $existingRepo = Get-PSRepository -Name $Name -ErrorAction Ignore
        if (-not $existingRepo) {
            try {
                Register-PSRepository -Name $Name -SourceLocation $SourceLocation -InstallationPolicy $InstallationPolicy -Credential $Credential -ErrorAction Stop
            }
            catch {
                Write-Warning -Message "Error register Company-Internal Repository: $_"
                return
            }
        }else{
            if (($existingRepo.SourceLocation -ne $SourceLocation) -or ($existingRepo.InstallationPolicy -ne $InstallationPolicy)) {
                try {
                    Set-PSRepository -Name $Name -SourceLocation $SourceLocation -InstallationPolicy $InstallationPolicy -Credential $Credential -ErrorAction Stop
                }
                catch {
                    Write-Warning -Message "Error setting up Company-Internal Repository: $_"
                    return
                }
            }
        }
        
        $credFile = Join-Path $Script:configPath "RepoCred.clixml"
        $Credential | Export-Clixml -Path $credFile -Force

        $repository = [PSCustomObject]@{
            Name               = $Name
            SourceLocation     = $SourceLocation
            InstallationPolicy = $InstallationPolicy
        }
        $repoFile = Join-Path $Script:configPath "config.clixml"
        $repository | Export-Clixml -Path $repoFile -Force
        $Script:Config = $repository
    }
}

$Script:ConfigPath = Join-Path $env:LOCALAPPDATA "PowerShell\PSGetInternal"
$packagePath = Join-Path $env:LOCALAPPDATA "PackageManagement\ProviderAssemblies\nuget\2.8.5.208\Microsoft.PackageManagement.NuGetProvider.dll"

if(-not (Test-Path -Path $packagePath)){
    $null = New-Item -ItemType Directory -Path (Split-Path $packagePath) -Force
    Copy-Item -Path "$Script:ModuleRoot\bin\Microsoft.PackageManagement.NuGetProvider.dll" -Destination $packagePath -Force -Recurse
}

if(-not (Test-Path -Path $Script:ConfigPath)){
    $null = New-Item -ItemType Directory -Path $Script:ConfigPath -Force
}
if(Test-Path -Path (Join-Path $Script:ConfigPath 'config.clixml')){
    $script:config = Import-Clixml -Path (Join-Path $Script:ConfigPath 'config.clixml') -ErrorAction Ignore
}