nexuslib.ps1 Powershell library for uploading files to Nexus raw repository
After a few days' worth of research, I have finally settled on the way I can upload files to a Nexus repository of type raw. This function accepts multiple ways to pass in authentication: either the prebuilt header, or a regular Powershell credentials object, or just username and password. And yes, this function depends on credlib.ps1.
# Filename: nexuslib.ps1
# Location: \\rdputil1\e$\scripts\Functions\
# Author: bgstack15
# Startdate: 2020-06-09
# Title: Upload files to a Nexus raw repository
# Purpose: Upload arbitrary files to Nexus
# History:
# I originally tried http://blog.majcica.com/2016/03/31/uploading-artifacts-into-nexus-via-powershell/ but it must be out of date.
# Usage:
# . nexuslib.ps1
# Upload-File-To-Nexus Upload-File-To-Nexus -File "C:\Users\bgstack15\Downloads\input1.zip" -Repository "raw" -Directory "/somewhere" -FileName "output.zip" -Credential $hubtestCredential
# References:
# curl.exe -v -X POST -F "raw.directory=example/raw/dir/" -F "raw.asset1=@C:\Users\bgstack15\Downloads\example.zip" -F "raw.asset1.filename=example.zip" -u bgstack15:SOMETHINGHERE https://hubtest.example.com/service/rest/v1/components?repository=raw --trace-ascii outputfile.txt
# https://help.sonatype.com/repomanager3/rest-and-integration-api/components-api#ComponentsAPI-Raw
# https://stackoverflow.com/questions/22491129/how-to-send-multipart-form-data-with-powershell-invoke-restmethod/48580319#48580319
# Improve:
# Upload maven2 files? That use case will probably not come up here.
# Documentation:
# Dependencies:
# \\rdputil1\e$\scripts\Functions\credlib.ps1
Function Upload-File-To-Nexus {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True )][ValidateNotNullOrEmpty()][string]$File, # aka File
[Parameter(Mandatory=$False)][string]$Server = "hubtest.benefitfocus.com",
[Parameter(Mandatory=$False)][string]$Username,
[Parameter(Mandatory=$False)][string]$Password,
[Parameter(Mandatory=$False)][Hashtable]$AuthHeaders,
[Parameter(Mandatory=$False)][System.Management.Automation.PSCredential]$Credential,
[parameter(Mandatory=$True )][ValidateNotNullOrEmpty()][string]$Repository,
[parameter(Mandatory=$True )][ValidateNotNullOrEmpty()][string]$Directory,
[Parameter(Mandatory=$False)][ValidateNotNullOrEmpty()][string]$FileName # destination filename, which can be derived from uploaded file
)
Begin {
If (!($AuthHeaders -ne $Null)) {
If (!($Credential -ne $Null)) {
If ($Username -ne $null -And $Password -ne $Null -And $Username -ne "" -And $Password -ne "") {
$secret = $password | ConvertTo-SecureString -AsPlainText -Force
$Credential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList ${username}, ${secret}
} Else {
Throw "Need one of: -AuthHeaders or -Credential, or both -Username and -Password. Aborted."
}
}
# transform credential to authheader format
. \\rdputil1\e$\scripts\Functions\credlib.ps1
$AuthHeaders = Get-Basic-Base64-Auth-Headers -Credential $Credential
}
$Uri = "https://${Server}/service/rest/v1/components?repository=${Repository}"
$boundary = [System.Guid]::NewGuid().ToString()
$LF = "`r`n"
}
Process {
If (!($FileName -ne $Null -And $FileName -ne "")) {
# if filename is null, then just use the filename from the input file
$FileName = Split-Path $File -Leaf
}
Try { $fileBin = [System.IO.File]::ReadAlltext($File) }
Catch { Throw "Unable to read file $File. Aborted." }
$bodyLines = (
"--${boundary}",
"Content-Disposition: form-data; name=`"raw.directory`"",
"",
"${Directory}",
"--${boundary}",
"Content-Disposition: form-data; name=`"raw.asset1`"; filename=`"${FileName}`"",
"Content-Type: application/octet-stream",
"",
$fileBin,
"",
"--${boundary}",
"Content-Disposition: form-data; name=`"raw.asset1.filename`"",
"",
"${FileName}",
"--${boundary}--",
""
) -join $LF
$Response = Invoke-WebRequest -Uri $Uri -Method "POST" -Headers $AuthHeaders -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $bodyLines
If ($Response.StatusCode -ge 200 -And $Response.StatusCode -lt 300) {
$Output = "https://${Server}/repository/${repository}/${directory}/${FileName}" -Replace "//","/"
Write-Output $Output
} Else {
Write-Output $Response
}
}
}
References
Weblinks
- Components API | Sonatype Nexus documentation
- curl - How to send multipart/form-data with PowerShell Invoke-RestMethod - Stack Overflow
Alternate reading
- This page attempts to explain how to upload a file to Nexus, but it must be out of date or otherwise invalid. And the official Sonatype documentation even linked to it at one point somewhere! Uploading artifacts into Nexus via PowerShell – Mummy's blog
Comments