NexuShell.psm1

#Region '.\private\Configure-Tls.ps1' 0
function Configure-Tls
{
    <#
    .NOTES
    Take from: https://stackoverflow.com/a/48323495
    #>

    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$Url
    )

    [System.Uri]$uri = $Url;
    if ($uri.Scheme -eq "https")
    {
        Write-Verbose "Using TLS 1.2";
        [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;
    }
}
#EndRegion '.\private\Configure-Tls.ps1' 20
#Region '.\private\Convert-ObjectToHashtable.ps1' 0
function Convert-ObjectToHashtable {
    <#
    .SYNOPSIS
    Converts a PSObject to a Hashtable
 
    .DESCRIPTION
    Invoke-Nexus outputs PSObjects, due to the underlying use of Invoke-RestMethod.
    Invoke-Nexus takes a Hashtable as body. This allows some pass-between.
 
    .PARAMETER InputObject
    The object to convert.
 
    .EXAMPLE
    Get-NexusBlobStorage -Name default -Type File | Convert-ObjectToHashtable
    #>

    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        $InputObject
    )
    process {
        $Hashtable = @{}
        $InputObject.PSObject.Properties.ForEach{
            $Hashtable[$_.Name] = $_.Value
        }

        $Hashtable
    }
}
#EndRegion '.\private\Convert-ObjectToHashtable.ps1' 29
#Region '.\private\Get-BufferSize.ps1' 0
function Get-BufferSize
{
    <#
    .SYNOPSIS
    Returns a buffer size that is 1% of ByteLength, rounded in whole MB's or at least AtLeast size.
 
    .DESCRIPTION
    Returns a buffer size that is 1% of ByteLength, rounded to whole MB's or if 1% is smaller than AtLeast, then AtLeast size is returned which is 1MB by default.
 
    .PARAMETER ByteLength
    Length of the bytes for which to calculate a valid buffer size.
 
    .PARAMETER AtLeast
    The minimum required buffer size, default 1MB.
 
    .EXAMPLE
    Get-BufferSize 4283304773
 
    Returns 42991616 which is 41MB.
 
    .EXAMPLE
    Get-BufferSize 4283304
 
    Returns 1048576 which is 1MB.
 
    .EXAMPLE
    Get-BufferSize 4283304 5MB
 
    Returns 5242880 which is 5MB.
 
    .NOTES
    Taken from: https://stackoverflow.com/a/48323495
    #>

    param(
        [Parameter(Mandatory=$true)]
        [long]$ByteLength,

        [long]$AtLeast = 1MB
    )

    [long]$size = $ByteLength / 100;
    if ($size -lt $AtLeast)
    {
        $size = $AtLeast;
    }
    else
    {
        $size = [Math]::Round($size / 1MB) * 1MB;
    }

    return $size;
}
#EndRegion '.\private\Get-BufferSize.ps1' 53
#Region '.\private\Get-NexusUserToken.ps1' 0
function Get-NexusUserToken {
    <#
    .SYNOPSIS
    Fetches a User Token for the provided credential
     
    .DESCRIPTION
    Fetches a User Token for the provided credential
     
    .PARAMETER Credential
    The Nexus user for which to receive a token
     
    .NOTES
    This is a private function not exposed to the end user.
    #>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory)]
        [PSCredential]
        $Credential
    )

    process {
        $UriBase = "$($protocol)://$($Hostname):$($port)$($ContextPath)"
        
        $slug = '/service/extdirect'

        $uri = $UriBase + $slug

        $credPair = "{0}:{1}" -f $Credential.UserName,$Credential.GetNetworkCredential().Password
        $encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($credPair))
        $ApiKeyHeader = @{ Authorization = "Basic $encodedCreds"}


        $data = @{
            action = 'rapture_Security'
            method = 'authenticationToken'
            data   = @("$([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($($Credential.Username))))", "$([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($($Credential.GetNetworkCredential().Password))))")
            type   = 'rpc'
            tid    = 16 
        }

        Write-Verbose ($data | ConvertTo-Json)
        $result = Invoke-RestMethod -Uri $uri -Headers $ApiKeyHeader -Method POST -Body ($data | ConvertTo-Json) -ContentType 'application/json' -UseBasicParsing
        $token = $result.result.data
        $token
    }

}
#EndRegion '.\private\Get-NexusUserToken.ps1' 49
#Region '.\private\Get-UseChunkedUpload.ps1' 0
function Get-UseChunkedUpload
{
    <#
    .NOTES
    Taken from: https://stackoverflow.com/a/48323495
    #>

    param(
        [Parameter(Mandatory=$true)]
        [long]$FileSize,

        [Parameter(Mandatory=$true)]
        [long]$BufferSize
    )

    return $FileSize -gt $BufferSize;
}
#EndRegion '.\private\Get-UseChunkedUpload.ps1' 17
#Region '.\private\Invoke-Nexus.ps1' 0
function Invoke-Nexus {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [String]
        $UriSlug,

        [Parameter()]
        [Hashtable]
        $Body,

        [Parameter()]
        [Array]
        $BodyAsArray,

        [Parameter()]
        [String]
        $BodyAsString,

        [Parameter()]
        [SecureString]
        $BodyAsSecureString,

        [Parameter()]
        [String]
        $File,

        [Parameter()]
        [String]
        $ContentType = 'application/json',

        [Parameter(Mandatory)]
        [String]
        $Method
    )
    process {
        $UriBase = "$($protocol)://$($Hostname):$($port)$($ContextPath)"
        $Uri = $UriBase + $UriSlug
        $Params = @{
            Headers = $header
            ContentType = $ContentType
            Uri = $Uri
            Method = $Method
            UseBasicParsing = $true
        }

        if($Body){
            $Params.Add('Body',$($Body | ConvertTo-Json -Depth 3))
        }

        if($BodyAsArray){
            $Params.Add('Body',$($BodyAsArray | ConvertTo-Json -Depth 3))
        }

        if($BodyAsString){
            $Params.Add('Body',$BodyAsString)
        }

        if($BodyAsSecureString){
            $Params.Add(
                'Body',
                [Runtime.InteropServices.Marshal]::PtrToStringBSTR(
                    [Runtime.InteropServices.Marshal]::SecureStringToBSTR($BodyAsSecureString)
                )
            )
        }

        if($File){
            $Params.Remove('ContentType')
            $Params.Add('InFile',$File)
        }

        Invoke-RestMethod @Params
    }
}
#EndRegion '.\private\Invoke-Nexus.ps1' 76
#Region '.\private\New-HttpQueryString.ps1' 0
function New-HttpQueryString
{
    #Shamelessly taken from https://powershellmagazine.com/2019/06/14/pstip-a-better-way-to-generate-http-query-strings-in-powershell/
    [CmdletBinding()]
    param 
    (
        [Parameter(Mandatory = $true)]
        [String]
        $Uri,

        [Parameter(Mandatory = $true)]
        [Hashtable]
        $QueryParameter
    )
    # Add System.Web
    Add-Type -AssemblyName System.Web
    
    # Create a http name value collection from an empty string
    $nvCollection = [System.Web.HttpUtility]::ParseQueryString([String]::Empty)
    
    foreach ($key in $QueryParameter.Keys)
    {
        $nvCollection.Add($key, $QueryParameter.$key)
    }
    
    # Build the uri
    $uriRequest = [System.UriBuilder]$uri
    $uriRequest.Query = $nvCollection.ToString()
    
    return $uriRequest.Uri.OriginalString
}
#EndRegion '.\private\New-HttpQueryString.ps1' 32
#Region '.\private\New-HttpWebRequest.ps1' 0
function New-HttpWebRequest
{
    <#
    .SYNOPSIS
    Creates a new [System.Net.HttpWebRequest] ready for file transmission.
 
    .DESCRIPTION
    Creates a new [System.Net.HttpWebRequest] ready for file transmission.
    The method will be Put. If the filesize is larger than the buffersize,
    the HttpWebRequest will be configured for chunked transfer.
 
    .PARAMETER Url
    Url to connect to.
 
    .PARAMETER Credential
    Credential for authentication at the Url resource.
 
    .EXAMPLE
    An example
 
    .NOTES
    Taken from: https://stackoverflow.com/a/48323495
    #>

    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$Url,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [pscredential]$Credential,

        [Parameter(Mandatory=$true)]
        [long]$FileSize,

        [Parameter(Mandatory=$true)]
        [long]$BufferSize
    )

    $webRequest = [System.Net.HttpWebRequest]::Create($Url)
    $webRequest.Timeout = 600 * 1000;
    $webRequest.ReadWriteTimeout = 600 * 1000;
    $webRequest.ProtocolVersion = [System.Net.HttpVersion]::Version11;
    $webRequest.Method = "PUT";
    $webRequest.ContentType = "application/octet-stream";
    $webRequest.KeepAlive = $true;
    $webRequest.UserAgent = "<I use a specific UserAgent>";
    #$webRequest.UserAgent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)';
    $webRequest.PreAuthenticate = $true;
    $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Credential.UserName + ":" + $Credential.GetNetworkCredential().Password));
    $webRequest.Headers["Authorization"] = "Basic $auth"

    if (Get-UseChunkedUpload -FileSize $FileSize -BufferSize $BufferSize)
    {
        Write-Verbose "FileSize is greater than BufferSize, using chunked transfer.";
        $webRequest.AllowWriteStreamBuffering = $false;
        $webRequest.SendChunked = $true;
    }
    else
    {
        # Filesize is equal to or smaller than the BufferSize. The file will be transferred in one write.
        # Chunked cannot be used in this case.
        $webRequest.AllowWriteStreamBuffering = $true;
        $webRequest.SendChunked = $false;
        $webRequest.ContentLength = $FileSize;
    }

    return $webRequest;
}
#EndRegion '.\private\New-HttpWebRequest.ps1' 70
#Region '.\private\Send-PreAuthenticate.ps1' 0
function Send-PreAuthenticate
{
    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$Url,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [pscredential]$Credential
    )

    $response = $null;
    try
    {
        [System.Uri]$uri = $Url;
        $repositoryAuthority = (($uri.GetLeftPart([System.UriPartial]::Authority)).TrimEnd('/') + '/');
        Write-Verbose "Send-PreAuthenticate - Sending HEAD to $repositoryAuthority";
        $wr = [System.Net.WebRequest]::Create($repositoryAuthority);
        $wr.Method = "HEAD";
        $wr.PreAuthenticate = $true;
        $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Credential.UserName + ":" + $Credential.GetNetworkCredential().Password));
        $wr.Headers["Authorization"] = "Basic $auth"
        $response = $wr.GetResponse();
    }
    finally
    {
        if ($response)
        {
            $response.Close();
            $response.Dispose();
            $response = $null;
        }
    }
}
#EndRegion '.\private\Send-PreAuthenticate.ps1' 36
#Region '.\private\Upload-File.ps1' 0
function Upload-File
{
    <#
    .SYNOPSIS
    Uploads a file to the Nexus repository.
 
    .DESCRIPTION
    Uploads a file to the Nexus repository.
    If the file was uploaded successfully, the url via which the resource can be downloaded is returned.
 
    .PARAMETER Url
    The Url where the resource should be created.
    Please note that underscores and dots should be encoded, otherwise the Nexus repository does not accept the upload.
 
    .PARAMETER File
    The file that should be uploaded.
 
    .PARAMETER Credential
    Credential used for authentication at the Nexus repository.
 
    .EXAMPLE
    Upload-File -Url https://nexusrepo.domain.com/repository/repo-name/myfolder/myfile%2Eexe -File (Get-ChildItem .\myfile.exe) -Credential (Get-Credential)
 
    .OUTPUTS
    If the file was uploaded successfully, the url via which the resource can be downloaded.
    #>

    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$Url,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [System.IO.FileInfo]$File,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [pscredential]$Credential
    )

    Write-Verbose "Upload-File Url:$Url"

    Configure-Tls -Url $Url;

    $fileSizeBytes = $File.Length;
    #$bufSize = Get-BufferSize $fileSizeBytes;
    $bufSize = 4 * 1MB;
    Write-Verbose ("FileSize is {0} bytes ({1:N0}MB). BufferSize is {2} bytes ({3:N0}MB)" -f $fileSizeBytes,($fileSizeBytes/1MB),$bufSize,($bufSize/1MB));
    if (Get-UseChunkedUpload -FileSize $fileSizeBytes -BufferSize $bufSize)
    {
        Write-Verbose "Using chunked upload. Send pre-auth first.";
        Send-PreAuthenticate -Url $Url -Credential $Credential;
    }

    $progressActivityMessage = ("Sending file {0} - {1} bytes" -f $File.Name, $File.Length);
    $webRequest = New-HttpWebRequest -Url $Url -Credential $Credential -FileSize $fileSizeBytes -BufferSize $bufSize;
    $chunk = New-Object byte[] $bufSize;
    $bytesWritten = 0;
    $fileStream = [System.IO.File]::OpenRead($File.FullName);
    $requestStream = $WebRequest.GetRequestStream();
    try
    {
        while($bytesRead = $fileStream.Read($chunk,0,$bufSize))
        {
            $requestStream.Write($chunk, 0, $bytesRead);
            $requestStream.Flush();
            $bytesWritten += $bytesRead;
            $progressStatusMessage = ("Sent {0} bytes - {1:N0}MB" -f $bytesWritten, ($bytesWritten / 1MB));
            Write-Progress -Activity $progressActivityMessage -Status $progressStatusMessage -PercentComplete ($bytesWritten/$fileSizeBytes*100);
        }
    }
    catch
    {
        throw;
    }
    finally
    {
        if ($fileStream)
        {
            $fileStream.Close();
        }
        if ($requestStream)
        {
            $requestStream.Close();
            $requestStream.Dispose();
            $requestStream = $null;
        }
        Write-Progress -Activity $progressActivityMessage -Completed;
    }

    # Read the response.
    $response = $null;
    try
    {
        $response = $webRequest.GetResponse();
        Write-Verbose ("{0} responded with {1} at {2}" -f $response.Server,$response.StatusCode,$response.ResponseUri);
        return $response.ResponseUri;
    }
    catch
    {
        if ($_.Exception.InnerException -and ($_.Exception.InnerException -like "*bad request*"))
        {
            throw ("ERROR: " + $_.Exception.InnerException.Message + " Possibly the file already exists or the content type of the file does not match the file extension. In that case, disable MIME type validation on the server.")
        }

        throw;
    }
    finally
    {
        if ($response)
        {
            $response.Close();
            $response.Dispose();
            $response = $null;
        }
        if ($webRequest)
        {
            $webRequest = $null;
        }
    }
}
#EndRegion '.\private\Upload-File.ps1' 122
#Region '.\public\Connect-NexusServer.ps1' 0
function Connect-NexusServer {
    <#
    .SYNOPSIS
    Creates the authentication header needed for REST calls to your Nexus server
     
    .DESCRIPTION
    Creates the authentication header needed for REST calls to your Nexus server
     
    .PARAMETER Hostname
    The hostname or ip address of your Nexus server
     
    .PARAMETER Credential
    The credentials to authenticate to your Nexus server
 
    .PARAMETER Path
    The optional context path used by the Nexus server
     
    .PARAMETER UseSSL
    Use https instead of http for REST calls. Defaults to 8443.
     
    .PARAMETER Sslport
    If not the default 8443 provide the current SSL port your Nexus server uses
     
    .EXAMPLE
    Connect-NexusServer -Hostname nexus.fabrikam.com -Credential (Get-Credential)
 
    .EXAMPLE
    Connect-NexusServer -Hostname nexus.fabrikam.com -Credential (Get-Credential) -UseSSL
 
    .EXAMPLE
    Connect-NexusServer -Hostname nexus.fabrikam.com -Credential $Cred -UseSSL -Sslport 443
    #>

    [cmdletBinding(HelpUri='https://nexushell.dev/Connect-NexusServer/')]
    param(
        [Parameter(Mandatory,Position=0)]
        [Alias('Server')]
        [String]
        $Hostname,

        [Parameter(Mandatory,Position=1)]
        [System.Management.Automation.PSCredential]
        $Credential,

        [Parameter()]
        [String]
        $Path = "/",

        [Parameter()]
        [Switch]
        $UseSSL,

        [Parameter()]
        [String]
        $Sslport = '8443'
    )

    process {

        if($UseSSL){
            $script:protocol = 'https'
            $script:port = $Sslport
        } else {
            $script:protocol = 'http'
            $script:port = '8081'
        }

        $script:HostName = $Hostname
        $script:ContextPath = $Path.TrimEnd('/')

        $credPair = "{0}:{1}" -f $Credential.UserName,$Credential.GetNetworkCredential().Password

        $encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($credPair))

        $script:header = @{ Authorization = "Basic $encodedCreds"}
        $script:Credential = $Credential

        try {
            $url = "$($protocol)://$($Hostname):$($port)$($ContextPath)/service/rest/v1/status"

            $params = @{
                Headers = $header
                ContentType = 'application/json'
                Method = 'GET'
                Uri = $url
                UseBasicParsing = $true
            }

            $result = Invoke-RestMethod @params -ErrorAction Stop
            Write-Host "Connected to $Hostname" -ForegroundColor Green
        }

        catch {
            $_.Exception.Message
        }
    }
}
#EndRegion '.\public\Connect-NexusServer.ps1' 97
#Region '.\public\Anonymous\Get-NexusAnonymousAuthStatus.ps1' 0
function Get-NexusAnonymousAuthStatus {
    <#
    .SYNOPSIS
    Returns the state of Nexus Anonymous Auth
     
    .DESCRIPTION
    Returns the state of Nexus Anonymous Auth
     
    .EXAMPLE
    Get-NexusAnonymousAuth
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Get-NexusAnonymousAuthStatus/')]
    Param()

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/security/anonymous"
    }
    process {

        Invoke-Nexus -UriSlug $urislug -Method 'GET'
    }
}
#EndRegion '.\public\Anonymous\Get-NexusAnonymousAuthStatus.ps1' 28
#Region '.\public\Anonymous\Set-NexusAnonymousAuth.ps1' 0
function Set-NexusAnonymousAuth {
    <#
    .SYNOPSIS
    Turns Anonymous Authentication on or off in Nexus
     
    .DESCRIPTION
    Turns Anonymous Authentication on or off in Nexus
     
    .PARAMETER Enabled
    Turns on Anonymous Auth
     
    .PARAMETER Disabled
    Turns off Anonymous Auth
     
    .EXAMPLE
    Set-NexusAnonymousAuth -Enabled
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Set-NexusAnonymousAuth/')]
    Param(
        [Parameter()]
        [Switch]
        $Enabled,

        [Parameter()]
        [Switch]
        $Disabled
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/security/anonymous"
    }

    process {

        Switch($true){

            $Enabled {
                $Body = @{
                    enabled = $true
                    userId = 'anonymous'
                    realmName = 'NexusAuthorizingRealm'
                }

                Invoke-Nexus -UriSlug $urislug -Body $Body -Method 'PUT'
            }

            $Disabled {
                $Body = @{
                    enabled = $false
                    userId = 'anonymous'
                    realmName = 'NexusAuthorizingRealm'
                }

                Invoke-Nexus -UriSlug $urislug -Body $Body -Method 'PUT'

            }
        }
    }
}
#EndRegion '.\public\Anonymous\Set-NexusAnonymousAuth.ps1' 65
#Region '.\public\APIKey\Get-NexusNuGetApiKey.ps1' 0
function Get-NexusNuGetApiKey {
    <#
    .SYNOPSIS
    Retrieves the NuGet API key of the given user credential
     
    .DESCRIPTION
    Retrieves the NuGet API key of the given user credential
     
    .PARAMETER Credential
    The Nexus User whose API key you wish to retrieve
     
    .EXAMPLE
    Get-NexusNugetApiKey -Credential (Get-Credential)
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/API%20Key/Get-NexusNuGetApiKey/')]
    Param(
        [Parameter(Mandatory)]
        [PSCredential]
        $Credential
    )

    process {
        $token = Get-NexusUserToken -Credential $Credential
        $base64Token = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($token))
        $UriBase = "$($protocol)://$($Hostname):$($port)$($ContextPath)"
        
        $slug = "/service/rest/internal/nuget-api-key?authToken=$base64Token&_dc=$(([DateTime]::ParseExact("01/02/0001 21:08:29", "MM/dd/yyyy HH:mm:ss",$null)).Ticks)"

        $uri = $UriBase + $slug


        $credPair = "{0}:{1}" -f $Credential.UserName,$Credential.GetNetworkCredential().Password
        $encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($credPair))
        $ApiKeyHeader = @{ Authorization = "Basic $encodedCreds"}

        Invoke-RestMethod -Uri $uri -Headers $ApiKeyHeader -Method GET -ContentType 'application/json' -UseBasicParsing

    }
}
#EndRegion '.\public\APIKey\Get-NexusNuGetApiKey.ps1' 43
#Region '.\public\Asset\Get-NexusAsset.ps1' 0
function Get-NexusAsset {
    <#
    .SYNOPSIS
    Retrieve asset information from Nexus
     
    .DESCRIPTION
    Retrieve asset informatino from Nexus
     
    .PARAMETER RepositoryName
    The repository to query for assets
     
    .PARAMETER Id
    A specific asset to retrieve
     
    .EXAMPLE
    Get-NexusAsset -RepositoryName Dev
 
    .EXAMPLE
    Get-NexusAsset -Id RGV2OmM2MGJjNmI5NjEyZjQ3ZDM5ZTc2ZmMwNTI1ODg0M2Rj
     
    .NOTES
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Assets/Get-NexusAsset/',DefaultParameterSetName="repo")]
    Param(
        [Parameter(ParameterSetName="repo",Mandatory)]
        [String]
        $RepositoryName,

        [Parameter(ParameterSetName="Id",Mandatory)]
        [String]
        $Id
    )

    process {

        if ($Id) {
            $urislug = "/service/rest/v1/assets/$($Id)"
            Invoke-Nexus -Urislug $urislug -Method GET
        }

        else {
            $urislug = "/service/rest/v1/assets?repository=$($RepositoryName)"

            $result = Invoke-Nexus -Urislug $urislug -Method GET

            $result.items

            if ($($result.continuationToken)) {

                $urislug = "/service/rest/v1/assets?continuationToken=$($result.continuationToken)&repository=$($RepositoryName)"
                $result = Invoke-Nexus -Urislug $urislug -Method GET
                $result.items
            }
        }
    }
}
#EndRegion '.\public\Asset\Get-NexusAsset.ps1' 57
#Region '.\public\Asset\Remove-NexusAsset.ps1' 0
function Remove-NexusAsset {
    <#
    .SYNOPSIS
    Removes an asset from a Nexus Repository
     
    .DESCRIPTION
    Removes an asset from a Nexus Repository
     
    .PARAMETER Id
    The id of the asset for removal
     
    .PARAMETER Force
    Don't prompt for confirmation before deleting
     
    .EXAMPLE
    Remove-NexusAsset -Id RGV2OmM2MGJjNmI5NjEyZjQ3ZDM5ZTc2ZmMwNTI1ODg0M2Rj
 
    .EXAMPLE
    Remove-NexusAsset -Id RGV2OmM2MGJjNmI5NjEyZjQ3ZDM5ZTc2ZmMwNTI1ODg0M2Rj -Force
     
    .NOTES
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Assets/Remove-NexusAsset/',SupportsShouldProcess,ConfirmImpact='High')]
    Param(
        [Parameter(Mandatory)]
        [String[]]
        $Id,

        [Parameter()]
        [Switch]
        $Force
    )

    process {
        $Id | Foreach-Object {
            $urislug = "/service/rest/v1/assets/$($_)"
            if ($Force -and -not $Confirm) {
                $ConfirmPreference = 'None'
                if ($PSCmdlet.ShouldProcess("$($_)", "Remove Asset")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE
                }
            }
            else {
                if ($PSCmdlet.ShouldProcess("$($_)", "Remove Asset")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE
                }
            }
        }    
    }
}
#EndRegion '.\public\Asset\Remove-NexusAsset.ps1' 51
#Region '.\public\BlobStore\Get-NexusBlobStore.ps1' 0
function Get-NexusBlobStore {
    <#
    .SYNOPSIS
    Get information about a blob store
     
    .DESCRIPTION
    Get basic or detailed blob store configuration information
     
    .PARAMETER Name
    The blob store to get information from
     
    .PARAMETER Type
    The type of the blob store
     
    .PARAMETER Detailed
    Return detailed information about the blob store
     
    .EXAMPLE
    Get-NexusBlobStore
 
    .EXAMPLE
    Get-NexusBlobStore -Name default -Type file
 
    .EXAMPLE
    Get-NexusBlobStore -Name TreasureBlob -Type file -Detailed
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Get-NexusBlobStore/',DefaultParameterSetName = "Default")]
    Param(
        [Parameter(Mandatory, ParameterSetName = "Name")]
        [String]
        $Name,
        
        [Parameter(Mandatory, ParameterSetName = "Type")]
        [Parameter(Mandatory, ParameterSetName = "Name")]
        [ValidateSet('File', 'S3')]
        [String]
        $Type,

        [Parameter(ParameterSetName = "Name")]
        [Parameter(ParameterSetName = "Type")]
        [Switch]
        $Detailed
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/blobstores"
    }

    process {

        switch ($PSCmdlet.ParameterSetName) {
            
            { $Name } {
                if (-not $Detailed) {
                    switch ($Type) {
                        'File' {
                            $urlType = '/file'
                            $Uri = $urislug + $urlType + "/$Name"
    
                            Invoke-Nexus -UriSlug $Uri -Method 'GET'
                        }
    
                        'S3' {
                            $urlType = '/s3'
                            $Uri = $urislug + $urlType + "/$Name"
    
                            Invoke-Nexus -UriSlug $Uri -Method 'GET'
                        }
                    }

                }

                else {
                    $result = Invoke-Nexus -UriSlug $urislug -Method 'GET'
                    $result | Where-Object { $_.name -eq $Name }
                }
                
            }

            default {
                Invoke-Nexus -UriSlug $urislug -Method 'GET'

            }
        }
        
    }
}
#EndRegion '.\public\BlobStore\Get-NexusBlobStore.ps1' 93
#Region '.\public\BlobStore\Get-NexusBlobStoreQuota.ps1' 0
function Get-NexusBlobStoreQuota {
    <#
    .SYNOPSIS
    Get the quota settings of a blob store
     
    .DESCRIPTION
    Get the quota settings of a blob store
     
    .PARAMETER Name
    The blob store to retrieve quota settings
     
    .EXAMPLE
    Get-NexusBlobStoreQuota -Name TestBlob
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Get-NexusBlobStoreQuota/')]
    Param(
        [Parameter(Mandatory)]
        [String[]]
        $Name
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/blobstores"
    }
    process {

        $Name | Foreach-Object {

            $Uri = $urislug + "/$_/quota-status"
            Invoke-Nexus -UriSlug $Uri -Method 'GET'

        }
    }
}
#EndRegion '.\public\BlobStore\Get-NexusBlobStoreQuota.ps1' 40
#Region '.\public\BlobStore\New-NexusBlobStore.ps1' 0
function New-NexusBlobStore {
    <#
    .SYNOPSIS
    Creates a new blob store
     
    .DESCRIPTION
    Nexus stores artifacts for repositories in blobs. This cmdlet creates a new Nexus Blob for your artifacts
     
    .PARAMETER Type
    The type of Blob Store to create. This can be File, or S3
     
    .PARAMETER Name
    The name of the blob store
     
    .PARAMETER UseQuota
    Enforce a Quota on the blob
     
    .PARAMETER QuotaType
    The type of Quota to enforce
     
    .PARAMETER SoftQuotaInMB
    The storage limit for the Quota
     
    .PARAMETER Path
    The path for the File type blob
     
    .PARAMETER Bucket
    The bucket for the S3 type blob
     
    .PARAMETER Region
    The AWS region of the S3 bucket
     
    .PARAMETER Prefix
    (Optional) Prefix of S3 bucket
     
    .PARAMETER ExpirationDays
    The amount of time to wait after removing an S3 blob store for the underlying bucket to be deleted
     
    .PARAMETER UseAuthentication
    Require authentication for an S3 blob
     
    .PARAMETER AccessKey
    The access key needed to connect an S3 blob when using authentication
     
    .PARAMETER SecretKey
    The Secret Key needed to connect an S3 blob when using authentication
     
    .PARAMETER AssumeRoleARN
    Optional AssumeRoleARN for s3 blob authentication
     
    .PARAMETER SessionTokenARN
    Optional SessionTokenARN for s3 blob authentication
     
    .PARAMETER UseEncryption
    Require encryption of the S3 blob
     
    .PARAMETER EncryptionType
    The type of encryption to use
     
    .PARAMETER KMSKeyId
    If using KMS Encryption the KMS Key Id needed
     
    .EXAMPLE
    New-NexusBlobStore -Name TreasureBlobQuota -Type File -Path C:\blob2 -UseQuota -QuotaType spaceRemainingQuota -SoftQuotaInMB 300
 
    .EXAMPLE
    New-NexusBlobStore -Name TreasureBlob -Type File -Path C:\blob
     
    .NOTES
    S3 buckets are currently not supported by the cmdlet until I can get S3 for testing
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/New-NexusBlobStore/')]
    Param(
        [Parameter(Mandatory,ParameterSetName="File")]
        [Parameter(Mandatory,ParameterSetName="S3")]
        [ValidateSet('File','S3')]
        [String]
        $Type,

        [Parameter(Mandatory,ParameterSetName="File")]
        [Parameter(Mandatory,ParameterSetName="S3")]
        [String]
        $Name,

        [Parameter(ParameterSetName="File")]
        [Parameter(Mandatory,ParameterSetName="FileQuota")]
        [Switch]
        $UseQuota,

        [Parameter(ParameterSetName="File")]
        [Parameter(Mandatory,ParameterSetName="FileQuota")]
        [ValidateSet('spaceUsedQuota','spaceRemainingQuota')]
        [String]
        $QuotaType,

        [Parameter(ParameterSetName="File")]
        [Parameter(Mandatory,ParameterSetName="FileQuota")]
        [Int]
        $SoftQuotaInMB,

        [Parameter(ParameterSetName="File")]
        [String]
        $Path,

        [Parameter(Mandatory,ParameterSetName="S3Options")]
        [String]
        $Bucket,

        [Parameter(ParameterSetName="S3Options")]
        [String]
        $Region,

        [Parameter(ParameterSetName="S3Options")]
        [String]
        $Prefix,

        [Parameter(ParameterSetName="S3Options")]
        [Int]
        $ExpirationDays = 3,

        [Parameter(Mandatory,ParameterSetName="S3AuthenticationSettings")]
        [Switch]
        $UseAuthentication,

        [Parameter(Mandatory,ParameterSetName="S3AuthenticationSettings")]
        [String]
        $AccessKey,

        [Parameter(Mandatory,ParameterSetName="S3AuthenticationSettings")]
        [String]
        $SecretKey,

        [Parameter(ParameterSetName="S3AuthenticationSettings")]
        [String]
        $AssumeRoleARN,

        [Parameter(ParameterSetName="S3AuthenticationSettings")]
        [String]
        $SessionTokenARN,

        [Parameter(Mandatory,ParameterSetname="S3EncryptionSettings")]
        [Switch]
        $UseEncryption,

        [Parameter(Mandatory,ParameterSetname="S3EncryptionSettings")]
        [ValidateSet('None','S3Managed','KMS')]
        [String]
        $EncryptionType,

        [Parameter(ParameterSetName="S3EncryptionSettings")]
        [String]
        $KMSKeyId

    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/blobstores"
    }

    process {

        switch($PSCmdlet.ParameterSetname){
            'File' {

                $Body = @{
                    name = $Name
                    path = $Path
                }

                if($UseQuota) {
                    $quota = @{
                        type = $QuotaType
                        limit = $SoftQuotaInMB
                    }

                    $Body.Add('softQuota',$quota)
                }

                $Uri = $urislug + '/file'

                Write-Verbose ($Body | ConvertTo-Json)
                try {
                    Invoke-Nexus -UriSlug $Uri -Body $Body -Method 'POST' -ErrorAction Stop
                    $obj = @{
                        Status = 'Success'
                        Name = $Name
                        Type = $Type
                        Path = $Path
                    }

                    if($UseQuota){
                        $options = @{
                            QuotaType = $QuotaType
                            QuotaLimit = $SoftQuotaInMB
                        }

                        $obj.Add('Options',$options)
                    }

                    [pscustomobject]$obj
                }

                catch {
                    $_.exception.Message
                }
            }

            'S3' {

                Write-Warning "S3 buckets are currently unimplemented"
            }
        }

    }
}
#EndRegion '.\public\BlobStore\New-NexusBlobStore.ps1' 221
#Region '.\public\BlobStore\Remove-NexusBlobStore.ps1' 0
function Remove-NexusBlobStore {
    <#
    .SYNOPSIS
    Deletes a Nexus blob store
     
    .DESCRIPTION
    Deletes a Nexus blob store
     
    .PARAMETER Name
    The blob store to remove
     
    .PARAMETER Force
    Disable confirmation of the delete action.
     
    .EXAMPLE
    Remove-NexusBlobStore -Name TreasureBlob
 
    .EXAMPLE
    Remove-NexusBlobStore -Name TreasureBlob -Force
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Remove-NexusBlobStore/',SupportsShouldProcess, ConfirmImpact = 'High')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter()]
        [Switch]
        $Force
    )
    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/blobstores"
    }

    process {
        $Uri = $urislug + "/$Name"

        try {

           
            if ($Force -and -not $Confirm) {
                $ConfirmPreference = 'None'
                if ($PSCmdlet.ShouldProcess("$name", "Remove Blob Store")) {
                    $result = Invoke-Nexus -UriSlug $Uri -Method 'DELETE' -ErrorAction Stop
                    [pscustomobject]@{
                        Status    = 'Success'
                        Blob      = $Name        
                    }
                }
            } 

            else {
                if ($PSCmdlet.ShouldProcess("$name", "Remove Blob Store")) {
                    $result = Invoke-Nexus -UriSlug $Uri -Method 'DELETE' -ErrorAction Stop
                    [pscustomobject]@{
                        Status    = 'Success'
                        Blob      = $Name
                        Timestamp = $result.date
    
                    }
                }

            }
           
            
        }

        catch {
            $_.exception.message
        }
    }
}
#EndRegion '.\public\BlobStore\Remove-NexusBlobStore.ps1' 78
#Region '.\public\BlobStore\Update-NexusFileBlobStore.ps1' 0
function Update-NexusFileBlobStore {
    <#
    .SYNOPSIS
    Updates some properties of a given file blobstore
 
    .PARAMETER Name
    The Name of the file blobstore to update
 
    .PARAMETER Path
    The path for the blob store to use
 
    .PARAMETER SoftQuotaType
    The type of soft quota limit to enforce
 
    .PARAMETER SoftQuotaLimit
    The size of the soft quota limit, in MB
 
    .NOTES
    This does not automatically migrate blobs from the previous location.
    There may be some time where the store is inaccessible.
 
    .EXAMPLE
    Update-NexusFileBlobStore -Name default -Path D:\NexusStore
 
    # Sets the default blobstore to the location listed
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/Update-NexusFileBlobStore/', SupportsShouldProcess, ConfirmImpact = 'High')]
    param(
        [Parameter(Mandatory)]
        [string]
        $Name,

        [string]
        $Path,

        [ValidateSet("Remaining", "Used")]
        [string]
        $SoftQuotaType,

        [ValidateRange(1, [int]::MaxValue)]
        [int]
        $SoftQuotaLimit
    )
    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }
    end {
        $urislug = "/service/rest/v1/blobstores/file/$Name"

        $Body = Get-NexusBlobStore -Name $Name -Type File | Convert-ObjectToHashtable

        $Modified = $false
        switch -Wildcard ($PSBoundParameters.Keys) {
            "Path" {
                if ($Body.path -ne $Path) {
                    $Body.path = $Path
                    $Modified = $true
                }
            }
            "SoftQuota*" {
                if (-not $Body.softQuota) {
                    $Body.softQuota = @{}
                }
            }
            "SoftQuotaType" {
                if ($Body.softQuota.type -ne "space$($SoftQuotaType)Quota") {
                    $Body.softQuota.type = "space$($SoftQuotaType)Quota"
                    $Modified = $true
                }
            }
            "SoftQuotaLimit" {
                if ($Body.softQuota.limit -ne $SoftQuotaLimit) {
                    $Body.softQuota.limit = $SoftQuotaLimit * 1MB
                    $Modified = $true
                }
            }
        }

        if ($Modified) {
            if ($PSCmdlet.ShouldProcess($Name, "Update File Blob Store")) {
                Invoke-Nexus -UriSlug $urislug -Method Put -Body $Body
            }
        } else {
            Write-Verbose "No change to '$($Name)' was required."
        }
    }
}
#EndRegion '.\public\BlobStore\Update-NexusFileBlobStore.ps1' 90
#Region '.\public\Certificate\Get-NexusCertificate.ps1' 0
function Get-NexusCertificate {
    <#
    .SYNOPSIS
    Retrieve a list of certificates added to the trust store
     
    .DESCRIPTION
    Retrieve a list of certificates added to the trust store
     
    .EXAMPLE
    Get-Nexuscertificate
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Get-NexusCertificate/')]
    Param()

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {
        $urislug = '/service/rest/v1/security/ssl/truststore'
        $result = Invoke-Nexus -Urislug $urislug -Method GET

        $result | Foreach-Object {
            [pscustomobject]@{
                ExpiresOn = $_.expiresOn
                Fingerprint = $_.fingerprint
                Id = $_.id
                IssuedOn = $_.issuedOn
                IssuerCommonName = $_.issuerCommonName
                IssuerOrganization = $_.issuerOrganization
                IssuerOrganizationalUnit = $_.issueOrganizationalUnit
                Pem = $_.pem
                SerialNumber = $_.serialNumber
                SubjectCommonName = $_.subjectCommonName
                SubjectOrganization = $_.subjectOrganization
                SubjectOrganizationalUnit = $_.subjectOrganizationalUnit
            }
        }
    }
}
#EndRegion '.\public\Certificate\Get-NexusCertificate.ps1' 46
#Region '.\public\Certificate\New-NexusCertificate.ps1' 0
function New-NexusCertificate {
    <#
    .SYNOPSIS
    Add a certificate to the trust store.
     
    .DESCRIPTION
    Add a certificate to the trust store.
     
    .PARAMETER PemFile
    The certificate to add encoded in PEM format
     
    .EXAMPLE
    New-NexusCertificate -PemFile C:\cert\prod.pem
     
    .NOTES
     
    #>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory)]
        [ValidateScript({ 
            Test-Path $_ 
        })]
        [String]
        $PemFile
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {
        $urislug = '/service/rest/v1/security/ssl/truststore'
        $Cert = Get-Content $PemFile -Raw
        $result = Invoke-Nexus -Urislug $urislug -BodyAsString $Cert -Method POST

        $result | Foreach-Object {
            [pscustomobject]@{
                ExpiresOn = $_.expiresOn
                Fingerprint = $_.fingerprint
                Id = $_.id
                IssuedOn = $_.issuedOn
                IssuerCommonName = $_.issuerCommonName
                IssuerOrganization = $_.issuerOrganization
                IssuerOrganizationalUnit = $_.issueOrganizationalUnit
                Pem = $_.pem
                SerialNumber = $_.serialNumber
                SubjectCommonName = $_.subjectCommonName
                SubjectOrganization = $_.subjectOrganization
                SubjectOrganizationalUnit = $_.subjectOrganizationalUnit
            }
        }

    }
}
#EndRegion '.\public\Certificate\New-NexusCertificate.ps1' 58
#Region '.\public\Certificate\Remove-NexusCertificate.ps1' 0
function Remove-NexusCertificate {
    <#
    .SYNOPSIS
    Remove a certificate in the trust store.
     
    .DESCRIPTION
    Remove a certificate in the trust store.
     
    .PARAMETER Thumbprint
    The id of the certificate that should be removed.
     
    .PARAMETER Force
    Don't prompt before removing
     
    .EXAMPLE
    Remove-NexusCertificate -Thumbprint 1a:25:25:25:93:85:94
     
    .EXAMPLE
    Remove-NexusCertificate -Thumbprint 1a:25:25:25:93:85:94 -Force
 
    .EXAMPLE
    Get-NexusCertificate | Remove-NexusCertificate
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Remove-NexusCertificate/',SupportsShouldProcess,ConfirmImpact='High')]
    Param(
        [Alias('Id')]
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [String]
        $Thumbprint,

        [Parameter()]
        [Switch]
        $Force
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {
        $urislug = "/service/rest/v1/security/ssl/truststore/$Thumbprint"
        if ($Force -and -not $Confirm) {
            $ConfirmPreference = 'None'
            if ($PSCmdlet.ShouldProcess("$Thumbprint", "Remove certificate")) {
                Invoke-Nexus -UriSlug $urislug -Method DELETE
            }
        }
        else {
            if ($PSCmdlet.ShouldProcess("$Thumbprint", "Remove certificate")) {
                Invoke-Nexus -UriSlug $urislug -Method DELETE
            }
        }
}
}
#EndRegion '.\public\Certificate\Remove-NexusCertificate.ps1' 59
#Region '.\public\Component\Get-NexusComponent.ps1' 0
function Get-NexusComponent {
    <#
    .SYNOPSIS
    Retrieve component information from Nexus
     
    .DESCRIPTION
    Retrieve component information from Nexus
     
    .PARAMETER RepositoryName
    The repository to query for components
     
    .PARAMETER Id
    A specific component to retrieve
     
    .EXAMPLE
    Get-NexusComponent -RepositoryName Dev
 
    .EXAMPLE
    Get-NexusComponent -Id RGV2OmM2MGJjNmI5NjEyZjQ3ZDM5ZTc2ZmMwNTI1ODg0M2Rj
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/Components/Get-NexusComponent/', DefaultParameterSetName = "repo")]
    Param(
        [Parameter(ParameterSetName = "repo", Mandatory)]
        [String]
        $RepositoryName,

        [Parameter(ParameterSetName = "Id", Mandatory)]
        [String]
        $Id
    )

    process {

        if ($Id) {
            $urislug = "/service/rest/v1/components/$($Id)"
            Invoke-Nexus -Urislug $urislug -Method GET
        }

        else {

            $resultCollection = [System.Collections.Generic.List[psobject]]::new()
            $urislug = "/service/rest/v1/components?repository=$($RepositoryName)"

            $result = Invoke-Nexus -Urislug $urislug -Method GET

            $result.items | Foreach-Object {
                $temp = [PsCustomObject]@{
                    Id         = $_.id
                    Repository = $_.repository
                    Format     = $_.format
                    Group      = $_.group
                    Name       = $_.name
                    Version    = $_.version
                    Assets     = $_.assets
                }
                $resultCollection.Add($temp)
            }

            do {
                $urislug = "/service/rest/v1/components?repository=$($RepositoryName)&continuationToken=$($result.continuationToken)"
                $result = Invoke-Nexus -Urislug $urislug -Method GET
                
                $result.items | Foreach-Object {
                    $temp = [PsCustomObject]@{
                        Id         = $_.id
                        Repository = $_.repository
                        Format     = $_.format
                        Group      = $_.group
                        Name       = $_.name
                        Version    = $_.version
                        Assets     = $_.assets
                    }
                    $resultCollection.Add($temp)
                }
            }
            
            while ($null -ne $result.continuationToken)
            $resultCollection

        }
    }
}
#EndRegion '.\public\Component\Get-NexusComponent.ps1' 83
#Region '.\public\Component\New-NexusNugetComponent.ps1' 0
function New-NexusNugetComponent {
    <#
    .SYNOPSIS
    Uploads a NuGet package to Nexus through the Components API
     
    .DESCRIPTION
    Uploads a NuGet package to Nexus through the Components API
     
    .PARAMETER RepositoryName
    The repository to upload too
     
    .PARAMETER NuGetComponent
    The NuGet package to upload
     
    .EXAMPLE
    New-NexusNugetComponent -RepositoryName ProdNuGet -NuGetComponent C:\temp\awesomepackage.0.1.0.nupkg
     
    .NOTES
     
    #>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory)]
        [String]
        $RepositoryName,

        [Parameter(Mandatory)]
        [ValidateScript( {
                Test-Path $_
            })]
        [String]
        $NuGetComponent
    )

    process {

        $urislug = "/service/rest/v1/components?repository=$($RepositoryName)"
        $UriBase = "$($protocol)://$($Hostname):$($port)$($ContextPath)"
        $Uri = $UriBase + $UriSlug

        $boundary = [System.Guid]::NewGuid().ToString(); 
        $ContentType = 'application/octet-stream'
        $FileStream = [System.IO.FileStream]::new($NuGetComponent, [System.IO.FileMode]::Open)
        $FileHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new('form-data')
        $FileHeader.Name = 'nuget.asset'
        $FileHeader.FileName = Split-Path -leaf $NuGetComponent
        $FileContent = [System.Net.Http.StreamContent]::new($FileStream)
        $FileContent.Headers.ContentDisposition = $FileHeader
        $FileContent.Headers.ContentType = [System.Net.Http.Headers.MediaTypeHeaderValue]::Parse($ContentType)

        $MultipartContent = [System.Net.Http.MultipartFormDataContent]::new()
        $MultipartContent.Add($FileContent)

        $params = @{
            Uri         = $Uri
            Method      = 'POST'
            ContentType = "multipart/form-data; boundary=----WebKitFormBoundary$($Boundary)"
            Body        = $MultipartContent
            Headers     = $header
            UseBasicParsing = $true
        }

        $null = Invoke-WebRequest @params
        
    }
    

}
#EndRegion '.\public\Component\New-NexusNugetComponent.ps1' 69
#Region '.\public\Component\New-NexusRawComponent.ps1' 0
function New-NexusRawComponent {
    <#
    .SYNOPSIS
    Uploads a file to a Raw repository
     
    .DESCRIPTION
    Uploads a file to a Raw repository
     
    .PARAMETER RepositoryName
    The Raw repository to upload too
     
    .PARAMETER File
    The file to upload
     
    .PARAMETER Directory
    The directory to store the file on the repo
     
    .PARAMETER Name
    The name of the file stored into the repo. Can be different than the file name being uploaded.
     
    .EXAMPLE
    New-NexusRawComponent -RepositoryName GeneralFiles -File C:\temp\service.1234.log
 
    .EXAMPLE
    New-NexusRawComponent -RepositoryName GeneralFiles -File C:\temp\service.log -Directory logs
 
    .EXAMPLE
    New-NexusRawComponent -RepositoryName GeneralFile -File C:\temp\service.log -Directory logs -Name service.99999.log
     
    .NOTES
    #>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory)]
        [String]
        $RepositoryName,

        [Parameter(Mandatory)]
        [String]
        $File,

        [Parameter()]
        [String]
        $Directory,

        [Parameter()]
        [String]
        $Name = (Split-Path -Leaf $File)
    )

    process {

        if(-not $Directory){
            $urislug = "/repository/$($RepositoryName)/$($Name)"
        }
        else {
            $urislug = "/repository/$($RepositoryName)/$($Directory)/$($Name)"

        }
        $UriBase = "$($protocol)://$($Hostname):$($port)$($ContextPath)"
        $Uri = $UriBase + $UriSlug


        $params = @{
            Url         = $Uri
            File        = $File
            Credential = $Credential
        }

        Upload-File @params
    }
}
#EndRegion '.\public\Component\New-NexusRawComponent.ps1' 73
#Region '.\public\Component\Remove-NexusComponent.ps1' 0
function Remove-NexusComponent {
    <#
    .SYNOPSIS
    Removes a component from a Nexus Repository
 
    .DESCRIPTION
    Removes a component from a Nexus Repository
 
    .PARAMETER Id
    The ID of the component to remove
 
    .EXAMPLE
    Remove-NexusComponent -Id RGV2OmM2MGJjNmI5NjEyZjQ3ZDM5ZTc2ZmMwNTI1ODg0M2Rj
 
    .EXAMPLE
    Get-NexusComponent -Repository dev | Where-Object {$_.Name -eq "somePackage" -and $_.Version "1.2.3"} | Remove-NexusComponent -Confirm:$false
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Assets/Remove-NexusComponent/', SupportsShouldProcess, ConfirmImpact='High')]
    Param(
        [Parameter(Mandatory, ValueFromPipelineByPropertyName)]
        [String[]]
        $Id
    )
    process {
        $Id | ForEach-Object {
            $urislug = "/service/rest/v1/components/$($_)"

            if ($PSCmdlet.ShouldProcess("$($_)", "Remove Component")) {
                $null = Invoke-Nexus -UriSlug $urislug -Method DELETE
            }
        }
    }
}
#EndRegion '.\public\Component\Remove-NexusComponent.ps1' 34
#Region '.\public\ContentSelector\Get-NexusContentSelector.ps1' 0
function Get-NexusContentSelector {
    <#
    .SYNOPSIS
    List Nexus Content Selectors
     
    .DESCRIPTION
    List Nexus Content Selectors
     
    .PARAMETER Name
    The content selector name
     
    .EXAMPLE
    Get-NexusContentSelector
 
    .EXAMPLE
    Get-NexusContentSelector -Name 'MavenSelector'
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/Content%20Selectors/Get-NexusContentSelector/')]
    Param(
        [Parameter()]
        [String[]]
        $Name
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {

        if($Name){
            $Name | Foreach-Object {
                $urislug = "/service/rest/v1/security/content-selectors/$_"

                $result = Invoke-Nexus -Urislug $urislug -Method GET

                if($result){
                    [pscustomobject]@{
                        Name = $result.name
                        Description = $result.Description
                        Expression = $result.expression
                    }
                }
                
            }
        } else {
            $urislug = '/service/rest/v1/security/content-selectors'

            $result = Invoke-Nexus -Urislug $urislug -Method GET
            if($result){
                [pscustomobject]@{
                    Name = $result.name
                    Description = $result.Description
                    Expression = $result.expression
                }
            }
        }
    }
}
#EndRegion '.\public\ContentSelector\Get-NexusContentSelector.ps1' 65
#Region '.\public\ContentSelector\New-NexusContentSelector.ps1' 0
function New-NexusContentSelector {
    <#
    .SYNOPSIS
    Creates a new Content Selector in Nexus
     
    .DESCRIPTION
    Creates a new Content Selector in Nexus
     
    .PARAMETER Name
    The content selector name cannot be changed after creation
     
    .PARAMETER Description
    A human-readable description
     
    .PARAMETER Expression
    The expression used to identify content
     
    .EXAMPLE
    New-NexusContentSelector -Name MavenContent -Expression 'format == "maven2" and path =^ "/org/sonatype/nexus"'
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/Content%20Selectors/New-NexusContentSelector/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter()]
        [String]
        $Description,

        [Parameter(Mandatory)]
        [String]
        $Expression
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {

        $urislug = '/service/rest/v1/security/content-selectors'
        $Body = @{
            name = $Name
            description = $Description
            expression = $Expression
        }

        Invoke-Nexus -Urislug $urislug -Body $Body -Method POST
    }
}
#EndRegion '.\public\ContentSelector\New-NexusContentSelector.ps1' 57
#Region '.\public\ContentSelector\Remove-NexusContentSelector.ps1' 0
function Remove-NexusContentSelector {
    <#
    .SYNOPSIS
    Removes a Nexus Content Selector
     
    .DESCRIPTION
    Removes a Nexus Content Selector
     
    .PARAMETER Name
    The Content Selector to remove
 
    .PARAMETER Force
    Don't prompt for confirmation before removing
     
    .EXAMPLE
    Remove-NexusContentSelector -Name MavenContent
 
    .EXAMPLE
    Remove-NexusContentSelect -Name MavenContent -Force
 
    .EXAMPLE
    Get-NexusContentSelector | Remove-NexusContentSelector -Force
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/Security/Content%20Selectors/Remove-NexusContentSelector/',SupportsShouldProcess,ConfirmImpact='High')]
    Param(
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ArgumentCompleter( {
                param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

                $r = (Get-NexusContentSelector).Name

                if ($WordToComplete) {
                    $r.Where($_ -match "^$WordToComplete")
                }
                else {
                    $r
                }
            })]
        [String[]]
        $Name,

        [Parameter()]
        [Switch]
        $Force
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }
    
    process {

        $Name | Foreach-Object {

            $urislug = "/service/rest/v1/security/content-selectors/$_"
            if ($Force -and -not $Confirm) {
                $ConfirmPreference = 'None'
                if ($PSCmdlet.ShouldProcess("$($_)", "Remove Content Selector")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                }
            }
            else {
                if ($PSCmdlet.ShouldProcess("$($_)", "Remove Content Selector")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                }
            }
        }
    }
}
#EndRegion '.\public\ContentSelector\Remove-NexusContentSelector.ps1' 75
#Region '.\public\ContentSelector\Set-NexusContentSelector.ps1' 0
function Set-NexusContentSelector {
    <#
    .SYNOPSIS
    Updates a Content Selector in Nexus
     
    .DESCRIPTION
    Updates a Content Selector in Nexus
     
    .PARAMETER Name
    The content selector to update
     
    .PARAMETER Description
    A human-readable description
     
    .PARAMETER Expression
    The expression used to identify content
     
    .EXAMPLE
    Set-NexusContentSelector -Name MavenContent -Expression 'format == "maven2" and path =^ "/org/sonatype/nexus"'
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/Content%20Selectors/Set-NexusContentSelector/')]
    Param(
        [Parameter(Mandatory)]
        [ArgumentCompleter({
            param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

            $r = (Get-NexusContentSelector).Name

            if($WordToComplete){
                $r.Where($_ -match "^$WordToComplete")
            }
            else {
                $r
            }
        })]
        [String]
        $Name,

        [Parameter()]
        [String]
        $Description,

        [Parameter()]
        [String]
        $Expression
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {

        $CurrentSettings = Get-NexusContentSelector -Name $Name

        if(-not $Description){
            $Description = $CurrentSettings.Description
        }
        if(-not $Expression){
            $Expression = $CurrentSettings.Expression
        }

        $urislug = "/service/rest/v1/security/content-selectors/$Name"
        $Body = @{
            name = $Name
            description = $Description
            expression = $Expression
        }

        Invoke-Nexus -Urislug $urislug -Body $Body -Method PUT
    }
}
#EndRegion '.\public\ContentSelector\Set-NexusContentSelector.ps1' 78
#Region '.\public\Email\Clear-NexusEmailConfig.ps1' 0
function Clear-NexusEmailConfig {
    <#
    .SYNOPSIS
    Clears and disables the Smtp configuration in Nexus
     
    .DESCRIPTION
    Clears and disables the Smtp configuration in Nexus
     
    .PARAMETER Force
    Don't prompt before clearing settings
     
    .EXAMPLE
    Clear-NexusEmailConfig
 
    .EXAMPLE
    Clear-NexusEmailConfig -Force
     
    .NOTES
 
    #>

    [CmdletBinding(SupportsShouldProcess,ConfirmImpact='High')]
    Param(
        [Parameter()]
        [Switch]
        $Force
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {
        $urislug = '/service/rest/v1/email'

        try {
            if ($Force -and -not $Confirm) {
                $ConfirmPreference = 'None'
                if ($PSCmdlet.ShouldProcess("$Hostname", "Remove SMTP Connection")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                    
                }
            }
            else {
                if ($PSCmdlet.ShouldProcess("$Hostname", "Remove SMTP Connection")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                }
            }
        }

        catch {
            $_.exception.message
        }
    }
}
#EndRegion '.\public\Email\Clear-NexusEmailConfig.ps1' 57
#Region '.\public\Email\Get-NexusEmailConfig.ps1' 0
function Get-NexusEmailConfig {
    <#
    .SYNOPSIS
    Gets current Nexus email configuration
     
    .DESCRIPTION
    Gets current Nexus email configuration
     
    .EXAMPLE
    Get-NexusEmailConfig
     
    .NOTES
     
    #>

    [CmdletBinding()]
    Param()

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {
        $urislug = '/service/rest/v1/email'

        $result = Invoke-Nexus -Urislug $urislug -Method GET

        [pscustomobject]@{
            Enabled                       = $result.enabled
            Host                          = $result.host
            Port                          = $result.port
            Username                      = $result.username
            Password                      = $result.password
            FromAddress                   = $result.fromaddress
            SubjectPrefix                 = $result.subjectprefix
            StartTlsEnabled               = $result.starttlsenabled
            StartTlsRequired              = $result.starttlsrequired
            SslOnConnectEnabled           = $result.sslonconnectenabled
            SslServerIdentityCheckEnabled = $result.sslserveridentitycheckenabled
            NexusTrustStoreEnabled        = $result.nexustruststoreenabled
        }
    }
}
#EndRegion '.\public\Email\Get-NexusEmailConfig.ps1' 45
#Region '.\public\Email\Set-NexusEmailConfig.ps1' 0
function Set-NexusEmailConfig {
    <#
    .SYNOPSIS
    Sets the email settings for Nexus
     
    .DESCRIPTION
    Sets the email settings for Nexus
     
    .PARAMETER SmtpServer
    The hostname or IP address of your mail server
     
    .PARAMETER SmtpPort
    The SMTP port of your mail server
     
    .PARAMETER Enabled
    Enable sending mail from Nexus
     
    .PARAMETER Credential
    Credentials to connect to your SMTP server if required
     
    .PARAMETER FromAddress
    Messages from Nexus with be sent from this email address
     
    .PARAMETER SubjectPrefix
    Append a prefix to messages from Nexus if desired
     
    .PARAMETER StartTlsEnabled
    Enable StartTLS
     
    .PARAMETER StartTlsRequired
    Require TLS on the smtp connection
     
    .PARAMETER SSLOnConnect
    Require SSL on the smtp connection
     
    .PARAMETER VerifyServerIdentity
    Verify mail server identity before sending messages
     
    .PARAMETER UseNexusTrustStore
    Use Nexus Trust Store for email certificates
     
    .EXAMPLE
    Set-NexusEmailConfig -SmtpSerer mail.foo.org -Port 25 -Enabled
 
    .EXAMPLE
    Set-NexusEmailConfig -SmtpServer mail.foo.org -Port 427 -Enabled -StartTlsEnabled -StartTlsrequired
     
    .NOTES
     
    #>

    [CmdletBinding()]
    Param(
        [Parameter()]
        [String]
        $SmtpServer,

        [Parameter(Mandatory)]
        [Int32]
        $SmtpPort,

        [Parameter()]
        [Switch]
        $Enabled,

        [Parameter()]
        [PSCredential]
        $Credential,

        [Parameter()]
        [String]
        $FromAddress,

        [Parameter()]
        [String]
        $SubjectPrefix,

        [Parameter()]
        [Switch]
        $StartTlsEnabled,

        [Parameter()]
        [Switch]
        $StartTlsRequired,

        [Parameter()]
        [Switch]
        $SSLOnConnect,

        [Parameter()]
        [Switch]
        $VerifyServerIdentity,

        [Parameter()]
        [Switch]
        $UseNexusTrustStore
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {
        $urislug = '/service/rest/v1/email'

        if($Credential){
            $username = $Credential.UserName
            $password = $Credential.GetNetworkCredential().Password
        }

        $Body = @{
            enabled= [bool]$Enabled
            host= $SmtpServer
            port= $SmtpPort
            username= $username
            password= $password
            fromAddress= $FromAddress
            subjectPrefix= $SubjectPrefix
            startTlsEnabled= [bool]$StartTlsEnabled
            startTlsRequired= [bool]$StartTlsRequired
            sslOnConnectEnabled= [bool]$SSLOnConnect
            sslServerIdentityCheckEnabled= [bool]$VerifyServerIdentity
            nexusTrustStoreEnabled= [bool]$UseNexusTrustStore
          }

          Write-verbose ($Body | ConvertTo-Json)
          Invoke-Nexus -Urislug $urislug -Body $Body -Method PUT
    }
}
#EndRegion '.\public\Email\Set-NexusEmailConfig.ps1' 131
#Region '.\public\Email\Test-NexusEmailConfig.ps1' 0
function Test-NexusEmailConfig {
    <#
    .SYNOPSIS
    Verifies Nexus Smtp configuration
     
    .DESCRIPTION
    Verifies Nexus Smtp configuration
     
    .PARAMETER Recipient
    Email address to send test message too
     
    .EXAMPLE
    Test-NexusEmailConfig -Recipient tim@foo.org
     
    .NOTES
     
    #>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Recipient
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {
        $urislug = '/service/rest/v1/email/verify'

        Invoke-Nexus -Urislug $urislug -BodyAsString $Recipient -Method POST
    }
}
#EndRegion '.\public\Email\Test-NexusEmailConfig.ps1' 37
#Region '.\public\Format\Get-NexusFormat.ps1' 0
function Get-NexusFormat {
    <#
    .SYNOPSIS
    Returns detailed format information
     
    .DESCRIPTION
    Returns detailed information about the upload specifications for each format supported
     
    .PARAMETER RepositoryFormat
    Retrieve information about a specific format
     
    .EXAMPLE
    Get-NexusFormat
 
    .EXAMPLE
    Get-NexusFormat -RepositoryFormat nuget
    #>

    [Cmdletbinding(HelpUri='https://nexushell.dev/Formats/Get-NexusFormat/')]
    Param(
        [Parameter()]
        [Alias('Format')]
        [ValidateSet('helm',
            'r',
            'pypi',
            'docker',
            'yum',
            'rubygems',
            'nuget',
            'npm',
            'raw',
            'apt',
            'maven2'
        )]
        [String]
        $RepositoryFormat
    )
    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = if (-not $RepositoryFormat) {
            "/service/rest/v1/formats/upload-specs"
        }
        else {
            "/service/rest/v1/formats/$RepositoryFormat/upload-specs"
        }
    }
    process {
        Invoke-Nexus -UriSlug $urislug -Method 'GET'
    }
}
#EndRegion '.\public\Format\Get-NexusFormat.ps1' 53
#Region '.\public\License\Get-NexusLicenseStatus.ps1' 0
function Get-NexusLicenseStatus {
    <#
    .SYNOPSIS
    Gets license information from a Nexus instance, if available
     
    .DESCRIPTION
    Gets license information from a Nexus instance, if available
     
    .EXAMPLE
    Get-NexusLicenseStatus
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Get-NexusLicenseStatus/')]
    Param()
    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/system/license"
    }

    process {
        try {
            Invoke-Nexus -UriSlug $urislug -Method 'GET' -ErrorAction Stop
        }

        catch {

            Write-Warning "Nexus license not found, running in OSS mode"
        }
    }
}
#EndRegion '.\public\License\Get-NexusLicenseStatus.ps1' 34
#Region '.\public\License\Install-NexusLicense.ps1' 0
function Install-NexusLicense {
    <#
    .SYNOPSIS
    Installs a license on a nexus instance.
     
    .DESCRIPTION
    Installs a license on a nexus instance.
     
    .PARAMETER NexusLicense
    The license file to install
     
    .EXAMPLE
    Install-NexusLicense -NexusLicense 'C:\temp\sonatype-repository-manager.lic'
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Install-NexusLicense/')]
    Param(
        [Parameter(Mandatory)]
        [ValidateScript({ Test-Path $_})]
        [String]
        $NexusLicense
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/system/license"
    }

    process {
        $file = Get-Item $NexusLicense

        Invoke-Nexus -UriSlug $urislug -Method 'POST' -Body $file -ContentType 'application/octetstream'
    }
}
#EndRegion '.\public\License\Install-NexusLicense.ps1' 38
#Region '.\public\License\Remove-NexusLicense.ps1' 0
function Remove-NexusLicense {
    <#
    .SYNOPSIS
    Removes the license from a Nexus instance
     
    .DESCRIPTION
    Removes the license from a Nexus instance
 
    .PARAMETER Force
    Don't prompt for confirmation before removing the license
     
    .EXAMPLE
    Remove-NexusLicense
     
    .EXAMPLE
    Remove-NexusLicense -Force
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Remove-NexusLicense/',SupportsShouldProcess,ConfirmImpact='High')]
    Param(
        [Parameter()]
        [Switch]
        $Force
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/system/license"
    }


    process {

        try {
           
            if ($Force -and -not $Confirm) {
                $ConfirmPreference = 'None'
                if ($PSCmdlet.ShouldProcess("$Hostname", "Remove Nexus license")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                    Write-Warning "License has been removed. Nexus service restart necessary"
                }
            }
            else {
                if ($PSCmdlet.ShouldProcess("$Hostname", "Remove Nexus license")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                    Write-Warning "License has been removed. Nexus service restart necessary"
                }
            }
        }

        catch {
            $_.exception.message
        }
    }
}
#EndRegion '.\public\License\Remove-NexusLicense.ps1' 61
#Region '.\public\Lifecycle\Get-NexusCurrentLifecyclePhase.ps1' 0
function Get-NexusCurrentLifecyclePhase {
    <#
    .SYNOPSIS
    Move to new lifecycle phase
     
    .DESCRIPTION
    Move to new lifecycle phase
     
    .EXAMPLE
    Get-NexusCurrentLifecyclePhase
 
    .EXAMPLE
    Get-NexusLifecycle
     
    .NOTES
     
    #>

    [Alias('Get-NexusLifecycle')]
    [CmdletBinding(HelpUri='')]
    Param()

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        if( -not (Get-NexusLicenseStatus)) {
            throw "Cmdlet requires Nexus Pro"
        }
    }

    process {
        $urislug = '/service/rest/v1/lifecycle/phase'

        Invoke-Nexus -Urislug $urislug -Method GET
    }

}
#EndRegion '.\public\Lifecycle\Get-NexusCurrentLifecyclePhase.ps1' 39
#Region '.\public\Lifecycle\New-NexusLifecyclePhase.ps1' 0
function New-NexusLifecyclePhase {
    <#
    .SYNOPSIS
    Move to new lifecycle phase
     
    .DESCRIPTION
    Move to new lifecycle phase
     
    .PARAMETER Phase
    The phase to move to
     
    .EXAMPLE
    New-NexusLifecyclePhase -Phase NextPhase
     
    .NOTES
 
    #>

    [Alias('New-NexusLifecycle')]
    [CmdletBinding(HelpUri='')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Phase
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        if( -not (Get-NexusLicenseStatus)) {
            throw "Cmdlet requires Nexus Pro"
        }
    }

    process {
        $urislug = '/service/rest/v1/lifecycle'
        Invoke-Nexus -Urislug $urislug -BodyAsString $Phase -Method PUT
    }
}
#EndRegion '.\public\Lifecycle\New-NexusLifecyclePhase.ps1' 41
#Region '.\public\Lifecycle\Restart-NexusLifecyclePhase.ps1' 0
function Restart-NexusLifecyclePhase {
    <#
    .SYNOPSIS
    Re-runs all phases from the given phase to the current phase
     
    .DESCRIPTION
    Re-runs all phases from the given phase to the current phase
     
    .PARAMETER Phase
    The phase to bounce
     
    .EXAMPLE
    Restart-NexusLifecyclePhase -Phase 'SomePreviousPhase'
     
    .NOTES
     
    #>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Phase
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        if( -not (Get-NexusLicenseStatus)) {
            throw "Cmdlet requires Nexus Pro"
        }
    }

    process {
        $urislug = '/service/rest/v1/lifecycle/bounce'
        Invoke-Nexus -Urislug $urislug -BodyAsString $Phase -Method PUT
    }
}
#EndRegion '.\public\Lifecycle\Restart-NexusLifecyclePhase.ps1' 40
#Region '.\public\ReadOnly\Get-NexusReadOnlyState.ps1' 0
function Get-NexusReadOnlyState {
    <#
    .SYNOPSIS
    Returns the Read-Only state of the nexus instance
     
    .DESCRIPTION
    Returns the Read-Only state of the nexus instance
     
    .EXAMPLE
    Get-NexusReadOnlyState
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Get-NexusReadOnlyState/')]
    Param()
    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/read-only"
    }

    process {

        Invoke-Nexus -UriSlug $urislug -Method 'GET'
    }
}
#EndRegion '.\public\ReadOnly\Get-NexusReadOnlyState.ps1' 28
#Region '.\public\ReadOnly\Set-NexusReadOnlyMode.ps1' 0
function Set-NexusReadOnlyMode {
    <#
    .SYNOPSIS
    Sets the nexus instance Read-Only mode
     
    .DESCRIPTION
    Either Disable or Enable Read-Only mode of your nexus instance
     
    .PARAMETER Enable
    Sets the nexus instance to Read-Only mode
     
    .PARAMETER Disable
    Sets the nexus instance to write-enabled mode
     
    .EXAMPLE
    Set-NexusReadOnlyMode -Enable
 
    .EXAMPLE
    Set-NexusReadOnlyMode -Disable
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Set-NexusReadOnlyMode/',SupportsShouldProcess, DefaultParameterSetName = "Enable", ConfirmImpact = 'High')]
    Param(
        [Parameter(Mandatory, ParameterSetName = "Enable")]
        [Switch]
        $Enable,

        [Parameter(Mandatory, ParameterSetName = "Disable")]
        [Switch]
        $Disable,

        [Parameter(ParameterSetName = "Disable")]
        [Switch]
        $Force

    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/read-only"
    }

    process {
        
        switch ($PSCmdlet.ParameterSetName) {
            'Enable' {
                $Uri = $urislug + "/freeze"
                Invoke-Nexus -UriSlug $Uri -Method 'POST'
            }
            'Disable' {
                if ($Force -and -not $Confirm) {
                    $ConfirmPreference = 'None'
                    if ($PSCmdlet.ShouldProcess("Read-Only", "Forcibly release mode")) {
                        $Uri = $urislug + "/force-release"
                        Invoke-Nexus -UriSlug $Uri -Method 'POST'
        
                    }
                } 
    
                else {
                    Write-Warning "Caution! This operation could result in data loss"
                    if ($PSCmdlet.ShouldProcess("Read-Only", "Forcibly release mode")) {
                        $Uri = $urislug + "/release"
                        Invoke-Nexus -UriSlug $Uri -Method 'POST'
                    }
                }
            }
        }
    }
}
#EndRegion '.\public\ReadOnly\Set-NexusReadOnlyMode.ps1' 74
#Region '.\public\Realm\Disable-NexusRealm.ps1' 0
function Disable-NexusRealm {
    <#
    .SYNOPSIS
    Disable realms in Nexus
     
    .DESCRIPTION
    Disable realms in Nexus
     
    .PARAMETER Realm
    The realms you wish to activate
     
    .EXAMPLE
    Disable-NexusRealm -Realm 'NuGet Api-Key Realm', 'Rut Auth Realm'
 
    .EXAMPLE
    Disable-NexusRealm -Realm 'LDAP Realm'
     
    .NOTES
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/Disable-NexusRealm/',SupportsShouldProcess,ConfirmImpact = 'High')]
    Param(
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ArgumentCompleter( {
                param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

                $r = (Get-NexusRealm).name

                if ($WordToComplete) {
                    $r.Where($_ -match "^$WordToComplete")
                }
                else {
                    $r
                }
            }
        )]
        [Alias('Name')]
        [String[]]
        $Realm,

        [Parameter()]
        [Switch]
        $Force
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/security/realms/active"

    }

    process {

        $body = @((Get-NexusRealm -Active| Where-Object { $_.Name -notin $Realm }).id)

        try {
           
            if ($Force -and -not $Confirm) {
                $ConfirmPreference = 'None'
                if ($PSCmdlet.ShouldProcess("$_", "Remove Repository")) {
                    Write-Verbose $($Body | ConvertTo-Json)
                    Invoke-Nexus -UriSlug $urislug -BodyAsArray $Body -Method PUT -ErrorAction Stop
                    
                }
            }
            else {
                if ($PSCmdlet.ShouldProcess("$_", "Remove Repository")) {
                    Write-Verbose $($Body | ConvertTo-Json)
                    Invoke-Nexus -UriSlug $urislug -BodyAsArray $Body -Method PUT -ErrorAction Stop
                }
            }
        }

        catch {
            $_.exception.message
        }

    }
}
#EndRegion '.\public\Realm\Disable-NexusRealm.ps1' 83
#Region '.\public\Realm\Enable-NexusRealm.ps1' 0
function Enable-NexusRealm {
    <#
    .SYNOPSIS
    Enable realms in Nexus
     
    .DESCRIPTION
    Enable realms in Nexus
     
    .PARAMETER Realm
    The realms you wish to activate
     
    .EXAMPLE
    Enable-NexusRealm -Realm 'NuGet Api-Key Realm', 'Rut Auth Realm'
 
    .EXAMPLE
    Enable-NexusRealm -Realm 'LDAP Realm'
     
    .NOTES
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/Enable-NexusRealm/')]
    Param(
        [Parameter(Mandatory)]
        [ArgumentCompleter({
            param($Command,$Parameter,$WordToComplete,$CommandAst,$FakeBoundParams)

            $r = (Get-NexusRealm).name

            if($WordToComplete){
                $r.Where($_ -match "^$WordToComplete")
            } else {
                $r
            }
        }
        )]
        [String[]]
        $Realm
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/security/realms/active"

    }

    process {

        $collection = @()

        Get-NexusRealm -Active | ForEach-Object { $collection += $_.id }

        $Realm | Foreach-Object {

            switch($_){
                'Conan Bearer Token Realm' { $id = 'org.sonatype.repository.conan.internal.security.token.ConanTokenRealm' }
                'Default Role Realm' { $id = 'DefaultRole' }
                'Docker Bearer Token Realm' { $id = 'DockerToken' }
                'LDAP Realm' { $id = 'LdapRealm' }
                'Local Authentication Realm' { $id = 'NexusAuthenticatingRealm'}
                'Local Authorizing Realm' {$id = 'NexusAuthorizingRealm'}
                'npm Bearer Token Realm' {$id = 'NpmToken'}
                'NuGet API-Key Realm' { $id = 'NuGetApiKey'}
                'Rut Auth Realm' { $id = 'rutauth-realm'}
            }

            $collection += $id
    
        }

        $body = $collection

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -BodyAsArray $Body -Method PUT

    }
}
#EndRegion '.\public\Realm\Enable-NexusRealm.ps1' 80
#Region '.\public\Realm\Get-NexusRealm.ps1' 0
function Get-NexusRealm {
    <#
    .SYNOPSIS
    Gets Nexus Realm information
     
    .DESCRIPTION
    Gets Nexus Realm information
     
    .PARAMETER Active
    Returns only active realms
     
    .EXAMPLE
    Get-NexusRealm
 
    .EXAMPLE
    Get-NexusRealm -Active
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/Get-NexusRealm/')]
    Param(
        [Parameter()]
        [Switch]
        $Active
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        
        $urislug = "/service/rest/v1/security/realms/available"
        

    }

    process {

        if ($Active) {
            $current = Invoke-Nexus -UriSlug $urislug -Method 'GET'
            $urislug = '/service/rest/v1/security/realms/active'
            $Activated = Invoke-Nexus -UriSlug $urislug -Method 'GET'
            $current | Where-Object { $_.Id -in $Activated }
        }
        else {
            $result = Invoke-Nexus -UriSlug $urislug -Method 'GET' 

            $result | Foreach-Object {
                [pscustomobject]@{
                    Id   = $_.id
                    Name = $_.name
                }
            }
        }
    }
}
#EndRegion '.\public\Realm\Get-NexusRealm.ps1' 57
#Region '.\public\Repository\Get-NexusRepository.ps1' 0
function Get-NexusRepository {
    <#
    .SYNOPSIS
    Returns info about configured Nexus repository
     
    .DESCRIPTION
    Returns details for currently configured repositories on your Nexus server
     
    .PARAMETER Format
    Query for only a specific repository format. E.g. nuget, maven2, or docker
     
    .PARAMETER Name
    Query for a specific repository by name
     
    .EXAMPLE
    Get-NexusRepository
 
    .EXAMPLE
    Get-NexusRepository -Format nuget
 
    .EXAMPLE
    Get-NexusRepository -Name CompanyNugetPkgs
    #>

    [cmdletBinding(HelpUri='https://nexushell.dev/Get-NexusRepository/',DefaultParameterSetName="default")]
    param(
        [Parameter(ParameterSetName="Format",Mandatory)]
        [String]
        [ValidateSet('apt','bower','cocoapods','conan','conda','docker','gitlfs','go','helm','maven2','npm','nuget','p2','pypi','r','raw','rubygems','yum')]
        $Format,

        [Parameter(ParameterSetName="Type",Mandatory)]
        [String]
        [ValidateSet('hosted','group','proxy')]
        $Type,

        [Parameter(ParameterSetName="Name",Mandatory)]
        [String]
        $Name
    )


    begin {

        if(-not $header){
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories"
    }
    process {

        switch($PSCmdlet.ParameterSetName){
            {$Format} {
                $filter = { $_.format -eq $Format}

                $result = Invoke-Nexus -UriSlug $urislug -Method Get
                $result | Where-Object $filter
                
            }

            {$Name} {
                $filter = { $_.name -eq $Name }

                $result = Invoke-Nexus -UriSlug $urislug -Method Get
                $result | Where-Object $filter

            }

            {$Type} {
                $filter = { $_.type -eq $Type }
                $result = Invoke-Nexus -UriSlug $urislug -Method Get
                $result | Where-Object $filter
            }

            default {
                Invoke-Nexus -UriSlug $urislug -Method Get| ForEach-Object { 
                    [pscustomobject]@{
                        Name = $_.SyncRoot.name
                        Format = $_.SyncRoot.format
                        Type = $_.SyncRoot.type
                        Url = $_.SyncRoot.url
                        Attributes = $_.SyncRoot.attributes
                    }
                }
            }
        }
    }
}
#EndRegion '.\public\Repository\Get-NexusRepository.ps1' 89
#Region '.\public\Repository\New-NexusAptHostedRepository.ps1' 0
function New-NexusAptHostedRepository {
    <#
    .SYNOPSIS
    Creates a new Hosted Apt repository
     
    .DESCRIPTION
    Creates a new Hosted Apt repository
     
    .PARAMETER Name
    The name given to the repository
     
    .PARAMETER Distribution
    Distribution to fetch e.g. bionic
     
    .PARAMETER SigningKey
    PGP signing key pair (armored private key e.g. gpg --export-secret-key --armor )
     
    .PARAMETER SigningKeyPassphrase
    Passphrase to access PGP Signing Key
     
    .PARAMETER BlobStore
    Blob store used to store repository contents
     
    .PARAMETER StrictContentValidation
    Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
 
    .PARAMETER DeploymentPolicy
    Controls if deployments of and updates to artifacts are allowed
     
    .PARAMETER CleanupPolicy
    Components that match any of the Applied policies will be deleted
     
    .PARAMETER Online
    The repository accepts incoming requests
     
    .PARAMETER HasProprietaryComponents
    Components in this repository count as proprietary for namespace conflict attacks (requires Sonatype Nexus Firewall)
     
    .EXAMPLE
    $RepoParams = @{
        Name = 'AptPackages'
        Distribution = 'bionic'
        SigningKey = 'SuperSecretString'
        DeploymentPolicy = 'Allow_Once'
    }
     
    New-NexusAptHostedRepository @RepoParams
 
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/New-NexusAptHostedRepository/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter(Mandatory)]
        [String]
        $Distribution,

        [Parameter(Mandatory)]
        [String]
        $SigningKey,

        [Parameter()]
        [String]
        $SigningKeyPassphrase,

        [Parameter()]
        [String]
        $BlobStore = 'default',

        [Parameter()]
        [Switch]
        $StrictContentValidation,

        [Parameter(Mandatory)]
        [ValidateSet('Allow', 'Deny', 'Allow_Once')]
        [String]
        $DeploymentPolicy,

        [Parameter()]
        [String]
        $CleanupPolicy,

        [Parameter()]
        [Switch]
        $Online = $true,

        [Parameter()]
        [Switch]
        $HasProprietaryComponents
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories/apt/hosted"
    }
    process {
        $Body = @{
            name       = $Name
            online     = [bool]$Online
            apt        = @{
                distribution = $Distribution
            }
            aptSigning = @{
                keypair    = $SigningKey
                passprhase = $SigningKeyPassphrase
            }
            cleanup    = @{
                policyNames = @($CleanupPolicy )
            }
            storage    = @{
                strictContentTypeValidation = [bool]$StrictContentValidation
                blobStoreName               = $BlobStore
                writePolicy                 = $DeploymentPolicy.ToUpper()
            }
            component = @{
                proprietaryComponents = [bool]$HasProprietaryComponents
            }
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST

    }
}
#EndRegion '.\public\Repository\New-NexusAptHostedRepository.ps1' 130
#Region '.\public\Repository\New-NexusAptProxyRepository.ps1' 0
function New-NexusAptProxyRepository {
    <#
    .SYNOPSIS
    Creates a new Apt Proxy Repository
     
    .DESCRIPTION
    Creates a new Apt Proxy Repository
     
    .PARAMETER Name
    The name given to the repository
     
    .PARAMETER Distribution
    Distribution to fetch e.g. bionic
     
    .PARAMETER SigningKey
    PGP signing key pair (armored private key e.g. gpg --export-secret-key --armor )
     
    .PARAMETER SigningKeyPassphrase
    Passphrase to access PGP Signing Key
     
    .PARAMETER BlobStore
    Blob store used to store repository contents
     
    .PARAMETER UseStrictContentValidation
    Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
 
    .PARAMETER DeploymentPolicy
    Controls if deployments of and updates to artifacts are allowed
     
    .PARAMETER CleanupPolicy
    Components that match any of the Applied policies will be deleted
     
    .PARAMETER Online
    The repository accepts incoming requests
     
    .PARAMETER HasProprietaryComponents
    Components in this repository count as proprietary for namespace conflict attacks (requires Sonatype Nexus Firewall)
     
    .PARAMETER ProxyRemoteUrl
    Location of the remote repository being proxied
     
    .PARAMETER ContentMaxAgeMinutes
    How long (in minutes) to cache artifacts before rechecking the remote repository. Release repositories should use -1.
     
    .PARAMETER MetadataMaxAgeMinutes
    How long (in minutes) to cache metadata before rechecking the remote repository.
     
    .PARAMETER QueryCacheItemMaxAgSeconds
    How long to cache the fact that a file was not found in the repository (in minutes)
     
    .PARAMETER UseNegativeCache
    Cache responses for content not present in the proxied repository
 
    .PARAMETER NegativeCacheTTLMinutes
    How long to cache the fact that a file was not found in the repository (in minutes)
     
    .PARAMETER FlatUpstream
    Is this repository flat?
 
    .PARAMETER UseAuthentication
    Use authentication for the upstream repository
 
    .PARAMETER AuthenticationType
    The type of authentication required by the upstream repository
 
    .PARAMETER Credential
    Credentials to use to connecto to upstream repository
 
    .PARAMETER HostnameFqdn
    If using NTLM authentication, the Hostname of the NTLM host to query
 
    .PARAMETER DomainName
    The domain name of the NTLM host
 
    .PARAMETER BlockOutboundConnections
    Block outbound connections on the repository
 
    .PARAMETER EnableAutoBlocking
    Auto-block outbound connections on the repository if remote peer is detected as unreachable/unresponsive
 
    .PARAMETER ConnectionRetries
    Connection attempts to upstream repository before a failure
 
    .PARAMETER ConnectionTimeoutSeconds
    Amount of time to wait before retrying the connection to the upstream repository
 
    .PARAMETER EnableCircularRedirects
    Enable redirects to the same location (may be required by some servers)
 
    .PARAMETER EnableCookies
    Allow cookies to be stored and used
 
    .PARAMETER CustomUserAgent
    Custom fragment to append to "User-Agent" header in HTTP requests
 
    .EXAMPLE
    $RepoParams = @{
        Name = 'AptProxy'
        Distribution = 'bionic'
        SigningKey = 'SuperSecretKey'
        DeploymentPolicy = 'Allow_Once'
        ProxyUrl = 'https://upstream.deb.com'
    }
 
    New-NexusAptProxyRepository @RepoParams
     
    .NOTES
    General notes
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/New-NexusAptProxyRepository/',DefaultParameterSetName = 'Hosted')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter(Mandatory)]
        [String]
        $Distribution,

        [Parameter(Mandatory)]
        [String]
        $SigningKey,

        [Parameter()]
        [String]
        $SigningKeyPassphrase,

        [Parameter()]
        [String]
        $BlobStore = 'default',

        [Parameter()]
        [Switch]
        $UseStrictContentValidation,

        [Parameter(Mandatory)]
        [ValidateSet('Allow', 'Deny', 'Allow_Once')]
        [String]
        $DeploymentPolicy,

        [Parameter()]
        [String]
        $CleanupPolicy,

        [Parameter()]
        [Switch]
        $Online = $true,

        [Parameter()]
        [Switch]
        $HasProprietaryComponents,

        [Parameter(Mandatory)]
        [String]
        $ProxyRemoteUrl,

        [Parameter()]
        [String]
        $ContentMaxAgeMinutes = '1440',

        [Parameter()]
        [String]
        $MetadataMaxAgeMinutes = '1440',

        [Parameter()]
        [String]
        $QueryCacheItemMaxAgSeconds = '3600',

        [Parameter()]
        [Switch]
        $UseNegativeCache,

        [Parameter()]
        [String]
        $NegativeCacheTTLMinutes = '1440',

        [Parameter()]
        [Switch]
        $FlatUpstream = $true,

        [Parameter(ParameterSetName = "Authentication")]
        [Switch]
        $UseAuthentication,

        [Parameter(ParameterSetName = "Authentication", Mandatory)]
        [ValidateSet('Username', 'NTLM')]
        [String]
        $AuthenticationType,

        [Parameter(ParameterSetName = "Authentication", Mandatory)]
        [System.Management.Automation.PSCredential]
        $Credential,

        [Parameter(ParameterSetName = "Authentication")]
        [String]
        $HostnameFqdn,

        [Parameter(ParameterSetName = "Authentication")]
        [String]
        $DomainName,

        [Parameter()]
        [Switch]
        $BlockOutboundConnections = $false,

        [Parameter()]
        [Switch]
        $EnableAutoBlocking = $false,

        [Parameter()]
        [ValidateRange(0, 10)]
        [String]
        $ConnectionRetries,

        [Parameter()]
        [String]
        $ConnectionTimeoutSeconds,

        [Parameter()]
        [Switch]
        $EnableCircularRedirects = $false,

        [Parameter()]
        [Switch]
        $EnableCookies = $false,

        [Parameter()]
        [String]
        $CustomUserAgent

    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories/apt/proxy"

    }

    process {
        $Body = @{
            name          = $Name
            online        = [bool]$Online
            apt           = @{
                distribution = $Distribution
                flat = [bool]$FlatUpstream
            }
            aptSigning    = @{
                keypair    = $SigningKey
                passprhase = $SigningKeyPassphrase
            }
            cleanup       = @{
                policyNames = @($CleanupPolicy )
            }
            storage       = @{
                strictContentTypeValidation = [bool]$UseStrictContentValidation
                blobStoreName               = $BlobStore
                writePolicy                 = $($DeploymentPolicy.ToUpper())
            }
            proxy         = @{
                remoteUrl      = $ProxyRemoteUrl
                contentMaxAge  = $ContentMaxAgeMinutes
                metadataMaxAge = $MetadataMaxAgeMinutes
            }
            negativeCache = @{
                enabled    = [bool]$UseNegativeCache
                timeToLive = $NegativeCacheTTLMinutes

            }
            httpClient    = @{
                blocked   = [bool]$BlockOutboundConnections
                autoBlock = [bool]$EnableAutoBlocking 
            }
        }

        if ($UseAuthentication) {
            
            switch ($AuthenticationType) {
                'Username' {
                    $authentication = @{
                        type       = $AuthenticationType
                        username   = $Credential.UserName
                        password   = $Credential.GetNetworkCredential().Password
                        ntlmHost   = ''
                        ntlmDomain = ''
                    }
        
                    $body.httpClient.Add('authentication', $authentication)
                }

                'NTLM' {
                    if (-not $HostnameFqdn -and $DomainName) {
                        throw "Parameter HostnameFqdn and DomainName are required when using WindowsNTLM authentication"
                    }
                    else {
                        $authentication = @{
                            type       = $AuthenticationType
                            username   = $Credential.UserName
                            password   = $Credential.GetNetworkCredential().Password
                            ntlmHost   = $HostnameFqdn
                            ntlmDomain = $DomainName
                        }
                    }
       
                    $body.httpClient.Add('authentication', $authentication)
                }
            }
            
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST
    }
}
#EndRegion '.\public\Repository\New-NexusAptProxyRepository.ps1' 318
#Region '.\public\Repository\New-NexusBowerGroupRepository.ps1' 0
function New-NexusBowerGroupRepository {
    <#
    .SYNOPSIS
    Creates a Bower Group repository
     
    .DESCRIPTION
    Creates a Bower Group repository
     
    .PARAMETER Name
    The name of the repository
     
    .PARAMETER GroupMembers
    The Bower Repositories to add as group members
     
    .PARAMETER Online
    Marks the repository as online
     
    .PARAMETER BlobStore
    The blob store to attach to the repository
     
    .PARAMETER UseStrictContentTypeValidation
    Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
     
    .PARAMETER ContentDisposition
    Add Content-Disposition header as 'Attachment' to disable some content from being inline in a browser
     
    .PARAMETER DeploymentPolicy
    Required by the API, but thrown away by the underlying system. Use whatever you want here from the set
     
    .EXAMPLE
    New-NexusBowerGroupRepository -Name AllArtifacts -GroupMembers BinaryArtifacts,Documentation -DeploymentPolicy Allow
     
    .NOTES
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusBowerGroupRepository/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter(Mandatory)]
        [String[]]
        $GroupMembers,

        [Parameter()]
        [Switch]
        $Online = $true,

        [Parameter()]
        [String]
        $BlobStore = 'default',

        [Parameter()]
        [Switch]
        $UseStrictContentTypeValidation,

        [Parameter(Mandatory)]
        [ValidateSet('Allow', 'Deny', 'Allow_Once')]
        [String]
        $DeploymentPolicy = 'Allow_Once'
    )
    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories/bower/group"

    }

    process {

        $body = @{
            name    = $Name
            online  = [bool]$Online
            storage = @{
                blobStoreName               = $BlobStore
                strictContentTypeValidation = [bool]$UseStrictContentTypeValidation
                writePolicy                 = $DeploymentPolicy.ToLower()
            }
            group   = @{
                memberNames = $GroupMembers
            }
        }
        
        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST

    }

}
#EndRegion '.\public\Repository\New-NexusBowerGroupRepository.ps1' 93
#Region '.\public\Repository\New-NexusBowerHostedRepository.ps1' 0
function New-NexusBowerHostedRepository {
    <#
    .SYNOPSIS
    Creates a new Bower Hosted repository
     
    .DESCRIPTION
    Creates a new Bower Hosted repository
     
    .PARAMETER Name
    The name of the repository
     
    .PARAMETER CleanupPolicy
    The Cleanup Policies to apply to the repository
     
    .PARAMETER Online
    Marks the repository to accept incoming requests
     
    .PARAMETER BlobStoreName
    Blob store to use to store Bower packages
     
    .PARAMETER StrictContentValidation
    Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
     
    .PARAMETER DeploymentPolicy
    Controls if deployments of and updates to artifacts are allowed
     
    .PARAMETER HasProprietaryComponents
    Components in this repository count as proprietary for namespace conflict attacks (requires Sonatype Nexus Firewall)
     
    .EXAMPLE
    New-NexusBowerHostedRepository -Name BowerHostedTest -DeploymentPolicy Allow
 
    .EXAMPLE
 
    $RepoParams = @{
        Name = 'MyBowerRepo'
        CleanupPolicy = '90 Days'
        DeploymentPolicy = 'Allow'
        UseStrictContentValidation = $true
    }
     
    New-NexusBowerHostedRepository @RepoParams
 
    .NOTES
    General notes
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusBowerHostedRepository/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter()]
        [String]
        $CleanupPolicy,

        [Parameter()]
        [ValidateSet('True', 'False')]
        [String]
        $Online = 'True',

        [Parameter()]
        [String]
        $BlobStoreName = 'default',

        [Parameter()]
        [ValidateSet('True', 'False')]
        [String]
        $UseStrictContentValidation = 'True',

        [Parameter()]
        [ValidateSet('Allow', 'Deny', 'Allow_Once')]
        [String]
        $DeploymentPolicy,

        [Parameter()]
        [Switch]
        $HasProprietaryComponents
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories/bower/hosted"

    }

    process {
        $body = @{
            name    = $Name
            online  = $Online
            storage = @{
                blobStoreName               = $BlobStoreName
                strictContentTypeValidation = $UseStrictContentValidation
                writePolicy                 = $DeploymentPolicy
            }
            cleanup = @{
                policyNames = @($CleanupPolicy)
            }
        }

        if ($HasProprietaryComponents) {
            $Prop = @{
                proprietaryComponents = 'True'
            }
    
            $Body.Add('component', $Prop)
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST

    }
}
#EndRegion '.\public\Repository\New-NexusBowerHostedRepository.ps1' 118
#Region '.\public\Repository\New-NexusBowerProxyRepository.ps1' 0
function New-NexusBowerProxyRepository {
    <#
    .SYNOPSIS
    Creates a new Bower Proxy Repository
     
    .DESCRIPTION
    Creates a new Bower Proxy Repository
     
    .PARAMETER Name
    The name to give the repository
     
    .PARAMETER ProxyRemoteUrl
    Location of the remote repository being proxied, e.g. https://api.Bower.org/v3/index.json
     
    .PARAMETER RewritePackageUrls
    Whether to force Bower to retrieve packages through this proxy repository
 
    .PARAMETER ContentMaxAgeMinutes
    Time before cached content is refreshed. Defaults to 1440
     
    .PARAMETER MetadataMaxAgeMinutes
    Time before cached metadata is refreshed. Defaults to 1440
     
    .PARAMETER UseNegativeCache
    Use the built-in Negative Cache feature
     
    .PARAMETER NegativeCacheTTLMinutes
    The Negative Cache Time To Live value. Defaults to 1440
     
    .PARAMETER CleanupPolicy
    The Cleanup Policy to apply to this repository
     
    .PARAMETER RoutingRule
    Routing Rules you wish to apply to this repository
     
    .PARAMETER Online
    Mark the repository as Online. Defaults to True
     
    .PARAMETER BlobStoreName
    The back-end blob store in which to store cached packages
     
    .PARAMETER StrictContentValidation
    Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
     
    .PARAMETER DeploymentPolicy
    Controls whether packages can be overwritten
     
    .PARAMETER UseNexusTrustStore
    Use certificates stored in the Nexus truststore to connect to external systems
     
    .PARAMETER UseAuthentication
    Use authentication for the upstream repository
     
    .PARAMETER AuthenticationType
    The type of authentication required by the upstream repository
     
    .PARAMETER Credential
    Credentials to use to connecto to upstream repository
     
    .PARAMETER HostnameFqdn
    If using NTLM authentication, the Hostname of the NTLM host to query
     
    .PARAMETER DomainName
    The domain name of the NTLM host
     
    .PARAMETER BlockOutboundConnections
    Block outbound connections on the repository
     
    .PARAMETER EnableAutoBlocking
    Auto-block outbound connections on the repository if remote peer is detected as unreachable/unresponsive
     
    .PARAMETER ConnectionRetries
    Connection attempts to upstream repository before a failure
     
    .PARAMETER ConnectionTimeoutSeconds
    Amount of time to wait before retrying the connection to the upstream repository
     
    .PARAMETER EnableCircularRedirects
    Enable redirects to the same location (may be required by some servers)
     
    .PARAMETER EnableCookies
    Allow cookies to be stored and used
     
    .PARAMETER CustomUserAgent
    Custom fragment to append to "User-Agent" header in HTTP requests
     
    .EXAMPLE
     
    $ProxyParameters = @{
        Name = 'BowerProxy'
        ProxyRemoteUrl = 'https://upstream.bowerpkgs.com'
        DeploymentPolicy = 'Allow'
    }
     
    New-NexusBowerProxyRepository @ProxyParameters
     
    .EXAMPLE
     
    $ProxyParameters = @{
        Name = 'BowerProxy'
        ProxyRemoteUrl = 'https://upstream.bowerpkgs.com'
        DeploymentPolicy = 'Allow'
        UseAuthentication = $true
        AuthenticationType = 'Username'
        Credential = (Get-Credential)
     
    }
     
    New-NexusBowerProxyRepository @ProxyParameters
    #>

        [CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusBowerProxyRepository/',DefaultParameterSetname="Default")]
        Param(
            [Parameter(Mandatory)]
            [String]
            $Name,
    
            [Parameter(Mandatory)]
            [String]
            $ProxyRemoteUrl,

            [Parameter()]
            [Switch]
            $RewritePackageUrls,
    
            [Parameter()]
            [String]
            $ContentMaxAgeMinutes = '1440',
    
            [Parameter()]
            [String]
            $MetadataMaxAgeMinutes = '1440',
        
            [Parameter()]
            [Switch]
            $UseNegativeCache,
    
            [Parameter()]
            [String]
            $NegativeCacheTTLMinutes = '1440',
    
            [Parameter()]
            [String]
            $CleanupPolicy,
    
            [Parameter()]
            [String]
            $RoutingRule,
    
            [Parameter()]
            [Switch]
            $Online = $true,
    
            [Parameter()]
            [String]
            $BlobStoreName = 'default',
    
            [Parameter()]
            [Switch]
            $StrictContentValidation = $true,
    
            [Parameter()]
            [ValidateSet('Allow', 'Deny', 'Allow_Once')]
            [String]
            $DeploymentPolicy,
    
            [Parameter()]
            [Switch]
            $UseNexusTrustStore = $false,
    
            [Parameter(ParameterSetName = "Authentication")]
            [Switch]
            $UseAuthentication,
    
            [Parameter(ParameterSetName = "Authentication", Mandatory)]
            [ValidateSet('Username', 'NTLM')]
            [String]
            $AuthenticationType,
    
            [Parameter(ParameterSetName = "Authentication", Mandatory)]
            [System.Management.Automation.PSCredential]
            $Credential,
    
            [Parameter(ParameterSetName = "Authentication")]
            [String]
            $HostnameFqdn,
    
            [Parameter(ParameterSetName = "Authentication")]
            [String]
            $DomainName,
    
            [Parameter()]
            [Switch]
            $BlockOutboundConnections = $false,
    
            [Parameter()]
            [Switch]
            $EnableAutoBlocking = $false,
    
            [Parameter()]
            [ValidateRange(0,10)]
            [String]
            $ConnectionRetries,
    
            [Parameter()]
            [String]
            $ConnectionTimeoutSeconds,
    
            [Parameter()]
            [Switch]
            $EnableCircularRedirects = $false,
    
            [Parameter()]
            [Switch]
            $EnableCookies = $false,
    
            [Parameter()]
            [String]
            $CustomUserAgent
        )
        begin {
    
            if (-not $header) {
                throw "Not connected to Nexus server! Run Connect-NexusServer first."
            }
    
            $urislug = "/service/rest/v1/repositories/bower/proxy"
    
        }
        process {
        
            $body = @{
                name          = $Name
                online        = [bool]$Online
                storage       = @{
                    blobStoreName               = $BlobStoreName
                    strictContentTypeValidation = [bool]$StrictContentValidation
                    writePolicy                 = $DeploymentPolicy
                }
                cleanup       = @{
                    policyNames = @($CleanupPolicy)
                }
                proxy         = @{
                    remoteUrl      = $ProxyRemoteUrl
                    contentMaxAge  = $ContentMaxAgeMinutes
                    metadataMaxAge = $MetadataMaxAgeMinutes
                }
    
                negativeCache = @{
                    enabled    = [bool]$UseNegativeCache
                    timeToLive = $NegativeCacheTTLMinutes
                }

                bower = @{
                    rewritePackageUrls = [bool]$RewritePackageUrls
                }
    
                httpClient    = @{
                    blocked    = [bool]$BlockOutboundConnections
                    autoBlock  = [bool]$EnableAutoBlocking
                    connection = @{
                        retries                 = $ConnectionRetries
                        userAgentSuffix         = $CustomUserAgent
                        timeout                 = $ConnectionTimeoutSeconds
                        enableCircularRedirects = [bool]$EnableCircularRedirects
                        enableCookies           = [bool]$EnableCookies
                        useTrustStore           = [bool]$UseNexusTrustStore
                    }
                }
        
            }
    
            if ($UseAuthentication) {
                
                switch($AuthenticationType){
                    'Username' {
                        $authentication = @{
                            type       = $AuthenticationType.ToLower()
                            username   = $Credential.UserName
                            password   = $Credential.GetNetworkCredential().Password
                            ntlmHost = ''
                            ntlmDomain = ''
                        }
            
                        $body.httpClient.Add('authentication', $authentication)
                    }
    
                    'NTLM' {
                        if(-not $HostnameFqdn -and $DomainName){
                            throw "Parameter HostnameFqdn and DomainName are required when using WindowsNTLM authentication"
                        } else {
                            $authentication = @{
                                type       = $AuthenticationType
                                username   = $Credential.UserName
                                password   = $Credential.GetNetworkCredential().Password
                                ntlmHost   = $HostnameFqdn
                                ntlmDomain = $DomainName
                            }
                        }
           
                        $body.httpClient.Add('authentication', $authentication)
                    }
                }
                
            }
    
            Write-Verbose $($Body | ConvertTo-Json)
            Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST
    
        }
    }
#EndRegion '.\public\Repository\New-NexusBowerProxyRepository.ps1' 311
#Region '.\public\Repository\New-NexusCocoaPodProxyRepository.ps1' 0
function New-NexusCocoaPodProxyRepository {
        <#
    .SYNOPSIS
    Creates a new CocoaPod Proxy Repository
     
    .DESCRIPTION
    Creates a new CocoaPod Proxy Repository
     
    .PARAMETER Name
    The name to give the repository
     
    .PARAMETER ProxyRemoteUrl
    Location of the remote repository being proxied, e.g. https://api.CocoaPod.org/v3/index.json
     
    .PARAMETER ContentMaxAgeMinutes
    Time before cached content is refreshed. Defaults to 1440
     
    .PARAMETER MetadataMaxAgeMinutes
    Time before cached metadata is refreshed. Defaults to 1440
     
    .PARAMETER UseNegativeCache
    Use the built-in Negative Cache feature
     
    .PARAMETER NegativeCacheTTLMinutes
    The Negative Cache Time To Live value. Defaults to 1440
     
    .PARAMETER CleanupPolicy
    The Cleanup Policy to apply to this repository
     
    .PARAMETER RoutingRule
    Routing Rules you wish to apply to this repository
     
    .PARAMETER Online
    Mark the repository as Online. Defaults to True
     
    .PARAMETER BlobStoreName
    The back-end blob store in which to store cached packages
     
    .PARAMETER StrictContentValidation
    Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
     
    .PARAMETER DeploymentPolicy
    Controls whether packages can be overwritten
     
    .PARAMETER UseNexusTrustStore
    Use certificates stored in the Nexus truststore to connect to external systems
     
    .PARAMETER UseAuthentication
    Use authentication for the upstream repository
     
    .PARAMETER AuthenticationType
    The type of authentication required by the upstream repository
     
    .PARAMETER Credential
    Credentials to use to connecto to upstream repository
     
    .PARAMETER HostnameFqdn
    If using NTLM authentication, the Hostname of the NTLM host to query
     
    .PARAMETER DomainName
    The domain name of the NTLM host
     
    .PARAMETER BlockOutboundConnections
    Block outbound connections on the repository
     
    .PARAMETER EnableAutoBlocking
    Auto-block outbound connections on the repository if remote peer is detected as unreachable/unresponsive
     
    .PARAMETER ConnectionRetries
    Connection attempts to upstream repository before a failure
     
    .PARAMETER ConnectionTimeoutSeconds
    Amount of time to wait before retrying the connection to the upstream repository
     
    .PARAMETER EnableCircularRedirects
    Enable redirects to the same location (may be required by some servers)
     
    .PARAMETER EnableCookies
    Allow cookies to be stored and used
     
    .PARAMETER CustomUserAgent
    Custom fragment to append to "User-Agent" header in HTTP requests
     
    .EXAMPLE
     
    $ProxyParameters = @{
        Name = 'CocoaPodProxy'
        ProxyRemoteUrl = 'https://upstream.CocoaPodpkgs.com'
        DeploymentPolicy = 'Allow'
    }
     
    New-NexusCocoaPodProxyRepository @ProxyParameters
     
    .EXAMPLE
     
    $ProxyParameters = @{
        Name = 'CocoaPodProxy'
        ProxyRemoteUrl = 'https://upstream.CocoaPodpkgs.com'
        DeploymentPolicy = 'Allow'
        UseAuthentication = $true
        AuthenticationType = 'Username'
        Credential = (Get-Credential)
     
    }
     
    New-NexusCocoaPodProxyRepository @ProxyParameters
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusCocoaPodProxyRepository/',DefaultParameterSetname="Default")]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter(Mandatory)]
        [String]
        $ProxyRemoteUrl,

        [Parameter()]
        [String]
        $ContentMaxAgeMinutes = '1440',

        [Parameter()]
        [String]
        $MetadataMaxAgeMinutes = '1440',
    
        [Parameter()]
        [Switch]
        $UseNegativeCache,

        [Parameter()]
        [String]
        $NegativeCacheTTLMinutes = '1440',

        [Parameter()]
        [String]
        $CleanupPolicy,

        [Parameter()]
        [String]
        $RoutingRule,

        [Parameter()]
        [Switch]
        $Online = $true,

        [Parameter()]
        [String]
        $BlobStoreName = 'default',

        [Parameter()]
        [Switch]
        $StrictContentValidation = $true,

        [Parameter()]
        [ValidateSet('Allow', 'Deny', 'Allow_Once')]
        [String]
        $DeploymentPolicy,

        [Parameter()]
        [Switch]
        $UseNexusTrustStore = $false,

        [Parameter(ParameterSetName = "Authentication")]
        [Switch]
        $UseAuthentication,

        [Parameter(ParameterSetName = "Authentication", Mandatory)]
        [ValidateSet('Username', 'NTLM')]
        [String]
        $AuthenticationType,

        [Parameter(ParameterSetName = "Authentication", Mandatory)]
        [System.Management.Automation.PSCredential]
        $Credential,

        [Parameter(ParameterSetName = "Authentication")]
        [String]
        $HostnameFqdn,

        [Parameter(ParameterSetName = "Authentication")]
        [String]
        $DomainName,

        [Parameter()]
        [Switch]
        $BlockOutboundConnections = $false,

        [Parameter()]
        [Switch]
        $EnableAutoBlocking = $false,

        [Parameter()]
        [ValidateRange(0,10)]
        [String]
        $ConnectionRetries,

        [Parameter()]
        [String]
        $ConnectionTimeoutSeconds,

        [Parameter()]
        [Switch]
        $EnableCircularRedirects = $false,

        [Parameter()]
        [Switch]
        $EnableCookies = $false,

        [Parameter()]
        [String]
        $CustomUserAgent
    )
    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories/cocoapods/proxy"

    }
    process {
    
        $body = @{
            name          = $Name
            online        = [bool]$Online
            storage       = @{
                blobStoreName               = $BlobStoreName
                strictContentTypeValidation = [bool]$StrictContentValidation
                writePolicy                 = $DeploymentPolicy
            }
            cleanup       = @{
                policyNames = @($CleanupPolicy)
            }
            proxy         = @{
                remoteUrl      = $ProxyRemoteUrl
                contentMaxAge  = $ContentMaxAgeMinutes
                metadataMaxAge = $MetadataMaxAgeMinutes
            }
            negativeCache = @{
                enabled    = [bool]$UseNegativeCache
                timeToLive = $NegativeCacheTTLMinutes
            }
            routingRule = $RoutingRule
            httpClient    = @{
                blocked    = [bool]$BlockOutboundConnections
                autoBlock  = [bool]$EnableAutoBlocking
                connection = @{
                    retries                 = $ConnectionRetries
                    userAgentSuffix         = $CustomUserAgent
                    timeout                 = $ConnectionTimeoutSeconds
                    enableCircularRedirects = [bool]$EnableCircularRedirects
                    enableCookies           = [bool]$EnableCookies
                    useTrustStore           = [bool]$UseNexusTrustStore
                }
            }
    
        }

        if ($UseAuthentication) {
            
            switch($AuthenticationType){
                'Username' {
                    $authentication = @{
                        type       = $AuthenticationType.ToLower()
                        username   = $Credential.UserName
                        password   = $Credential.GetNetworkCredential().Password
                        ntlmHost = ''
                        ntlmDomain = ''
                    }
        
                    $body.httpClient.Add('authentication', $authentication)
                }

                'NTLM' {
                    if(-not $HostnameFqdn -and $DomainName){
                        throw "Parameter HostnameFqdn and DomainName are required when using WindowsNTLM authentication"
                    } else {
                        $authentication = @{
                            type       = $AuthenticationType
                            username   = $Credential.UserName
                            password   = $Credential.GetNetworkCredential().Password
                            ntlmHost   = $HostnameFqdn
                            ntlmDomain = $DomainName
                        }
                    }
       
                    $body.httpClient.Add('authentication', $authentication)
                }
            }
            
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST

    }

}
#EndRegion '.\public\Repository\New-NexusCocoaPodProxyRepository.ps1' 300
#Region '.\public\Repository\New-NexusConanProxyRepository.ps1' 0
function New-NexusConanProxyRepository {
    <#
.SYNOPSIS
Creates a new Conan Proxy Repository
 
.DESCRIPTION
Creates a new Conan Proxy Repository
 
.PARAMETER Name
The name to give the repository
 
.PARAMETER ProxyRemoteUrl
Location of the remote repository being proxied, e.g. https://api.Conan.org/v3/index.json
 
.PARAMETER ContentMaxAgeMinutes
Time before cached content is refreshed. Defaults to 1440
 
.PARAMETER MetadataMaxAgeMinutes
Time before cached metadata is refreshed. Defaults to 1440
 
.PARAMETER UseNegativeCache
Use the built-in Negative Cache feature
 
.PARAMETER NegativeCacheTTLMinutes
The Negative Cache Time To Live value. Defaults to 1440
 
.PARAMETER CleanupPolicy
The Cleanup Policy to apply to this repository
 
.PARAMETER RoutingRule
Routing Rules you wish to apply to this repository
 
.PARAMETER Online
Mark the repository as Online. Defaults to True
 
.PARAMETER BlobStoreName
The back-end blob store in which to store cached packages
 
.PARAMETER StrictContentValidation
Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
 
.PARAMETER DeploymentPolicy
Controls whether packages can be overwritten
 
.PARAMETER UseNexusTrustStore
Use certificates stored in the Nexus truststore to connect to external systems
 
.PARAMETER UseAuthentication
Use authentication for the upstream repository
 
.PARAMETER AuthenticationType
The type of authentication required by the upstream repository
 
.PARAMETER Credential
Credentials to use to connecto to upstream repository
 
.PARAMETER HostnameFqdn
If using NTLM authentication, the Hostname of the NTLM host to query
 
.PARAMETER DomainName
The domain name of the NTLM host
 
.PARAMETER BlockOutboundConnections
Block outbound connections on the repository
 
.PARAMETER EnableAutoBlocking
Auto-block outbound connections on the repository if remote peer is detected as unreachable/unresponsive
 
.PARAMETER ConnectionRetries
Connection attempts to upstream repository before a failure
 
.PARAMETER ConnectionTimeoutSeconds
Amount of time to wait before retrying the connection to the upstream repository
 
.PARAMETER EnableCircularRedirects
Enable redirects to the same location (may be required by some servers)
 
.PARAMETER EnableCookies
Allow cookies to be stored and used
 
.PARAMETER CustomUserAgent
Custom fragment to append to "User-Agent" header in HTTP requests
 
.EXAMPLE
 
$ProxyParameters = @{
    Name = 'ConanProxy'
    ProxyRemoteUrl = 'https://upstream.Conanpkgs.com'
    DeploymentPolicy = 'Allow'
}
 
New-NexusConanProxyRepository @ProxyParameters
 
.EXAMPLE
 
$ProxyParameters = @{
    Name = 'ConanProxy'
    ProxyRemoteUrl = 'https://upstream.Conanpkgs.com'
    DeploymentPolicy = 'Allow'
    UseAuthentication = $true
    AuthenticationType = 'Username'
    Credential = (Get-Credential)
 
}
 
New-NexusConanProxyRepository @ProxyParameters
#>

[CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusConanProxyRepository/',DefaultParameterSetname="Default")]
Param(
    [Parameter(Mandatory)]
    [String]
    $Name,

    [Parameter(Mandatory)]
    [String]
    $ProxyRemoteUrl,

    [Parameter()]
    [String]
    $ContentMaxAgeMinutes = '1440',

    [Parameter()]
    [String]
    $MetadataMaxAgeMinutes = '1440',

    [Parameter()]
    [Switch]
    $UseNegativeCache,

    [Parameter()]
    [String]
    $NegativeCacheTTLMinutes = '1440',

    [Parameter()]
    [String]
    $CleanupPolicy,

    [Parameter()]
    [String]
    $RoutingRule,

    [Parameter()]
    [Switch]
    $Online = $true,

    [Parameter()]
    [String]
    $BlobStoreName = 'default',

    [Parameter()]
    [Switch]
    $StrictContentValidation = $true,

    [Parameter()]
    [ValidateSet('Allow', 'Deny', 'Allow_Once')]
    [String]
    $DeploymentPolicy,

    [Parameter()]
    [Switch]
    $UseNexusTrustStore = $false,

    [Parameter(ParameterSetName = "Authentication")]
    [Switch]
    $UseAuthentication,

    [Parameter(ParameterSetName = "Authentication", Mandatory)]
    [ValidateSet('Username', 'NTLM')]
    [String]
    $AuthenticationType,

    [Parameter(ParameterSetName = "Authentication", Mandatory)]
    [System.Management.Automation.PSCredential]
    $Credential,

    [Parameter(ParameterSetName = "Authentication")]
    [String]
    $HostnameFqdn,

    [Parameter(ParameterSetName = "Authentication")]
    [String]
    $DomainName,

    [Parameter()]
    [Switch]
    $BlockOutboundConnections = $false,

    [Parameter()]
    [Switch]
    $EnableAutoBlocking = $false,

    [Parameter()]
    [ValidateRange(0,10)]
    [String]
    $ConnectionRetries,

    [Parameter()]
    [String]
    $ConnectionTimeoutSeconds,

    [Parameter()]
    [Switch]
    $EnableCircularRedirects = $false,

    [Parameter()]
    [Switch]
    $EnableCookies = $false,

    [Parameter()]
    [String]
    $CustomUserAgent
)
begin {

    if (-not $header) {
        throw "Not connected to Nexus server! Run Connect-NexusServer first."
    }

    $urislug = "/service/rest/v1/repositories/conan/proxy"

}
process {

    $body = @{
        name          = $Name
        online        = [bool]$Online
        storage       = @{
            blobStoreName               = $BlobStoreName
            strictContentTypeValidation = [bool]$StrictContentValidation
            writePolicy                 = $DeploymentPolicy
        }
        cleanup       = @{
            policyNames = @($CleanupPolicy)
        }
        proxy         = @{
            remoteUrl      = $ProxyRemoteUrl
            contentMaxAge  = $ContentMaxAgeMinutes
            metadataMaxAge = $MetadataMaxAgeMinutes
        }
        negativeCache = @{
            enabled    = [bool]$UseNegativeCache
            timeToLive = $NegativeCacheTTLMinutes
        }
        routingRule = $RoutingRule
        httpClient    = @{
            blocked    = [bool]$BlockOutboundConnections
            autoBlock  = [bool]$EnableAutoBlocking
            connection = @{
                retries                 = $ConnectionRetries
                userAgentSuffix         = $CustomUserAgent
                timeout                 = $ConnectionTimeoutSeconds
                enableCircularRedirects = [bool]$EnableCircularRedirects
                enableCookies           = [bool]$EnableCookies
                useTrustStore           = [bool]$UseNexusTrustStore
            }
        }

    }

    if ($UseAuthentication) {
        
        switch($AuthenticationType){
            'Username' {
                $authentication = @{
                    type       = $AuthenticationType.ToLower()
                    username   = $Credential.UserName
                    password   = $Credential.GetNetworkCredential().Password
                    ntlmHost = ''
                    ntlmDomain = ''
                }
    
                $body.httpClient.Add('authentication', $authentication)
            }

            'NTLM' {
                if(-not $HostnameFqdn -and $DomainName){
                    throw "Parameter HostnameFqdn and DomainName are required when using WindowsNTLM authentication"
                } else {
                    $authentication = @{
                        type       = $AuthenticationType
                        username   = $Credential.UserName
                        password   = $Credential.GetNetworkCredential().Password
                        ntlmHost   = $HostnameFqdn
                        ntlmDomain = $DomainName
                    }
                }
   
                $body.httpClient.Add('authentication', $authentication)
            }
        }
        
    }

    Write-Verbose $($Body | ConvertTo-Json)
    Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST

}

}
#EndRegion '.\public\Repository\New-NexusConanProxyRepository.ps1' 300
#Region '.\public\Repository\New-NexusCondaProxyRepository.ps1' 0
function New-NexusCondaProxyRepository {
    <#
.SYNOPSIS
Creates a new Conda Proxy Repository
 
.DESCRIPTION
Creates a new Conda Proxy Repository
 
.PARAMETER Name
The name to give the repository
 
.PARAMETER ProxyRemoteUrl
Location of the remote repository being proxied, e.g. https://api.Conda.org/v3/index.json
 
.PARAMETER ContentMaxAgeMinutes
Time before cached content is refreshed. Defaults to 1440
 
.PARAMETER MetadataMaxAgeMinutes
Time before cached metadata is refreshed. Defaults to 1440
 
.PARAMETER UseNegativeCache
Use the built-in Negative Cache feature
 
.PARAMETER NegativeCacheTTLMinutes
The Negative Cache Time To Live value. Defaults to 1440
 
.PARAMETER CleanupPolicy
The Cleanup Policy to apply to this repository
 
.PARAMETER RoutingRule
Routing Rules you wish to apply to this repository
 
.PARAMETER Online
Mark the repository as Online. Defaults to True
 
.PARAMETER BlobStoreName
The back-end blob store in which to store cached packages
 
.PARAMETER StrictContentValidation
Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
 
.PARAMETER DeploymentPolicy
Controls whether packages can be overwritten
 
.PARAMETER UseNexusTrustStore
Use certificates stored in the Nexus truststore to connect to external systems
 
.PARAMETER UseAuthentication
Use authentication for the upstream repository
 
.PARAMETER AuthenticationType
The type of authentication required by the upstream repository
 
.PARAMETER Credential
Credentials to use to connecto to upstream repository
 
.PARAMETER HostnameFqdn
If using NTLM authentication, the Hostname of the NTLM host to query
 
.PARAMETER DomainName
The domain name of the NTLM host
 
.PARAMETER BlockOutboundConnections
Block outbound connections on the repository
 
.PARAMETER EnableAutoBlocking
Auto-block outbound connections on the repository if remote peer is detected as unreachable/unresponsive
 
.PARAMETER ConnectionRetries
Connection attempts to upstream repository before a failure
 
.PARAMETER ConnectionTimeoutSeconds
Amount of time to wait before retrying the connection to the upstream repository
 
.PARAMETER EnableCircularRedirects
Enable redirects to the same location (may be required by some servers)
 
.PARAMETER EnableCookies
Allow cookies to be stored and used
 
.PARAMETER CustomUserAgent
Custom fragment to append to "User-Agent" header in HTTP requests
 
.EXAMPLE
 
$ProxyParameters = @{
    Name = 'CondaProxy'
    ProxyRemoteUrl = 'https://upstream.Condapkgs.com'
    DeploymentPolicy = 'Allow'
}
 
New-NexusCondaProxyRepository @ProxyParameters
 
.EXAMPLE
 
$ProxyParameters = @{
    Name = 'CondaProxy'
    ProxyRemoteUrl = 'https://upstream.Condapkgs.com'
    DeploymentPolicy = 'Allow'
    UseAuthentication = $true
    AuthenticationType = 'Username'
    Credential = (Get-Credential)
 
}
 
New-NexusCondaProxyRepository @ProxyParameters
#>

[CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusCondaProxyRepository/',DefaultParameterSetname="Default")]
Param(
    [Parameter(Mandatory)]
    [String]
    $Name,

    [Parameter(Mandatory)]
    [String]
    $ProxyRemoteUrl,

    [Parameter()]
    [String]
    $ContentMaxAgeMinutes = '1440',

    [Parameter()]
    [String]
    $MetadataMaxAgeMinutes = '1440',

    [Parameter()]
    [Switch]
    $UseNegativeCache,

    [Parameter()]
    [String]
    $NegativeCacheTTLMinutes = '1440',

    [Parameter()]
    [String]
    $CleanupPolicy,

    [Parameter()]
    [String]
    $RoutingRule,

    [Parameter()]
    [Switch]
    $Online = $true,

    [Parameter()]
    [String]
    $BlobStoreName = 'default',

    [Parameter()]
    [Switch]
    $StrictContentValidation = $true,

    [Parameter()]
    [ValidateSet('Allow', 'Deny', 'Allow_Once')]
    [String]
    $DeploymentPolicy,

    [Parameter()]
    [Switch]
    $UseNexusTrustStore = $false,

    [Parameter(ParameterSetName = "Authentication")]
    [Switch]
    $UseAuthentication,

    [Parameter(ParameterSetName = "Authentication", Mandatory)]
    [ValidateSet('Username', 'NTLM')]
    [String]
    $AuthenticationType,

    [Parameter(ParameterSetName = "Authentication", Mandatory)]
    [System.Management.Automation.PSCredential]
    $Credential,

    [Parameter(ParameterSetName = "Authentication")]
    [String]
    $HostnameFqdn,

    [Parameter(ParameterSetName = "Authentication")]
    [String]
    $DomainName,

    [Parameter()]
    [Switch]
    $BlockOutboundConnections = $false,

    [Parameter()]
    [Switch]
    $EnableAutoBlocking = $false,

    [Parameter()]
    [ValidateRange(0,10)]
    [String]
    $ConnectionRetries,

    [Parameter()]
    [String]
    $ConnectionTimeoutSeconds,

    [Parameter()]
    [Switch]
    $EnableCircularRedirects = $false,

    [Parameter()]
    [Switch]
    $EnableCookies = $false,

    [Parameter()]
    [String]
    $CustomUserAgent
)
begin {

    if (-not $header) {
        throw "Not connected to Nexus server! Run Connect-NexusServer first."
    }

    $urislug = "/service/rest/v1/repositories/conda/proxy"

}
process {

    $body = @{
        name          = $Name
        online        = [bool]$Online
        storage       = @{
            blobStoreName               = $BlobStoreName
            strictContentTypeValidation = [bool]$StrictContentValidation
            writePolicy                 = $DeploymentPolicy
        }
        cleanup       = @{
            policyNames = @($CleanupPolicy)
        }
        proxy         = @{
            remoteUrl      = $ProxyRemoteUrl
            contentMaxAge  = $ContentMaxAgeMinutes
            metadataMaxAge = $MetadataMaxAgeMinutes
        }
        negativeCache = @{
            enabled    = [bool]$UseNegativeCache
            timeToLive = $NegativeCacheTTLMinutes
        }
        routingRule = $RoutingRule
        httpClient    = @{
            blocked    = [bool]$BlockOutboundConnections
            autoBlock  = [bool]$EnableAutoBlocking
            connection = @{
                retries                 = $ConnectionRetries
                userAgentSuffix         = $CustomUserAgent
                timeout                 = $ConnectionTimeoutSeconds
                enableCircularRedirects = [bool]$EnableCircularRedirects
                enableCookies           = [bool]$EnableCookies
                useTrustStore           = [bool]$UseNexusTrustStore
            }
        }

    }

    if ($UseAuthentication) {
        
        switch($AuthenticationType){
            'Username' {
                $authentication = @{
                    type       = $AuthenticationType.ToLower()
                    username   = $Credential.UserName
                    password   = $Credential.GetNetworkCredential().Password
                    ntlmHost = ''
                    ntlmDomain = ''
                }
    
                $body.httpClient.Add('authentication', $authentication)
            }

            'NTLM' {
                if(-not $HostnameFqdn -and $DomainName){
                    throw "Parameter HostnameFqdn and DomainName are required when using WindowsNTLM authentication"
                } else {
                    $authentication = @{
                        type       = $AuthenticationType
                        username   = $Credential.UserName
                        password   = $Credential.GetNetworkCredential().Password
                        ntlmHost   = $HostnameFqdn
                        ntlmDomain = $DomainName
                    }
                }
   
                $body.httpClient.Add('authentication', $authentication)
            }
        }
        
    }

    Write-Verbose $($Body | ConvertTo-Json)
    Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST

}

}
#EndRegion '.\public\Repository\New-NexusCondaProxyRepository.ps1' 300
#Region '.\public\Repository\New-NexusDockerGroupRepository.ps1' 0
function New-NexusDockerGroupRepository {
    <#
    .SYNOPSIS
    Creates a new Docker Group repository
 
    .DESCRIPTION
    Creates a new Docker Group repository
     
    .PARAMETER Name
    The name of the repository
     
    .PARAMETER Online
    Marks the repository to accept incoming requests
     
    .PARAMETER BlobStoreName
    Blob store to use to store Docker packages
     
    .PARAMETER StrictContentValidation
    Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
     
    .PARAMETER EnableV1
    Whether to allow clients to use the V1 API to interact with this repository
     
    .PARAMETER ForceBasicAuth
    Whether to force authentication (Docker Bearer Token Realm required if false)
     
    .PARAMETER HttpPort
    Create an HTTP connector at specified port
     
    .PARAMETER HttpsPort
    Create an HTTPS connector at specified port
     
    .EXAMPLE
    New-NexusDockerGroupRepository -Name DockerGroup -GroupMembers DockerHostedLinux,DockerProd -Online
     
    .NOTES
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusDockerGroupRepository/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter(Mandatory)]
        [String[]]
        $GroupMembers,

        [Parameter()]
        [String]
        $WritableMember,

        [Parameter()]
        [Switch]
        $Online = $true,

        [Parameter()]
        [String]
        $BlobStoreName = 'default',

        [Parameter()]
        [Switch]
        $UseStrictContentTypeValidation,

        [Parameter()]
        [Switch]
        $EnableV1,

        [Parameter()]
        [Switch]
        $ForceBasicAuth,

        [Parameter()]
        [String]
        $HttpPort,
        
        [Parameter()]
        [String]
        $HttpsPort
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    
        $urislug = "/service/rest/v1/repositories/docker/group"
    
    }

    process {

        $body = @{
            name    = $Name
            online  = [bool]$Online
            storage = @{
                blobStoreName               = $BlobStoreName
                strictContentTypeValidation = [bool]$UseStrictContentValidation
            }
            group   = @{
                memberNames = $GroupMembers
                writableMember = $WritableMember
            }
            docker = @{
                v1Enabled = [bool]$EnableV1
                forceBasicAuth = [bool]$ForceBasicAuth
                httpPort = $HttpPort
                httpsPort = $HttpsPort
            }
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST

        if($ForceBasicAuth -eq $false){
            Write-Warning "Docker Bearer Token Realm required since -ForceBasicAuth was not passed."
            Write-Warning "Use Add-NexusRealm to enable if desired."
        }


    }

}
#EndRegion '.\public\Repository\New-NexusDockerGroupRepository.ps1' 124
#Region '.\public\Repository\New-NexusDockerHostedRepository.ps1' 0
function New-NexusDockerHostedRepository {
    <#
    .SYNOPSIS
    Creates a new Docker Hosted repository
     
    .DESCRIPTION
    Creates a new Docker Hosted repository
     
    .PARAMETER Name
    The name of the repository
     
    .PARAMETER CleanupPolicy
    The Cleanup Policies to apply to the repository
     
    .PARAMETER Online
    Marks the repository to accept incoming requests
     
    .PARAMETER BlobStoreName
    Blob store to use to store Docker packages
     
    .PARAMETER StrictContentValidation
    Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
     
    .PARAMETER DeploymentPolicy
    Controls if deployments of and updates to artifacts are allowed
     
    .PARAMETER HasProprietaryComponents
    Components in this repository count as proprietary for namespace conflict attacks (requires Sonatype Nexus Firewall)
     
    .PARAMETER EnableV1
    Whether to allow clients to use the V1 API to interact with this repository
     
    .PARAMETER ForceBasicAuth
    Whether to force authentication (Docker Bearer Token Realm required if false)
     
    .PARAMETER HttpPort
    Create an HTTP connector at specified port
     
    .PARAMETER HttpsPort
    Create an HTTPS connector at specified port
     
    .EXAMPLE
    New-NexusDockerHostedRepository -Name DockerHostedTest -DeploymentPolicy Allow -EnableV1 -ForceBasicAuth
 
    .EXAMPLE
 
    $RepoParams = @{
        Name = MyDockerRepo
        CleanupPolicy = '90 Days'
        DeploymentPolicy = 'Allow'
        UseStrictContentValidation = $true
        ForceBasicAuth = $true
        HttpPort = '8082'
        EnableV1 = $true
    }
     
    New-NexusDockerHostedRepository @RepoParams
 
     
    .NOTES
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusDockerHostedRepository/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter()]
        [String]
        $CleanupPolicy,

        [Parameter()]
        [Switch]
        $Online = $true,

        [Parameter()]
        [String]
        $BlobStoreName = 'default',

        [Parameter()]
        [ValidateSet('True', 'False')]
        [String]
        $UseStrictContentValidation = 'True',

        [Parameter()]
        [ValidateSet('Allow', 'Deny', 'Allow_Once')]
        [String]
        $DeploymentPolicy,

        [Parameter()]
        [Switch]
        $HasProprietaryComponents,

        [Parameter()]
        [Switch]
        $EnableV1,

        [Parameter()]
        [Switch]
        $ForceBasicAuth,

        [Parameter()]
        [String]
        $HttpPort,
        
        [Parameter()]
        [String]
        $HttpsPort
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    
        $urislug = "/service/rest/v1/repositories/docker/hosted"
    
    }

    
    process {

        $body = @{
            name    = $Name
            online  = [bool]$Online
            storage = @{
                blobStoreName               = $BlobStoreName
                strictContentTypeValidation = $UseStrictContentValidation
                writePolicy                 = $DeploymentPolicy
            }
            cleanup = @{
                policyNames = @($CleanupPolicy)
            }
            docker = @{
                v1Enabled = [bool]$EnableV1
                forceBasicAuth = [bool]$ForceBasicAuth
                httpPort = $HttpPort
                httpsPort = $HttpsPort
            }

        }

        if ($HasProprietaryComponents) {
            $Prop = @{
                proprietaryComponents = 'True'
            }
    
            $Body.Add('component', $Prop)
        }


        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST

        if($ForceBasicAuth -eq $false){
            Write-Warning "Docker Bearer Token Realm required since -ForceBasicAuth was not passed."
            Write-Warning "Use Add-NexusRealm to enable if desired."
        }
    
    }
}
#EndRegion '.\public\Repository\New-NexusDockerHostedRepository.ps1' 163
#Region '.\public\Repository\New-NexusDockerProxyRepository.ps1' 0
function New-NexusDockerProxyRepository {
    <#
    .SYNOPSIS
    Creates a new Conda Proxy Repository
 
    .DESCRIPTION
    Creates a new Conda Proxy Repository
 
    .PARAMETER Name
    The name to give the repository
 
    .PARAMETER ProxyRemoteUrl
    Location of the remote repository being proxied, e.g. https://api.Conda.org/v3/index.json
 
    .PARAMETER ContentMaxAgeMinutes
    Time before cached content is refreshed. Defaults to 1440
 
    .PARAMETER MetadataMaxAgeMinutes
    Time before cached metadata is refreshed. Defaults to 1440
 
    .PARAMETER UseNegativeCache
    Use the built-in Negative Cache feature
 
    .PARAMETER NegativeCacheTTLMinutes
    The Negative Cache Time To Live value. Defaults to 1440
 
    .PARAMETER CleanupPolicy
    The Cleanup Policy to apply to this repository
 
    .PARAMETER RoutingRule
    Routing Rules you wish to apply to this repository
 
    .PARAMETER Online
    Mark the repository as Online. Defaults to True
 
    .PARAMETER BlobStoreName
    The back-end blob store in which to store cached packages
 
    .PARAMETER UseStrictContentValidation
    Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
 
    .PARAMETER UseNexusTrustStore
    Use certificates stored in the Nexus truststore to connect to external systems
 
    .PARAMETER UseAuthentication
    Use authentication for the upstream repository
 
    .PARAMETER AuthenticationType
    The type of authentication required by the upstream repository
 
    .PARAMETER Credential
    Credentials to use to connecto to upstream repository
 
    .PARAMETER HostnameFqdn
    If using NTLM authentication, the Hostname of the NTLM host to query
 
    .PARAMETER DomainName
    The domain name of the NTLM host
 
    .PARAMETER BlockOutboundConnections
    Block outbound connections on the repository
 
    .PARAMETER EnableAutoBlocking
    Auto-block outbound connections on the repository if remote peer is detected as unreachable/unresponsive
 
    .PARAMETER ConnectionRetries
    Connection attempts to upstream repository before a failure
 
    .PARAMETER ConnectionTimeoutSeconds
    Amount of time to wait before retrying the connection to the upstream repository
 
    .PARAMETER EnableCircularRedirects
    Enable redirects to the same location (may be required by some servers)
 
    .PARAMETER EnableCookies
    Allow cookies to be stored and used
 
    .PARAMETER CustomUserAgent
    Custom fragment to append to "User-Agent" header in HTTP requests
 
    .PARAMETER EnableV1
    Whether to allow clients to use the V1 API to interact with this repository
     
    .PARAMETER ForceBasicAuth
    Whether to force authentication (Docker Bearer Token Realm required if false)
     
    .PARAMETER HttpPort
    Create an HTTP connector at specified port
     
    .PARAMETER HttpsPort
    Create an HTTPS connector at specified port
 
    .PARAMETER ProxyIndexType
    Type of Docker Index
 
    .PARAMETER IndexUrl
    Url of Docker Index to use. Required only if ProxyIndexType is Custom
     
    .EXAMPLE
    New-NexusDockerProxyRepository -Name DockerProxyTest -ProxyRemoteUrl https://hub.docker.io -Online
     
    .NOTES
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusDockerProxyRepository/',DefaultParameterSetName = "Default")]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter()]
        [Switch]
        $Online,

        [Parameter()]
        [String]
        $BlobStoreName = 'default',

        [Parameter()]
        [Switch]
        $UseStrictContentValidation,

        [Parameter()]
        [String]
        $CleanupPolicy,

        [Parameter(Mandatory)]
        [String]
        $ProxyRemoteUrl,

        [Parameter()]
        [String]
        $ContentMaxAgeMinutes = '1440',

        [Parameter()]
        [String]
        $MetadataMaxAgeMinutes = '1440',

        [Parameter()]
        [Switch]
        $UseNegativeCache,

        [Parameter()]
        [String]
        $NegativeCacheTTLMinutes = '1440',

        [Parameter()]
        [String]
        $RoutingRule,

        [Parameter()]
        [Switch]
        $UseNexusTrustStore = $false,

        [Parameter(ParameterSetName = "Authentication")]
        [Switch]
        $UseAuthentication,

        [Parameter(ParameterSetName = "Authentication", Mandatory)]
        [ValidateSet('Username', 'NTLM')]
        [String]
        $AuthenticationType,

        [Parameter(ParameterSetName = "Authentication", Mandatory)]
        [System.Management.Automation.PSCredential]
        $Credential,

        [Parameter(ParameterSetName = "Authentication")]
        [String]
        $HostnameFqdn,

        [Parameter(ParameterSetName = "Authentication")]
        [String]
        $DomainName,

        [Parameter()]
        [Switch]
        $BlockOutboundConnections = $false,

        [Parameter()]
        [Switch]
        $EnableAutoBlocking = $false,

        [Parameter()]
        [ValidateRange(0, 10)]
        [String]
        $ConnectionRetries,

        [Parameter()]
        [String]
        $ConnectionTimeoutSeconds,

        [Parameter()]
        [Switch]
        $EnableCircularRedirects = $false,

        [Parameter()]
        [Switch]
        $EnableCookies = $false,

        [Parameter()]
        [String]
        $CustomUserAgent,

        [Parameter()]
        [Switch]
        $EnableV1,

        [Parameter()]
        [Switch]
        $ForceBasicAuth,

        [Parameter()]
        [String]
        $HttpPort,
        
        [Parameter()]
        [String]
        $HttpsPort,

        [Parameter()]
        [ValidateSet('Hub', 'Registry', 'Custom')]
        [String]
        $ProxyIndexType = 'Registry',

        [Parameter()]
        [String]
        $IndexUrl
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    
        $urislug = "/service/rest/v1/repositories/docker/proxy"
    
    }
    
    process {

        if($ProxyIndexType -eq 'Hub'){
            $IndexUrl = 'https://index.docker.io/'
        }

        if($ProxyIndexType -eq 'Custom'){
            if($null -eq $IndexUrl){
                throw "IndexUrl is required when using a custom ProxyIndexType"
            }
        }

        switch($ProxyIndexType){
            'Hub' { $IndexUrl = 'https://index.docker.io/'}
            'Registry' {$IndexUrl = $ProxyRemoteUrl}
            default {$null}
        }

        $body = @{
            name          = $Name
            online        = [bool]$Online
            storage       = @{
                blobStoreName               = $BlobStoreName
                strictContentTypeValidation = [bool]$StrictContentValidation
                writePolicy                 = $DeploymentPolicy
            }
            cleanup       = @{
                policyNames = @($CleanupPolicy)
            }
            proxy         = @{
                remoteUrl      = $ProxyRemoteUrl
                contentMaxAge  = $ContentMaxAgeMinutes
                metadataMaxAge = $MetadataMaxAgeMinutes
            }
            negativeCache = @{
                enabled    = [bool]$UseNegativeCache
                timeToLive = $NegativeCacheTTLMinutes
            }
            routingRule   = $RoutingRule
            httpClient    = @{
                blocked    = [bool]$BlockOutboundConnections
                autoBlock  = [bool]$EnableAutoBlocking
                connection = @{
                    retries                 = $ConnectionRetries
                    userAgentSuffix         = $CustomUserAgent
                    timeout                 = $ConnectionTimeoutSeconds
                    enableCircularRedirects = [bool]$EnableCircularRedirects
                    enableCookies           = [bool]$EnableCookies
                    useTrustStore           = [bool]$UseNexusTrustStore
                }
            }
            docker        = @{
                v1Enabled      = [bool]$EnableV1
                forceBasicAuth = [bool]$ForceBasicAuth
                httpPort       = $HttpPort
                httpsPort      = $HttpsPort
            }
            dockerProxy   = @{
                indexType = $ProxyIndexType.ToUpper()
                indexUrl  = $IndexUrl
            }
    
        }
    
        if ($UseAuthentication) {
            
            switch ($AuthenticationType) {
                'Username' {
                    $authentication = @{
                        type       = $AuthenticationType.ToLower()
                        username   = $Credential.UserName
                        password   = $Credential.GetNetworkCredential().Password
                        ntlmHost   = ''
                        ntlmDomain = ''
                    }
        
                    $body.httpClient.Add('authentication', $authentication)
                }
    
                'NTLM' {
                    if (-not $HostnameFqdn -and $DomainName) {
                        throw "Parameter HostnameFqdn and DomainName are required when using WindowsNTLM authentication"
                    }
                    else {
                        $authentication = @{
                            type       = $AuthenticationType
                            username   = $Credential.UserName
                            password   = $Credential.GetNetworkCredential().Password
                            ntlmHost   = $HostnameFqdn
                            ntlmDomain = $DomainName
                        }
                    }
       
                    $body.httpClient.Add('authentication', $authentication)
                }
            }
            
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST

        if ($ForceBasicAuth -eq $false) {
            Write-Warning "Docker Bearer Token Realm required since -ForceBasicAuth was not passed."
            Write-Warning "Use Add-NexusRealm to enable if desired."
        }

    }
}
#EndRegion '.\public\Repository\New-NexusDockerProxyRepository.ps1' 349
#Region '.\public\Repository\New-NexusGitLfsHostedRepository.ps1' 0
function New-NexusGitlfsHostedRepository {
    <#
.SYNOPSIS
    Creates a new GitLfs Hosted repository
     
    .DESCRIPTION
    Creates a new GitLfs Hosted repository
     
    .PARAMETER Name
    The name of the repository
     
    .PARAMETER CleanupPolicy
    The Cleanup Policies to apply to the repository
     
    .PARAMETER Online
    Marks the repository to accept incoming requests
     
    .PARAMETER BlobStoreName
    Blob store to use to store GitLfs packages
     
    .PARAMETER StrictContentValidation
    Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
     
    .PARAMETER DeploymentPolicy
    Controls if deployments of and updates to artifacts are allowed
     
    .PARAMETER HasProprietaryComponents
    Components in this repository count as proprietary for namespace conflict attacks (requires Sonatype Nexus Firewall)
     
    .EXAMPLE
    New-NexusGitLfsHostedRepository -Name GitLfsHostedTest -DeploymentPolicy Allow
 
    .EXAMPLE
 
    $RepoParams = @{
        Name = 'MyGitLfsRepo'
        CleanupPolicy = '90 Days'
        DeploymentPolicy = 'Allow'
        UseStrictContentValidation = $true
    }
     
    New-NexusGitLfsHostedRepository @RepoParams
 
    .NOTES
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusGitlfsHostedRepository/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter()]
        [String]
        $CleanupPolicy,

        [Parameter()]
        [Switch]
        $Online,

        [Parameter()]
        [String]
        $BlobStoreName = 'default',

        [Parameter()]
        [Switch]
        $UseStrictContentValidation,

        [Parameter()]
        [ValidateSet('Allow', 'Deny', 'Allow_Once')]
        [String]
        $DeploymentPolicy,

        [Parameter()]
        [Switch]
        $HasProprietaryComponents
    )
    
    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories/gitlfs/hosted"

    }

    process {
        $body = @{
            name    = $Name
            online  = [bool]$Online
            storage = @{
                blobStoreName               = $BlobStoreName
                strictContentTypeValidation = [bool]$UseStrictContentValidation
                writePolicy                 = $DeploymentPolicy
            }
            cleanup = @{
                policyNames = @($CleanupPolicy)
            }
        }

        if ($HasProprietaryComponents) {
            $Prop = @{
                proprietaryComponents = 'True'
            }
    
            $Body.Add('component', $Prop)
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST
    }
}
#EndRegion '.\public\Repository\New-NexusGitLfsHostedRepository.ps1' 114
#Region '.\public\Repository\New-NexusGoGroupRepository.ps1' 0
function New-NexusGoGroupRepository {
    <#
    .SYNOPSIS
    Creates a new Go Group repository
 
    .DESCRIPTION
    Creates a new Go Group repository
     
    .PARAMETER Name
    The name of the repository
     
    .PARAMETER Online
    Marks the repository to accept incoming requests
     
    .PARAMETER BlobStoreName
    Blob store to use to store Go packages
     
    .PARAMETER StrictContentValidation
    Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
     
    .PARAMETER GroupMembers
    Member repositories' names
 
    .EXAMPLE
    New-NexusGoGroupRepository -Name GoGroup -GroupMembers GoHostedLinux,GoProd -Online
     
    .NOTES
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusGoGroupRepository/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter(Mandatory)]
        [String[]]
        $GroupMembers,

        [Parameter()]
        [Switch]
        $Online,

        [Parameter()]
        [String]
        $BlobStoreName = 'default',

        [Parameter()]
        [Switch]
        $UseStrictContentTypeValidation
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    
        $urislug = "/service/rest/v1/repositories/go/group"
    
    }

    process {

        $body = @{
            name    = $Name
            online  = [bool]$Online
            storage = @{
                blobStoreName               = $BlobStoreName
                strictContentTypeValidation = [bool]$UseStrictContentValidation
            }
            group   = @{
                memberNames = $GroupMembers
                writableMember = $WritableMember
            }
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST
    }

}
#EndRegion '.\public\Repository\New-NexusGoGroupRepository.ps1' 82
#Region '.\public\Repository\New-NexusGoProxyRepository.ps1' 0
function New-NexusGoProxyRepository {
<#
.SYNOPSIS
Creates a new Go Proxy Repository
 
.DESCRIPTION
Creates a new Go Proxy Repository
 
.PARAMETER Name
The name to give the repository
 
.PARAMETER ProxyRemoteUrl
Location of the remote repository being proxied, e.g. https://api.Go.org/v3/index.json
 
.PARAMETER ContentMaxAgeMinutes
Time before cached content is refreshed. Defaults to 1440
 
.PARAMETER MetadataMaxAgeMinutes
Time before cached metadata is refreshed. Defaults to 1440
 
.PARAMETER UseNegativeCache
Use the built-in Negative Cache feature
 
.PARAMETER NegativeCacheTTLMinutes
The Negative Cache Time To Live value. Defaults to 1440
 
.PARAMETER CleanupPolicy
The Cleanup Policy to apply to this repository
 
.PARAMETER RoutingRule
Routing Rules you wish to apply to this repository
 
.PARAMETER Online
Mark the repository as Online. Defaults to True
 
.PARAMETER BlobStoreName
The back-end blob store in which to store cached packages
 
.PARAMETER StrictContentValidation
Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
 
.PARAMETER DeploymentPolicy
Controls whether packages can be overwritten
 
.PARAMETER UseNexusTrustStore
Use certificates stored in the Nexus truststore to connect to external systems
 
.PARAMETER UseAuthentication
Use authentication for the upstream repository
 
.PARAMETER AuthenticationType
The type of authentication required by the upstream repository
 
.PARAMETER Credential
Credentials to use to connecto to upstream repository
 
.PARAMETER HostnameFqdn
If using NTLM authentication, the Hostname of the NTLM host to query
 
.PARAMETER DomainName
The domain name of the NTLM host
 
.PARAMETER BlockOutboundConnections
Block outbound connections on the repository
 
.PARAMETER EnableAutoBlocking
Auto-block outbound connections on the repository if remote peer is detected as unreachable/unresponsive
 
.PARAMETER ConnectionRetries
Connection attempts to upstream repository before a failure
 
.PARAMETER ConnectionTimeoutSeconds
Amount of time to wait before retrying the connection to the upstream repository
 
.PARAMETER EnableCircularRedirects
Enable redirects to the same location (may be required by some servers)
 
.PARAMETER EnableCookies
Allow cookies to be stored and used
 
.PARAMETER CustomUserAgent
Custom fragment to append to "User-Agent" header in HTTP requests
 
.EXAMPLE
 
$ProxyParameters = @{
    Name = 'GoProxy'
    ProxyRemoteUrl = 'https://upstream.Gopkgs.com'
    DeploymentPolicy = 'Allow'
}
 
New-NexusGoProxyRepository @ProxyParameters
 
.EXAMPLE
 
$ProxyParameters = @{
    Name = 'GoProxy'
    ProxyRemoteUrl = 'https://upstream.Gopkgs.com'
    DeploymentPolicy = 'Allow'
    UseAuthentication = $true
    AuthenticationType = 'Username'
    Credential = (Get-Credential)
 
}
 
New-NexusGoProxyRepository @ProxyParameters
#>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusGoProxyRepository/', DefaultParameterSetname = "Default")]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter(Mandatory)]
        [String]
        $ProxyRemoteUrl,

        [Parameter()]
        [String]
        $ContentMaxAgeMinutes = '1440',

        [Parameter()]
        [String]
        $MetadataMaxAgeMinutes = '1440',

        [Parameter()]
        [Switch]
        $UseNegativeCache,

        [Parameter()]
        [String]
        $NegativeCacheTTLMinutes = '1440',

        [Parameter()]
        [String]
        $CleanupPolicy,

        [Parameter()]
        [String]
        $RoutingRule,

        [Parameter()]
        [Switch]
        $Online = $true,

        [Parameter()]
        [String]
        $BlobStoreName = 'default',

        [Parameter()]
        [Switch]
        $StrictContentValidation = $true,

        [Parameter()]
        [ValidateSet('Allow', 'Deny', 'Allow_Once')]
        [String]
        $DeploymentPolicy,

        [Parameter()]
        [Switch]
        $UseNexusTrustStore = $false,

        [Parameter(ParameterSetName = "Authentication")]
        [Switch]
        $UseAuthentication,

        [Parameter(ParameterSetName = "Authentication", Mandatory)]
        [ValidateSet('Username', 'NTLM')]
        [String]
        $AuthenticationType,

        [Parameter(ParameterSetName = "Authentication", Mandatory)]
        [System.Management.Automation.PSCredential]
        $Credential,

        [Parameter(ParameterSetName = "Authentication")]
        [String]
        $HostnameFqdn,

        [Parameter(ParameterSetName = "Authentication")]
        [String]
        $DomainName,

        [Parameter()]
        [Switch]
        $BlockOutboundConnections = $false,

        [Parameter()]
        [Switch]
        $EnableAutoBlocking = $false,

        [Parameter()]
        [ValidateRange(0, 10)]
        [String]
        $ConnectionRetries,

        [Parameter()]
        [String]
        $ConnectionTimeoutSeconds,

        [Parameter()]
        [Switch]
        $EnableCircularRedirects = $false,

        [Parameter()]
        [Switch]
        $EnableCookies = $false,

        [Parameter()]
        [String]
        $CustomUserAgent
    )
    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories/go/proxy"

    }
    process {

        $body = @{
            name          = $Name
            online        = [bool]$Online
            storage       = @{
                blobStoreName               = $BlobStoreName
                strictContentTypeValidation = [bool]$StrictContentValidation
                writePolicy                 = $DeploymentPolicy
            }
            cleanup       = @{
                policyNames = @($CleanupPolicy)
            }
            proxy         = @{
                remoteUrl      = $ProxyRemoteUrl
                contentMaxAge  = $ContentMaxAgeMinutes
                metadataMaxAge = $MetadataMaxAgeMinutes
            }
            negativeCache = @{
                enabled    = [bool]$UseNegativeCache
                timeToLive = $NegativeCacheTTLMinutes
            }
            routingRule   = $RoutingRule
            httpClient    = @{
                blocked    = [bool]$BlockOutboundConnections
                autoBlock  = [bool]$EnableAutoBlocking
                connection = @{
                    retries                 = $ConnectionRetries
                    userAgentSuffix         = $CustomUserAgent
                    timeout                 = $ConnectionTimeoutSeconds
                    enableCircularRedirects = [bool]$EnableCircularRedirects
                    enableCookies           = [bool]$EnableCookies
                    useTrustStore           = [bool]$UseNexusTrustStore
                }
            }

        }

        if ($UseAuthentication) {
        
            switch ($AuthenticationType) {
                'Username' {
                    $authentication = @{
                        type       = $AuthenticationType.ToLower()
                        username   = $Credential.UserName
                        password   = $Credential.GetNetworkCredential().Password
                        ntlmHost   = ''
                        ntlmDomain = ''
                    }
    
                    $body.httpClient.Add('authentication', $authentication)
                }

                'NTLM' {
                    if (-not $HostnameFqdn -and $DomainName) {
                        throw "Parameter HostnameFqdn and DomainName are required when using WindowsNTLM authentication"
                    }
                    else {
                        $authentication = @{
                            type       = $AuthenticationType
                            username   = $Credential.UserName
                            password   = $Credential.GetNetworkCredential().Password
                            ntlmHost   = $HostnameFqdn
                            ntlmDomain = $DomainName
                        }
                    }
   
                    $body.httpClient.Add('authentication', $authentication)
                }
            }
        
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST

    }

}
#EndRegion '.\public\Repository\New-NexusGoProxyRepository.ps1' 301
#Region '.\public\Repository\New-NexusNugetHostedRepository.ps1' 0
function New-NexusNugetHostedRepository {
    <#
    .SYNOPSIS
    Creates a new NuGet Hosted repository
     
    .DESCRIPTION
    Creates a new NuGet Hosted repository
     
    .PARAMETER Name
    The name of the repository
     
    .PARAMETER CleanupPolicy
    The Cleanup Policies to apply to the repository
     
 
     
    .PARAMETER Online
    Marks the repository to accept incoming requests
     
    .PARAMETER BlobStoreName
    Blob store to use to store NuGet packages
     
    .PARAMETER StrictContentValidation
    Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
     
    .PARAMETER DeploymentPolicy
    Controls if deployments of and updates to artifacts are allowed
     
    .PARAMETER HasProprietaryComponents
    Components in this repository count as proprietary for namespace conflict attacks (requires Sonatype Nexus Firewall)
     
    .EXAMPLE
    New-NexusNugetHostedRepository -Name NugetHostedTest -DeploymentPolicy Allow
 
    .EXAMPLE
 
    $RepoParams = @{
        Name = MyNuGetRepo
        CleanupPolicy = '90 Days'
        DeploymentPolicy = 'Allow'
        UseStrictContentValidation = $true
    }
     
    New-NexusNugetHostedRepository @RepoParams
 
    .NOTES
    General notes
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusNugetHostedRepository/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter()]
        [String]
        $CleanupPolicy,

        [Parameter()]
        [Switch]
        $Online = $true,

        [Parameter()]
        [String]
        $BlobStoreName = 'default',

        [Parameter()]
        [ValidateSet('True', 'False')]
        [String]
        $UseStrictContentValidation = 'True',

        [Parameter()]
        [ValidateSet('Allow', 'Deny', 'Allow_Once')]
        [String]
        $DeploymentPolicy,

        [Parameter()]
        [Switch]
        $HasProprietaryComponents
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories"

    }

    process {
        $formatUrl = $urislug + '/nuget'

        $FullUrlSlug = $formatUrl + '/hosted'


        $body = @{
            name    = $Name
            online  = [bool]$Online
            storage = @{
                blobStoreName               = $BlobStoreName
                strictContentTypeValidation = $UseStrictContentValidation
                writePolicy                 = $DeploymentPolicy
            }
            cleanup = @{
                policyNames = @($CleanupPolicy)
            }
        }

        if ($HasProprietaryComponents) {
            $Prop = @{
                proprietaryComponents = 'True'
            }
    
            $Body.Add('component', $Prop)
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $FullUrlSlug -Body $Body -Method POST

    }
}
#EndRegion '.\public\Repository\New-NexusNugetHostedRepository.ps1' 124
#Region '.\public\Repository\New-NexusNugetProxyRepository.ps1' 0
function New-NexusNugetProxyRepository {
<#
.SYNOPSIS
Creates a new NuGet Proxy Repository
 
.DESCRIPTION
Creates a new NuGet Proxy Repository
 
.PARAMETER Name
The name to give the repository
 
.PARAMETER ProxyRemoteUrl
Location of the remote repository being proxied, e.g. https://api.nuget.org/v3/index.json
 
.PARAMETER ContentMaxAgeMinutes
Time before cached content is refreshed. Defaults to 1440
 
.PARAMETER MetadataMaxAgeMinutes
Time before cached metadata is refreshed. Defaults to 1440
 
.PARAMETER QueryCacheItemMaxAgeSeconds
Time before the query cache expires. Defaults to 3600
 
.PARAMETER NugetVersion
Upstream NuGet version. Can either be V2 or V3
 
.PARAMETER UseNegativeCache
Use the built-in Negative Cache feature
 
.PARAMETER NegativeCacheTTLMinutes
The Negative Cache Time To Live value. Defaults to 1440
 
.PARAMETER CleanupPolicy
The Cleanup Policy to apply to this repository
 
.PARAMETER RoutingRule
Routing Rules you wish to apply to this repository
 
.PARAMETER Online
Mark the repository as Online. Defaults to True
 
.PARAMETER BlobStoreName
The back-end blob store in which to store cached packages
 
.PARAMETER StrictContentValidation
Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
 
.PARAMETER DeploymentPolicy
Controls whether packages can be overwritten
 
.PARAMETER UseNexusTrustStore
Use certificates stored in the Nexus truststore to connect to external systems
 
.PARAMETER UseAuthentication
Use authentication for the upstream repository
 
.PARAMETER AuthenticationType
The type of authentication required by the upstream repository
 
.PARAMETER Credential
Credentials to use to connecto to upstream repository
 
.PARAMETER HostnameFqdn
If using NTLM authentication, the Hostname of the NTLM host to query
 
.PARAMETER DomainName
The domain name of the NTLM host
 
.PARAMETER BlockOutboundConnections
Block outbound connections on the repository
 
.PARAMETER EnableAutoBlocking
Auto-block outbound connections on the repository if remote peer is detected as unreachable/unresponsive
 
.PARAMETER ConnectionRetries
Connection attempts to upstream repository before a failure
 
.PARAMETER ConnectionTimeoutSeconds
Amount of time to wait before retrying the connection to the upstream repository
 
.PARAMETER EnableCircularRedirects
Enable redirects to the same location (may be required by some servers)
 
.PARAMETER EnableCookies
Allow cookies to be stored and used
 
.PARAMETER CustomUserAgent
Custom fragment to append to "User-Agent" header in HTTP requests
 
.EXAMPLE
 
$ProxyParameters = @{
    Name = 'ChocoProxy'
    ProxyRemoteUrl = 'https://community.chocolatey.org/api/v2'
    NugetVersion = 'V2'
    DeploymentPolicy = 'Allow'
 
}
 
New-NexusNugetProxyRepository @ProxyParameters
 
.EXAMPLE
 
$ProxyParameters = @{
    Name = 'ChocoProxy'
    ProxyRemoteUrl = 'https://community.chocolatey.org/api/v2'
    NugetVersion = 'V2'
    DeploymentPolicy = 'Allow'
    UseAuthentication = $true
    AuthenticationType = 'Username'
    Credential = (Get-Credential)
 
}
 
New-NexusNugetProxyRepository @ProxyParameters
#>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusNugetProxyRepository/',DefaultParameterSetname="Default")]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter(Mandatory)]
        [String]
        $ProxyRemoteUrl,

        [Parameter()]
        [String]
        $ContentMaxAgeMinutes = '1440',

        [Parameter()]
        [String]
        $MetadataMaxAgeMinutes = '1440',

        [Parameter()]
        [String]
        $QueryCacheItemMaxAgeSeconds = '3600',

        [Parameter(Mandatory)]
        [ValidateSet('V2', 'V3')]
        [String]
        $NugetVersion,

        [Parameter()]
        [Switch]
        $UseNegativeCache,

        [Parameter()]
        [String]
        $NegativeCacheTTLMinutes = '1440',

        [Parameter()]
        [String]
        $CleanupPolicy,

        [Parameter()]
        [String]
        $RoutingRule,

        [Parameter()]
        [Switch]
        $Online = $true,

        [Parameter()]
        [String]
        $BlobStoreName = 'default',

        [Parameter()]
        [Switch]
        $StrictContentValidation = $true,

        [Parameter()]
        [ValidateSet('Allow', 'Deny', 'Allow_Once')]
        [String]
        $DeploymentPolicy,

        [Parameter()]
        [Switch]
        $UseNexusTrustStore = $false,

        [Parameter(ParameterSetName = "Authentication")]
        [Switch]
        $UseAuthentication,

        [Parameter(ParameterSetName = "Authentication", Mandatory)]
        [ValidateSet('Username', 'NTLM')]
        [String]
        $AuthenticationType,

        [Parameter(ParameterSetName = "Authentication", Mandatory)]
        [System.Management.Automation.PSCredential]
        $Credential,

        [Parameter(ParameterSetName = "Authentication")]
        [String]
        $HostnameFqdn,

        [Parameter(ParameterSetName = "Authentication")]
        [String]
        $DomainName,

        [Parameter()]
        [Switch]
        $BlockOutboundConnections = $false,

        [Parameter()]
        [Switch]
        $EnableAutoBlocking = $false,

        [Parameter()]
        [ValidateRange(0,10)]
        [String]
        $ConnectionRetries,

        [Parameter()]
        [String]
        $ConnectionTimeoutSeconds,

        [Parameter()]
        [Switch]
        $EnableCircularRedirects = $false,

        [Parameter()]
        [Switch]
        $EnableCookies = $false,

        [Parameter()]
        [String]
        $CustomUserAgent
    )
    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories"

    }
    process {
        $formatUrl = $urislug + "/nuget"

        $FullUrlSlug = $formatUrl + "/proxy"

        $AuthenticationType = $AuthenticationType.ToLower()

        $body = @{
            name          = $Name
            online        = [bool]$Online
            storage       = @{
                blobStoreName               = $BlobStoreName
                strictContentTypeValidation = [bool]$StrictContentValidation
                writePolicy                 = $DeploymentPolicy
            }
            cleanup       = @{
                policyNames = @($CleanupPolicy)
            }
            proxy         = @{
                remoteUrl      = $ProxyRemoteUrl
                contentMaxAge  = $ContentMaxAgeMinutes
                metadataMaxAge = $MetadataMaxAgeMinutes
            }

            nugetProxy    = @{
                queryCacheItemMaxAge = $QueryCacheItemMaxAgSeconds
                nugetVersion         = $NugetVersion
            }

            negativeCache = @{
                enabled    = [bool]$UseNegativeCache
                timeToLive = $NegativeCacheTTLMinutes
            }

            httpClient    = @{
                blocked    = [bool]$BlockOutboundConnections
                autoBlock  = [bool]$EnableAutoBlocking
                connection = @{
                    retries                 = $ConnectionRetries
                    userAgentSuffix         = $CustomUserAgent
                    timeout                 = $ConnectionTimeoutSeconds
                    enableCircularRedirects = [bool]$EnableCircularRedirects
                    enableCookies           = [bool]$EnableCookies
                    useTrustStore           = [bool]$UseNexusTrustStore
                }
            }
    
        }

        if ($UseAuthentication) {
            
            switch($AuthenticationType){
                'Username' {
                    $authentication = @{
                        type       = $AuthenticationType
                        username   = $Credential.UserName
                        password   = $Credential.GetNetworkCredential().Password
                        ntlmHost = ''
                        ntlmDomain = ''
                    }
        
                    $body.httpClient.Add('authentication', $authentication)
                }

                'NTLM' {
                    if(-not $HostnameFqdn -and $DomainName){
                        throw "Parameter HostnameFqdn and DomainName are required when using WindowsNTLM authentication"
                    } else {
                        $authentication = @{
                            type       = $AuthenticationType
                            username   = $Credential.UserName
                            password   = $Credential.GetNetworkCredential().Password
                            ntlmHost   = $HostnameFqdn
                            ntlmDomain = $DomainName
                        }
                    }
       
                    $body.httpClient.Add('authentication', $authentication)
                }
            }
            
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $FullUrlSlug -Body $Body -Method POST

    }
}
#EndRegion '.\public\Repository\New-NexusNugetProxyRepository.ps1' 328
#Region '.\public\Repository\New-NexusRawGroupRepository.ps1' 0
function New-NexusRawGroupRepository {
    <#
    .SYNOPSIS
    Creates a Raw Group repository
     
    .DESCRIPTION
    Creates a Raw Group repository
     
    .PARAMETER Name
    The name of the repository
     
    .PARAMETER GroupMembers
    The Raw Repositories to add as group members
     
    .PARAMETER Online
    Marks the repository as online
     
    .PARAMETER BlobStore
    The blob store to attach to the repository
     
    .PARAMETER UseStrictContentTypeValidation
    Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
     
    .PARAMETER ContentDisposition
    Add Content-Disposition header as 'Attachment' to disable some content from being inline in a browser
     
    .PARAMETER DeploymentPolicy
    Required by the API, but thrown away by the underlying system. Use whatever you want here from the set
     
    .EXAMPLE
    New-NexusRawGroupRepository -Name AllArtifacts -GroupMembers BinaryArtifacts,Documentation -DeploymentPolicy Allow
     
    .NOTES
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/New-NexusRawGroupRepository/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter(Mandatory)]
        [String[]]
        $GroupMembers,

        [Parameter()]
        [Switch]
        $Online = $true,

        [Parameter()]
        [String]
        $BlobStore = 'default',

        [Parameter()]
        [Switch]
        $UseStrictContentTypeValidation,

        [Parameter(Mandatory)]
        [ValidateSet('Inline', 'Attachment')]
        [String]
        $ContentDisposition,

        [Parameter(Mandatory)]
        [ValidateSet('Allow', 'Deny', 'Allow_Once')]
        [String]
        $DeploymentPolicy = 'Allow_Once'
    )
    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories/raw/group"

    }

    process {

        $body = @{
            name    = $Name
            online  = [bool]$Online
            storage = @{
                blobStoreName               = $BlobStore
                strictContentTypeValidation = [bool]$UseStrictContentTypeValidation
                writePolicy                 = $DeploymentPolicy.ToLower()
            }
            group   = @{
                memberNames = $GroupMembers
            }
            raw     = @{
                contentDisposition = $ContentDisposition
            }
        }
        
        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST

    }

}
#EndRegion '.\public\Repository\New-NexusRawGroupRepository.ps1' 101
#Region '.\public\Repository\New-NexusRawHostedRepository.ps1' 0
function New-NexusRawHostedRepository {
    <#
    .SYNOPSIS
    Creates a new Raw Hosted repository
     
    .DESCRIPTION
    Creates a new Raw Hosted repository
     
    .PARAMETER Name
    The Name of the repository to create
     
    .PARAMETER Online
    Mark the repository as Online. Defaults to True
     
    .PARAMETER BlobStore
    The blob store to attach the repository too. Defaults to 'default'
     
    .PARAMETER UseStrictContentTypeValidation
    Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
     
    .PARAMETER DeploymentPolicy
    Controls if deployments of and updates to artifacts are allowed
     
    .PARAMETER CleanupPolicy
    Components that match any of the Applied policies will be deleted
     
    .PARAMETER HasProprietaryComponents
    Components in this repository count as proprietary for namespace conflict attacks (requires Sonatype Nexus Firewall)
     
    .PARAMETER ContentDisposition
    Add Content-Disposition header as 'Attachment' to disable some content from being inline in a browser.
     
    .EXAMPLE
    New-NexusRawHostedRepository -Name BinaryArtifacts -ContentDisposition Attachment
 
    .EXAMPLE
    $RepoParams = @{
        Name = 'BinaryArtifacts'
        Online = $true
        UseStrictContentTypeValidation = $true
        DeploymentPolicy = 'Allow'
        CleanupPolicy = '90Days',
        BlobStore = 'AmazonS3Bucket'
    }
 
    New-NexusRawHostedRepository @RepoParams
     
    .NOTES
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusRawHostedRepository/', DefaultParameterSetname = "Default")]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter()]
        [Switch]
        $Online = $true,

        [Parameter()]
        [String]
        $BlobStore = 'default',

        [Parameter()]
        [Switch]
        $UseStrictContentTypeValidation,

        [Parameter()]
        [ValidateSet('Allow', 'Deny', 'Allow_Once')]
        [String]
        $DeploymentPolicy = 'Allow_Once',

        [Parameter()]
        [String]
        $CleanupPolicy,

        [Parameter()]
        [Switch]
        $HasProprietaryComponents,

        [Parameter(Mandatory)]
        [ValidateSet('Inline','Attachment')]
        [String]
        $ContentDisposition
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories/raw/hosted"

    }

    process {

        $Body = @{
            name = $Name
            online = [bool]$Online
            storage = @{
                blobStoreName = $BlobStore
                strictContentTypeValidation = [bool]$UseStrictContentTypeValidation
                writePolicy = $DeploymentPolicy.ToLower()
            }
            cleanup = @{
                policyNames = @($CleanupPolicy)
            }
            component = @{
                proprietaryComponents = [bool]$HasProprietaryComponents
            }
            raw = @{
                contentDisposition = $ContentDisposition.ToUpper()
            }
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST


    }
}
#EndRegion '.\public\Repository\New-NexusRawHostedRepository.ps1' 124
#Region '.\public\Repository\New-NexusRawProxyRepository.ps1' 0
function New-NexusRawProxyRepository {
    <#
.SYNOPSIS
Creates a new NuGet Proxy Repository
 
.DESCRIPTION
Creates a new NuGet Proxy Repository
 
.PARAMETER Name
The name to give the repository
 
.PARAMETER ProxyRemoteUrl
Location of the remote repository being proxied, e.g. https://api.nuget.org/v3/index.json
 
.PARAMETER ContentDisposition
Add Content-Disposition header as 'Attachment' to disable some content from being inline in a browser.
 
.PARAMETER ContentMaxAgeMinutes
Time before cached content is refreshed. Defaults to 1440
 
.PARAMETER MetadataMaxAgeMinutes
Time before cached metadata is refreshed. Defaults to 1440
 
.PARAMETER QueryCacheItemMaxAgeSeconds
Time before the query cache expires. Defaults to 3600
 
.PARAMETER UseNegativeCache
Use the built-in Negative Cache feature
 
.PARAMETER NegativeCacheTTLMinutes
The Negative Cache Time To Live value. Defaults to 1440
 
.PARAMETER CleanupPolicy
The Cleanup Policy to apply to this repository
 
.PARAMETER RoutingRule
Routing Rules you wish to apply to this repository
 
.PARAMETER Online
Mark the repository as Online. Defaults to True
 
.PARAMETER BlobStoreName
The back-end blob store in which to store cached packages
 
.PARAMETER StrictContentValidation
Validate that all content uploaded to this repository is of a MIME type appropriate for the repository format
 
.PARAMETER DeploymentPolicy
Controls whether packages can be overwritten
 
.PARAMETER UseNexusTrustStore
Use certificates stored in the Nexus truststore to connect to external systems
 
.PARAMETER UseAuthentication
Use authentication for the upstream repository
 
.PARAMETER AuthenticationType
The type of authentication required by the upstream repository
 
.PARAMETER Credential
Credentials to use to connecto to upstream repository
 
.PARAMETER HostnameFqdn
If using NTLM authentication, the Hostname of the NTLM host to query
 
.PARAMETER DomainName
The domain name of the NTLM host
 
.PARAMETER BlockOutboundConnections
Block outbound connections on the repository
 
.PARAMETER EnableAutoBlocking
Auto-block outbound connections on the repository if remote peer is detected as unreachable/unresponsive
 
.PARAMETER ConnectionRetries
Connection attempts to upstream repository before a failure
 
.PARAMETER ConnectionTimeoutSeconds
Amount of time to wait before retrying the connection to the upstream repository
 
.PARAMETER EnableCircularRedirects
Enable redirects to the same location (may be required by some servers)
 
.PARAMETER EnableCookies
Allow cookies to be stored and used
 
.PARAMETER CustomUserAgent
Custom fragment to append to "User-Agent" header in HTTP requests
 
.EXAMPLE
 
$ProxyParameters = @{
    Name = 'ChocoProxy'
    ProxyRemoteUrl = 'https://community.chocolatey.org/api/v2'
    DeploymentPolicy = 'Allow'
}
 
New-NexusRawProxyRepository @ProxyParameters
 
.EXAMPLE
 
$ProxyParameters = @{
    Name = 'ChocoProxy'
    ProxyRemoteUrl = 'https://community.chocolatey.org/api/v2'
    DeploymentPolicy = 'Allow'
    UseAuthentication = $true
    AuthenticationType = 'Username'
    Credential = (Get-Credential)
}
 
New-NexusRawProxyRepository @ProxyParameters
#>

    [CmdletBinding(HelpUri = 'https://github.com/steviecoaster/NexuShell/blob/develop/docs/New-NexusRawProxyRepository.md', DefaultParameterSetname = "Default")]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter(Mandatory)]
        [String]
        $ProxyRemoteUrl,

        [Parameter(Mandatory)]
        [ValidateSet('Inline','Attachment')]
        [String]
        $ContentDisposition,

        [Parameter()]
        [String]
        $ContentMaxAgeMinutes = '1440',

        [Parameter()]
        [String]
        $MetadataMaxAgeMinutes = '1440',

        [Parameter()]
        [String]
        $QueryCacheItemMaxAgeSeconds = '3600',

        [Parameter()]
        [Switch]
        $UseNegativeCache,

        [Parameter()]
        [String]
        $NegativeCacheTTLMinutes = '1440',

        [Parameter()]
        [String]
        $CleanupPolicy,

        [Parameter()]
        [String]
        $RoutingRule,

        [Parameter()]
        [Switch]
        $Online = $true,

        [Parameter()]
        [String]
        $BlobStoreName = 'default',

        [Parameter()]
        [Switch]
        $StrictContentValidation = $true,

        [Parameter()]
        [Switch]
        $UseNexusTrustStore = $false,

        [Parameter(ParameterSetName = "Authentication")]
        [Switch]
        $UseAuthentication,

        [Parameter(ParameterSetName = "Authentication", Mandatory)]
        [ValidateSet('Username', 'NTLM')]
        [String]
        $AuthenticationType,

        [Parameter(ParameterSetName = "Authentication", Mandatory)]
        [System.Management.Automation.PSCredential]
        $Credential,

        [Parameter(ParameterSetName = "Authentication")]
        [String]
        $HostnameFqdn,

        [Parameter(ParameterSetName = "Authentication")]
        [String]
        $DomainName,

        [Parameter()]
        [Switch]
        $BlockOutboundConnections = $false,

        [Parameter()]
        [Switch]
        $EnableAutoBlocking = $false,

        [Parameter()]
        [ValidateRange(0, 10)]
        [String]
        $ConnectionRetries,

        [Parameter()]
        [String]
        $ConnectionTimeoutSeconds,

        [Parameter()]
        [Switch]
        $EnableCircularRedirects = $false,

        [Parameter()]
        [Switch]
        $EnableCookies = $false,

        [Parameter()]
        [String]
        $CustomUserAgent
    )
    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories/raw/proxy"

    }
    process {

        $AuthenticationType = $AuthenticationType.ToLower()

        $body = @{
            name          = $Name
            online        = [bool]$Online
            storage       = @{
                blobStoreName               = $BlobStoreName
                strictContentTypeValidation = [bool]$StrictContentValidation
            }
            cleanup       = @{
                policyNames = @($CleanupPolicy)
            }
            proxy         = @{
                remoteUrl      = $ProxyRemoteUrl
                contentMaxAge  = $ContentMaxAgeMinutes
                metadataMaxAge = $MetadataMaxAgeMinutes
            }
            negativeCache = @{
                enabled    = [bool]$UseNegativeCache
                timeToLive = $NegativeCacheTTLMinutes
            }
            httpClient    = @{
                blocked    = [bool]$BlockOutboundConnections
                autoBlock  = [bool]$EnableAutoBlocking
                connection = @{
                    retries                 = $ConnectionRetries
                    userAgentSuffix         = $CustomUserAgent
                    timeout                 = $ConnectionTimeoutSeconds
                    enableCircularRedirects = [bool]$EnableCircularRedirects
                    enableCookies           = [bool]$EnableCookies
                    useTrustStore           = [bool]$UseNexusTrustStore
                }
            }
            routingRule = $RoutingRule
            raw = @{
                contentDisposition = $ContentDisposition
            }
        }

        if ($UseAuthentication) {
            
            switch ($AuthenticationType) {
                'Username' {
                    $authentication = @{
                        type       = $AuthenticationType
                        username   = $Credential.UserName
                        password   = $Credential.GetNetworkCredential().Password
                        ntlmHost   = ''
                        ntlmDomain = ''
                    }
        
                    $body.httpClient.Add('authentication', $authentication)
                }

                'NTLM' {
                    if (-not $HostnameFqdn -and $DomainName) {
                        throw "Parameter HostnameFqdn and DomainName are required when using WindowsNTLM authentication"
                    }
                    else {
                        $authentication = @{
                            type       = $AuthenticationType
                            username   = $Credential.UserName
                            password   = $Credential.GetNetworkCredential().Password
                            ntlmHost   = $HostnameFqdn
                            ntlmDomain = $DomainName
                        }
                    }
       
                    $body.httpClient.Add('authentication', $authentication)
                }
            }
            
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST
    }
}
#EndRegion '.\public\Repository\New-NexusRawProxyRepository.ps1' 311
#Region '.\public\Repository\New-NexusRepository.ps1' 0
function New-NexusRepository {
    <#
    .SYNOPSIS
    Creates a new repository in your Nexus server
     
    .DESCRIPTION
    Creates a new repository of the specified type and settings in your Nexus server
     
    .PARAMETER Name
    The name to give to the new repository
     
    .PARAMETER Format
    The format of the new repository
     
    .PARAMETER Type
    The type of repository to create: Hosted,Group,Proxy
     
    .PARAMETER GroupMember
    Members to add to group repository types. Must be of the same repository format as the repository you are creating
     
    .PARAMETER ProxyRemoteUrl
    When setting a Proxy type repository, this is the upstream repository url to point the new repository
     
    .PARAMETER ContentMaxAgeMinutes
    When using a Proxy type repository, the length of time to cache package contents before reaching back out to the upstream url
     
    .PARAMETER MetadataMaxAgeMinutes
    When using a Proxy type repository, the length of time to cache package metadata before reaching back out to the upstream url
     
    .PARAMETER QueryCacheItemMaxAgSeconds
    When using a Proxy type repository, the length of time to cache upstream url repsonses
     
    .PARAMETER NugetVersion
    For Nuget proxy repositories the version of nuget packages your upstream url contains
     
    .PARAMETER UseNegativeCache
    Use Negative Cache for proxy url
     
    .PARAMETER NegativeCacheTTLMinutes
    The Negative Cache TTL value
     
    .PARAMETER CleanupPolicy
    The cleanup policy to apply to the new repository
     
    .PARAMETER RoutingRule
    The Routing Rule to apply to the new repository
     
    .PARAMETER Online
    Make the new repository immediately available for use. This basically means "Enabled", or "Disabled"
     
    .PARAMETER BlobStoreName
    The blob store to use with the new repository
     
    .PARAMETER StrictContentValidation
    Specify that uploaded artifacts adhere to the MIME type of the specified format
     
    .PARAMETER DeploymentPolicy
    Controls whether you can push the same package version repeatedly, or push packages at all
     
    .EXAMPLE
    New-NexusRepository -Name NugetCenter -Format nuget -Type hosted -DeploymentPolicy Allow
     
    .EXAMPLE
    New-NexusRepository -Name ChocoUpstream -Format nuget -Type proxy -ProxyRemoteUrl 'https://chocolatey.org/api/v2'
    #>

    [CmdletBinding(HelpUri='https://github.com/steviecoaster/NexuShell/blob/develop/docs/New-NexusRepository.md')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter(Mandatory)]
        [ValidateSet('apt','bower','cocoapods','conan','conda','docker','gitlfs','go','helm','maven2','npm','nuget','p2','pypi','r','raw','rubygems','yum')]
        [String]
        $Format,

        [Parameter(Mandatory)]
        [Parameter(Mandatory,ParameterSetName="Group")]
        [Parameter(Mandatory,ParameterSetName="Hosted")]
        [Parameter(Mandatory,ParameterSetName="Proxy")]
        [ValidateSet('hosted','proxy','group')]
        [String]
        $Type,

        [Parameter(Mandatory,ParameterSetName="Group")]
        [String[]]
        $GroupMember,

        [Parameter(Mandatory,ParameterSetName="Proxy")]
        [String]
        $ProxyRemoteUrl,

        [Parameter(ParameterSetName="Proxy")]
        [String]
        $ContentMaxAgeMinutes = '1440',

        [Parameter(ParameterSetName="Proxy")]
        [String]
        $MetadataMaxAgeMinutes = '1440',

        [Parameter(ParameterSetName="Proxy")]
        [String]
        $QueryCacheItemMaxAgSeconds = '3600',

        [Parameter(ParameterSetName="Proxy")]
        [String]
        $NugetVersion = 'V3',

        [Parameter(ParameterSetName="Proxy")]
        [ValidateSet('True','False')]
        [String]
        $UseNegativeCache = 'True',

        [Parameter(ParameterSetName="Proxy")]
        [String]
        $NegativeCacheTTLMinutes = '1440',

        [Parameter(ParameterSetName="Group")]
        [Parameter(ParameterSetName="Hosted")]
        [Parameter(ParameterSetName="Proxy")]
        [String]
        $CleanupPolicy,

        [Parameter(ParameterSetName="Group")]
        [Parameter(ParameterSetName="Hosted")]
        [Parameter(ParameterSetName="Proxy")]
        [String]
        $RoutingRule,

        [Parameter(ParameterSetName="Group")]
        [Parameter(ParameterSetName="Hosted")]
        [Parameter(ParameterSetName="Proxy")]
        [ValidateSet('True','False')]
        [String]
        $Online = 'True',

        [Parameter(ParameterSetName="Group")]
        [Parameter(ParameterSetName="Hosted")]
        [Parameter(ParameterSetName="Proxy")]
        [String]
        $BlobStoreName = 'default',

        [Parameter(ParameterSetName="Group")]
        [Parameter(ParameterSetName="Hosted")]
        [Parameter(ParameterSetName="Proxy")]
        [ValidateSet('True','False')]
        [String]
        $StrictContentValidation = 'True',

        [Parameter(ParameterSetName="Hosted")]
        [Parameter(ParameterSetName="Proxy")]
        [ValidateSet('Allow','Deny','Allow_Once')]
        [String]
        $DeploymentPolicy
    )

    begin {

        if(-not $header){
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories"

    }

    process {
        $formatUrl = $urislug + "/$Format"

        $FullUrlSlug = $formatUrl + "/$Type"

        switch ($PSCmdlet.ParameterSetName){
            'Group' {}
            'Hosted' {
                $Body = @{
                    name          = $Name
                    online        = $Online
                    cleanup       = @{
                        policyNames = @($CleanupPolicy )
                    }
                    storage       = @{
                        strictContentTypeValidation = $StrictContentValidation
                        blobStoreName               = $BlobStoreName
                        writePolicy = $($DeploymentPolicy.ToUpper())
                    }
                }

                Write-Verbose $($Body | ConvertTo-Json)
                Invoke-Nexus -UriSlug $FullUrlSlug -Body $Body -Method POST

            }
            'Proxy' {

               $Body = @{
                    name          = $Name
                    proxy         = @{
                        remoteUrl = $ProxyRemoteUrl
                        metadataMaxAge  = $MetadataMaxAgeMinutes
                        contentMaxAge   = $ContentMaxAgeMinutes 
                    }
                    online        = $Online
                    nugetProxy    = @{
                        nugetVersion         = $NugetVersion
                        queryCacheItemMaxAge = $QueryCacheItemMaxAgSeconds
                    }
                    negativeCache = @{
                        enabled    = $UseNegativeCache
                        timeToLive = $NegativeCacheTTLMinutes
                    }
                    httpClient    = @{
                        blocked        = $false 
                        autoBlock      = $true 
                        <#connection = @{
                            retries = 0
                            userAgentSuffix = ''
                            timeout = 60
                            enableCircularRedirects = $false
                            enableCookies = $false
                        }#>

                        <#authentication = @{
                            type = "username"
                            username = ''
                            ntlmHost = ''
                            ntlmDomain = ''
                        }
                        #>

                    }
                    cleanup       = @{
                        policyNames = @($CleanupPolicy )
                    }
                    storage       = @{
                        strictContentTypeValidation = $StrictContentValidation
                        blobStoreName               = $BlobStoreName 
                    }
                }

                Write-Verbose $($Body | ConvertTo-Json)
                Invoke-Nexus -UriSlug $FullUrlSlug -Body $Body -Method POST

            }
        }
        
    }
}
#EndRegion '.\public\Repository\New-NexusRepository.ps1' 245
#Region '.\public\Repository\Remove-NexusRepository.ps1' 0
function Remove-NexusRepository {
    <#
    .SYNOPSIS
    Removes a given repository from the Nexus instance
     
    .DESCRIPTION
    Removes a given repository from the Nexus instance
     
    .PARAMETER Repository
    The repository to remove
     
    .PARAMETER Force
    Disable prompt for confirmation before removal
     
    .EXAMPLE
    Remove-NexusRepository -Repository ProdNuGet
 
    .EXAMPLE
    Remove-NexusRepository -Repository MavenReleases -Force()
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/Remove-NexusRepository/', SupportsShouldProcess, ConfirmImpact = 'High')]
    Param(
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [Alias('Name')]
        [ArgumentCompleter( {
                param($CommandName, $ParameterName, $WordToComplete, $CommandAst, $FakeBoundParameters)
                $repositories = (Get-NexusRepository).Name

                if ($WordToComplete) {
                    $repositories.Where{ $_ -match "^$WordToComplete" }
                }
                else {
                    $repositories
                }
            })]
        [String[]]
        $Repository,

        [Parameter()]
        [Switch]
        $Force
    )
    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/repositories"
    }
    process {

        $Repository | Foreach-Object {
            $Uri = $urislug + "/$_"

            try {
           
                if ($Force -and -not $Confirm) {
                    $ConfirmPreference = 'None'
                    if ($PSCmdlet.ShouldProcess("$_", "Remove Repository")) {
                        $result = Invoke-Nexus -UriSlug $Uri -Method 'DELETE' -ErrorAction Stop
                        [pscustomobject]@{
                            Status     = 'Success'
                            Repository = $_     
                        }
                    }
                }
                else {
                    if ($PSCmdlet.ShouldProcess("$_", "Remove Repository")) {
                        $result = Invoke-Nexus -UriSlug $Uri -Method 'DELETE' -ErrorAction Stop
                        [pscustomobject]@{
                            Status     = 'Success'
                            Repository = $_
                            Timestamp  = $result.date
                        }
                    }
                }
            }

            catch {
                $_.exception.message
            }
        }
    }
}
#EndRegion '.\public\Repository\Remove-NexusRepository.ps1' 86
#Region '.\public\Repository\Cleanup Policy\Get-NexusCleanupPolicy.ps1' 0
function Get-NexusCleanupPolicy {
    <#
    .SYNOPSIS
    Gets Nexus Cleanup Policy information
     
    .DESCRIPTION
    Gets Nexus Cleanup Policy information
     
    .PARAMETER Name
    The specific policy to retrieve
     
    .EXAMPLE
    Get-NexusCleanupPolicy
 
    .EXAMPLE
    Get-NexusCleanupPolicy -Name TestPol
 
    .EXAMPLE
    Get-NexusCleanupPolicy -Name TestPol,ProdPol
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Repository/Cleanup%20Policy/Get-NexusCleanupPolicy/')]
    Param(
        [Parameter()]
        [Alias('Policy','CleanupPolicy')]
        [String[]]
        $Name
    )

    process {
        
        $urislug = "/service/rest/internal/cleanup-policies?_dc=$(([DateTime]::ParseExact("01/02/0001 21:08:29", "MM/dd/yyyy HH:mm:ss",$null)).Ticks)"

        if(-not $CleanupPolicy){
            Invoke-Nexus -Urislug $urislug -Method GET
        } else {
            $result = Invoke-Nexus -Urislug $urislug -Method GET

            $result | Where-Object { $_.name -in $CleanupPolicy}
        }
    }

}
#EndRegion '.\public\Repository\Cleanup Policy\Get-NexusCleanupPolicy.ps1' 46
#Region '.\public\Repository\Cleanup Policy\New-NexusCleanupPolicy.ps1' 0
function New-NexusCleanupPolicy {
    <#
    .SYNOPSIS
    Create a new Nexus Cleanup Policy
     
    .DESCRIPTION
    Create a new Nexus Cleanup Policy
     
    .PARAMETER Name
    Unique name for the cleanup policy
     
    .PARAMETER Format
    The format that this cleanup policy can be applied to
     
    .PARAMETER Notes
    Additional details about the policy
     
    .PARAMETER ComponentAge
    Remove components that were published over this many days
     
    .PARAMETER ComponentUsage
    Remove components that haven't been downloaded in this many days
     
    .PARAMETER AssetMatcher
    Remove components that have at least one asset name matching the following regular expression pattern
     
     
    .EXAMPLE
    New-NexusCleanupPolicy -Name SamplePol -Format nuget -ComponentAge 180
 
    .EXAMPLE
    New-NexusCleanupPolicy -Name SamplePol -Format Go -ComponentUsage 90 -AssetMatcher '*.+'
     
    .NOTES
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Repository/Cleanup%20Policy/New-NexusCleanupPolicy/',DefaultParameterSetName = "Default")]
    Param(
        [Parameter(Mandatory)]
        [Parameter(ParameterSetName = 'Age', Mandatory)]
        [Parameter(ParameterSetName = 'Usage', Mandatory)]

        [String]
        $Name,

        [Parameter(Mandatory)]
        [Parameter(ParameterSetName = 'Age', Mandatory)]
        [Parameter(ParameterSetName = 'Usage', Mandatory)]
        [ValidateSet('All', 'Apt', 'Bower', 'CocoaPods', 'Conan', 'Conda', 'Docker', 'GitLFS', 'Go', 'Helm', 'Maven2', 'Npm', 'Nuget', 'P2', 'PyPi', 'R', 'Raw', 'RubyGems', 'Yum')]
        [String]
        $Format,

        [Parameter()]
        [String]
        $Notes,

        [Parameter(ParameterSetName = 'Age', Mandatory)]
        [Int]
        $ComponentAge,

        [Parameter(ParameterSetName = 'Usage', Mandatory)]
        [Int]
        $ComponentUsage,

        [Parameter(ParameterSetName = 'Age')]
        [Parameter(ParameterSetName = 'Usage')]
        [String]
        $AssetMatcher
    )

    process {

        $urislug = "/service/rest/internal/cleanup-policies?_dc=$(([DateTime]::ParseExact("01/02/0001 21:08:29", "MM/dd/yyyy HH:mm:ss",$null)).Ticks)"

        switch ($PSCmdlet.ParameterSetName) {
            'Age' {
                $Body = @{
                    name                    = $Name
                    notes                   = $Notes
                    criteriaLastBlobUpdated = $ComponentAge
                    format                  = $Format.ToLower()
                }
            }
            'Usage' {
                $Body = @{
                    name                   = $Name
                    notes                  = $Notes
                    criteriaLastDownloaded = $ComponentUsage
                    format                 = $Format.ToLower()
                }
            }
        }

        if ($AssetMatcher) {
            if ($Format -ne 'All') {
                $Body.Add('criteriaAssetRegex', $AssetMatcher)
            } else {
                Write-Warning "Asset matcher will be thrown out as it doesn't apply to All formats"
            }
        }

        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST
    }
}
#EndRegion '.\public\Repository\Cleanup Policy\New-NexusCleanupPolicy.ps1' 104
#Region '.\public\Repository\Cleanup Policy\Remove-NexusCleanupPolicy.ps1' 0
function Remove-NexusCleanupPolicy {
    <#
    .SYNOPSIS
    Removes a Nexus Cleanup Policy
     
    .DESCRIPTION
    Removes a Nexus Cleanup Policy
     
    .PARAMETER Name
    The policy to remove
     
    .PARAMETER Force
    Don't prompt for confirmation before removal
     
    .EXAMPLE
    Remove-NexusCleanupPolicy -Name TestPolicy
 
    .EXAMPLE
    Remove-NexusCleanupPolicy -Name TestPolicy -Force
 
    .EXAMPLE
    Get-NexusCleanupPolicy -Name TestPol | Remove-NexusCleanupPolicy -Force
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Repository/Cleanup%20Policy/Remove-NexusCleanupPolicy/',SupportsShouldProcess, ConfirmImpact = 'High')]
    Param(
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ArgumentCompleter( {
                param($Command, $Parameters, $WordToComplete, $CommandAst, $FakeBoundParams)

                $r = (Get-NexusCleanupPolicy).Name

                if ($WordToComplete) {
                    $r.Where($_ -match "^$WordToComplete")
                } 

                else {
                    $r
                }
            })]
        [String]
        $Name,

        [Parameter()]
        [Switch]
        $Force
    )

    process {

        $Name | Foreach-Object {
            $urislug = "/service/rest/internal/cleanup-policies/$($_)?_dc=$(([DateTime]::ParseExact("01/02/0001 21=08=29", "MM/dd/yyyy HH=mm=ss",$null)).Ticks)"
            if ($Force -and -not $Confirm) {
                $ConfirmPreference = 'None'
                if ($PSCmdlet.ShouldProcess("$($_)", "Remove Cleanup Policy")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE
                }
            }
            else {
                if ($PSCmdlet.ShouldProcess("$($_)", "Remove Cleanup Policy")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE
                }
            }
        }    }
}
#EndRegion '.\public\Repository\Cleanup Policy\Remove-NexusCleanupPolicy.ps1' 68
#Region '.\public\Repository\Cleanup Policy\Set-NexusCleanupPolicy.ps1' 0
function Set-NexusCleanupPolicy {
    <#
    .SYNOPSIS
    Updates a Nexus Cleanup Policy
     
    .DESCRIPTION
    Updates a Nexus Cleanup Policy
     
    .PARAMETER Name
    The cleanup policy to update
     
    .PARAMETER Format
    The format that this cleanup policy can be applied to
     
    .PARAMETER Notes
    Additional details about the policy
     
    .PARAMETER ComponentAge
    Remove components that were published over this many days
     
    .PARAMETER ComponentUsage
    Remove components that haven't been downloaded in this many days
     
    .PARAMETER AssetMatcher
    Remove components that have at least one asset name matching the following regular expression pattern
     
    .EXAMPLE
    Set-NexusCleanupPolicy -Name TestPol -Notes "New notes here" -ComponentAge 60
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Repository/Cleanup%20Policy/Set-NexusCleanupPolicy/')]
    Param(
        [Parameter(Mandatory)]
        [ArgumentCompleter( {
                param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

                $r = (Get-NexusCleanupPolicy).Name

                if ($WordToComplete) {
                    $r.Where($_ -match "^$WordToComplete")
                }

                else {
                    $r
                }
            })]
        [String]
        $Name,

        [ValidateSet('All', 'Apt', 'Bower', 'CocoaPods', 'Conan', 'Conda', 'Docker', 'GitLFS', 'Go', 'Helm', 'Maven2', 'Npm', 'Nuget', 'P2', 'PyPi', 'R', 'Raw', 'RubyGems', 'Yum')]
        [String]
        $Format,

        [Parameter()]
        [String]
        $Notes,

        [Int]
        $ComponentAge,

        [Int]
        $ComponentUsage,

        [String]
        $AssetMatcher
    )

    $currentSettings = Get-NexusCleanupPolicy -CleanupPolicy $Name

    $currentSettings = [pscustomobject]@{
        Name                    = $Name
        Format                  = $currentSettings.format
        Notes                   = $currentSettings.notes
        CriteriaLastBlobUpdated = $currentSettings.criteriaLastBlobUpdated
        CriteriaLastDownloaded  = $currentSettings.criteriaLastDownloaded
        CriteriaReleaseType     = $currentSettings.criteriaReleaseType
        CriteriaAssetRegex      = $currentSettings.criteriaAssetRegex
        InUseCount              = $currentSettings.inUseCount
    }

    $urislug = "/service/rest/internal/cleanup-policies/$($Name)?_dc=$(([DateTime]::ParseExact("01/02/0001 21=08=29", "MM/dd/yyyy HH=mm=ss",$null)).Ticks)"
    
    $Body = @{
        name                    = $Name
        notes                   = if($Notes){ $Notes } else { $currentSettings.Notes}
        criteriaLastDownloaded  = if($ComponentUsage) { $ComponentUsage} else {$currentSettings.CriteriaLastDownloaded}
        criteriaLastBlobUpdated = if($ComponentAge) { $ComponentAge} else {$currentSettings.CriteriaLastBlobUpdated}
        criteriaAssetRegex      = if($AssetMatcher) {$AssetMatcher} else { $currentSettings.CriteriaAssetRegex}
        format                  = if($Format) { $Format.ToLower()} else {$currentSettings.Format}
    }

    Write-Verbose ($Body | ConvertTo-Json)
    Invoke-Nexus -Urislug $urislug -Body $Body -Method PUT
}
#EndRegion '.\public\Repository\Cleanup Policy\Set-NexusCleanupPolicy.ps1' 97
#Region '.\public\RoutingRule\Get-NexusRoutingRule.ps1' 0
function Get-NexusRoutingRule {
    <#
    .SYNOPSIS
    Get Nexus Routing rule information
     
    .DESCRIPTION
    Get Nexus Routing rule information
     
    .PARAMETER Name
    Specific routing rule to return
     
    .EXAMPLE
    Get-NexusRoutingRule
 
    .EXAMPLE
    Get-NexusRoutingRule -Name NugetRule
     
    .NOTES
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Get-NexusRoutingRule/')]
    Param(
        [Parameter()]
        [String[]]
        $Name
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

    }
    process {
        if(-not $Name){
            $urislug = "/service/rest/v1/routing-rules"

            $result = Invoke-Nexus -UriSlug $urislug -Method GET
            $result | ForEach-Object {
                [pscustomobject]@{
                    Name = $_.name
                    Description = $_.description
                    Mode = $_.mode
                    Matchers = $_.matchers
                }
            }
        } else {
            $name | ForEach-Object {
                $urislug = "/service/rest/v1/routing-rules/$_"

                $result = Invoke-Nexus -Urislug $urislug -Method GET
                $result | ForEach-Object {
                    [pscustomobject]@{
                        Name = $_.name
                        Description = $_.description
                        Mode = $_.mode
                        Matchers = $_.matchers
                    }
                }
            }
        }
    }
}
#EndRegion '.\public\RoutingRule\Get-NexusRoutingRule.ps1' 63
#Region '.\public\RoutingRule\New-NexusRoutingRule.ps1' 0
function New-NexusRoutingRule {
    <#
    .SYNOPSIS
    Create a new Nexus routing rule
     
    .DESCRIPTION
    Create a new Nexus routing rule
     
    .PARAMETER Name
    The name of the rule
 
    .PARAMETER Description
    A brief explanation of the routing rule
     
    .PARAMETER Mode
    Allow the connection, or block the connection
     
    .PARAMETER Matchers
    Regex strings to match for the route
     
    .EXAMPLE
    New-NexusRoutingRule -Name BlockNuGet -Mode Block -Matchers 'NuGet','[\w]Nuget.+'
     
    .NOTES
    General notes
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/New-NexusRoutingRule/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter()]
        [String]
        $Description,

        [Parameter(Mandatory)]
        [ValidateSet('Allow','Block')]
        [String]
        $Mode,

        [Parameter(Mandatory)]
        [String[]]
        $Matchers
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/routing-rules"
    }

    process {

        $Body = @{
            name = $Name
            description = $Description
            mode = $Mode.ToUpper()
            matchers = @($Matchers)
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST

    }
}
#EndRegion '.\public\RoutingRule\New-NexusRoutingRule.ps1' 70
#Region '.\public\RoutingRule\Remove-NexusRoutingRule.ps1' 0
function Remove-NexusRoutingRule {
    <#
    .SYNOPSIS
    Disable realms in Nexus
     
    .DESCRIPTION
    Disable realms in Nexus
     
    .PARAMETER Rule
    The realms you wish to activate
 
    .PARAMETER Force
    Don't prompt for confirmation
     
    .EXAMPLE
    Remove-NexusRoutingRule -Rule NugetRule
 
    .EXAMPLE
    Remove-NexusRoutingRule -Rule NugetRule -Force
     
    .NOTES
    #>

    [CmdletBinding(HelpUri = 'https://github.com/steviecoaster/NexuShell/blob/develop/docs/Remove-NexusRoutingRule.md',SupportsShouldProcess,ConfirmImpact = 'High')]
    Param(
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ArgumentCompleter( {
                param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

                $r = (Get-NexusRoutingRule).name

                if ($WordToComplete) {
                    $r.Where($_ -match "^$WordToComplete")
                }
                else {
                    $r
                }
            }
        )]
        [Alias('Name')]
        [String[]]
        $Rule,

        [Parameter()]
        [Switch]
        $Force
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {
        $Rule | ForEach-Object {
            $urislug = "/service/rest/v1/routing-rules/$_"

            try {
           
                if ($Force -and -not $Confirm) {
                    $ConfirmPreference = 'None'
                    if ($PSCmdlet.ShouldProcess("$_", "Remove Routing rule")) {
                        Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                        
                    }
                }
                else {
                    if ($PSCmdlet.ShouldProcess("$_", "Remove Routing rule")) {
                        Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                    }
                }
            }
    
            catch {
                $_.exception.message
            }
    
        }

    }
}
#EndRegion '.\public\RoutingRule\Remove-NexusRoutingRule.ps1' 83
#Region '.\public\RoutingRule\Set-NexusRoutingRule.ps1' 0
function Set-NexusRoutingRule {
    <#
    .SYNOPSIS
    Updates a Nexus routing rule
     
    .DESCRIPTION
    Updates a Nexus routing rule
     
    .PARAMETER Name
    The name of the rule
 
    .PARAMETER Description
    A brief explanation of the routing rule
     
    .PARAMETER Mode
    Allow the connection, or block the connection
     
    .PARAMETER Matchers
    Regex strings to match for the route
     
    .EXAMPLE
    Set-NexusRoutingRule -Name BlockNuGet -Mode Block -Matchers 'NuGet','[\w]Nuget.+'
     
    .NOTES
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/Set-NexusRoutingRule/')]
    Param(
        [Parameter(Mandatory)]
        [ArgumentCompleter( {
            param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

            $r = (Get-NexusRoutingRule).name

            if ($WordToComplete) {
                $r.Where($_ -match "^$WordToComplete")
            }
            else {
                $r
            }
        }
    )]
        [String]
        $Name,

        [Parameter()]
        [String]
        $Description,

        [Parameter(Mandatory)]
        [ValidateSet('Allow','Block')]
        [String]
        $Mode,

        [Parameter(Mandatory)]
        [String[]]
        $Matchers
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = "/service/rest/v1/routing-rules/$Name"
    }

    process {

        $Body = @{
            name = $Name
            description = $Description
            mode = $Mode.ToUpper()
            matchers = @($Matchers)
        }

        Write-Verbose $($Body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method PUT

    }
}
#EndRegion '.\public\RoutingRule\Set-NexusRoutingRule.ps1' 82
#Region '.\public\Script\Get-NexusScript.ps1' 0
function Get-NexusScript {
    <#
    .SYNOPSIS
    Returns scripts stored for execution in Nexus
     
    .DESCRIPTION
    Returns scripts stored for execution in Nexus
 
    .PARAMETER Name
    Return a specific script's details
     
    .EXAMPLE
    Get-NexusScript
 
    .EXAMPLE
    Get-NexusScript -Name SuperAwesomeScript
     
    .NOTES
     
    #>

    [CmdletBinding()]
    Param(
        [Parameter()]
        [String[]]
        $Name
    )
    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {

        if (-not $Name) {
            $urislug = "/service/rest/v1/script"
            $result = Invoke-Nexus -UriSlug $urislug -Method GET
            $result | ForEach-Object {
                [pscustomobject]@{
                    Name    = $_.name
                    Content = $_.content
                    Type    = $_.type
                }
            }
    
        }
        else {

            $Name | Foreach-Object {
                $urislug = "/service/rest/v1/script/$_"
                $result = Invoke-Nexus -UriSlug $urislug -Method GET
                $result | ForEach-Object {
                    [pscustomobject]@{
                        Name    = $_.name
                        Content = $_.content
                        Type    = $_.type
                    }
                }
            }
        }

    }
}
#EndRegion '.\public\Script\Get-NexusScript.ps1' 64
#Region '.\public\Script\New-NexusScript.ps1' 0
function New-NexusScript {
    <#
    .SYNOPSIS
    Stores a new script in Nexus
     
    .DESCRIPTION
    Stores a new script in Nexus
     
    .PARAMETER Name
    The name of the script
     
    .PARAMETER Content
    The contents of the script
     
    .PARAMETER Type
    The language of the script
     
    .EXAMPLE
    New-NexusScript -Name TestScript -Content 'Get-ComputerInfo' -Type powershell
     
    .NOTES
     
    #>

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

        [Parameter(Mandatory)]
        [String]
        $Content,

        [Parameter(Mandatory)]
        [String]
        $Type
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {

        $urislug = "/service/rest/v1/script"

        $body = @{
            name = $Name
            content = $Content
            type = $Type
        }
        
        Write-Verbose ($body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method POST

    }
}
#EndRegion '.\public\Script\New-NexusScript.ps1' 60
#Region '.\public\Script\Remove-NexusScript.ps1' 0
function Remove-NexusScript {
    <#
    .SYNOPSIS
    Deletes a stored script from Nexus
     
    .DESCRIPTION
    Deletes a stored script from Nexus
     
    .PARAMETER Name
    The script to remove
     
    .PARAMETER Force
    Don't prompt for confirmation before removing
     
    .EXAMPLE
    Remove-NexusScript -Name TestScript
 
    .EXAMPLE
    Remove-NexusScript -Name TestScript -Force
 
    .EXAMPLE
    GetNexusScript | Remove-NexusScript -Force
     
    .NOTES
 
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
    Param(
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ArgumentCompleter( {
                param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

                $r = (Get-NexusScript).name

                if ($WordToComplete) {
                    $r.Where{ $_ -match "^$WordToComplete" }
                }
                else {
                    $r
                }
            }
        )]
        [String[]]
        $Name,

        [Parameter()]
        [Switch]
        $Force
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {
       
        $Name | Foreach-Object {

            $urislug = "/service/rest/v1/script/$_"

            if ($Force -and -not $Confirm) {
                $ConfirmPreference = 'None'
                if ($PSCmdlet.ShouldProcess("$_", "Remove Script")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                }
            }
            else {
                if ($PSCmdlet.ShouldProcess("$_", "Remove Script")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                }
            }

        } 
    }
}
#EndRegion '.\public\Script\Remove-NexusScript.ps1' 78
#Region '.\public\Script\Set-NexusScript.ps1' 0
function Set-NexusScript {
    <#
    .SYNOPSIS
    Updates a script saved in Nexus
     
    .DESCRIPTION
    Updates a script saved in Nexus
     
    .PARAMETER Name
    The script to update
     
    .PARAMETER Content
    The new content of the script
     
    .PARAMETER Type
    The new type, if different
     
    .EXAMPLE
    Set-NexusScript -Name SuperAwesomeScript -Content "some awesome groovy code" -Type groovy
     
    .NOTES
     
    #>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,
        
        [Parameter(Mandatory)]
        [String]
        $Content,

        [Parameter(Mandatory)]
        [String]
        $Type
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {

        $urislug = "/service/rest/v1/script/$Name"

        $body = @{
            name = $Name
            content = $Content
            type = $Type
        }
        
        Write-Verbose ($body | ConvertTo-Json)
        Invoke-Nexus -UriSlug $urislug -Body $Body -Method PUT

    }

}
#EndRegion '.\public\Script\Set-NexusScript.ps1' 61
#Region '.\public\Script\Start-NexusScript.ps1' 0
function Start-NexusScript {
    <#
    .SYNOPSIS
    Executes a saved script in Nexus
     
    .DESCRIPTION
    Executes a saved script in Nexus
     
    .PARAMETER Name
    The name of the script to execute
     
    .EXAMPLE
    Start-NexusScript -Name TestScript
     
    .NOTES
     
    #>

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {
        $urislug = "/service/rest/v1/script/$Name/run"

        Invoke-Nexus -Urislug $urislug -BodyAsString $Name -ContentType 'text/plain' -Method POST -ErrorAction Stop
    }
}
#EndRegion '.\public\Script\Start-NexusScript.ps1' 37
#Region '.\public\Security\LDAP\Get-NexusLDAPServer.ps1' 0
function Get-NexusLDAPServerConnection {
    <#
    .SYNOPSIS
    Returns a list of conigured LDAP sources
     
    .DESCRIPTION
    Returns a list of configured LDAP sources. Annoyingly...it does not include the name
     
    .PARAMETER Name
    The name of the LDAP source to retrieve. You'll have to know this value, as it isn't returned by the API
    when you run wthis command without any parameters
     
    .EXAMPLE
    Get-NexusLDAPServerConnection
 
    .EXAMPLE
    Get-NexusLDAPServerConnection -Name ActiveDirectoryConnection
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/LDAP/Get-NexusLDAPServerConnection/')]
    Param(
        [Parameter()]
        [String[]]
        $Name
    )
    
    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

    }

    process {

        if (-not $Name) {
            $urislug = '/service/rest/v1/security/ldap'
            $result = Invoke-Nexus -Urislug $urislug -Method GET
            
            [pscustomobject]@{
                Protocol                    = $result.protocol
                UseTrustStore               = $result.useTrustStore
                Host                        = $result.host
                Port                        = $result.port
                SearchBase                  = $result.searchBase
                AuthScheme                  = $result.authScheme
                AuthRealm                   = $result.authRealm
                AuthUsername                = $result.authUsername
                ConnectionTimeoutSeconds    = $result.connectionTimeoutSeconds
                ConnectionRetryDelaySeconds = $result.connectionRetryDelaySeconds
                MaxIncidentsCount           = $result.maxIncidentsCount
                UserBaseDn                  = $result.userBaseDn
                UserSubtree                 = $result.userSubtree
                UserObjectClass             = $result.userObjectClass
                UserLdapFilter              = $result.userLdapFilter
                UserIdAttribute             = $result.userIdAttribute
                UserRealNameAttribute       = $result.userRealNameAttribute
                UserEmailAddressAttribute   = $result.userEmailAddressAttribute
                UserPasswordAttribute       = $result.userPasswordAttribute
                LdapGroupsAsRoles           = $result.ldapGroupsAsRoles
                GroupType                   = $result.groupType
                GroupBaseDn                 = $result.groupBaseDn
                GroupSubtree                = $result.groupSubtree
                GroupObjectClass            = $result.groupObjectClass
                GroupIdAttribute            = $result.groupIdAttribute
                GroupMemberAttribute        = $result.groupMemberAttribute
                GroupMemberFormat           = $result.groupMemberFormat
                UserMemberOfAttribute       = $result.userMemberOfAttribute
                Id                          = $result.id
                Order                       = $result.order
            }
        }
        else {
            $Name | Foreach-Object {
                $urislug = "/service/rest/v1/security/ldap/$_"
                $result = Invoke-Nexus -Urislug $urislug -Method GET
                $result | Foreach-Object {
                    [pscustomobject]@{
                        Protocol                    = $_.protocol
                        UseTrustStore               = $_.useTrustStore
                        Host                        = $_.host
                        Port                        = $_.port
                        SearchBase                  = $_.searchBase
                        AuthScheme                  = $_.authScheme
                        AuthRealm                   = $_.authRealm
                        AuthUsername                = $_.authUsername
                        ConnectionTimeoutSeconds    = $_.connectionTimeoutSeconds
                        ConnectionRetryDelaySeconds = $_.connectionRetryDelaySeconds
                        MaxIncidentsCount           = $_.maxIncidentsCount
                        UserBaseDn                  = $_.userBaseDn
                        UserSubtree                 = $_.userSubtree
                        UserObjectClass             = $_.userObjectClass
                        UserLdapFilter              = $_.userLdapFilter
                        UserIdAttribute             = $_.userIdAttribute
                        UserRealNameAttribute       = $_.userRealNameAttribute
                        UserEmailAddressAttribute   = $_.userEmailAddressAttribute
                        UserPasswordAttribute       = $_.userPasswordAttribute
                        LdapGroupsAsRoles           = $_.ldapGroupsAsRoles
                        GroupType                   = $_.groupType
                        GroupBaseDn                 = $_.groupBaseDn
                        GroupSubtree                = $_.groupSubtree
                        GroupObjectClass            = $_.groupObjectClass
                        GroupIdAttribute            = $_.groupIdAttribute
                        GroupMemberAttribute        = $_.groupMemberAttribute
                        GroupMemberFormat           = $_.groupMemberFormat
                        UserMemberOfAttribute       = $_.userMemberOfAttribute
                        Id                          = $_.id
                        Order                       = $_.order
                    }
        
                }
            }
        }
    }
}
#EndRegion '.\public\Security\LDAP\Get-NexusLDAPServer.ps1' 118
#Region '.\public\Security\LDAP\New-NexusLDAPServer.ps1' 0
function New-NexusLDAPServerConnection {
    <#
    .SYNOPSIS
    Creates a new LDAP Connection in Nexus
     
    .DESCRIPTION
    Creates a new LDAP connection in Nexus, allowing domain users to authenticate
     
    .PARAMETER Name
    The Name of the LDAP Connection
     
    .PARAMETER LdapProtocol
    The LDAP Protocol to use
     
    .PARAMETER UseTrustStore
    Whether to use certificates stored in Nexus Repository Manager's truststore
     
    .PARAMETER LdapHost
    LDAP server connection hostname
     
    .PARAMETER LdapPort
    Typically 389 for ldap:// and 636 for ldaps://
     
    .PARAMETER SearchBase
    LDAP location to be added to the connection URL
     
    .PARAMETER AuthenticationScheme
    Authentication scheme used for connecting to LDAP server
     
    .PARAMETER AuthenticationRealm
    The SASL realm to bind to. Required if authScheme is CRAM_MD5 or DIGEST_MD5
     
    .PARAMETER Credential
    Used to generate the authUsername and authPassword fields required when using an Authentication Scheme other than 'None'
     
    .PARAMETER ConnectionTimeoutSeconds
    How long to wait before timeout
     
    .PARAMETER RetryDelaySeconds
    How long to wait before retrying
     
    .PARAMETER MaxIncidentCount
    The number of retries before failure
     
    .PARAMETER UserBaseDN
    The relative DN where user objects are found (e.g. ou=people). This value will have the Search base DN value appended to form the full User search base DN.
     
    .PARAMETER WalkUserSubtree
    Are users located in structures below the user base DN?
     
    .PARAMETER UserObjectClass
    LDAP class for user objects
     
    .PARAMETER UserLDAPFilter
    LDAP search filter to limit user search (e.g. (|(mail=*@example.com)(uid=dom*)) )
     
    .PARAMETER UserIdAttribute
    This is used to find a user given its user ID (e.g. 'uid')
     
    .PARAMETER UserRealNameAttribute
    This is used to find a real name given the user ID (e.g. 'cn')
     
    .PARAMETER UserEmailAddressAttribute
    This is used to find an email address given the user ID (e.g. 'mail')
     
    .PARAMETER UserPasswordAttribute
    If this field is blank the user will be authenticated against a bind with the LDAP server
     
    .PARAMETER LDAPGroupsAsRoles
    Denotes whether LDAP assigned roles are used as Nexus Repository Manager roles
     
    .PARAMETER GroupType
    Defines a type of groups used: static (a group contains a list of users) or dynamic (a user contains a list of groups). Required if ldapGroupsAsRoles is true.
     
    .PARAMETER GroupBaseDN
    The relative DN where group objects are found (e.g. ou=Group). This value will have the Search base DN value appended to form the full Group search base DN.
     
    .PARAMETER WalkGroupSubtree
    Are groups located in structures below the group base DN
     
    .PARAMETER GroupObjectClass
    LDAP class for group objects. Required if groupType is static
     
    .PARAMETER GroupIdAttribute
    This field specifies the attribute of the Object class that defines the Group ID. Required if groupType is static
     
    .PARAMETER GroupMemberAttribute
    LDAP attribute containing the usernames for the group. Required if groupType is static
     
    .PARAMETER GroupMemberFormat
    The format of user ID stored in the group member attribute. Required if groupType is static (e.g. uid=${username},ou=people,dc=example,dc=com)
     
    .PARAMETER UserMemberOfAttribute
    Set this to the attribute used to store the attribute which holds groups DN in the user object. Required if groupType is dynamic (e.g. 'memberOf')
     
    .EXAMPLE
    $params = @{
        Name = 'ExampleLDAPConnection'
        LdapProtocol = 'Ldap'
        LdapHost = 'domaincontroller'
        LdapPort = 389
        SearchBase = "OU=Sales,DC=domain,DC=com"
        ConnectionTimeoutSeconds = 50
        RetryDelaySeconds = 50
        MaxIncidentCount = 50
        UserBaseDN = "CN=Users,DC=domain,DC=com"
        WalkUserSubtree = $true
        UserObjectClass = 'user'
        UserLDAPFilter = 'phone=foo'
        UserIdAttribute = 'samAccountName'
        UserRealNameAttribute = 'cn'
        UserEmailAddressAttribute = 'mail'
        LDAPGroupsAsRoles = $true
        GroupType = 'Dynamic'
        WalkGroupSubtree = $true
    }
 
    New-NexusLDAPServerConnection @params
     
    .NOTES
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/LDAP/New-NexusLDAPServerConnection/',DefaultParameterSetName = "default")]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter(Mandatory)]
        [ValidateSet('Ldap', 'Ldaps')]
        [String]
        $LdapProtocol,

        [Parameter()]
        [Switch]
        $UseTrustStore,

        [Parameter(Mandatory)]
        [String]
        $LdapHost,

        [Parameter(Mandatory)]
        [Int]
        $LdapPort,

        [Parameter(Mandatory)]
        [String]
        $SearchBase,

        [Parameter()]
        [Parameter(Mandatory, ParameterSetName = 'Auth')]
        [ValidateSet('None', 'Simple', 'DigestMD5', 'CramMD5')]
        [String]
        $AuthenticationScheme,

        [Parameter(Mandatory, ParameterSetName = 'Auth')]
        [Alias('Domain')]
        [String]
        $AuthenticationRealm,

        [Parameter(Mandatory, ParameterSetName = 'Auth')]
        [PSCredential]
        $Credential,

        [Parameter(Mandatory)]
        [ValidateRange(0, 3600)]
        [Int]
        $ConnectionTimeoutSeconds,

        [Parameter(Mandatory)]
        [Int]
        $RetryDelaySeconds,

        [Parameter(Mandatory)]
        [Int]
        $MaxIncidentCount,

        [Parameter(Mandatory)]
        [String]
        $UserBaseDN,

        [Parameter()]
        [Switch]
        $WalkUserSubtree,

        [Parameter(Mandatory)]
        [String]
        $UserObjectClass,

        [Parameter(Mandatory)]
        [String]
        $UserLDAPFilter,

        [Parameter()]
        [String]
        $UserIdAttribute = 'uid',

        [Parameter()]
        [String]
        $UserRealNameAttribute = 'cn',

        [Parameter()]
        [String]
        $UserEmailAddressAttribute = 'mail',

        [Parameter()]
        [String]
        $UserPasswordAttribute,

        [Parameter()]
        [Switch]
        $LDAPGroupsAsRoles,

        [Parameter()]
        [ValidateSet('Static', 'Dynamic')]
        [String]
        $GroupType = 'Static',

        [Parameter()]
        [String]
        $GroupBaseDN,

        [Parameter()]
        [Switch]
        $WalkGroupSubtree,

        [Parameter()]
        [String]
        $GroupObjectClass,

        [Parameter()]
        [String]
        $GroupIdAttribute,

        [Parameter()]
        [String]
        $GroupMemberAttribute,

        [Parameter()]
        [String]
        $GroupMemberFormat,

        [Parameter()]
        [String]
        $UserMemberOfAttribute = 'memberOf'
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

    }

    process {
        $urislug = '/service/rest/v1/security/ldap'

        $body = @{
            name                        = $Name
            protocol                    = $LdapProtocol.ToLower()
            useTrustStore               = [bool]$UseTrustStore
            host                        = $LdapHost
            port                        = $LdapPort
            searchBase                  = $SearchBase
            connectionTimeoutSeconds    = $ConnectionTimeoutSeconds
            connectionRetryDelaySeconds = $RetryDelaySeconds
            maxIncidentsCount           = $MaxIncidentCount
            userBaseDn                  = $UserBaseDN
            userSubtree                 = [bool]$WalkUserSubtree
            userObjectClass             = $UserObjectClass
            userLdapFilter              = $UserLDAPFilter
            userIdAttribute             = $UserIdAttribute
            userRealNameAttribute       = $UserRealNameAttribute
            userEmailAddressAttribute   = $UserEmailAddressAttribute
            userPasswordAttribute       = $UserPasswordAttribute
            ldapGroupsAsRoles           = [bool]$LDAPGroupsAsRoles
            groupType                   = $GroupType.ToLower()
            groupBaseDn                 = $GroupBaseDN
            groupSubtree                = [bool]$WalkGroupSubtree
            groupObjectClass            = $GroupObjectClass
            groupIdAttribute            = $GroupIdAttribute
            groupMemberAttribute        = $GroupMemberAttribute
            groupMemberFormat           = $GroupMemberFormat
            userMemberOfAttribute       = $UserMemberOfAttribute
        }

        if ($AuthenticationScheme -ne 'None' -and $null -ne $AuthenticationScheme) {
            $AuthenticationUsername = $Credential.UserName
            $AuthenticationPassword = $Credential.GetNetworkCredential().Password
        }
        switch ($AuthenticationScheme) {
            'None' { $body.Add('authScheme', 'NONE') }

            'Simple' { 
                $body.Add('authScheme', "$($AuthenticationScheme.ToUpper())")
                $body.Add('authRealm', $AuthenticationRealm)
                $body.Add('authUsername', $AuthenticationUsername)
                $body.Add('authPassword', $AuthenticationPassword)
            }

            
            'DigestMD5' { 
                $body.Add('authScheme', "$($AuthenticationScheme.ToUpper())")
                $body.Add('authRealm', $AuthenticationRealm)
                $body.Add('authUsername', $AuthenticationUsername)
                $body.Add('authPassword', $AuthenticationPassword)
            }
            
            'DigestMD5' { 
                $body.Add('authScheme', "$($AuthenticationScheme.ToUpper())")
                $body.Add('authRealm', $AuthenticationRealm)
                $body.Add('authUsername', $AuthenticationUsername)
                $body.Add('authPassword', $AuthenticationPassword)
            }

            'CramMD5' { 
                $body.Add('authScheme', "$($AuthenticationScheme.ToUpper())")
                $body.Add('authRealm', $AuthenticationRealm)
                $body.Add('authUsername', $AuthenticationUsername)
                $body.Add('authPassword', $AuthenticationPassword)
            }

            default { $body.Add('authScheme', 'NONE') }
        }

        Write-Verbose ($body | ConvertTo-Json)
        Invoke-Nexus -Urislug $urislug -Body $Body -Method POST
    }
}
#EndRegion '.\public\Security\LDAP\New-NexusLDAPServer.ps1' 329
#Region '.\public\Security\LDAP\Remove-NexusLDAPServer.ps1' 0
function Remove-NexusLDAPServerConnection {
    <#
    .SYNOPSIS
    Renove LDAP Connection from Nexus
     
    .DESCRIPTION
    Renove LDAP Connection from Nexus
     
    .PARAMETER Name
    The LDAP Connection you wish to remove
 
    .PARAMETER Force
    Don't prompt for confirmation
     
    .EXAMPLE
    Remove-NexusLDAPServerConnection -Name DevLDAP
 
    .EXAMPLE
    Remove-NexusLDAPServerConnection -Name DevLDAP -Force
     
    .NOTES
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/Security/LDAP/Remove-NexusLDAPServerConnection/',SupportsShouldProcess,ConfirmImpact = 'High')]
    Param(
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [String[]]
        $Name,

        [Parameter()]
        [Switch]
        $Force
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }


    }

    process {

        $Name | ForEach-Object {
            $urislug = "/service/rest/v1/security/ldap/$_"

            try {
           
                if ($Force -and -not $Confirm) {
                    $ConfirmPreference = 'None'
                    if ($PSCmdlet.ShouldProcess("$_", "Remove LDAP Connection")) {
                        Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                        
                    }
                }
                else {
                    if ($PSCmdlet.ShouldProcess("$_", "Remove LDAP Connection")) {
                        Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                    }
                }
            }
    
            catch {
                $_.exception.message
            }
    

        }

    }
}
#EndRegion '.\public\Security\LDAP\Remove-NexusLDAPServer.ps1' 73
#Region '.\public\Security\LDAP\Set-NexusLDAPServerConnection.ps1' 0
function Set-NexusLDAPServerConnection {
    <#
    .SYNOPSIS
    Updates a new LDAP Connection in Nexus
     
    .DESCRIPTION
    Updates a new LDAP connection in Nexus, allowing domain users to authenticate
     
    .PARAMETER Name
    The Name of the LDAP Connection
     
    .PARAMETER LdapProtocol
    The LDAP Protocol to use
     
    .PARAMETER UseTrustStore
    Whether to use certificates stored in Nexus Repository Manager's truststore
     
    .PARAMETER LdapHost
    LDAP server connection hostname
     
    .PARAMETER LdapPort
    Typically 389 for ldap:// and 636 for ldaps://
     
    .PARAMETER SearchBase
    LDAP location to be added to the connection URL
     
    .PARAMETER AuthenticationScheme
    Authentication scheme used for connecting to LDAP server
     
    .PARAMETER AuthenticationRealm
    The SASL realm to bind to. Required if authScheme is CRAM_MD5 or DIGEST_MD5
     
    .PARAMETER Credential
    Used to generate the authUsername and authPassword fields required when using an Authentication Scheme other than 'None'
     
    .PARAMETER ConnectionTimeoutSeconds
    How long to wait before timeout
     
    .PARAMETER RetryDelaySeconds
    How long to wait before retrying
     
    .PARAMETER MaxIncidentCount
    The number of retries before failure
     
    .PARAMETER UserBaseDN
    The relative DN where user objects are found (e.g. ou=people). This value will have the Search base DN value appended to form the full User search base DN.
     
    .PARAMETER WalkUserSubtree
    Are users located in structures below the user base DN?
     
    .PARAMETER UserObjectClass
    LDAP class for user objects
     
    .PARAMETER UserLDAPFilter
    LDAP search filter to limit user search (e.g. (|(mail=*@example.com)(uid=dom*)) )
     
    .PARAMETER UserIdAttribute
    This is used to find a user given its user ID (e.g. 'uid')
     
    .PARAMETER UserRealNameAttribute
    This is used to find a real name given the user ID (e.g. 'cn')
     
    .PARAMETER UserEmailAddressAttribute
    This is used to find an email address given the user ID (e.g. 'mail')
     
    .PARAMETER UserPasswordAttribute
    If this field is blank the user will be authenticated against a bind with the LDAP server
     
    .PARAMETER LDAPGroupsAsRoles
    Denotes whether LDAP assigned roles are used as Nexus Repository Manager roles
     
    .PARAMETER GroupType
    Defines a type of groups used: static (a group contains a list of users) or dynamic (a user contains a list of groups). Required if ldapGroupsAsRoles is true.
     
    .PARAMETER GroupBaseDN
    The relative DN where group objects are found (e.g. ou=Group). This value will have the Search base DN value appended to form the full Group search base DN.
     
    .PARAMETER WalkGroupSubtree
    Are groups located in structures below the group base DN
     
    .PARAMETER GroupObjectClass
    LDAP class for group objects. Required if groupType is static
     
    .PARAMETER GroupIdAttribute
    This field specifies the attribute of the Object class that defines the Group ID. Required if groupType is static
     
    .PARAMETER GroupMemberAttribute
    LDAP attribute containing the usernames for the group. Required if groupType is static
     
    .PARAMETER GroupMemberFormat
    The format of user ID stored in the group member attribute. Required if groupType is static (e.g. uid=${username},ou=people,dc=example,dc=com)
     
    .PARAMETER UserMemberOfAttribute
    Set this to the attribute used to store the attribute which holds groups DN in the user object. Required if groupType is dynamic (e.g. 'memberOf')
     
    .EXAMPLE
    $params = @{
        Name = 'ExampleLDAPConnection'
        LdapProtocol = 'Ldap'
        LdapHost = 'domaincontroller'
        LdapPort = 389
        SearchBase = "OU=Sales,DC=domain,DC=com"
        ConnectionTimeoutSeconds = 50
        RetryDelaySeconds = 50
        MaxIncidentCount = 50
        UserBaseDN = "CN=Users,DC=domain,DC=com"
        WalkUserSubtree = $true
        UserObjectClass = 'user'
        UserLDAPFilter = 'phone=foo'
        UserIdAttribute = 'samAccountName'
        UserRealNameAttribute = 'cn'
        UserEmailAddressAttribute = 'mail'
        LDAPGroupsAsRoles = $true
        GroupType = 'Dynamic'
        WalkGroupSubtree = $true
    }
 
    Set-NexusLDAPServerConnection @params
     
    .NOTES
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/Security/LDAP/Set-NexusLDAPServerConnection/', DefaultParameterSetName = "default")]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter()]
        [String]
        $NewName,

        [Parameter(Mandatory)]
        [ValidateSet('Ldap', 'Ldaps')]
        [String]
        $LdapProtocol,

        [Parameter()]
        [Switch]
        $UseTrustStore,

        [Parameter(Mandatory)]
        [String]
        $LdapHost,

        [Parameter(Mandatory)]
        [Int]
        $LdapPort,

        [Parameter(Mandatory)]
        [String]
        $SearchBase,

        [Parameter()]
        [Parameter(Mandatory, ParameterSetName = 'Auth')]
        [ValidateSet('None', 'Simple', 'DigestMD5', 'CramMD5')]
        [String]
        $AuthenticationScheme,

        [Parameter(Mandatory, ParameterSetName = 'Auth')]
        [Alias('Domain')]
        [String]
        $AuthenticationRealm,

        [Parameter(Mandatory, ParameterSetName = 'Auth')]
        [PSCredential]
        $Credential,

        [Parameter(Mandatory)]
        [ValidateRange(0, 3600)]
        [Int]
        $ConnectionTimeoutSeconds,

        [Parameter(Mandatory)]
        [Int]
        $RetryDelaySeconds,

        [Parameter(Mandatory)]
        [Int]
        $MaxIncidentCount,

        [Parameter(Mandatory)]
        [String]
        $UserBaseDN,

        [Parameter()]
        [Switch]
        $WalkUserSubtree,

        [Parameter(Mandatory)]
        [String]
        $UserObjectClass,

        [Parameter(Mandatory)]
        [String]
        $UserLDAPFilter,

        [Parameter()]
        [String]
        $UserIdAttribute = 'uid',

        [Parameter()]
        [String]
        $UserRealNameAttribute = 'cn',

        [Parameter()]
        [String]
        $UserEmailAddressAttribute = 'mail',

        [Parameter()]
        [String]
        $UserPasswordAttribute,

        [Parameter()]
        [Switch]
        $LDAPGroupsAsRoles,

        [Parameter()]
        [ValidateSet('Static', 'Dynamic')]
        [String]
        $GroupType = 'Static',

        [Parameter()]
        [String]
        $GroupBaseDN,

        [Parameter()]
        [Switch]
        $WalkGroupSubtree,

        [Parameter()]
        [String]
        $GroupObjectClass,

        [Parameter()]
        [String]
        $GroupIdAttribute,

        [Parameter()]
        [String]
        $GroupMemberAttribute,

        [Parameter()]
        [String]
        $GroupMemberFormat,

        [Parameter()]
        [String]
        $UserMemberOfAttribute = 'memberOf'
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

    }

    process {
        $urislug = '/service/rest/v1/security/ldap/$Name'

        $UpdatedName = if ($NewName) {
            $NewName
        }
        else { 
            $Name 
        }

        $body = @{
            name                        = $UpdatedName
            protocol                    = $LdapProtocol.ToLower()
            useTrustStore               = [bool]$UseTrustStore
            host                        = $LdapHost
            port                        = $LdapPort
            searchBase                  = $SearchBase
            connectionTimeoutSeconds    = $ConnectionTimeoutSeconds
            connectionRetryDelaySeconds = $RetryDelaySeconds
            maxIncidentsCount           = $MaxIncidentCount
            userBaseDn                  = $UserBaseDN
            userSubtree                 = [bool]$WalkUserSubtree
            userObjectClass             = $UserObjectClass
            userLdapFilter              = $UserLDAPFilter
            userIdAttribute             = $UserIdAttribute
            userRealNameAttribute       = $UserRealNameAttribute
            userEmailAddressAttribute   = $UserEmailAddressAttribute
            userPasswordAttribute       = $UserPasswordAttribute
            ldapGroupsAsRoles           = [bool]$LDAPGroupsAsRoles
            groupType                   = $GroupType.ToLower()
            groupBaseDn                 = $GroupBaseDN
            groupSubtree                = [bool]$WalkGroupSubtree
            groupObjectClass            = $GroupObjectClass
            groupIdAttribute            = $GroupIdAttribute
            groupMemberAttribute        = $GroupMemberAttribute
            groupMemberFormat           = $GroupMemberFormat
            userMemberOfAttribute       = $UserMemberOfAttribute
        }

        if ($AuthenticationScheme -ne 'None' -and $null -ne $AuthenticationScheme) {
            $AuthenticationUsername = $Credential.UserName
            $AuthenticationPassword = $Credential.GetNetworkCredential().Password
        }
        switch ($AuthenticationScheme) {
            'None' { $body.Add('authScheme', 'NONE') }

            'Simple' { 
                $body.Add('authScheme', "$($AuthenticationScheme.ToUpper())")
                $body.Add('authRealm', $AuthenticationRealm)
                $body.Add('authUsername', $AuthenticationUsername)
                $body.Add('authPassword', $AuthenticationPassword)
            }

            
            'DigestMD5' { 
                $body.Add('authScheme', "$($AuthenticationScheme.ToUpper())")
                $body.Add('authRealm', $AuthenticationRealm)
                $body.Add('authUsername', $AuthenticationUsername)
                $body.Add('authPassword', $AuthenticationPassword)
            }
            
            'DigestMD5' { 
                $body.Add('authScheme', "$($AuthenticationScheme.ToUpper())")
                $body.Add('authRealm', $AuthenticationRealm)
                $body.Add('authUsername', $AuthenticationUsername)
                $body.Add('authPassword', $AuthenticationPassword)
            }

            'CramMD5' { 
                $body.Add('authScheme', "$($AuthenticationScheme.ToUpper())")
                $body.Add('authRealm', $AuthenticationRealm)
                $body.Add('authUsername', $AuthenticationUsername)
                $body.Add('authPassword', $AuthenticationPassword)
            }

            default { $body.Add('authScheme', 'NONE') }
        }

        Write-Verbose ($body | ConvertTo-Json)
        Invoke-Nexus -Urislug $urislug -Body $Body -Method PUT
    }
}
#EndRegion '.\public\Security\LDAP\Set-NexusLDAPServerConnection.ps1' 340
#Region '.\public\Security\LDAP\Switch-NexusLdapOrder.ps1' 0
function Switch-NexusLdapOrder {
    <#
    .SYNOPSIS
    Reorders LDAP Server priority if there are multiple
     
    .DESCRIPTION
    Reorders LDAP Server priority if there are multiple
     
    .PARAMETER NewOrder
    The new order of LDAP Server Names. You can't retrieve these via API, so you'll need to look in the web interface or know what they are
     
    .EXAMPLE
    Switch-NexusLdapOrder -NewOrder ProductionLDAP,EuropeLDAP,AsiaLDAP
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/LDAP/Switch-NexusLdapOrder/')]
    Param(
        [Parameter(Mandatory)]
        [Array]
        $NewOrder
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

    }

    process {
        $urislug = '/service/rest/v1/security/ldap/change-order'
        Invoke-Nexus -Urislug $urislug -BodyAsArray $NewOrder -Method POST
    }
}
#EndRegion '.\public\Security\LDAP\Switch-NexusLdapOrder.ps1' 37
#Region '.\public\Security\Privileges\Get-NexusPrivilege.ps1' 0
function Get-NexusPrivilege {
    <#
    .SYNOPSIS
    Retrieve Privilege information from Nexus
     
    .DESCRIPTION
    Retrieve Privilege information from Nexus
     
    .PARAMETER PrivilegeId
    The id of the privilege to retrieve.
     
    .EXAMPLE
    Get-NexusPrivilege
 
    .EXAMPLE
    Get-NexusPrivilege -PrivilegeId NuGetProdAdmin
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/Privileges/Get-NexusPrivilege/')]
    Param(
        [Parameter()]
        [String]
        $PrivilegeId
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {


        if ($PrivilegeId) {
            $urislug = "/service/rest/v1/security/privileges/$PrivilegeId"

            try {
                $result = Invoke-Nexus -Urislug $urislug -Method GET

                [pscustomobject]@{
                    Name        = $result.name
                    Type        = $result.type
                    Description = $result.description
                    ReadOnly    = $result.readonly
                    Actions     = $result.actions
                    Domain      = $result.domain
                }
            }
            catch {
                $_.Exception.Message
            }
        }
        else {
            $urislug = '/service/rest/v1/security/privileges'

            $result = Invoke-Nexus -Urislug $urislug -Method GET

            $result | Foreach-Object {
                [pscustomobject]@{
                    Name        = $_.name
                    Type        = $_.type
                    Description = $_.description
                    ReadOnly    = $_.readOnly
                    Pattern     = $_.pattern
                }
            }
    
        }

    }
}
#EndRegion '.\public\Security\Privileges\Get-NexusPrivilege.ps1' 75
#Region '.\public\Security\Privileges\New-NexusPrivilege.ps1' 0
function New-NexusPrivilege {
    <#
    .SYNOPSIS
 
    Creates a new Nexus privilege which can be assigned to Roles
     
    .DESCRIPTION
 
    Creates a new Nexus privilege which can be assigned to Roles
     
    .PARAMETER Type
 
    Privilege type to create
     
    .PARAMETER Name
 
    The name of the privilege. This value cannot be changed.
     
    .PARAMETER Description
 
    Brief description for the new privilege
     
    .PARAMETER Action
 
    A collection of actions to associate with the privilege, using BREAD syntax (browse,read,edit,add,delete,all) as well as 'run' for script privileges.
     
    .PARAMETER Repository
 
    The name of the repository this privilege will grant access to (or * for all).
     
    .PARAMETER Format
 
    The repository format (i.e 'nuget', 'npm') this privilege will grant access to (or * for all).
     
    .PARAMETER ScriptName
 
    The name of a script to give access to.
     
    .PARAMETER Domain
 
    The domain (i.e. 'blobstores', 'capabilities' or even '*' for all) that this privilege is granting access to. Note that creating new privileges with a domain is only necessary when using plugins that define their own domain(s).
     
    .PARAMETER ContentSelector
 
    Name of a ContentSelector for Content Selector privilege type
     
    .PARAMETER WildcardPattern
 
    A colon separated list of parts that create a permission string.
     
    .EXAMPLE
 
    $params = @{
        Type = 'Application'
        Name = 'ApplicationPrivilegeExample'
        Description = 'Briefly describe the privilege'
        Action = 'Browse,Edit'
        Domain = 'blobstores''
    }
 
    New-NexusPrivilege @params
 
    .EXAMPLE
 
        $params = @{
        Type = 'Repository-Admin'
        Name = 'RepositoryAdminPrivilegeExample'
        Description = 'Briefly describe the privilege'
        Action = 'Browse,Edit'
        Format = 'npm'
        Repository = 'npmWebDevRepo'
    }
 
    New-NexusPrivilege @params
 
    .EXAMPLE
 
        $params = @{
        Type = 'Repository-Content-Selector'
        Name = 'RepoContentSelectorPrivilegeExample'
        Description = 'Briefly describe the privilege'
        Action = 'Browse,Edit'
        Format = 'nuget'
        Repository = 'NuGetProductionRepo'
        ContentSelector = 'LargeNupkgContent'
    }
 
    New-NexusPrivilege @params
 
    .EXAMPLE
 
        $params = @{
        Type = 'Repository-View'
        Name = 'RepoViewPrivilegeExample'
        Description = 'Briefly describe the privilege'
        Action = 'Browse,Edit'
        Format = 'nuget'
        Repostiory = 'NuGetProductionRepo'
    }
 
    New-NexusPrivilege @params
 
    .EXAMPLE
 
        $params = @{
        Type = 'Script'
        Name = 'ScriptPrivilegeExample'
        Description = 'Briefly describe the privilege'
        Action = 'Browse','Read','Edit'
        ScriptName = 'GroovySurfaceApiKeyDetails'
         
    }
 
    New-NexusPrivilege @params
 
    .EXAMPLE
     
        $params = @{
        Type = 'Wildcard'
        Name = 'WildcardPrivilegeExample'
        Description = 'Briefly describe the privilege'
        WildcardPattern = 'nuget:npm:*'
    }
 
    New-NexusPrivilege @params
 
    .NOTES
 
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/Privileges/New-NexusPrivilege/',DefaultParameterSetName="Default")]
    Param(
        [Parameter(Mandatory,ParameterSetName="Default")]
        [Parameter(Mandatory,ParameterSetName="Repo")]
        [Parameter(Mandatory,ParameterSetName="Application")]
        [Parameter(Mandatory,ParameterSetName="Script")]
        [Parameter(Mandatory,ParameterSetName="Content")]
        [Parameter(Mandatory,ParameterSetname="Wildcard")]
        [ValidateSet('Application','Repository-Admin','Repository-Content-Selector','Repository-View','Script','Wildcard')]
        [String]
        $Type,

        [Parameter(Mandatory,ParameterSetName="Default")]
        [Parameter(Mandatory,ParameterSetName="Repo")]
        [Parameter(Mandatory,ParameterSetName="Script")]
        [String]
        $Name,

        [Parameter(Mandatory,ParameterSetName="Repo")]
        [Parameter(Mandatory,ParameterSetName="Script")]
        [String]
        $Description,

        [Parameter(Mandatory,ParameterSetName="Repo")]
        [Parameter(Mandatory,ParameterSetName="Script")]
        [ValidateSet('Read','Browse','Edit','Add','Delete','Run','Associate','Disassociate','All')]
        [String[]]
        $Action,

        [Parameter(Mandatory,ParameterSetName="Repo")]
        [ArgumentCompleter({
            param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

            $r = (Get-NexusRepository).Name

            if($WordToComplete){
                $r.Where($_ -match "^$WordToComplete")
            }
            else {
                $r
            }
        })]
        [String]
        $Repository,

        [Parameter(Mandatory,ParameterSetName="Repo")]
        [String]
        $Format,

        [Parameter(Mandatory,ParameterSetName="Script")]
        [String]
        $ScriptName,

        [Parameter(Mandatory,ParameterSetName="Application")]
        [String]
        $Domain,
        
        [Parameter(Mandatory,ParameterSetName="Content")]
        [String]
        $ContentSelector,

        [Parameter(Mandatory,ParameterSetname="Wildcard")]
        [String]
        $WildcardPattern
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }
    
    process {
        switch($Type){
            'Application' {
                $urislug = "/service/rest/v1/security/privileges/$($Type.ToLower())"

                $Body = @{
                    name = $Name
                    description = $Description
                    actions = @($Action)
                    domain = $Domain
                }

            }
            'Repository-Admin' {
                $urislug = "/service/rest/v1/security/privileges/$($Type.ToLower())"

                $Body = @{
                    name = $Name
                    description = $Description
                    actions = @($Action)
                    format = $Format
                    repository = $Repository
                }

            }
            'Repository-Content-Selector' {
                $urislug = "/service/rest/v1/security/privileges/$($Type.ToLower())"

                $Body = @{
                    name = $Name
                    description = $Description
                    actions = @($Action)
                    format = $Format
                    repository = $Repository
                    contentSelector = $ContentSelector
                }

            }
            'Repository-View' {
                $urislug = "/service/rest/v1/security/privileges/$($Type.ToLower())"

                $Body = @{
                    name = $Name
                    description = $Description
                    actions = @($Action)
                    format = $Format
                    repository = $Repository
                }

            }
            'Script' {
                $urislug = "/service/rest/v1/security/privileges/$($Type.ToLower())"

                $Body = @{
                    name = $Name
                    description = $Description
                    actions = @($Action)
                    scriptName = $ScriptName
                }
            }
            'Wildcard' {
                $urislug = "/service/rest/v1/security/privileges/$($Type.ToLower())"

                $Body = @{
                    name = $Name
                    description = $Description
                    pattern = $WildcardPattern
                }
            }   
        }

        Write-Verbose ($Body | ConvertTo-Json)
        Invoke-Nexus -Urislug $urislug -Body $Body -Method POST

    }
}
#EndRegion '.\public\Security\Privileges\New-NexusPrivilege.ps1' 278
#Region '.\public\Security\Privileges\Remove-NexusPrivilege.ps1' 0
function Remove-NexusPrivilege {
    <#
    .SYNOPSIS
    Remove a Nexus Privilege
     
    .DESCRIPTION
    Remove a Nexus Privilege
     
    .PARAMETER PrivilegeId
    The id of the privilege to delete.
 
    .PARAMETER Force
    Don't prompt for confirmation before removal
     
    .EXAMPLE
    Remove-NexusPrivilege -PrivilegeId NuGetSuperAdmin
 
    .EXAMPLE
    Get-NexusPrivilege -PrivilegeId NuGetSuperAdmin | Remove-NexusPrivilege
 
    .EXAMPLE
    Remove-NexusPrivilege -PrivilegeId NuGetSuperAdmin -Force
     
    .NOTES
    General notes
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/Privileges/Remove-NexusPrivilege/',SupportsShouldProcess,ConfirmImpact="High")]
    Param(
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [ArgumentCompleter({
            param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

            $r = (Get-NexusPrivilege).Name

            if($WordToComplete){
                $r.Where($_ -match "^$WordToComplete")
            }
            else {
                $r
            }
        })]
        [String[]]
        [Alias('Name')]
        $PrivilegeId,

        [Parameter()]
        [Switch]
        $Force
    )

    process {
        $PrivilegeId | Foreach-Object {
            $urislug = "/service/rest/v1/security/privileges/$($_)"

            if ($Force -and -not $Confirm) {
                $ConfirmPreference = 'None'
                if ($PSCmdlet.ShouldProcess("$($_)", "Remove Privilege")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                }
            }
            else {
                if ($PSCmdlet.ShouldProcess("$($_)", "Remove Privilege")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                }
            }
        }
    }
}
#EndRegion '.\public\Security\Privileges\Remove-NexusPrivilege.ps1' 69
#Region '.\public\Security\Privileges\Set-NexusPrivilege.ps1' 0
function Set-NexusPrivilege {
    <#
    .SYNOPSIS
 
    Updates a Nexus privilege which can be assigned to Roles
     
    .DESCRIPTION
 
    Updates a Nexus privilege which can be assigned to Roles
     
    .PARAMETER Type
 
    Privilege type to update
     
    .PARAMETER Name
 
    The name of the privilege to update.
     
    .PARAMETER Description
 
    Brief description for the new privilege
     
    .PARAMETER Action
 
    A collection of actions to associate with the privilege, using BREAD syntax (browse,read,edit,add,delete,all) as well as 'run' for script privileges.
     
    .PARAMETER Repository
 
    The name of the repository this privilege will grant access to (or * for all).
     
    .PARAMETER Format
 
    The repository format (i.e 'nuget', 'npm') this privilege will grant access to (or * for all).
     
    .PARAMETER ScriptName
 
    The name of a script to give access to.
     
    .PARAMETER Domain
 
    The domain (i.e. 'blobstores', 'capabilities' or even '*' for all) that this privilege is granting access to. Note that creating new privileges with a domain is only necessary when using plugins that define their own domain(s).
     
    .PARAMETER ContentSelector
 
    Name of a ContentSelector for Content Selector privilege type
     
    .PARAMETER WildcardPattern
 
    A colon separated list of parts that create a permission string.
     
    .EXAMPLE
 
    $params = @{
        Type = 'Application'
        Name = 'ApplicationPrivilegeExample'
        Description = 'Briefly describe the privilege'
        Action = 'Browse','Edit'
        Domain = 'blobstores''
    }
 
    Set-NexusPrivilege @params
 
    .EXAMPLE
 
        $params = @{
        Type = 'Repository-Admin'
        Name = 'RepositoryAdminPrivilegeExample'
        Description = 'Briefly describe the privilege'
        Action = 'Browse','Edit'
        Format = 'npm'
        Repository = 'npmWebDevRepo'
    }
 
    Set-NexusPrivilege @params
 
    .EXAMPLE
 
        $params = @{
        Type = 'Repository-Content-Selector'
        Name = 'RepoContentSelectorPrivilegeExample'
        Description = 'Briefly describe the privilege'
        Action = 'Browse','Edit'
        Format = 'nuget'
        Repository = 'NuGetProductionRepo'
        ContentSelector = 'LargeNupkgContent'
    }
 
    Set-NexusPrivilege @params
 
    .EXAMPLE
 
        $params = @{
        Type = 'Repository-View'
        Name = 'RepoViewPrivilegeExample'
        Description = 'Briefly describe the privilege'
        Action = 'Browse','Edit'
        Format = 'nuget'
        Repository = 'NuGetProductionRepo'
    }
 
    Set-NexusPrivilege @params
 
    .EXAMPLE
 
        $params = @{
        Type = 'Script'
        Name = 'ScriptPrivilegeExample'
        Description = 'Briefly describe the privilege'
        Action = 'Browse','Read','Edit'
        ScriptName = 'GroovySurfaceApiKeyDetails'
         
    }
 
    Set-NexusPrivilege @params
 
    .EXAMPLE
     
        $params = @{
        Type = 'Wildcard'
        Name = 'WildcardPrivilegeExample'
        Description = 'Briefly describe the privilege'
        WildcardPattern = 'nuget:npm:*'
    }
 
    Set-NexusPrivilege @params
 
    .NOTES
 
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/Privileges/Set-NexusPrivilege/',DefaultParameterSetName="Default")]
    Param(
        [Parameter(Mandatory,ParameterSetName="Default")]
        [Parameter(Mandatory,ParameterSetName="Repo")]
        [Parameter(Mandatory,ParameterSetName="Application")]
        [Parameter(Mandatory,ParameterSetName="Script")]
        [Parameter(Mandatory,ParameterSetName="Content")]
        [Parameter(Mandatory,ParameterSetname="Wildcard")]
        [ValidateSet('Application','Repository-Admin','Repository-Content-Selector','Repository-View','Script','Wildcard')]
        [String]
        $Type,

        [Parameter(Mandatory,ParameterSetName="Default")]
        [Parameter(Mandatory,ParameterSetName="Repo")]
        [Parameter(Mandatory,ParameterSetName="Script")]
        [String]
        $Name,

        [Parameter(Mandatory,ParameterSetName="Repo")]
        [Parameter(Mandatory,ParameterSetName="Script")]
        [String]
        $Description,

        [Parameter(Mandatory,ParameterSetName="Repo")]
        [Parameter(Mandatory,ParameterSetName="Script")]
        [ValidateSet('Read','Browse','Edit','Add','Delete','Run','Associate','Disassociate','All')]
        [String[]]
        $Action,

        [Parameter(Mandatory,ParameterSetName="Repo")]
        [ArgumentCompleter({
            param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

            $r = (Get-NexusRepository).Name

            if($WordToComplete){
                $r.Where($_ -match "^$WordToComplete")
            }
            else {
                $r
            }
        })]
        [String]
        $Repository,

        [Parameter(Mandatory,ParameterSetName="Repo")]
        [String]
        $Format,

        [Parameter(Mandatory,ParameterSetName="Script")]
        [String]
        $ScriptName,

        [Parameter(Mandatory,ParameterSetName="Application")]
        [String]
        $Domain,
        
        [Parameter(Mandatory,ParameterSetName="Content")]
        [String]
        $ContentSelector,

        [Parameter(Mandatory,ParameterSetname="Wildcard")]
        [String]
        $WildcardPattern
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }
    
    process {
        switch($Type){
            'Application' {
                $urislug = "/service/rest/v1/security/privileges/$($Type.ToLower())/$Name"

                $Body = @{
                    name = $Name
                    description = $Description
                    actions = @($Action)
                    domain = $Domain
                }

            }
            'Repository-Admin' {
                $urislug = "/service/rest/v1/security/privileges/$($Type.ToLower())/$Name"

                $Body = @{
                    name = $Name
                    description = $Description
                    actions = @($Action)
                    format = $Format
                    repository = $Repository
                }

            }
            'Repository-Content-Selector' {
                $urislug = "/service/rest/v1/security/privileges/$($Type.ToLower())/$Name"

                $Body = @{
                    name = $Name
                    description = $Description
                    actions = @($Action)
                    format = $Format
                    repository = $Repository
                    contentSelector = $ContentSelector
                }

            }
            'Repository-View' {
                $urislug = "/service/rest/v1/security/privileges/$($Type.ToLower())/$Name"

                $Body = @{
                    name = $Name
                    description = $Description
                    actions = @($Action)
                    format = $Format
                    repository = $Repository
                }

            }
            'Script' {
                $urislug = "/service/rest/v1/security/privileges/$($Type.ToLower())/$Name"

                $Body = @{
                    name = $Name
                    description = $Description
                    actions = @($Action)
                    scriptName = $ScriptName
                }
            }
            'Wildcard' {
                $urislug = "/service/rest/v1/security/privileges/$($Type.ToLower())/$Name"

                $Body = @{
                    name = $Name
                    description = $Description
                    pattern = $WildcardPattern
                }
            }   
        }

        Write-Verbose ($Body | ConvertTo-Json)
        Invoke-Nexus -Urislug $urislug -Body $Body -Method PUT

    }
}
#EndRegion '.\public\Security\Privileges\Set-NexusPrivilege.ps1' 278
#Region '.\public\Security\Roles\Get-NexusRole.ps1' 0
function Get-NexusRole {
    <#
    .SYNOPSIS
    Retrieve Nexus Role information
     
    .DESCRIPTION
    Retrieve Nexus Role information
     
    .PARAMETER Role
    The role to retrieve
     
    .PARAMETER Source
    The source to retrieve from
     
    .EXAMPLE
    Get-NexusRole
 
    .EXAMPLE
    Get-NexusRole -Role ExampleRole
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/Roles/Get-NexusRole/')]
    Param(
        [Parameter()]
        [Alias('id')]
        [String]
        $Role,

        [Parameter()]
        [String]
        $Source
    )
    begin { if (-not $header) { throw 'Not connected to Nexus server! Run Connect-NexusServer first.' } }
    process {
        
        $urislug = '/service/rest/v1/security/roles'

        if ($Role) {
            $urislug = "/service/rest/v1/security/roles/$Role"
        }

        if ($Source) {
            $urislug = "/service/rest/v1/security/roles?source=$Source"
        }

        if ($Role -and $Source) {
            $urislug = "/service/rest/v1/security/roles/$($Role)?source=$Source"
        }

        Write-verbose $urislug
        $result = Invoke-Nexus -Urislug $urislug -Method GET

        $result | ForEach-Object {
            [PSCustomObject]@{
                Id          = $_.id
                Source       = $_.source
                Name        = $_.name
                Description = $_.description
                Privileges  = $_.privileges
                Roles       = $_.roles
            }
        }
    }
}
#EndRegion '.\public\Security\Roles\Get-NexusRole.ps1' 67
#Region '.\public\Security\Roles\New-NexusRole.ps1' 0
function New-NexusRole {
    <#
    .SYNOPSIS
    Creates a new Nexus Role
     
    .DESCRIPTION
    Creates a new Nexus Role
     
    .PARAMETER Id
    The ID of the role
     
    .PARAMETER Name
    The friendly name of the role
     
    .PARAMETER Description
    A description of the role
     
    .PARAMETER Privileges
    Included privileges for the role
     
    .PARAMETER Roles
    Included nested roles
     
    .EXAMPLE
    New-NexusRole -Id SamepleRole
 
    .EXAMPLE
    New-NexusRole -Id SampleRole -Description "A sample role" -Privileges nx-all
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/Roles/New-NexusRole/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Id,

        [Parameter(Mandatory)]
        [String]
        $Name,

        [Parameter()]
        [String]
        $Description,

        [Parameter(Mandatory)]
        [String[]]
        $Privileges,

        [Parameter()]
        [String[]]
        $Roles
    )

    begin {
        if (-not $header) { 
            throw 'Not connected to Nexus server! Run Connect-NexusServer first.' 
        } 
    }
    
    process {

        $urislug = '/service/rest/v1/security/roles'
        $Body = @{
            
            id          = $Id
            name        = $Name
            description = $Description
            privileges  = @($Privileges)
            roles       = $Roles
            
        }

        Invoke-Nexus -Urislug $urislug -Body $Body -Method POST | Foreach-Object {
            [PSCustomobject]@{
                Id = $_.id
                Name = $_.name
                Description = $_.description
                Privileges = $_.privileges
                Roles = $_.roles
            }
        }

    }
}
#EndRegion '.\public\Security\Roles\New-NexusRole.ps1' 87
#Region '.\public\Security\Roles\Remove-NexusRole.ps1' 0
function Remove-NexusRole {
    <#
    .SYNOPSIS
    Remove a Nexus Role
     
    .DESCRIPTION
    Remove a Nexus Role
     
    .PARAMETER Role
    The role to remove
 
    .PARAMETER Force
    Don't prompt for confirmation prior to removal
     
    .EXAMPLE
    Remove-NexusRole -Role SampleRole
 
    .EXAMPLE
    Remove-NexusRole -Role SampleRole -Force
 
    .EXAMPLE
    Get-NexusRole -Role SampleRole | Remove-Nexus Role
     
    .NOTES
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/Roles/Remove-NexusRole/',SupportsShouldProcess,ConfirmImpact='High')]
    Param(
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ArgumentCompleter( {
                param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

                $r = (Get-NexusRole).id

                if ($WordToComplete) {
                    $r.Where($_ -match "^$WordToComplete")
                } 

                else { 
                    $r
                }
            })]
        [Alias('Id', 'Name')]
        [String[]]
        $Role,

        [Parameter()]
        [Switch]
        $Force
    )

    process {
        $Role | Foreach-Object {
            $urislug = "/service/rest/v1/security/roles/$($_)"

            if ($Force -and -not $Confirm) {
                $ConfirmPreference = 'None'
                if ($PSCmdlet.ShouldProcess("$($_)", "Remove Role")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                }
            }
            else {
                if ($PSCmdlet.ShouldProcess("$($_)", "Remove Role")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE -ErrorAction Stop
                }
            }
        }
    }

}
#EndRegion '.\public\Security\Roles\Remove-NexusRole.ps1' 70
#Region '.\public\Security\Roles\Set-NexusRole.ps1' 0
function Set-NexusRole {
    <#
    .SYNOPSIS
    Modifies an existing Nexus Role
     
    .DESCRIPTION
    Modifies an existing Nexus Role
     
    .PARAMETER Role
    The role to modify
     
    .PARAMETER Name
    The new name of the role
     
    .PARAMETER Description
    Update the description
     
    .PARAMETER Privileges
    Update privileges
     
    .PARAMETER Roles
    Update nested roles
     
    .EXAMPLE
    Set-NexusRole -Role Example -Description "This is an updated description"
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/Roles/Set-NexusRole/')]
    Param(
        [Parameter(Mandatory)]
        [ArgumentCompleter( {
                param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

                $r = (Get-NexusRole).id

                if ($WordToComplete) {
                    $r.Where($_ -match "^$WordToComplete")
                }

                else {
                    $r
                }
            })]
        [String]
        $Role,

        [Parameter()]
        [String]
        $Name = $Role,

        [Parameter()]
        [String]
        $Description,

        [Parameter()]
        [String[]]
        $Privileges,

        [Parameter()]
        [String[]]
        $Roles
    )

    begin {
        if (-not $header) { 
            throw 'Not connected to Nexus server! Run Connect-NexusServer first.' 
        } 
    }
    
    process {

        $Id = $Role

        $urislug = "/service/rest/v1/security/roles/$Id"

        $CurrentSetting = Get-NexusRole -Role $Role


        if (-not $Name) {
            $Name = $Role
        }

        $Privileges = if (-not $Privileges) {
            @($($CurrentSetting.privileges))
        }
        else { @($Privileges) }

        $Roles = if (-not $Roles -eq $null) {
            if ($null -ne $($CurrentSetting.roles)) {
                $null
            }
        }
        else { @($Roles) }

        $Body = @{
            
            id          = $Id
            name        = $Name
            description = $Description
            privileges  = $Privileges
            roles       = $Roles
            
        }

        Write-Verbose ($Body | ConvertTo-Json)

        Invoke-Nexus -Urislug $urislug -Body $Body -Method PUT 

    }
}
#EndRegion '.\public\Security\Roles\Set-NexusRole.ps1' 113
#Region '.\public\Status\Get-NexusStatus.ps1' 0
function Get-NexusStatus {
    <#
    .SYNOPSIS
    Returns Nexus System Status information
     
    .DESCRIPTION
    Returns Nexus System Status information
     
    .PARAMETER VerifyRead
    Verifies that Nexus can accept read requests
     
    .PARAMETER VerifySystem
    Returns system information
     
    .PARAMETER VerifyWrite
    Verifies that Nexus can accpet write requests
     
    .EXAMPLE
    Get-NexusStatus
 
    Returns system information
 
    .EXAMPLE
    Get-NexusStatus -VerifyRead
 
    .EXAMPLE
    Get-NexusStatus -VerifySystem
 
    .EXAMPLE
    Get-NexusStatus -VerifyWrite
 
    .EXAMPLE
    Get-NexusStatus -VerifyRead -VerifyWrite -VerifySystem
     
    .NOTES
    General notes
    #>

    [CmdletBinding()]
    Param(
        [Parameter()]
        [Switch]
        $VerifyRead,

        [Parameter()]
        [Switch]
        $VerifySystem,

        [Parameter()]
        [Switch]
        $VerifyWrite
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

    }

    process {
        switch ($true) {
            $VerifyRead { 
                $urislug = '/service/rest/v1/status'
                try {
                    Invoke-Nexus -Urislug $urislug -Method GET
                    Write-Host "System can accept read requests"
                }
                catch {
                    $_.Exception.Message
                }
            }
            $VerifySystem { 
                $urislug = '/service/rest/v1/status/check'
                try {
                    $result = Invoke-Nexus -Urislug $urislug -Method GET

                    [pscustomobject]@{
                        'Available CPUs'            = [pscustomobject]@{
                            Healthy   = $result.'Available CPUs'.healthy
                            Message   = $result.'Available CPUs'.message
                            Error     = $result.'Available CPUs'.error
                            Details   = $result.'Available CPUs'.details
                            Time      = $result.'Available CPUs'.time
                            Duration  = $result.'Available CPUs'.duration
                            Timestamp = $result.'Available CPUs'.timestamp
                        }
                        'Blob Stores'               = [pscustomobject]@{
                            Healthy   = $result.'Blob Stores'.healty
                            Message   = $result.'Blob Stores'.message
                            Error     = $result.'Blob Stores'.error
                            Details   = $result.'Blob Stores'.details
                            Time      = $result.'Blob Stores'.time
                            Duration  = $result.'Blob Stores'.duration
                            Timestamp = $result.'Blob Stores'.timestamp
                        }
                        'Default Admin Credentials' = [pscustomobject]@{
                            Healthy   = $result.'Default Admin Credentials'.healthy
                            Message   = $result.'Default Admin Credentials'.message
                            Error     = $result.'Default Admin Credentials'.error
                            Details   = $result.'Default Admin Credentials'.details
                            Time      = $result.'Default Admin Credentials'.time
                            Duration  = $result.'Default Admin Credentials'.duration
                            Timestamp = $result.'Default Admin Credentials'.timestamp
                        }
                        DefaultRoleRealm            = [pscustomobject]@{
                            Healthy   = $result.DefaultRoleRealm.healthy
                            Message   = $result.DefaultRoleRealm.message
                            Error     = $result.DefaultRoleRealm.error
                            Details   = $result.DefaultRoleRealm.details
                            Time      = $result.DefaultRoleRealm.time
                            Duration  = $result.DefaultRoleRealm.duration
                            Timestamp = $result.DefaultRoleRealm.timestamp
                        }
                        'File Blob Stores Path'     = [pscustomobject]@{
                            Healthy   = $result.'File Blob Stores Path'.healthy
                            Message   = $result.'File Blob Stores Path'.message
                            Error     = $result.'File Blob Stores Path'.error
                            Details   = $result.'File Blob Stores Path'.details
                            Time      = $result.'File Blob Stores Path'.time
                            Duration  = $result.'File Blob Stores Path'.duration
                            Timestamp = $result.'File Blob Stores Path'.timestamp
                        }
                        'File Descriptors'          = [pscustomobject]@{
                            Healthy   = $result.'File Descriptors'.healthy
                            Message   = $result.'File Descriptors'.message
                            Error     = $result.'File Descriptors'.error
                            Details   = $result.'File Descriptors'.details
                            Time      = $result.'File Descriptors'.time
                            Duration  = $result.'File Descriptors'.duration
                            Timestamp = $result.'File Descriptors'.timestamp
                        }
                        'Lifecycle Phase'           = [pscustomobject]@{
                            Healthy   = $result.'Lifecycle Phase'.healthy
                            Message   = $result.'Lifecycle Phase'.message
                            Error     = $result.'Lifecycle Phase'.error
                            Details   = $result.'Lifecycle Phase'.details
                            Time      = $result.'Lifecycle Phase'.time
                            Duration  = $result.'Lifecycle Phase'.duration
                            Timestamp = $result.'Lifecycle Phase'.timestamp
                        }
                        'Read-Only Detector'        = [pscustomobject]@{
                            Healthy   = $result.'Read-Only Detector'.healthy
                            Message   = $result.'Read-Only Detector'.message
                            Error     = $result.'Read-Only Detector'.error
                            Details   = $result.'Read-Only Detector'.details
                            Time      = $result.'Read-Only Detector'.time
                            Duration  = $result.'Read-Only Detector'.duration
                            Timestamp = $result.'Read-Only Detector'.timestamp
                        }
                        Scheduler                   = [pscustomobject]@{
                            Healthy   = $result.Scheduler.healthy
                            Message   = $result.Scheduler.message
                            Error     = $result.Scheduler.error
                            Details   = $result.Scheduler.details
                            Time      = $result.Scheduler.time
                            Duration  = $result.Scheduler.duration
                            Timestamp = $result.Scheduler.timestamp
                        }
                        'Thread Deadlock Detector'  = [pscustomobject]@{
                            Healthy   = $result.'Thread Deadlock Detector'.healthy
                            Message   = $result.'Thread Deadlock Detector'.message
                            Error     = $result.'Thread Deadlock Detector'.error
                            Details   = $result.'Thread Deadlock Detector'.details
                            Time      = $result.'Thread Deadlock Detector'.time
                            Duration  = $result.'Thread Deadlock Detector'.duration
                            Timestamp = $result.'Thread Deadlock Detector'.timestamp
                        }
                        Transactions                = [pscustomobject]@{
                            Healthy   = $result.Transactions.healthy
                            Message   = $result.Transactions.message
                            Error     = $result.Transactions.error
                            Details   = $result.Transactions.details
                            Time      = $result.Transactions.time
                            Duration  = $result.Transactions.duration
                            Timestamp = $result.Transactions.timestamp
                        }
                    }
                
                }
                catch {
                    $_.Exception.Message
                }
            }
            $VerifyWrite { 
                $urislug = '/service/rest/v1/status/writable'
                try {
                    Invoke-Nexus -Urislug $urislug -Method GET
                    Write-Host "System can accept write requests"
                }
                catch {
                    $_.Exception.Message
                }
            }
            default {
                $urislug = '/service/rest/v1/status/check'
                try {
                    $result = Invoke-Nexus -Urislug $urislug -Method GET

                    [pscustomobject]@{
                        'Available CPUs'            = [pscustomobject]@{
                            Healthy   = $result.'Available CPUs'.healthy
                            Message   = $result.'Available CPUs'.message
                            Error     = $result.'Available CPUs'.error
                            Details   = $result.'Available CPUs'.details
                            Time      = $result.'Available CPUs'.time
                            Duration  = $result.'Available CPUs'.duration
                            Timestamp = $result.'Available CPUs'.timestamp
                        }
                        'Blob Stores'               = [pscustomobject]@{
                            Healthy   = $result.'Blob Stores'.healty
                            Message   = $result.'Blob Stores'.message
                            Error     = $result.'Blob Stores'.error
                            Details   = $result.'Blob Stores'.details
                            Time      = $result.'Blob Stores'.time
                            Duration  = $result.'Blob Stores'.duration
                            Timestamp = $result.'Blob Stores'.timestamp
                        }
                        'Default Admin Credentials' = [pscustomobject]@{
                            Healthy   = $result.'Default Admin Credentials'.healthy
                            Message   = $result.'Default Admin Credentials'.message
                            Error     = $result.'Default Admin Credentials'.error
                            Details   = $result.'Default Admin Credentials'.details
                            Time      = $result.'Default Admin Credentials'.time
                            Duration  = $result.'Default Admin Credentials'.duration
                            Timestamp = $result.'Default Admin Credentials'.timestamp
                        }
                        DefaultRoleRealm            = [pscustomobject]@{
                            Healthy   = $result.DefaultRoleRealm.healthy
                            Message   = $result.DefaultRoleRealm.message
                            Error     = $result.DefaultRoleRealm.error
                            Details   = $result.DefaultRoleRealm.details
                            Time      = $result.DefaultRoleRealm.time
                            Duration  = $result.DefaultRoleRealm.duration
                            Timestamp = $result.DefaultRoleRealm.timestamp
                        }
                        'File Blob Stores Path'     = [pscustomobject]@{
                            Healthy   = $result.'File Blob Stores Path'.healthy
                            Message   = $result.'File Blob Stores Path'.message
                            Error     = $result.'File Blob Stores Path'.error
                            Details   = $result.'File Blob Stores Path'.details
                            Time      = $result.'File Blob Stores Path'.time
                            Duration  = $result.'File Blob Stores Path'.duration
                            Timestamp = $result.'File Blob Stores Path'.timestamp
                        }
                        'File Descriptors'          = [pscustomobject]@{
                            Healthy   = $result.'File Descriptors'.healthy
                            Message   = $result.'File Descriptors'.message
                            Error     = $result.'File Descriptors'.error
                            Details   = $result.'File Descriptors'.details
                            Time      = $result.'File Descriptors'.time
                            Duration  = $result.'File Descriptors'.duration
                            Timestamp = $result.'File Descriptors'.timestamp
                        }
                        'Lifecycle Phase'           = [pscustomobject]@{
                            Healthy   = $result.'Lifecycle Phase'.healthy
                            Message   = $result.'Lifecycle Phase'.message
                            Error     = $result.'Lifecycle Phase'.error
                            Details   = $result.'Lifecycle Phase'.details
                            Time      = $result.'Lifecycle Phase'.time
                            Duration  = $result.'Lifecycle Phase'.duration
                            Timestamp = $result.'Lifecycle Phase'.timestamp
                        }
                        'Read-Only Detector'        = [pscustomobject]@{
                            Healthy   = $result.'Read-Only Detector'.healthy
                            Message   = $result.'Read-Only Detector'.message
                            Error     = $result.'Read-Only Detector'.error
                            Details   = $result.'Read-Only Detector'.details
                            Time      = $result.'Read-Only Detector'.time
                            Duration  = $result.'Read-Only Detector'.duration
                            Timestamp = $result.'Read-Only Detector'.timestamp
                        }
                        Scheduler                   = [pscustomobject]@{
                            Healthy   = $result.Scheduler.healthy
                            Message   = $result.Scheduler.message
                            Error     = $result.Scheduler.error
                            Details   = $result.Scheduler.details
                            Time      = $result.Scheduler.time
                            Duration  = $result.Scheduler.duration
                            Timestamp = $result.Scheduler.timestamp
                        }
                        'Thread Deadlock Detector'  = [pscustomobject]@{
                            Healthy   = $result.'Thread Deadlock Detector'.healthy
                            Message   = $result.'Thread Deadlock Detector'.message
                            Error     = $result.'Thread Deadlock Detector'.error
                            Details   = $result.'Thread Deadlock Detector'.details
                            Time      = $result.'Thread Deadlock Detector'.time
                            Duration  = $result.'Thread Deadlock Detector'.duration
                            Timestamp = $result.'Thread Deadlock Detector'.timestamp
                        }
                        Transactions                = [pscustomobject]@{
                            Healthy   = $result.Transactions.healthy
                            Message   = $result.Transactions.message
                            Error     = $result.Transactions.error
                            Details   = $result.Transactions.details
                            Time      = $result.Transactions.time
                            Duration  = $result.Transactions.duration
                            Timestamp = $result.Transactions.timestamp
                        }
                    }
                
                }
                catch {
                    $_.Exception.Message
                }
            }

        }
    }
}
#EndRegion '.\public\Status\Get-NexusStatus.ps1' 310
#Region '.\public\Support\New-NexusSupportZip.ps1' 0
function New-NexusSupportZip {
    <#
    .SYNOPSIS
    Prepares a support zip file on your Nexus Server
     
    .DESCRIPTION
    Prepares a support zip file on your Nexus Server
     
    .PARAMETER IncludeSystemInfo
    Includes system info in the zip
     
    .PARAMETER IncludeThreadDump
    Includes a thread dump in the zip
     
    .PARAMETER IncludeMetrics
    Includes metrics in the zip
     
    .PARAMETER IncludeConfiguration
    Includes server configuration in the zip
     
    .PARAMETER IncludeSecurity
    Include security information in the zip
     
    .PARAMETER IncludeNexusLog
    Include the nexus log in the zip
     
    .PARAMETER IncludeTaskLog
    Include the task log in the zip
     
    .PARAMETER IncludeAuditLog
    Include the audit log in the zip
     
    .PARAMETER IncludeJmx
    Include the jmx configuration in the zip
     
    .PARAMETER LimitFileSize
    Limit the output size of files in the zip
     
    .PARAMETER LimitZipSizes
    Limit the overall size of the zip
     
    .EXAMPLE
    New-NexusSupportZip -IncludeNexusLog -IncludeConfiguration
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Support/New-NexusSupportZip/')]
    Param(
        [Parameter()]
        [Switch]
        $IncludeSystemInfo,

        [Parameter()]
        [Switch]
        $IncludeThreadDump,

        [Parameter()]
        [Switch]
        $IncludeMetrics,

        [Parameter()]
        [Switch]
        $IncludeConfiguration,

        [Parameter()]
        [Switch]
        $IncludeSecurity,

        [Parameter()]
        [Switch]
        $IncludeNexusLog,

        [Parameter()]
        [Switch]
        $IncludeTaskLog,

        [Parameter()]
        [Switch]
        $IncludeAuditLog,

        [Parameter()]
        [Switch]
        $IncludeJmx,

        [Parameter()]
        [Switch]
        $LimitFileSize,

        [Parameter()]
        [Switch]
        $LimitZipSizes
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

    }

    process {
        $Body = @{
            systemInformation = [bool]$IncludeSystemInfo
            threadDump        = [bool]$IncludeThreadDump
            metrics           = [bool]$IncludeMetrics
            configuration     = [bool]$IncludeConfiguration
            security          = [bool]$IncludeSecurity
            log               = [bool]$IncludeNexusLog
            taskLog           = [bool]$IncludeTaskLog
            auditLog          = [bool]$IncludeAuditLog
            jmx               = [bool]$IncludeJmx
            limitFileSizes    = [bool]$LimitFileSize
            limitZipSize      = [bool]$LimitZipSizes
        }

        $urislug = '/service/rest/v1/support/supportzippath'
        Write-Verbose ($Body | ConvertTo-Json)
        $result = Invoke-Nexus -Urislug $urislug -Body $Body -Method POST
            
        [pscustomobject]@{
            File      = $result.file
            Name      = $result.name
            Size      = "$([Math]::Round($result.size,2)) MB"
            Truncated = $result.truncated
        }
            
    }
}
#EndRegion '.\public\Support\New-NexusSupportZip.ps1' 130
#Region '.\public\Tag\Add-NexusTagAssociation.ps1' 0
function Add-NexusTagAssociation {
    <#
    .SYNOPSIS
    Tags a component with the provided tag name based on the search query parameters
     
    .DESCRIPTION
    Tags a component based on the Query terms based via hashtable to the API endpoint.
     
    .PARAMETER Tag
    The tag to apply to the component(s)
     
    .PARAMETER SearchQuery
    A hashtable of search parameters by which to tag components
     
    .EXAMPLE
    Add-NexusTag -Tag SampleTag -SearchQuery @{ format = 'nuget' ; repository = 'ChocolateyPackages'}
     
    .LINK
    https://help.sonatype.com/en/tagging.html
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Tags/Add-NexusTagAssociation/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Tag,

        [Parameter()]
        [hashtable]
        $SearchQuery
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
        
        $urislug = '/service/rest/v1/tags/associate/{0}' -f $Tag
    }

    process {
        $UriBase = "$($protocol)://$($Hostname):$($port)$($ContextPath)"
        $Uri = $UriBase + $UriSlug

        $tagUrl = New-HttpQueryString -Uri $uri -QueryParameter $SearchQuery

        $Params = @{
            Headers = $header
            ContentType = 'application/json'
            Uri = $tagUrl
            Method = 'POST'
            UseBasicParsing = $true
        }

        Invoke-RestMethod @Params
    }
}
#EndRegion '.\public\Tag\Add-NexusTagAssociation.ps1' 57
#Region '.\public\Tag\Get-NexusTag.ps1' 0
function Get-NexusTag {
    [Cmdletbinding(HelpUri = 'https://nexushell.dev/Tags/Get-NexusTag/')]
    Param(
        [Parameter()]
        [String]
        $Name
    )

    begin {

        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

        $urislug = if (-not $Name) {
            '/service/rest/v1/tags'
        }
        else {
            "/service/rest/v1/tags/$Name"
        }

    }

    process {
        if(-not $Name){
            $result = Invoke-Nexus -Urislug $urislug -Method GET
            $result.items
        } else {
            Invoke-Nexus -UriSlug $urislug -Method GET
        }
    }
 
}
#EndRegion '.\public\Tag\Get-NexusTag.ps1' 34
#Region '.\public\Tag\New-NexusTag.ps1' 0
function New-NexusTag {
<#
.SYNOPSIS
Create a tag
 
.DESCRIPTION
Create a tag in Nexus Repository. Useful with CI/CD platforms, similar to git tags.
 
.PARAMETER Tag
The friendly name of the tag
 
.PARAMETER Attributes
Any additional metadata you wish to tag a component with
 
.EXAMPLE
 $tag = @{
    name = 'SampleTag'
    attributes = @{
        jvm = '9'
        builtby = 'Jenkins'
    }
 }
 
 New-NexusTag @tag
 
.LINK
https://help.sonatype.com/en/tagging.html
#>

    [CmdletBinding(HelpUri='https://nexushell.dev/Tags/New-NexusTag/')]
    Param(
        [Parameter(Mandatory)]
        [ValidateLength(1,256)]
        [String]
        $Tag,

        [Parameter()]
        [hashtable]
        $Attributes
    )
    begin{
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
        
        $urislug = '/service/rest/v1/tags'

        if ($Tag.Length -gt 256) {
            throw "Name cannot exceed 256 characters."
        }
        
        if ($Tag -notmatch '^[a-zA-Z0-9_.-]+$') {
            throw "Name can only contain letters, numbers, underscores, hyphens, and dots."
        }
        
        if ($Tag -match '^[_\.]') {
            throw "Name cannot start with an underscore or dot."
        }
    }

    process {

        $body = @{
            name = $Tag
            attributes = $Attributes
        }

        Invoke-Nexus -Urislug $urislug -Body $body -Method POST
    }

}
#EndRegion '.\public\Tag\New-NexusTag.ps1' 71
#Region '.\public\Tag\Remove-NexusTag.ps1' 0
function Remove-NexusTag {
    <#
    .SYNOPSIS
    Removes a tag from Sonatype Nexus
     
    .DESCRIPTION
    Removes a tag from Nexus. Completely disassociates all tagged components. Use Remove-NexusTagAssociation to modify tags on individual components.
     
    .PARAMETER Tag
    The tag to remove
     
    .PARAMETER Force
    Don't prompt for confirmation.
     
    .EXAMPLE
    Remove-NexusTag -Tag SampleTag
 
    This will prompt you to confirm the deletion
 
    .EXAMPLE
    Remove-NexusTag -Tag SampleTag -Force
 
    No prompts for confirmation. Potentially dangerous. Use -Whatif if not sure of results
 
    .LINK
    https://help.sonatype.com/en/tagging.html
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High', HelpUri = 'https://nexushell.dev/Tags/Remove-NexusTag/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Tag,

        [Parameter()]
        [Switch]
        $Force
    )
    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
        
        $urislug = '/service/rest/v1/tags/{0}' -f $Tag
    }
    process {
        if ($Force -and -not $Confirm) {
            $ConfirmPreference = 'None'
            if ($PSCmdlet.ShouldProcess("$($_)", "Remove Tag")) {
                Invoke-Nexus -Urislug $urislug -Method 'DELETE'
            }
        }
        else {
            if ($PSCmdlet.ShouldProcess("$($_)", "Remove Tag")) {
                Invoke-Nexus -Urislug $urislug -Method 'DELETE'
            }
        }
    }
}
#EndRegion '.\public\Tag\Remove-NexusTag.ps1' 59
#Region '.\public\Tag\Remove-NexusTagAssociation.ps1' 0
function Remove-NexusTagAssociation {
    <#
    .SYNOPSIS
    Removes a tag from a component
     
    .DESCRIPTION
    Disassociates a tag from a component within Nexus. Does not remove the tag itself from the system.
     
    .PARAMETER Tag
    The tag to disassociate
     
    .PARAMETER SearchQuery
    The search parameters to find components with the tag to remove
     
    .PARAMETER Force
    Don't prompt to remove the tag
     
    .EXAMPLE
    Remove-NexusTagAssociation -Tag SampleTag -SearchQuery @{ format = 'nuget' ; repository = 'ChocolateyInternal'}
     
    .LINK
    https://help.sonatype.com/en/tagging.html
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High', HelpUri = 'https://nexushell.dev/Tags/Remove-NexusTagAssociation/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Tag,

        [Parameter(Mandatory)]
        [hashtable]
        $SearchQuery,

        [Parameter()]
        [Switch]
        $Force
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
        
        $urislug = '/service/rest/v1/tags/associate/{0}' -f $Tag
    }

    process {
        $UriBase = "$($protocol)://$($Hostname):$($port)$($ContextPath)"
        $Uri = $UriBase + $UriSlug

        $tagUrl = New-HttpQueryString -Uri $uri -QueryParameter $SearchQuery
 
        $Params = @{
            Headers         = $header
            ContentType     = 'application/json'
            Uri             = $tagUrl
            Method          = 'DELETE'
            UseBasicParsing = $true
        }

        if ($Force -and -not $Confirm) {
            $ConfirmPreference = 'None'
            if ($PSCmdlet.ShouldProcess("$($_)", "Remove Tag Association")) {
                Invoke-RestMethod @Params
            }
        }
        else {
            if ($PSCmdlet.ShouldProcess("$($_)", "Remove Tag Association")) {
                Invoke-RestMethod @Params
            }
        }
    }
}
#EndRegion '.\public\Tag\Remove-NexusTagAssociation.ps1' 74
#Region '.\public\Tag\Set-NexusTag.ps1' 0
function Set-NexusTag {
    <#
    .SYNOPSIS
    Sets tag metadata for an existing tag
     
    .DESCRIPTION
    This command provides a mechanism to update tag metadata for existing tags within a Sonatype Nexus installation
     
    .PARAMETER Tag
    The tag to update
     
    .PARAMETER Attributes
    A hashtable of attributes to apply to the tag
     
    .EXAMPLE
    Set-NexusTag -Name 'Example' -Attributes @{ foo = 'bar' ; bazz = 'bizz'}
     
    .LINK
    https://help.sonatype.com/en/tagging.html
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Tags/Set-NexusTag/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Tag,

        [Parameter(Mandatory)]
        [hashtable]
        $Attributes
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
        
        $urislug = '/service/rest/v1/tags/{0}' -f $Tag
    }

    process {
        $Body = @{
            attributes = $Attributes
        }
        Invoke-Nexus -UriSlug $urislug -Method PUT -Body $Body
    }
}
#EndRegion '.\public\Tag\Set-NexusTag.ps1' 47
#Region '.\public\Task\Get-NexusTask.ps1' 0
function Get-NexusTask {
    <#
    .SYNOPSIS
    Gets a list of Nexus tasks
     
    .DESCRIPTION
    Gets a list of Nexus tasks
     
    .PARAMETER Type
    The type of task to return
     
    .EXAMPLE
    Get-NexusTask
 
    .EXAMPLE
    Get-NexusTask -Type repository.cleanup
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/Tasks/Get-NexusTask/')]
    Param(
        [Parameter()]
        [String[]]
        $Type
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {
        $urislug = '/service/rest/v1/tasks'
        if ($Type) {
            $Type | Foreach-Object {
                $urislug = '/service/rest/v1/tasks'
                $result = Invoke-Nexus -Urislug $urislug -BodyAsString $_ -Method Get

                $result.items | Foreach-Object {
                    [pscustomobject]@{
                        Id            = $_.id
                        Name          = $_.name
                        Type          = $_.type
                        Message       = $_.message
                        CurrentState  = $_.currentState
                        LastRunResult = $_.lastRunResult
                        NextRun       = $_.nextRun
                        LastRun       = $_.lastRun
                    }
                }            
            }
        }

        else {
            $result = Invoke-Nexus -Urislug $urislug -Method Get
            $result.items | Foreach-Object {
                [pscustomobject]@{
                    Id            = $_.id
                    Name          = $_.name
                    Type          = $_.type
                    Message       = $_.message
                    CurrentState  = $_.currentState
                    LastRunResult = $_.lastRunResult
                    NextRun       = $_.nextRun
                    LastRun       = $_.lastRun
                }
            }            
        }
    }
}
#EndRegion '.\public\Task\Get-NexusTask.ps1' 73
#Region '.\public\Task\Start-NexusTask.ps1' 0
function Start-NexusTask {
    <#
    .SYNOPSIS
    Starts a Nexus Task
     
    .DESCRIPTION
    Starts a Nexus Task
     
    .PARAMETER Task
    The task to start
     
    .EXAMPLE
    Stop-NexusTask -Task 'Cleanup Service'
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/Tasks/Start-NexusTask/')]
    Param(
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ArgumentCompleter( {
                param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

                $r = (Get-NexusTask).Name

                if ($WordToComplete) {
                    $r.Where($_ -match "^$WordToComplete")
                }

                else {
                    $r
                }
            })]
        [Alias('Name')]
        [String]
        $Task
    )

    process {

        $id = (Get-NexusTask | Where-Object { $_.Name -eq $Task }).Id
        $urislug = "/service/rest/v1/tasks/$id/run"
        Invoke-Nexus -Urislug $urislug -Method POST
    }
}
#EndRegion '.\public\Task\Start-NexusTask.ps1' 46
#Region '.\public\Task\Stop-NexusTask.ps1' 0
function Stop-NexusTask {
    <#
    .SYNOPSIS
    Stops a running Nexus Task
     
    .DESCRIPTION
    Stops a running Nexus Task
     
    .PARAMETER Task
    The task to stop
     
    .EXAMPLE
    Stop-NexusTask -Task 'Cleanup Service'
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri = 'https://nexushell.dev/Tasks/Stop-NexusTask/')]
    Param(
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ArgumentCompleter( {
                param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

                $r = (Get-NexusTask).Name

                if ($WordToComplete) {
                    $r.Where($_ -match "^$WordToComplete")
                }

                else {
                    $r
                }
            })]
        [Alias('Name')]
        [String]
        $Task
    )

    process {
        $id = (Get-NexusTask | Where-Object { $_.Name -eq $Task }).Id

        $urislug = "/service/rest/v1/tasks/$id/stop"
        Invoke-Nexus -Urislug $urislug -Method POST
    }
}
#EndRegion '.\public\Task\Stop-NexusTask.ps1' 46
#Region '.\public\User\Get-NexusUser.ps1' 0
function Get-NexusUser {
    <#
    .SYNOPSIS
    Retrieve a list of users. Note if the source is not 'default' the response is limited to 100 users.
     
    .DESCRIPTION
    Retrieve a list of users. Note if the source is not 'default' the response is limited to 100 users.
     
    .PARAMETER User
    The username to fetch
     
    .PARAMETER Source
    The source to fetch from
     
    .EXAMPLE
    Get-NexusUser
     
    .EXAMPLE
    Get-NexusUser -User bob
 
    .EXAMPLE
    Get-NexusUser -Source default
 
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/User/Get-NexusUser/')]
    Param(
        [Parameter()]
        [String]
        $User,

        [Parameter()]
        [String]
        $Source
    )

    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }
    }

    process {
        $urislug = '/service/rest/v1/security/users'

        if($User){
            $urislug = "/service/rest/v1/security/users?userId=$User"
        }

        if($Source){
            $urislug = "/service/rest/v1/security/users?source=$Source"
        }

        if($User -and $Source){
            $urislug = "/service/rest/v1/security/users?userId=$User&source=$Source"
        }

        $result = Invoke-Nexus -Urislug $urislug -Method GET

        $result | Foreach-Object {
            [pscustomobject]@{
                Username = $_.userId
                FirstName = $_.firstName
                LastName = $_.lastName
                EmailAddress = $_.emailAddress
                Source = $_.source
                Status = $_.status
                ReadOnly = $_.readOnly
                Roles = $_.roles
                ExternalRoles = $_.externalRoles
            }
        }
    }
}
#EndRegion '.\public\User\Get-NexusUser.ps1' 76
#Region '.\public\User\New-NexusUser.ps1' 0
function New-NexusUser {
    <#
    .SYNOPSIS
    Create a new user in the default source.
     
    .DESCRIPTION
    Create a new user in the default source.
     
    .PARAMETER Username
    The userid which is required for login. This value cannot be changed.
     
    .PARAMETER Password
    The password for the new user.
     
    .PARAMETER FirstName
    The first name of the user.
     
    .PARAMETER LastName
    The last name of the user.
     
    .PARAMETER EmailAddress
    The email address associated with the user.
     
    .PARAMETER Status
    The user's status, e.g. active or disabled.
     
    .PARAMETER Roles
    The roles which the user has been assigned within Nexus.
     
    .EXAMPLE
    $params = @{
        Username = 'jimmy'
        Password = ("sausage" | ConvertTo-SecureString -AsPlainText -Force)
        FirstName = 'Jimmy'
        LastName = 'Dean'
        EmailAddress = 'sausageking@jimmydean.com'
        Status = Active
        Roles = 'nx-admin'
    }
 
    New-NexusUser @params
     
    .NOTES
     
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/User/New-NexusUser/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Username,

        [Parameter(Mandatory)]
        [SecureString]
        $Password,

        [Parameter(Mandatory)]
        [String]
        $FirstName,

        [Parameter(Mandatory)]
        [String]
        $LastName,

        [Parameter(Mandatory)]
        [String]
        $EmailAddress,

        [Parameter(Mandatory)]
        [ValidateSet('Active', 'Locked', 'Disabled', 'ChangePassword')]
        [String]
        $Status,

        [Parameter(Mandatory)]
        [ArgumentCompleter({
            param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)
            (Get-NexusRole).Id.Where{$_ -like "*$WordToComplete*"}
        })]
        [String[]]
        $Roles
    )

    process {
        $urislug = '/service/rest/v1/security/users'

        $Body = @{
            userId       = $Username
            firstName    = $FirstName
            lastName     = $LastName
            emailAddress = $EmailAddress
            password     = [System.Net.NetworkCredential]::new($Username, $Password).Password
            status       = $Status
            roles        = $Roles
        }

        Write-Verbose ($Body | ConvertTo-Json)
        $result = Invoke-Nexus -Urislug $urislug -Body $Body -Method POST

        [pscustomObject]@{
            Username      = $result.userId
            FirstName     = $result.firstName
            LastName      = $result.lastName
            EmailAddress  = $result.emailAddress
            Source        = $result.source
            Status        = $result.status
            Roles         = $result.roles
            ExternalRoles = $result.externalRoles
        }
    }
}
#EndRegion '.\public\User\New-NexusUser.ps1' 110
#Region '.\public\User\Remove-NexusUser.ps1' 0
function Remove-NexusUser {
    <#
    .SYNOPSIS
    Delete a Nexus user.
     
    .DESCRIPTION
    Delete a Nexus user.
     
    .PARAMETER Username
    The userid the request should apply to.
     
    .PARAMETER Force
    Don't prompt for confirmation before deleting
     
    .EXAMPLE
    Remove-NexusUser -Username jimmy
 
    .EXAMPLE
    Remove-NexusUser -Username jimmy -Force
 
    .EXAMPLE
    Get-NexusUser -User jimmy | Remove-NexusUser -Force
     
    .NOTES
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/User/Remove-NexusUser/',SupportsShouldProcess, ConfirmImpact = 'High')]
    Param(
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [Alias('userId')]
        [String[]]
        $Username,

        [Parameter()]
        [Switch]
        $Force
    )

    process {

        $Username | Foreach-Object {
            $urislug = "/service/rest/v1/security/users/$_"
            if ($Force -and -not $Confirm) {
                $ConfirmPreference = 'None'
                if ($PSCmdlet.ShouldProcess("$($_)", "Remove User")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE
                }
            }
            else {
                if ($PSCmdlet.ShouldProcess("$($_)", "Remove User")) {
                    Invoke-Nexus -UriSlug $urislug -Method DELETE
                }
            }
        }
    }
}
#EndRegion '.\public\User\Remove-NexusUser.ps1' 56
#Region '.\public\User\Set-NexusUser.ps1' 0
function Set-NexusUser {
    <#
    .SYNOPSIS
    Update an existing user.
     
    .DESCRIPTION
    Update an existing user.
     
    .PARAMETER Username
    The userid the request should apply to.
     
    .PARAMETER FirstName
    The first name of the user.
     
    .PARAMETER LastName
    The last name of the user.
     
    .PARAMETER EmailAddress
    The email address associated with the user.
     
    .PARAMETER Source
    The user source which is the origin of this user. This value cannot be changed.
     
    .PARAMETER Status
    The user's status, e.g. active or disabled.
     
    .PARAMETER ReadOnly
    Indicates whether the user's properties could be modified by the Nexus Repository Manager. When false only roles are considered during update.
     
    .PARAMETER Roles
    The roles which the user has been assigned within Nexus.
     
    .PARAMETER ExternalRoles
    The roles which the user has been assigned in an external source, e.g. LDAP group. These cannot be changed within the Nexus Repository Manager.
     
    .EXAMPLE
    An example
     
    .NOTES
    General notes
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/User/Set-NexusUser/')]
    Param(
        [Parameter(Mandatory)]
        [ArgumentCompleter( {
                param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)

                $r = (Get-NexusUser).UserName

                if ($WordToComplete) {
                    $r.Where($_ -match "^$WordToComplete")
                }
                else {
                    $r
                }
            })]
        [String]
        $Username,

        [Parameter()]
        [String]
        $FirstName,

        [Parameter()]
        [String]
        $LastName,

        [Parameter()]
        [String]
        $EmailAddress,

        [Parameter()]
        [ValidateSet('Active', 'Locked', 'Disabled', 'ChangePassword')]
        [String]
        $Status,

        [Parameter()]
        [Switch]
        $ReadOnly,

        [Parameter()]
        [String[]]
        $Roles    
        )

    process {

        $user = Get-NexusUser -User $Username
        $urislug = "/service/rest/v1/security/users/$Username"

        if($Username -notin $((Get-nexusUser).Username)){
            throw "Username cannot be changed or not found in list of existing users"
        }

        switch($null){
            $FirstName { $FirstName = $user.FirstName}
            $LastName { $LastName = $user.LastName }
            $EmailAddress { $EmailAddress = $user.EmailAddress }
            $Status { $Status = $user.Status }
            $ReadOnly {[bool]$ReadOnly = $user.ReadOnly }
            $Roles { $Roles = $user.Roles}
        }

        $Body = @{
            userId = $Username
            firstName = $FirstName
            lastName = $LastName
            emailAddress = $EmailAddress
            status = $Status.ToLower()
            readOnly = [bool]$ReadOnly
            roles = $Roles
            source = $($user.Source)
        }

        Write-Verbose ($Body | ConvertTo-Json)
        Invoke-Nexus -Urislug $urislug -Body $Body -Method PUT
    }
}
#EndRegion '.\public\User\Set-NexusUser.ps1' 119
#Region '.\public\User\Set-NexusUserPassword.ps1' 0
function Set-NexusUserPassword {
    <#
    .SYNOPSIS
    Change a user's password.
 
    .DESCRIPTION
    Change a user's password.
 
    .PARAMETER Username
    The userid the request should apply to
 
    .PARAMETER NewPassword
    The new password to use.
 
    .EXAMPLE
    Set-NexusUserPassword -Username jimmy -NewPassword ("Sausage2021" | ConvertTo-SecureString -AsPlainText -Force)
 
    .NOTES
 
    #>

    [CmdletBinding(HelpUri='https://nexushell.dev/Security/User/Set-NexusUserPassword/')]
    Param(
        [Parameter(Mandatory)]
        [String]
        $Username,

        [Parameter(Mandatory)]
        [SecureString]
        $NewPassword
    )

    process {
        $urislug = "/service/rest/v1/security/users/$Username/change-password"

        Invoke-Nexus -Urislug $urislug -BodyAsSecureString $NewPassword -Method PUT -ContentType 'text/plain'
    }
}
#EndRegion '.\public\User\Set-NexusUserPassword.ps1' 38
#Region '.\public\User Source\Get-NexusUserSource.ps1' 0
Function Get-NexusUserSource {
<#
.SYNOPSIS
Retrieve a list of available user sources
 
.DESCRIPTION
Retrieve a list of available user sources. These sources are things that can handle authentication to Nexus
 
.EXAMPLE
Get-NexusUserSource
 
.NOTES
 
#>

[CmdletBinding(HelpUri='https://nexushell.dev/Security/User%20Sources/Get-NexusUserSource/')]
Param()
    begin {
        if (-not $header) {
            throw "Not connected to Nexus server! Run Connect-NexusServer first."
        }

    }

    process {
        $urislug = '/service/rest/v1/security/user-sources'

        $result = Invoke-Nexus -Urislug $urislug -Method GET

        $result | ForEach-Object {
            [pscustomobject]@{
                Id = $_.id
                Name = $_.Name
            }
        }
    }
}
#EndRegion '.\public\User Source\Get-NexusUserSource.ps1' 37