Public/Invoke-NuGetCommand.ps1

function Invoke-NuGetCommand
{
    <#
        .SYNOPSIS
            Invokes a NuGet command.
        .DESCRIPTION
            Invokes a NuGet command.
        .PARAMETER Command
            A string containing the NuGet command to invoke.
        .PARAMETER Target
            A string containing the target of the NuGet command to invoke.
        .PARAMETER NuGetPath
            A string containing the path to the NuGet executable.
        .PARAMETER NuGetCommand
            A string containing the command to execute NuGet.
        .PARAMETER Parameters
            An hashtable containing the additionnal parameters to specify to NuGet.
        .PARAMETER Help
            A switch to call help of the specified command.
        .INPUTS
        .OUTPUTS
            PsObject
            Returns the output that is generated by the invoked command (the value of the Command parameter).
        .EXAMPLE
            Invoke-NuGetCommand -Command "pack" -Target ".\package.nuspec" -Parameters @{ "NoDefaultExcludes" = $true ; "OutputDirectory" = "D:\packages" }
 
            Description
            -----------
            This example will build the package from the manifest, not excluding default content, and output it to D:\packages.
        .EXAMPLE
            Invoke-NuGetCommand -Command "restore" -NuGetCommand "nuget"
 
            Description
            -----------
            This example will restore using alias "nuget" as the command (e.g. for non-Windows OS).
        .EXAMPLE
            Invoke-NuGetCommand -Command "add" -Target "source https://api.nuget.org/v3/index.json" -Parameters @{ "name" = "NuGet.org" } -NuGetCommand "dotnet nuget"
 
            Description
            -----------
            This example will add Nuget.org as a source using the the dotnet CLI.
        .NOTES
            - This CmdLet does not stop on nuget error, output should be parsed.
            - To use this function on non-Windows OS, use NuGetCommand parameter to specify the command alias or dotnet command.
        .LINK
            https://docs.microsoft.com/en-us/nuget/tools/nuget-exe-cli-reference
    #>

    [CmdLetBinding(DefaultParameterSetName = "FromNugetCommand")]
    param(
        [Parameter(ParameterSetName = "FromNugetPath", Mandatory = $true)]
        [Parameter(ParameterSetName = "FromNugetCommand", Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string] $Command,
        [Parameter(ParameterSetName = "FromNugetPath", Mandatory = $false)]
        [Parameter(ParameterSetName = "FromNugetCommand", Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [string] $Target,
        [Parameter(ParameterSetName = "FromNugetPath", Mandatory = $false)]
        [Parameter(ParameterSetName = "FromNugetCommand", Mandatory = $false)]
        [alias("Options")]
        [hashtable] $Parameters, 
        [Parameter(ParameterSetName = "FromNugetPath", Mandatory = $false)]
        [string] $NuGetPath = (Get-NuGetPath),
        [Parameter(ParameterSetName = "FromNugetCommand", Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [string] $NuGetCommand = "nuget",
        [Parameter(ParameterSetName = "FromNugetPath", Mandatory = $false)]
        [Parameter(ParameterSetName = "FromNugetCommand", Mandatory = $false)]
        [switch] $Help
    )
    
    try 
    {
        switch ($PSCmdlet.ParameterSetName)
        {
            "FromNugetCommand"
            {
                $NuGetPath = ""
                $Expression = "$($NugetCommand) $Command $Target"
            }
            "FromNugetPath"
            {
                $NuGet = Get-Item $NuGetPath
                if ($NuGet.PSIsContainer)
                {
                    $NuGetPath = $NuGet.FullName
                    $NuGetCommand = (Get-ChildItem -Path (Join-Path $NuGet.FullName "nuget*.exe") | Sort-Object LastWriteTime -Descending | Select-Object -First 1).BaseName
                }
                else
                { 
                    $NuGetCommand = Split-Path $NuGet.FullName -Leaf
                    $NuGetPath = Split-Path $NuGet.FullName -Parent
                }
                $Expression = "./$($NugetCommand) $Command $Target"
            }
        }

        if ($Help) { $Expression += " -h" }
        else
        {
            if ($Parameters)
            {
                $Parameters.Keys | ForEach-Object {
                    if (($Parameters[$_] -eq $true) -or ($Parameters[$_] -eq $false))
                    {
                        if ($Parameters[$_]) { $Expression += (" -{0}" -f $_) }
                    } 
                    else { $Expression += (" -{0} '{1}'" -f $_, $Parameters[$_]) }
                }
            }
        }
        Write-Verbose "Invoking command: $Expression"
        if ($NuGetPath) { Push-Location $NuGetPath }
        Invoke-Expression $Expression
    }
    catch
    {
        Write-Error $_
    }
    finally
    {
        Pop-Location
    }
}