PSPublishHelper.psm1

$Script:Nuspec = @"
<?xml version="1.0"?>
<package >
    <metadata>
        <id>{0}</id>
        <version>{1}</version>
        <authors>{2}</authors>
        <owners>{3}</owners>
        <description>{4}</description>
        <releaseNotes>{5}</releaseNotes>
        <requireLicenseAcceptance>{6}</requireLicenseAcceptance>
        <copyright>{7}</copyright>
        <tags>{8}</tags>
        {9}
        {10}
        {11}
        <dependencies>
            {12}
        </dependencies>
    </metadata>
</package>
"@
#Region '.\src\PSPublishHelper\private\Copy-PSModule.ps1' 0
function Copy-PSModule {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [ValidateNotNull()]
        [PSModuleInfo]
        $Module,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Path
    )
    end {
        $Params = @{
            Path = $Path
            Recurse = $true
            Force = $true
            ErrorAction = 'SilentlyContinue'
        }
        Microsoft.PowerShell.Management\Remove-Item @Params
        $Params = @{
            Path = $Path
            ItemType = 'Directory'
            Force = $true
        }
        $null = Microsoft.PowerShell.Management\New-Item @Params
        Microsoft.PowerShell.Management\Get-ChildItem $Module.ModuleBase -recurse |
            ForEach-Object {
                if ($_.PSIsContainer) {
                    $Params = @{
                        Force = $true
                        Confirm = $false
                        WhatIf = $false
                        Recurse = $true
                        Container = $true
                        Destination = $Path
                    }
                    $_ | Microsoft.PowerShell.Management\Copy-Item @Params
                } else {
                    $Params = @{
                        Force = $true
                        Confirm = $false
                        WhatIf = $false
                        Destination = $Path
                    }
                    $_ | Microsoft.PowerShell.Management\Copy-Item @Params
                }
            }
    }
}
#EndRegion '.\src\PSPublishHelper\private\Copy-PSModule.ps1' 51
#Region '.\src\PSPublishHelper\private\Format-PSModuleDependency.ps1' 0
function Format-PSModuleDependency {
    [OutputType([string])]
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline)]
        [Microsoft.PowerShell.Commands.ModuleSpecification]
        $Dependency
    )
    process {
        if (-not $Dependency) {
            return
        }
        $Version = [string]::Empty
        # Version format in NuSpec:
        # "[2.0]" --> (== 2.0) Required Version
        # "2.0" --> (>= 2.0) Minimum Version
        #
        # When only MaximumVersion is specified in the ModuleSpecification
        # (,1.0] = x <= 1.0
        #
        # When both Minimum and Maximum versions are specified in the ModuleSpecification
        # [1.0,2.0] = 1.0 <= x <= 2.0
        if($Dependency.RequiredVersion) {
            $Version = "[{0}]" -f $Dependency.RequiredVersion
        } elseif($Dependency.Version -and $Dependency.MaximumVersion) {
            $Version = "[{0},{1}]" -f $Dependency.Version, $Dependency.MaximumVersion
        } elseif($Dependency.MaximumVersion) {
            $Version = "(,{0}]" -f $Dependency.MaximumVersion
        } elseif($Dependency.Version) {
            $Version = "{0}" -f $Dependency.Version
        }

        if ([System.string]::IsNullOrWhiteSpace($Version)) {
            "<dependency id='{0}'/>" -f $Dependency.Name
        } else {
            "<dependency id='{0}' version='{1}' />" -f $Dependency.Name, $Version
        }
    }
}
#EndRegion '.\src\PSPublishHelper\private\Format-PSModuleDependency.ps1' 39
#Region '.\src\PSPublishHelper\private\Get-AvailableRoleCapabilityName.ps1' 0
function Get-AvailableRoleCapabilityName {
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [PSModuleInfo]
        $Module
    )

    $RoleCapabilitiesDir = Join-Path $Module.ModuleBase 'RoleCapabilities'
    if(Microsoft.PowerShell.Management\Test-Path -Path $RoleCapabilitiesDir -PathType Container)
    {
        $Params = @{
            Path = $RoleCapabilitiesDir
            Filter = '*.psrc'
        }
        Microsoft.PowerShell.Management\Get-ChildItem @Params |
            ForEach-Object -MemberName BaseName
    }
}
#EndRegion '.\src\PSPublishHelper\private\Get-AvailableRoleCapabilityName.ps1' 20
#Region '.\src\PSPublishHelper\private\Get-EscapedString.ps1' 0
function Get-EscapedString
{
    [CmdletBinding()]
    [OutputType([String])]
    Param (
        [Parameter(ValueFromPipeline)]
        [string]
        $Value
    )

    process {
        [System.Security.SecurityElement]::Escape($Value)
    }
}
#EndRegion '.\src\PSPublishHelper\private\Get-EscapedString.ps1' 14
#Region '.\src\PSPublishHelper\private\Get-ExportedDscResources.ps1' 0
function Get-ExportedDscResources {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [PSModuleInfo]
        $Module
    )

    $Params = @{
        Name = 'Get-DscResource'
        Module = 'PSDesiredStateConfiguration'
        ErrorAction = 'Ignore'
    }
    if(-not $script:IsCoreCLR -and (Get-Command @Params)) {
        $OldPSModulePath = $env:PSModulePath

        try {
            $env:PSModulePath = Join-Path -Path $PSHOME -ChildPath "Modules"
            $ModuleBaseParent = Split-Path -Path $Module.ModuleBase -Parent
            $env:PSModulePath = "{0}{1}{2}" -f @(
                $env:PSModulePath,
                [System.IO.Path]::PathSeparator,
                $ModuleBaseParent
            )

            $Params = @{
                ErrorAction = 'SilentlyContinue'
                WarningAction = 'SilentlyContinue'
            }
            PSDesiredStateConfiguration\Get-DscResource @Params |
                Microsoft.PowerShell.Core\ForEach-Object {
                    if(
                        $_.Module -and
                        $_.Module.Name -eq $Module.Name
                    ){
                        $_.Name
                    }
                }
        } finally {
            $env:PSModulePath = $OldPSModulePath
        }
    } else {
        $dscResourcesDir = Join-Path $Module.ModuleBase "DscResources"
        if(Microsoft.PowerShell.Management\Test-Path $dscResourcesDir) {
            Microsoft.PowerShell.Management\Get-ChildItem -Path $dscResourcesDir -Directory -Name
        }
    }
}
#EndRegion '.\src\PSPublishHelper\private\Get-ExportedDscResources.ps1' 49
#Region '.\src\PSPublishHelper\private\Get-NupkgFilePath.ps1' 0
function Get-NupkgFilePath {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [ValidateNotNull()]
        [PSModuleInfo]
        $Module,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Path
    )
    end {
        $PSData = Resolve-PSData -Module $Module
        $Version = Resolve-PSModuleVersion -Module $Module -PSData $PSData
        $FileName = '{0}.{1}.nupkg' -f $Module.Name, $Version
        Join-Path $Path $FileName
    }
}
#EndRegion '.\src\PSPublishHelper\private\Get-NupkgFilePath.ps1' 20
#Region '.\src\PSPublishHelper\private\Get-NuspecContents.ps1' 0
function Get-NuspecContents {
    [OutputType([String])]
    [CmdletBinding()]
    param (
        [PSModuleInfo]
        $Module,

        [Hashtable]
        $PSData
    )
    end {

        $VersionText = Resolve-PSModuleVersion -Module $Module -PSData $PSData

        $TagsText = Resolve-PSModuleTags -Module $Module -Tags $PSData.Tags

        $RequireLicenseAcceptanceText = ([bool]$PSData.RequireLicenseAcceptance).ToString().ToLower()

        $Description = $Module.Description
        if ([string]::IsNullOrWhiteSpace($Description)) {
            $Description = $Module.Name
        }

        $ArgumentList = [System.Collections.Generic.List[string]]::new()
        @(
            $Module.Name,
            $VersionText,
            $Module.Author,
            $Module.CompanyName,
            $Description,
            $Module.ReleaseNotes,
            $RequireLicenseAcceptanceText,
            $Module.Copyright,
            $TagsText
        ) | Get-EscapedString | ForEach-Object {
            $ArgumentList.Add($_)
        }

        $LicenseUriText = if ($PSData.LicenseUri) {
            '<licenseUrl>{0}</licenseUrl>' -f ($PSData.LicenseUri | Get-EscapedString)
        }
        $ArgumentList.Add($LicenseUriText)

        $ProjectUriText = if ($PSData.ProjectUri) {
            '<projectUrl>{0}</projectUrl>' -f ($PSData.ProjectUri | Get-EscapedString)
        }
        $ArgumentList.Add($ProjectUriText)

        $IconUriText = if ($PSData.IconUri) {
            '<iconUrl>{0}</iconUrl>' -f ($PSData.IconUri | Get-EscapedString)
        }
        $ArgumentList.Add($IconUriText)

        $DependencyText = @(
            $Module | Resolve-PSModuleDependency -ExternalModuleDependencies $PSData.ExternalModuleDependencies | Format-PSModuleDependency
        ) -Join ([Environment]::NewLine)
        $ArgumentList.Add($DependencyText)

        $Script:Nuspec -f $ArgumentList.ToArray()
    }
}
#EndRegion '.\src\PSPublishHelper\private\Get-NuspecContents.ps1' 61
#Region '.\src\PSPublishHelper\private\Get-NuspecFilePath.ps1' 0
function Get-NuspecFilePath {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [ValidateNotNull()]
        [PSModuleInfo]
        $Module,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Path
    )
    end {
        $FileName = '{0}.nuspec' -f $Module.Name
        Join-Path $Path $FileName
    }
}
#EndRegion '.\src\PSPublishHelper\private\Get-NuspecFilePath.ps1' 18
#Region '.\src\PSPublishHelper\private\Get-PSModuleManifestData.ps1' 0
function Get-PSModuleManifestData {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory,ValueFromPipeline)]
        [ValidateNotNull()]
        [PSModuleInfo]
        $Module
    )
    process {
        if ($Module.Path -match '\.psd1$') {
            $Manifest = $Module.Path
        } else {
            $ManifestName = '{0}.psd1' -f $Module.Name
            $Manifest = Join-Path $Module.ModuleBase $ManifestName
        }
        Import-PowerShellDataFile -Path $Manifest
    }
}
#EndRegion '.\src\PSPublishHelper\private\Get-PSModuleManifestData.ps1' 18
#Region '.\src\PSPublishHelper\private\Get-TemporaryPath.ps1' 0
function Get-TemporaryPath {
    [OutputType([string])]
    [CmdletBinding()]
    param (
        [Parameter(Mandatory,ValueFromPipeline)]
        [ValidateNotNull()]
        [PSModuleInfo]
        $Module
    )
    process {
        $Base = Join-Path ([System.IO.Path]::GetTempPath()) (Get-Random)
        Join-Path $Base $Module.Name
    }
}
#EndRegion '.\src\PSPublishHelper\private\Get-TemporaryPath.ps1' 14
#Region '.\src\PSPublishHelper\private\Resolve-NugetCommand.ps1' 0
function Resolve-NugetCommand {
    [CmdletBinding()]
    param (
        [Parameter()]
        [System.Management.Automation.PSCmdlet]
        $Cmdlet
    )
    end {
        $ErrorCmdlet = $Cmdlet
        if (-not $Cmdlet) {
            $ErrorCmdlet = $PSCmdlet
        } 
        $Params = @{
            Name = 'nuget'
            CommandType = 'Application'
            ErrorAction = 'SilentlyContinue'
        }
        $Nuget = Get-Command @Params | Select-Object -First 1
        if(-not $Nuget) {
            $ErrorRecord = [System.Management.Automation.ErrorRecord]::new(
                [System.Management.Automation.ItemNotFoundException]::new(
                    "Unable to find nuget binary. Nuget is required"
                ),
                "NugetNotFound",
                [System.Management.Automation.ErrorCategory]::NotInstalled,
                $null
            )
            $ErrorCmdlet.ThrowTerminatingError($ErrorRecord)
        }
        $Nuget
    }
}
#EndRegion '.\src\PSPublishHelper\private\Resolve-NugetCommand.ps1' 32
#Region '.\src\PSPublishHelper\private\Resolve-PSData.ps1' 0
function Resolve-PSData {
    [OutputType([Hashtable])]
    [CmdletBinding()]
    param (
        [PSModuleInfo]
        $Module,

        [string]
        $ReleaseNotes,

        [string[]]
        $Tags,

        [Uri]
        $LicenseUri,

        [Uri]
        $IconUri,

        [Uri]
        $ProjectUri
    )
    end {
        $Result = @{}
        $PSData = @{
            ReleaseNotes = $ReleaseNotes
            Tags = $Tags
            LicenseUri = $LicenseUri
            IconUri = $IconUri
            ProjectUri = $ProjectUri
            Prerelease = $null
            RequireLicenseAcceptance = $null
            ExternalModuleDependencies = @()
        }
        foreach ($item in $PSData.GetEnumerator()) {
            $key = $item.key
            $Result[$key] = $item.value
            if (-not $item.value -and $key -ne 'Prerelease') {
                $Result[$key] = $Module.PrivateData.PSdata.$key
            } elseif (-not $item.value -and $key -eq 'Prerelease') {
                $Result[$key] = $Module.PrivateData.PSData.$key
            }
            Write-Verbose "$($key): $($Result[$key])"
        }
        $Result
    }
}
#EndRegion '.\src\PSPublishHelper\private\Resolve-PSData.ps1' 47
#Region '.\src\PSPublishHelper\private\Resolve-PSModule.ps1' 0
function Resolve-PSModule {
    [OutputType([System.Management.Automation.PSModuleInfo])]
    [CmdletBinding()]
    param (
        [Parameter()]
        [System.Management.Automation.PSCmdlet]
        $Cmdlet,

        [Parameter()]
        [string]
        $Name,

        [Parameter()]
        [string]
        $RequiredVersion
    )
    end {
        if($Cmdlet) {
            $ErrorCmdlet = $Cmdlet
        } else {
            $ErrorCmdlet = $PSCmdlet
        }

        $Version, $Prerelease = $RequiredVersion -split '-', 2
        
        $Filter = {
            $_.Version.ToString() -eq $Version -and
            (
                $_.PrivateData.PSData.Prerelease -eq $Prerelease -or
                $_.PrivateData.PSData.Prerelease -eq "-$Prerelease"
            )
        }

        $Result = Get-Module -ListAvailable -Name $Name |
            Where-Object -FilterScript $Filter |
            Select-Object -First 1
        
        if (-not $Result) {
            $ErrorRecord = [System.Management.Automation.ErrorRecord]::new(
                [System.Management.Automation.ItemNotFoundException]::new(
                    "Unable to find Module $Name Version $RequiredVersion"
                ),
                "ModuleNotFound",
                [System.Management.Automation.ErrorCategory]::InvalidArgument,
                $null
            )
            $ErrorCmdlet.ThrowTerminatingError($ErrorRecord)
        }
        $Result
    }
}
#EndRegion '.\src\PSPublishHelper\private\Resolve-PSModule.ps1' 51
#Region '.\src\PSPublishHelper\private\Resolve-PSModuleDependency.ps1' 0
function Resolve-PSModuleDependency {
    [OutputType([Microsoft.PowerShell.Commands.ModuleSpecification])]
    [CmdletBinding()]
    param (
        [Parameter(Mandatory, ValueFromPipeline)]
        [PSModuleInfo]
        $Module,

        [String[]]
        $ExternalModuleDependencies
    )
    process {
        # The manifest contains the actual ModuleSpec used for Version requirements
        $ModuleData = $Module | Get-PSModuleManifestData

        # A module in RequiredModules is not a dependency if it's listed in ExternalModuleDependencies
        $ModuleData.RequiredModules | Resolve-PSModuleInfo | Where-Object {
            $_.Name -notin $ExternalModuleDependencies
        }

        $NestModuleInfo = $ModuleData.NestedModules | Resolve-PSModuleInfo

        # A module in NestedModules become a dependency
        # when it is not not packaged with the module
        $NestedDependencies = $Module.NestedModules | Where-Object {
            -not $_.ModuleBase.StartsWith($Module.ModuleBase, [System.StringComparison]::OrdinalIgnoreCase) -or
            -not $_.Path -or
            -not (Microsoft.PowerShell.Management\Test-Path -LiteralPath $_.Path)
        } | Foreach-Object -MemberName Name

        $NestModuleInfo | Where-Object {$_.Name -in $NestedDependencies}
    }
}
#EndRegion '.\src\PSPublishHelper\private\Resolve-PSModuleDependency.ps1' 33
#Region '.\src\PSPublishHelper\private\Resolve-PSModuleInfo.ps1' 0
function Resolve-PSModuleInfo {
    [OutputType([Microsoft.PowerShell.Commands.ModuleSpecification])]
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline)]
        [PSObject]
        $InputObject
    )

    process {
        # '*' can be specified in the MaximumVersion of a ModuleSpecification to convey
        # that maximum possible value of that version part.
        # like 1.0.0.* --> 1.0.0.99999999
        if($InputObject.MaximumVersion){
            $InputObject.MaximumVersion = $InputObject.MaximumVersion -replace '\*','99999999'
        }

        [Microsoft.PowerShell.Commands.ModuleSpecification]$InputObject
    }
}
#EndRegion '.\src\PSPublishHelper\private\Resolve-PSModuleInfo.ps1' 20
#Region '.\src\PSPublishHelper\private\Resolve-PSModuleTags.ps1' 0
function Resolve-PSModuleTags {
    [CmdletBinding()]
    param (
        [PSModuleInfo]
        $Module,

        [String[]]
        $Tags
    )
    end {
        $TagsList = [System.Collections.Generic.HashSet[String]]::new()
        foreach($Tag in $Tags) {
            $null = $TagsList.Add($Tag)
        }

        $null = $TagsList.add('PSModule')

        foreach($Cmdlet in $Module.ExportedCmdlets.Keys) {
            $null = $TagsList.Add('PSIncludes_Cmdlet')
            $null = $TagsList.add(('PSCmdlet_{0}' -f $Cmdlet))
        }

        foreach($Func in $Module.ExportedFunctions.Keys) {
            $null = $TagsList.Add('PSIncludes_Function')
            $null = $TagsList.add(('PSFunction_{0}' -f $func))
        }

        foreach($Command in $Module.ExportedCommands.Keys) {
            $null = $TagsList.add(('PSCommand_{0}' -f $Command))
        }

        if(!$IsCoreCLR) {
          foreach ($DscResource in (Get-ExportedDscResources -Module $Module -ErrorAction SilentlyContinue)) {
              $null = $TagsList.Add('PSIncludes_DscResource')
              $null = $TagsList.add(('PSDscResource_{0}' -f $DscResource))
          }
        } else {
          Write-Verbose 'Skipping DSC resource enumeration as it is not supported on PS Core.'
          Write-Verbose 'Please use Windows PowerShell to build DSC modules.'
        }


        foreach ($Role in (Get-AvailableRoleCapabilityName -Module $Module)) {
            $null = $TagsList.Add('PSIncludes_RoleCapability')
            $null = $TagsList.add(('PSRoleCapability_{0}' -f $Role))
        }

        $TagsList -join ' '
    }
}
#EndRegion '.\src\PSPublishHelper\private\Resolve-PSModuleTags.ps1' 50
#Region '.\src\PSPublishHelper\private\Resolve-PSModuleVersion.ps1' 0
function Resolve-PSModuleVersion {
    [OutputType([string])]
    [CmdletBinding()]
    param (
        [Parameter()]
        [PsModuleInfo]
        $Module,

        [Parameter()]
        [Hashtable]
        $PSData
    )
    end {
        $Version = [string]$Module.Version
        if($PSData.Prerelease) {
            $Prerelease = $PSData.Prerelease
            if($Prerelease.StartsWith('-')) {
                $version = '{0}{1}' -f $Version, $Prerelease
            } else {
                $version = '{0}-{1}' -f $Version, $Prerelease
            }
        }
        $Version
    }
}
#EndRegion '.\src\PSPublishHelper\private\Resolve-PSModuleVersion.ps1' 25
#Region '.\src\PSPublishHelper\public\Publish-PSModuleNuget.ps1' 0
function Publish-PSModuleNuget {
    [CmdletBinding(DefaultParameterSetName = 'NameAndVersion')]
    param (
        [Parameter(
            Mandatory,
            ParameterSetName = 'NameAndVersion'
        )]
        [ValidateNotNullOrEmpty()]
        [string]
        $Name,

        [Parameter(
            Mandatory,
            ParameterSetName = 'NameAndVersion'
        )]
        [ValidateNotNullOrEmpty()]
        [string]
        $RequiredVersion,

        [Parameter(
            Mandatory,
            ParameterSetName = 'PSModuleInfo',
            ValueFromPipeline
        )]
        [ValidateNotNull()]
        [PSModuleInfo]
        $InputObject,

        [Parameter(
            Mandatory,
            ParameterSetName = 'NameAndVersion'
        )]
        [Parameter(
            Mandatory,
            ParameterSetName = 'PSModuleInfo'
        )]
        [ValidateNotNullOrEmpty()]
        [ValidateScript({
            if(-not (Test-Path -PathType Container -Path $_)){throw}
            else {$true}
        })]
        [string]
        $OutputPath,

        [Parameter(Mandatory = $false, ParameterSetName = 'PSModuleInfo')]
        [Parameter(Mandatory = $false, ParameterSetName = 'NameAndVersion')]
        [string]
        $ReleaseNotes,

        [Parameter(Mandatory = $false, ParameterSetName = 'PSModuleInfo')]
        [Parameter(Mandatory = $false, ParameterSetName = 'NameAndVersion')]
        [string[]]
        $Tags,

        [Parameter(Mandatory = $false, ParameterSetName = 'PSModuleInfo')]
        [Parameter(Mandatory = $false, ParameterSetName = 'NameAndVersion')]
        [Uri]
        $LicenseUri,

        [Parameter(Mandatory = $false, ParameterSetName = 'PSModuleInfo')]
        [Parameter(Mandatory = $false, ParameterSetName = 'NameAndVersion')]
        [Uri]
        $IconUri,

        [Parameter(Mandatory = $false, ParameterSetName = 'PSModuleInfo')]
        [Parameter(Mandatory = $false, ParameterSetName = 'NameAndVersion')]
        [Uri]
        $ProjectUri,

        [Parameter(Mandatory = $false, ParameterSetName = 'PSModuleInfo')]
        [Parameter(Mandatory = $false, ParameterSetName = 'NameAndVersion')]
        [Switch]
        $PassThru
    )
    
    begin {
        $Nuget = Resolve-NugetCommand -Cmdlet $PSCmdlet -ErrorAction Stop
        Write-Verbose "Nuget found at $($Nuget.Path)"
        $OutputPath = Convert-Path $OutputPath -ErrorAction Stop
        Write-Verbose "Output Path: $OutputPath"
    }
    
    process {
        if($PSCmdlet.ParameterSetName -eq 'NameAndVersion') {
            $Params = @{
                Cmdlet = $PSCmdlet
                Name = $Name
                RequiredVersion = $RequiredVersion
                ErrorAction = 'stop'
            }
            $InputObject = Resolve-PSModule @Params
        }

        Write-Verbose "Using Module from $($InputObject.ModuleBase)"

        $Params = @{
            IconUri = $IconUri
            ReleaseNotes = $ReleaseNotes
            Module = $InputObject
            Tags = $Tags
            ProjectUri = $ProjectUri
            LicenseUri = $LicenseUri
        }
        $PSData = Resolve-PSData @Params

        $Params = @{
            Module = $InputObject
            PSData = $PSData
            ErrorAction = 'stop'
        }
        $NuspecContents = Get-NuspecContents @Params

        $TempPath = $InputObject | Get-TemporaryPath
        try {
            Copy-PSModule -Module $InputObject -Path $TempPath -ErrorAction Stop
            $NuspecPath = Get-NuspecFilePath -Module $InputObject -Path $TempPath -ErrorAction Stop
            $NuspecContents | Set-Content -Path $NuspecPath -Force -Confirm:$false -WhatIf:$false -ErrorAction Stop
            $NupkgFilePath = Get-NupkgFilePath -Module $InputObject -Path $OutputPath -ErrorAction Stop
            Push-Location -StackName PSPublishHelperNugetPack -Path $TempPath -ErrorAction Stop
            $Output = & $Nuget pack $NuspecPath -OutputDirectory $OutputPath -BasePath $TempPath -Verbosity detailed -NonInteractive -NoDefaultExcludes
            Write-Verbose "Nuget Pack Output:"
            foreach($Line in $Output) {
                if($Line -notmatch 'NU5110|NU5111'){
                    Write-Verbose $Line
                }
            }
        }
        finally {
            Pop-Location -StackName PSPublishHelperNugetPack
            $Params = @{
                Path = Split-path -Parent $TempPath
                Recurse = $true
                Force = $true
                ErrorAction = 'SilentlyContinue'
            }
            Microsoft.PowerShell.Management\Remove-Item @Params
        }

        if($PassThru) {
            Get-item -Path $NupkgFilePath -ErrorAction SilentlyContinue
        }
    }
}
#EndRegion '.\src\PSPublishHelper\public\Publish-PSModuleNuget.ps1' 143