Shell script example
PowerShell Script Example (.ps1)
# =======================
# BEARING X Upload with Login, Progress Bar & Clear Error Messages
# Compatible: Windows PowerShell 5.1
# =======================
# --- CONFIG ---
$PROTOCOL = "https"
$BASE_URL = "example.app.bearingx.io" # without https://
$USERNAME = "exampleUserBEARINGX"
$PASSWORD = "examplePasswordBEARINGX"
$FILENAME = "C:\Users\DeniseHaddad\Desktop\BX Upload\BEARING X - CSV-Testliste-kurz.csv"
$WORKDIR = ".\"
# --- PREPARATION ---
$ProgressPreference = 'Continue'
$GLOBAL:BX_PROGRESS_ID = 1
# Base URI as Uri object (important for cookies)
$BASE_URI = [uri]("{0}://{1}" -f $PROTOCOL, $BASE_URL)
# --- HELPER FUNCTIONS ---
function Show-ErrorSpecific {
param(
[Parameter(Mandatory)]$Exception,
[string]$Context = ""
)
Write-Host ""
Write-Host "❌ $Context" -ForegroundColor Red
if ($Exception -is [System.Net.WebException]) {
$webEx = [System.Net.WebException]$Exception
try {
$resp = [System.Net.HttpWebResponse]$webEx.Response
if ($resp) {
$code = [int]$resp.StatusCode
Write-Host ("HTTP {0} {1}" -f $code, $resp.StatusDescription) -ForegroundColor Yellow
if ($code -eq 401) { Write-Host "Unauthorized – Username or password is incorrect." -ForegroundColor Yellow }
elseif ($code -eq 403) { Write-Host "Forbidden – Access denied." -ForegroundColor Yellow }
try {
$reader = New-Object System.IO.StreamReader($resp.GetResponseStream())
$body = $reader.ReadToEnd()
if ($body) {
Write-Host "--- Server response ---" -ForegroundColor DarkGray
Write-Host $body
Write-Host "-----------------------" -ForegroundColor DarkGray
}
} catch {}
} else {
switch ($webEx.Status) {
'NameResolutionFailure' { Write-Host "DNS resolution failed. Check BASE_URL: $($BASE_URI.Host)" -ForegroundColor Yellow }
'ConnectFailure' { Write-Host "Connection failed. Check Firewall/Proxy/URL." -ForegroundColor Yellow }
'Timeout' { Write-Host "Timeout. Server not responding." -ForegroundColor Yellow }
default { Write-Host "Network error: $($webEx.Status)" -ForegroundColor Yellow }
}
}
} catch {
Write-Host "Error while reading HTTP response." -ForegroundColor Yellow
}
} else {
Write-Host ($Exception.Message) -ForegroundColor Yellow
}
}
function Fail {
param([string]$Message = "Upload failed.")
Write-Host $Message -ForegroundColor Red
Write-Progress -Id $GLOBAL:BX_PROGRESS_ID -Activity "Upload" -Completed
exit 1
}
# Auth check via a protected API (returns 2xx only with a valid session)
function Test-AuthenticatedSession {
param(
[Parameter(Mandatory)][uri]$BaseUri,
[Parameter(Mandatory)][Microsoft.PowerShell.Commands.WebRequestSession]$WebSession
)
$testUri = [uri]("$($BaseUri.Scheme)://$($BaseUri.Host)/api/trades?page=0&size=1")
try {
$r = Invoke-WebRequest -Uri $testUri -WebSession $WebSession -Method GET -ErrorAction Stop
return ($r.StatusCode -ge 200 -and $r.StatusCode -lt 300)
} catch {
if ($_.Exception -is [System.Net.WebException]) {
try {
$resp = [System.Net.HttpWebResponse]$_.Exception.Response
if ($resp) {
$code = [int]$resp.StatusCode
if ($code -in 401,403) { return $false }
}
} catch {}
}
throw
}
}
# Upload with real progress bar
function Invoke-MultipartUploadWithProgress {
param(
[Parameter(Mandatory)] [string] $Uri,
[Parameter(Mandatory)] [string] $FilePath,
[Parameter(Mandatory)] [Microsoft.PowerShell.Commands.WebRequestSession] $WebSession
)
if (-not (Test-Path -LiteralPath $FilePath)) { Fail "CSV file not found: $FilePath" }
$fileInfo = Get-Item -LiteralPath $FilePath
if ($fileInfo.Length -le 0) { Fail "CSV file is empty: $FilePath" }
$boundary = "----BXBoundary$([System.Guid]::NewGuid().ToString('N'))"
$fileName = $fileInfo.Name
$pre = "--$boundary`r`n" +
"Content-Disposition: form-data; name=`"file`"; filename=`"$fileName`"`r`n" +
"Content-Type: text/csv`r`n`r`n"
$post = "`r`n--$boundary--`r`n"
$preBytes = [System.Text.Encoding]::UTF8.GetBytes($pre)
$postBytes = [System.Text.Encoding]::UTF8.GetBytes($post)
$totalLen = $preBytes.Length + $fileInfo.Length + $postBytes.Length
$req = [System.Net.HttpWebRequest]::Create($Uri)
$req.Method = "POST"
$req.ContentType = "multipart/form-data; boundary=$boundary"
$req.CookieContainer = $WebSession.Cookies
$req.AllowWriteStreamBuffering = $false
$req.SendChunked = $false
$req.ContentLength = $totalLen
$req.Timeout = 1000 * 60 * 10
$req.UserAgent = "PowerShell-Upload/1.0"
$req.Accept = "application/json, */*"
$req.Headers.Add("X-Requested-With","XMLHttpRequest")
$bufferSize = 64KB
$bytesSent = 0
try {
$requestStream = $req.GetRequestStream()
# Header
$requestStream.Write($preBytes, 0, $preBytes.Length)
$bytesSent += $preBytes.Length
$pct = [math]::Round(($bytesSent / $totalLen) * 100)
Write-Progress -Id $GLOBAL:BX_PROGRESS_ID -Activity "Preparing upload" -Status "Sending header..." -PercentComplete $pct
# File stream
$fs = [System.IO.File]::OpenRead($FilePath)
try {
$buffer = New-Object byte[] $bufferSize
while (($read = $fs.Read($buffer, 0, $buffer.Length)) -gt 0) {
$requestStream.Write($buffer, 0, $read)
$bytesSent += $read
$pct = [math]::Round(($bytesSent / $totalLen) * 100)
$mbSent = [math]::Round($bytesSent / 1MB, 2)
$mbTotal = [math]::Round($totalLen / 1MB, 2)
Write-Progress -Id $GLOBAL:BX_PROGRESS_ID -Activity "Uploading" -Status "$mbSent / $mbTotal MB transferred..." -PercentComplete $pct
}
} finally {
$fs.Close()
}
# Trailer
$requestStream.Write($postBytes, 0, $postBytes.Length)
Write-Progress -Id $GLOBAL:BX_PROGRESS_ID -Activity "Finalizing upload" -Status "Finishing..." -PercentComplete 100
$requestStream.Flush()
$requestStream.Close()
# Response
$resp = [System.Net.HttpWebResponse]$req.GetResponse()
try {
Write-Progress -Id $GLOBAL:BX_PROGRESS_ID -Activity "Upload" -Completed
Write-Host ("✅ Upload successful! HTTP {0} {1}" -f [int]$resp.StatusCode, $resp.StatusDescription) -ForegroundColor Green
} finally {
$resp.Close()
}
} catch {
Write-Progress -Id $GLOBAL:BX_PROGRESS_ID -Activity "Upload" -Completed
Show-ErrorSpecific -Exception $_.Exception -Context "Upload failed."
exit 1
}
}
# --- START ---
Write-Host "Starting automatic upload..." -ForegroundColor Cyan
# TLS
try {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13
} catch {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
}
# Working directory
try {
Set-Location -Path $WORKDIR -ErrorAction Stop
} catch {
Show-ErrorSpecific -Exception $_.Exception -Context "Could not set working directory: $WORKDIR"
exit 1
}
# Checks
if ([string]::IsNullOrWhiteSpace($BASE_URL)) { Fail "BASE_URL missing." }
if ($BASE_URL -match "^https?://") { Fail "BASE_URL must not include protocol (e.g. 'earlybrands.app.bearingx.io')." }
if (-not (Test-Path -LiteralPath $FILENAME)) { Fail "CSV file not found: $FILENAME" }
# Login
$loginUri = [uri]("$($BASE_URI.Scheme)://$($BASE_URI.Host)/login")
Write-Host "Logging in as '$USERNAME'..." -ForegroundColor Cyan
$Session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
try {
$loginResponse = Invoke-WebRequest -Uri $loginUri `
-Method POST `
-Body @{ username = $USERNAME; password = $PASSWORD } `
-ContentType "application/x-www-form-urlencoded" `
-WebSession $Session `
-ErrorAction Stop
$onLoginPage = $loginResponse.BaseResponse.ResponseUri.AbsolutePath -match '/login'
$showsFormAgain = $false
try { if ($loginResponse.Content -match 'name="username"') { $showsFormAgain = $true } } catch {}
$authOK = $false
if (-not $onLoginPage -and -not $showsFormAgain) {
$authOK = Test-AuthenticatedSession -BaseUri $BASE_URI -WebSession $Session
}
if ($authOK) {
Write-Host "✅ Login successful." -ForegroundColor Green
} else {
Fail "Login failed – incorrect username/password or no valid session."
}
} catch {
Show-ErrorSpecific -Exception $_.Exception -Context "Login failed."
exit 1
}
# Upload
$uploadUri = "$($BASE_URI.Scheme)://$($BASE_URI.Host)/api/orders/upload"
Write-Host "Starting upload: '$FILENAME'" -ForegroundColor Cyan
Invoke-MultipartUploadWithProgress -Uri $uploadUri -FilePath $FILENAME -WebSession $Session
Write-Host "Process completed." -ForegroundColor Cyan
exit 0
How does the script work?
The following description is based on the script shown above. The script is only an example of how an upload is possible.
To run the script, PowerShell ISE must be opened as an administrator (it is best to enter this in the Windows search and then right-click to open as an administrator). Then insert the script shown above. The lines with the URL, the user name, the password and the file path must be adapted (purple colored lines). Finally, simply execute the script (green play button).
If the upload is successful, the script gives positive feedback.