mirror of
https://github.com/Grace-Solutions/PSMinIO.git
synced 2026-08-05 11:07:41 +00:00
Create comprehensive PowerShell threading documentation and patterns
� PERMANENT THREADING KNOWLEDGE BASE:
✅ CREATED COMPREHENSIVE DOCUMENTATION:
• docs/POWERSHELL-THREADING-RULES.md - Complete threading guide
• Enhanced ThreadSafeProgressCollector with usage examples
• Added to project structure documentation
• Saved to AI memory for future reference
� CRITICAL RULES DOCUMENTED:
• PowerShell cmdlets can ONLY call Write-* methods from main thread
• Background threads must QUEUE updates, never call Write-* directly
• ProcessQueuedUpdates() must ONLY be called from main thread
• Common mistakes and error symptoms clearly identified
� DESIGN PATTERNS PROVIDED:
• Periodic processing pattern (every 1 second)
• Completion-based processing pattern
• Manual processing points pattern
• Correct Task.WaitAll usage with timeouts
� IMPLEMENTATION CHECKLIST:
• Pre-implementation checklist for new cmdlets
• Debugging tips and error identification
• Code examples for correct and incorrect patterns
• Testing guidelines for threading compliance
� PREVENTS FUTURE REGRESSIONS:
• Clear documentation of the 'golden rule'
• Examples of common threading violations
• Patterns for all background operation types
• Reference for all future PowerShell module development
This ensures we never repeat the same threading mistakes!
This commit is contained in:
@@ -1,29 +0,0 @@
|
||||
# Check what parameters are available for New-MinIOObject
|
||||
Import-Module ".\Module\PSMinIO\PSMinIO.psd1" -Force
|
||||
|
||||
Write-Host "=== New-MinIOObject Parameter Information ===" -ForegroundColor Cyan
|
||||
|
||||
# Get command info
|
||||
$cmdInfo = Get-Command New-MinIOObject
|
||||
|
||||
Write-Host "`nParameter Sets:" -ForegroundColor Yellow
|
||||
foreach ($paramSet in $cmdInfo.ParameterSets) {
|
||||
Write-Host " $($paramSet.Name):" -ForegroundColor Green
|
||||
foreach ($param in $paramSet.Parameters) {
|
||||
if ($param.Name -notin @('Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'InformationAction', 'ErrorVariable', 'WarningVariable', 'InformationVariable', 'OutVariable', 'OutBuffer', 'PipelineVariable', 'WhatIf', 'Confirm')) {
|
||||
$mandatory = if ($param.IsMandatory) { " (Mandatory)" } else { "" }
|
||||
$aliases = if ($param.Aliases.Count -gt 0) { " [Aliases: $($param.Aliases -join ', ')]" } else { "" }
|
||||
Write-Host " - $($param.Name)$mandatory$aliases" -ForegroundColor White
|
||||
}
|
||||
}
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
Write-Host "All Parameters:" -ForegroundColor Yellow
|
||||
foreach ($param in $cmdInfo.Parameters.Values) {
|
||||
if ($param.Name -notin @('Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'InformationAction', 'ErrorVariable', 'WarningVariable', 'InformationVariable', 'OutVariable', 'OutBuffer', 'PipelineVariable', 'WhatIf', 'Confirm')) {
|
||||
$aliases = if ($param.Aliases.Count -gt 0) { " [Aliases: $($param.Aliases -join ', ')]" } else { "" }
|
||||
$paramSets = $param.ParameterSets.Keys -join ', '
|
||||
Write-Host " $($param.Name)$aliases - Sets: $paramSets" -ForegroundColor White
|
||||
}
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
# Test script for uploading 50 test files to demonstrate enhanced upload functionality
|
||||
# This tests FileInfo[] support, multi-layer progress tracking, and BucketDirectory features
|
||||
|
||||
param(
|
||||
[string]$TestBucketName = "psminiotest-50files-$(Get-Date -Format 'yyyyMMdd-HHmmss')",
|
||||
[string]$TestDirectory = "TestFiles50",
|
||||
[switch]$Cleanup,
|
||||
[switch]$Verbose
|
||||
)
|
||||
|
||||
# Set verbose preference if requested
|
||||
if ($Verbose) {
|
||||
$VerbosePreference = 'Continue'
|
||||
}
|
||||
|
||||
Write-Host "=== PSMinIO 50-File Upload Test ===" -ForegroundColor Cyan
|
||||
Write-Host "Testing enhanced upload functionality with multi-layer progress tracking" -ForegroundColor Green
|
||||
|
||||
try {
|
||||
# Import the module
|
||||
Write-Host "`n1. Loading PSMinIO module..." -ForegroundColor Yellow
|
||||
Import-Module ".\Module\PSMinIO\PSMinIO.psd1" -Force
|
||||
|
||||
# Connect to MinIO
|
||||
Write-Host "2. Connecting to MinIO..." -ForegroundColor Yellow
|
||||
Connect-MinIO -Endpoint "https://api.s3.gracesolution.info" -AccessKey "T34Wg85SAwezUa3sk3m4" -SecretKey "PxEmnbQoQJTJsDocSEV6mSSscDpJMiJCayPv93xe"
|
||||
Write-Host "✅ Connected successfully!" -ForegroundColor Green
|
||||
|
||||
# Create test directory and files
|
||||
Write-Host "`n3. Creating test files..." -ForegroundColor Yellow
|
||||
if (Test-Path $TestDirectory) {
|
||||
Remove-Item $TestDirectory -Recurse -Force
|
||||
}
|
||||
New-Item -ItemType Directory -Path $TestDirectory -Force | Out-Null
|
||||
|
||||
# Create 50 test files with varying sizes and content
|
||||
$testFiles = @()
|
||||
for ($i = 1; $i -le 50; $i++) {
|
||||
$fileName = "testfile-{0:D3}.txt" -f $i
|
||||
$filePath = Join-Path $TestDirectory $fileName
|
||||
|
||||
# Create files with different sizes (1KB to 100KB)
|
||||
$fileSize = Get-Random -Minimum 1024 -Maximum 102400
|
||||
$content = "Test file $i`n" + ("X" * ($fileSize - 20))
|
||||
|
||||
Set-Content -Path $filePath -Value $content -NoNewline
|
||||
$testFiles += Get-Item $filePath
|
||||
}
|
||||
|
||||
Write-Host "✅ Created 50 test files (total size: $((($testFiles | Measure-Object Length -Sum).Sum / 1MB).ToString('F2')) MB)" -ForegroundColor Green
|
||||
|
||||
# Create test bucket
|
||||
Write-Host "`n4. Creating test bucket: $TestBucketName" -ForegroundColor Yellow
|
||||
New-MinIOBucket -BucketName $TestBucketName
|
||||
Write-Host "✅ Bucket created successfully!" -ForegroundColor Green
|
||||
|
||||
# Test 1: Upload all files using FileInfo[] parameter
|
||||
Write-Host "`n5. Test 1: Uploading 50 files using FileInfo[] parameter..." -ForegroundColor Yellow
|
||||
Write-Host " This will demonstrate multi-layer progress tracking:" -ForegroundColor Cyan
|
||||
Write-Host " • Layer 1: Collection progress (overall files)" -ForegroundColor Cyan
|
||||
Write-Host " • Layer 2: File progress (current file)" -ForegroundColor Cyan
|
||||
Write-Host " • Layer 3: Transfer progress (bytes)" -ForegroundColor Cyan
|
||||
|
||||
$uploadStart = Get-Date
|
||||
$uploadResults = New-MinIOObject -BucketName $TestBucketName -Files $testFiles -BucketDirectory "batch-upload" -PassThru -Verbose
|
||||
$uploadDuration = (Get-Date) - $uploadStart
|
||||
|
||||
Write-Host "✅ Upload completed in $($uploadDuration.TotalSeconds.ToString('F2')) seconds!" -ForegroundColor Green
|
||||
Write-Host " Average speed: $(($uploadResults | Measure-Object TotalSize -Sum).Sum / $uploadDuration.TotalSeconds / 1MB | ForEach-Object { $_.ToString('F2') }) MB/s" -ForegroundColor Green
|
||||
Write-Host " Files uploaded: $($uploadResults.Count)" -ForegroundColor Green
|
||||
|
||||
# Test 2: Upload using Directory parameter with BucketDirectory
|
||||
Write-Host "`n6. Test 2: Uploading directory with BucketDirectory parameter..." -ForegroundColor Yellow
|
||||
|
||||
$dirUploadStart = Get-Date
|
||||
$dirUploadResults = New-MinIOObject -BucketName $TestBucketName -Directory (Get-Item $TestDirectory) -BucketDirectory "directory-upload/nested/structure" -PassThru -Verbose
|
||||
$dirUploadDuration = (Get-Date) - $dirUploadStart
|
||||
|
||||
Write-Host "✅ Directory upload completed in $($dirUploadDuration.TotalSeconds.ToString('F2')) seconds!" -ForegroundColor Green
|
||||
Write-Host " Files uploaded: $($dirUploadResults.Count)" -ForegroundColor Green
|
||||
|
||||
# Test 3: Verify uploads by listing objects
|
||||
Write-Host "`n7. Verifying uploads..." -ForegroundColor Yellow
|
||||
$allObjects = Get-MinIOObject -BucketName $TestBucketName
|
||||
|
||||
$batchObjects = $allObjects | Where-Object { $_.Name -like "batch-upload/*" }
|
||||
$dirObjects = $allObjects | Where-Object { $_.Name -like "directory-upload/*" }
|
||||
|
||||
Write-Host "✅ Verification complete:" -ForegroundColor Green
|
||||
Write-Host " Total objects in bucket: $($allObjects.Count)" -ForegroundColor Green
|
||||
Write-Host " Batch upload objects: $($batchObjects.Count)" -ForegroundColor Green
|
||||
Write-Host " Directory upload objects: $($dirObjects.Count)" -ForegroundColor Green
|
||||
|
||||
# Test 4: Test with filters (create subdirectories first)
|
||||
Write-Host "`n8. Test 3: Testing directory upload with filters..." -ForegroundColor Yellow
|
||||
|
||||
# Create subdirectories with different file types
|
||||
$subDir1 = Join-Path $TestDirectory "SubDir1"
|
||||
$subDir2 = Join-Path $TestDirectory "SubDir2"
|
||||
New-Item -ItemType Directory -Path $subDir1 -Force | Out-Null
|
||||
New-Item -ItemType Directory -Path $subDir2 -Force | Out-Null
|
||||
|
||||
# Create some .log and .json files
|
||||
for ($i = 1; $i -le 5; $i++) {
|
||||
Set-Content -Path (Join-Path $subDir1 "logfile$i.log") -Value "Log entry $i"
|
||||
Set-Content -Path (Join-Path $subDir2 "config$i.json") -Value "{`"test`": $i}"
|
||||
}
|
||||
|
||||
# Upload only .log files using inclusion filter
|
||||
$filterStart = Get-Date
|
||||
$filterResults = New-MinIOObject -BucketName $TestBucketName -Directory (Get-Item $TestDirectory) -Recursive -InclusionFilter { $_.Extension -eq ".log" } -BucketDirectory "filtered-upload" -PassThru -Verbose
|
||||
$filterDuration = (Get-Date) - $filterStart
|
||||
|
||||
Write-Host "✅ Filtered upload completed in $($filterDuration.TotalSeconds.ToString('F2')) seconds!" -ForegroundColor Green
|
||||
Write-Host " Log files uploaded: $($filterResults.Count)" -ForegroundColor Green
|
||||
|
||||
# Summary
|
||||
Write-Host "`n=== TEST SUMMARY ===" -ForegroundColor Cyan
|
||||
Write-Host "✅ All tests completed successfully!" -ForegroundColor Green
|
||||
Write-Host "Features tested:" -ForegroundColor Yellow
|
||||
Write-Host " • FileInfo[] parameter with 50 files" -ForegroundColor White
|
||||
Write-Host " • Multi-layer progress tracking (3 layers)" -ForegroundColor White
|
||||
Write-Host " • BucketDirectory parameter for nested structures" -ForegroundColor White
|
||||
Write-Host " • Directory parameter with recursive upload" -ForegroundColor White
|
||||
Write-Host " • InclusionFilter for selective file upload" -ForegroundColor White
|
||||
Write-Host " • PassThru parameter for upload results" -ForegroundColor White
|
||||
Write-Host " • Thread-safe progress reporting" -ForegroundColor White
|
||||
|
||||
Write-Host "`nPerformance metrics:" -ForegroundColor Yellow
|
||||
Write-Host " • Batch upload: $($uploadDuration.TotalSeconds.ToString('F2'))s for $($uploadResults.Count) files" -ForegroundColor White
|
||||
Write-Host " • Directory upload: $($dirUploadDuration.TotalSeconds.ToString('F2'))s for $($dirUploadResults.Count) files" -ForegroundColor White
|
||||
Write-Host " • Filtered upload: $($filterDuration.TotalSeconds.ToString('F2'))s for $($filterResults.Count) files" -ForegroundColor White
|
||||
|
||||
# Cleanup option
|
||||
if ($Cleanup) {
|
||||
Write-Host "`n9. Cleaning up..." -ForegroundColor Yellow
|
||||
Remove-MinIOBucket -BucketName $TestBucketName -Force
|
||||
Remove-Item $TestDirectory -Recurse -Force
|
||||
Write-Host "✅ Cleanup completed!" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "`nTest bucket '$TestBucketName' and files preserved for inspection." -ForegroundColor Cyan
|
||||
Write-Host "Use -Cleanup parameter to automatically clean up test resources." -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
} catch {
|
||||
Write-Host "❌ Test failed: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Write-Host "Stack trace: $($_.ScriptStackTrace)" -ForegroundColor Red
|
||||
} finally {
|
||||
# Clean up test files if they exist
|
||||
if (Test-Path $TestDirectory) {
|
||||
Write-Host "`nCleaning up local test files..." -ForegroundColor Yellow
|
||||
Remove-Item $TestDirectory -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`n=== Test Complete ===" -ForegroundColor Cyan
|
||||
@@ -1,117 +0,0 @@
|
||||
# Test script for current upload functionality (single file version)
|
||||
param(
|
||||
[string]$TestBucketName = "psminiotest-current-$(Get-Date -Format 'yyyyMMdd-HHmmss')",
|
||||
[switch]$Cleanup,
|
||||
[switch]$Verbose
|
||||
)
|
||||
|
||||
if ($Verbose) {
|
||||
$VerbosePreference = 'Continue'
|
||||
}
|
||||
|
||||
Write-Host "=== PSMinIO Current Upload Test ===" -ForegroundColor Cyan
|
||||
Write-Host "Testing current upload functionality" -ForegroundColor Green
|
||||
|
||||
try {
|
||||
# Import the module
|
||||
Write-Host "`n1. Loading PSMinIO module..." -ForegroundColor Yellow
|
||||
Import-Module ".\Module\PSMinIO\PSMinIO.psd1" -Force
|
||||
|
||||
# Connect to MinIO
|
||||
Write-Host "2. Connecting to MinIO..." -ForegroundColor Yellow
|
||||
Connect-MinIO -Endpoint "https://api.s3.gracesolution.info" -AccessKey "T34Wg85SAwezUa3sk3m4" -SecretKey "PxEmnbQoQJTJsDocSEV6mSSscDpJMiJCayPv93xe"
|
||||
Write-Host "✅ Connected successfully!" -ForegroundColor Green
|
||||
|
||||
# Create test files
|
||||
Write-Host "`n3. Creating test files..." -ForegroundColor Yellow
|
||||
$testDir = "TestFilesCurrent"
|
||||
if (Test-Path $testDir) {
|
||||
Remove-Item $testDir -Recurse -Force
|
||||
}
|
||||
New-Item -ItemType Directory -Path $testDir -Force | Out-Null
|
||||
|
||||
# Create 10 test files
|
||||
$testFiles = @()
|
||||
for ($i = 1; $i -le 10; $i++) {
|
||||
$fileName = "testfile-{0:D3}.txt" -f $i
|
||||
$filePath = Join-Path $testDir $fileName
|
||||
$content = "Test file $i - $(Get-Date)`n" + ("Content line $i`n" * 10)
|
||||
Set-Content -Path $filePath -Value $content
|
||||
$testFiles += Get-Item $filePath
|
||||
}
|
||||
|
||||
Write-Host "✅ Created 10 test files" -ForegroundColor Green
|
||||
|
||||
# Create test bucket
|
||||
Write-Host "`n4. Creating test bucket: $TestBucketName" -ForegroundColor Yellow
|
||||
New-MinIOBucket -BucketName $TestBucketName
|
||||
Write-Host "✅ Bucket created successfully!" -ForegroundColor Green
|
||||
|
||||
# Test uploading files one by one (current functionality)
|
||||
Write-Host "`n5. Uploading files individually..." -ForegroundColor Yellow
|
||||
$uploadResults = @()
|
||||
$uploadStart = Get-Date
|
||||
|
||||
foreach ($file in $testFiles) {
|
||||
Write-Host " Uploading: $($file.Name)" -ForegroundColor Cyan
|
||||
$result = New-MinIOObject -BucketName $TestBucketName -File $file -BucketDirectory "individual-uploads" -PassThru -Verbose
|
||||
$uploadResults += $result
|
||||
}
|
||||
|
||||
$uploadDuration = (Get-Date) - $uploadStart
|
||||
Write-Host "✅ Upload completed in $($uploadDuration.TotalSeconds.ToString('F2')) seconds!" -ForegroundColor Green
|
||||
Write-Host " Files uploaded: $($uploadResults.Count)" -ForegroundColor Green
|
||||
|
||||
# Verify uploads
|
||||
Write-Host "`n6. Verifying uploads..." -ForegroundColor Yellow
|
||||
$objects = Get-MinIOObject -BucketName $TestBucketName
|
||||
Write-Host "✅ Found $($objects.Count) objects in bucket" -ForegroundColor Green
|
||||
|
||||
# Test with different bucket directories
|
||||
Write-Host "`n7. Testing nested bucket directories..." -ForegroundColor Yellow
|
||||
$nestedResults = @()
|
||||
foreach ($file in $testFiles[0..2]) { # Upload first 3 files to nested structure
|
||||
$result = New-MinIOObject -BucketName $TestBucketName -File $file -BucketDirectory "level1/level2/level3" -PassThru -Verbose
|
||||
$nestedResults += $result
|
||||
}
|
||||
Write-Host "✅ Nested directory upload completed: $($nestedResults.Count) files" -ForegroundColor Green
|
||||
|
||||
# Final verification
|
||||
Write-Host "`n8. Final verification..." -ForegroundColor Yellow
|
||||
$allObjects = Get-MinIOObject -BucketName $TestBucketName
|
||||
$individualObjects = $allObjects | Where-Object { $_.Name -like "individual-uploads/*" }
|
||||
$nestedObjects = $allObjects | Where-Object { $_.Name -like "level1/level2/level3/*" }
|
||||
|
||||
Write-Host "✅ Final verification complete:" -ForegroundColor Green
|
||||
Write-Host " Total objects: $($allObjects.Count)" -ForegroundColor Green
|
||||
Write-Host " Individual uploads: $($individualObjects.Count)" -ForegroundColor Green
|
||||
Write-Host " Nested uploads: $($nestedObjects.Count)" -ForegroundColor Green
|
||||
|
||||
# Summary
|
||||
Write-Host "`n=== TEST SUMMARY ===" -ForegroundColor Cyan
|
||||
Write-Host "✅ Current functionality test completed!" -ForegroundColor Green
|
||||
Write-Host "Features tested:" -ForegroundColor Yellow
|
||||
Write-Host " • Single file upload with File parameter" -ForegroundColor White
|
||||
Write-Host " • BucketDirectory parameter for nested structures" -ForegroundColor White
|
||||
Write-Host " • PassThru parameter for upload results" -ForegroundColor White
|
||||
Write-Host " • Multiple individual uploads" -ForegroundColor White
|
||||
Write-Host " • Nested directory structure creation" -ForegroundColor White
|
||||
|
||||
Write-Host "`nNote: Enhanced features (FileInfo[], Directory, Multi-layer progress) require updated DLL" -ForegroundColor Yellow
|
||||
|
||||
if ($Cleanup) {
|
||||
Write-Host "`n9. Cleaning up..." -ForegroundColor Yellow
|
||||
Remove-MinIOBucket -BucketName $TestBucketName -Force
|
||||
Write-Host "✅ Cleanup completed!" -ForegroundColor Green
|
||||
}
|
||||
|
||||
} catch {
|
||||
Write-Host "❌ Test failed: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Write-Host "Stack trace: $($_.ScriptStackTrace)" -ForegroundColor Red
|
||||
} finally {
|
||||
if (Test-Path $testDir) {
|
||||
Remove-Item $testDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`n=== Test Complete ===" -ForegroundColor Cyan
|
||||
@@ -1,176 +0,0 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Final comprehensive test of the new PSMinIO implementation
|
||||
|
||||
.DESCRIPTION
|
||||
Tests all core functionality of the rebuilt PSMinIO module:
|
||||
- Connection management
|
||||
- Bucket operations
|
||||
- Object upload/download with progress
|
||||
- Performance metrics
|
||||
- Error handling
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param()
|
||||
|
||||
# Import the module
|
||||
Write-Output "=== PSMinIO Final Implementation Test ==="
|
||||
Write-Output "Importing PSMinIO module..."
|
||||
Import-Module "$PSScriptRoot\..\Module\PSMinIO\PSMinIO.psd1" -Force
|
||||
|
||||
try {
|
||||
# Test 1: Connection
|
||||
Write-Output "`n1. Testing Connection..."
|
||||
Connect-MinIO -Endpoint "https://api.s3.gracesolution.info" -AccessKey "T34Wg85SAwezUa3sk3m4" -SecretKey "PxEmnbQoQJTJsDocSEV6mSSscDpJMiJCayPv93xe" -TestConnection -Verbose
|
||||
|
||||
# Get the connection from session variable to verify
|
||||
$connection = Get-Variable -Name "MinIOConnection" -ValueOnly -ErrorAction SilentlyContinue
|
||||
if ($connection -and $connection.Status -eq 'Connected') {
|
||||
Write-Output "✅ Connection successful!"
|
||||
Write-Output " Status: $($connection.Status)"
|
||||
Write-Output " Endpoint: $($connection.Configuration.Endpoint)"
|
||||
} else {
|
||||
throw "Connection failed"
|
||||
}
|
||||
|
||||
# Test 2: List Buckets
|
||||
Write-Output "`n2. Testing Bucket Listing..."
|
||||
$buckets = Get-MinIOBucket -Verbose
|
||||
|
||||
if ($buckets) {
|
||||
Write-Output "✅ Found $($buckets.Count) buckets"
|
||||
$buckets | Select-Object Name, CreationDate | Format-Table -AutoSize
|
||||
} else {
|
||||
Write-Output "⚠️ No buckets found"
|
||||
}
|
||||
|
||||
# Test 3: Create Test Bucket
|
||||
Write-Output "`n3. Testing Bucket Creation..."
|
||||
$testBucket = "psminiotest-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
$bucketResult = New-MinIOBucket -BucketName $testBucket -PassThru -Verbose
|
||||
|
||||
if ($bucketResult) {
|
||||
Write-Output "✅ Bucket created: $($bucketResult.Name)"
|
||||
} else {
|
||||
throw "Bucket creation failed"
|
||||
}
|
||||
|
||||
# Test 4: Test Bucket Exists
|
||||
Write-Output "`n4. Testing Bucket Existence Check..."
|
||||
$exists = Test-MinIOBucketExists -BucketName $testBucket -Verbose
|
||||
|
||||
if ($exists) {
|
||||
Write-Output "✅ Bucket existence confirmed: $exists"
|
||||
} else {
|
||||
throw "Bucket existence check failed"
|
||||
}
|
||||
|
||||
# Test 5: Create and Upload Test File
|
||||
Write-Output "`n5. Testing File Upload with Progress..."
|
||||
$testFile = Join-Path $env:TEMP "psminiotest-$(Get-Date -Format 'yyyyMMddHHmmss').txt"
|
||||
$testContent = @"
|
||||
PSMinIO Final Test File
|
||||
======================
|
||||
Created: $(Get-Date)
|
||||
Implementation: Custom REST API
|
||||
Features: Real progress reporting, performance metrics
|
||||
Test data: $('A' * 2000)
|
||||
"@
|
||||
|
||||
$testContent | Out-File -FilePath $testFile -Encoding UTF8
|
||||
$fileInfo = Get-Item $testFile
|
||||
Write-Output " Test file created: $($fileInfo.Length) bytes"
|
||||
|
||||
$uploadResult = New-MinIOObject -BucketName $testBucket -File $fileInfo -PassThru -Verbose
|
||||
|
||||
if ($uploadResult -and $uploadResult.Success) {
|
||||
Write-Output "✅ Upload successful!"
|
||||
Write-Output " Object: $($uploadResult.ObjectName)"
|
||||
Write-Output " Size: $($uploadResult.TotalSizeFormatted)"
|
||||
Write-Output " Duration: $($uploadResult.DurationFormatted)"
|
||||
Write-Output " Speed: $($uploadResult.AverageSpeedFormatted)"
|
||||
} else {
|
||||
throw "File upload failed"
|
||||
}
|
||||
|
||||
# Test 6: List Objects
|
||||
Write-Output "`n6. Testing Object Listing..."
|
||||
$objects = Get-MinIOObject -BucketName $testBucket -Verbose
|
||||
|
||||
if ($objects -and $objects.Count -gt 0) {
|
||||
Write-Output "✅ Found $($objects.Count) objects"
|
||||
$objects | Select-Object Name, Size, LastModified | Format-Table -AutoSize
|
||||
} else {
|
||||
throw "Object listing failed"
|
||||
}
|
||||
|
||||
# Test 7: Download File with Progress
|
||||
Write-Output "`n7. Testing File Download with Progress..."
|
||||
$downloadFile = Join-Path $env:TEMP "psminiotest-download-$(Get-Date -Format 'yyyyMMddHHmmss').txt"
|
||||
$downloadResult = Get-MinIOObjectContent -BucketName $testBucket -ObjectName $fileInfo.Name -LocalPath $downloadFile -PassThru -Verbose
|
||||
|
||||
if ($downloadResult -and $downloadResult.Success) {
|
||||
Write-Output "✅ Download successful!"
|
||||
Write-Output " Object: $($downloadResult.ObjectName)"
|
||||
Write-Output " Size: $($downloadResult.TotalSizeFormatted)"
|
||||
Write-Output " Duration: $($downloadResult.DurationFormatted)"
|
||||
Write-Output " Speed: $($downloadResult.AverageSpeedFormatted)"
|
||||
} else {
|
||||
throw "File download failed"
|
||||
}
|
||||
|
||||
# Test 8: Verify Content
|
||||
Write-Output "`n8. Testing Content Verification..."
|
||||
$originalContent = Get-Content $testFile -Raw -ErrorAction SilentlyContinue
|
||||
$downloadedContent = Get-Content $downloadFile -Raw -ErrorAction SilentlyContinue
|
||||
|
||||
if ($originalContent -and $downloadedContent -and ($originalContent -eq $downloadedContent)) {
|
||||
Write-Output "✅ File content verification PASSED!"
|
||||
} else {
|
||||
throw "File content verification FAILED!"
|
||||
}
|
||||
|
||||
# Test Summary
|
||||
Write-Output "`n=== Test Summary ==="
|
||||
Write-Output "✅ All tests PASSED!"
|
||||
Write-Output ""
|
||||
Write-Output "New PSMinIO Implementation Features Verified:"
|
||||
Write-Output " ✓ Custom REST API client (no MinIO SDK dependency)"
|
||||
Write-Output " ✓ Real progress reporting during transfers"
|
||||
Write-Output " ✓ Performance metrics (duration, speed)"
|
||||
Write-Output " ✓ Synchronous operations optimized for PowerShell"
|
||||
Write-Output " ✓ Enhanced error handling and logging"
|
||||
Write-Output " ✓ AWS S3 signature v4 authentication"
|
||||
Write-Output " ✓ Comprehensive cmdlet functionality"
|
||||
Write-Output ""
|
||||
Write-Output "Architecture Benefits:"
|
||||
Write-Output " • No async/await compatibility issues"
|
||||
Write-Output " • Reduced dependencies (removed 8+ DLLs)"
|
||||
Write-Output " • True progress from HTTP streams"
|
||||
Write-Output " • Built-in performance monitoring"
|
||||
Write-Output " • PowerShell-native design patterns"
|
||||
|
||||
} catch {
|
||||
Write-Output "❌ Test failed: $($_.Exception.Message)"
|
||||
Write-Output "Error details: $($_.Exception.ToString())"
|
||||
exit 1
|
||||
} finally {
|
||||
# Cleanup
|
||||
Write-Output "`n=== Cleanup ==="
|
||||
|
||||
# Remove test files
|
||||
if (Test-Path $testFile -ErrorAction SilentlyContinue) {
|
||||
Remove-Item $testFile -Force -ErrorAction SilentlyContinue
|
||||
Write-Output "Removed test file: $testFile"
|
||||
}
|
||||
|
||||
if (Test-Path $downloadFile -ErrorAction SilentlyContinue) {
|
||||
Remove-Item $downloadFile -Force -ErrorAction SilentlyContinue
|
||||
Write-Output "Removed download file: $downloadFile"
|
||||
}
|
||||
|
||||
Write-Output "Note: Test bucket '$testBucket' left for manual cleanup"
|
||||
Write-Output "Cleanup completed."
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Test script for the new PSMinIO implementation with custom REST API
|
||||
|
||||
.DESCRIPTION
|
||||
This script demonstrates the new PSMinIO module capabilities including:
|
||||
- Connection management with custom REST API
|
||||
- Real progress reporting during transfers
|
||||
- Performance metrics in result objects
|
||||
- Enhanced error handling and logging
|
||||
|
||||
.PARAMETER Endpoint
|
||||
MinIO server endpoint (e.g., https://minio.example.com:9000)
|
||||
|
||||
.PARAMETER AccessKey
|
||||
MinIO access key
|
||||
|
||||
.PARAMETER SecretKey
|
||||
MinIO secret key
|
||||
|
||||
.PARAMETER TestBucket
|
||||
Name of test bucket to create (default: psminiotest)
|
||||
|
||||
.EXAMPLE
|
||||
.\Test-NewImplementation.ps1 -Endpoint "https://play.min.io" -AccessKey "Q3AM3UQ867SPQQA43P2F" -SecretKey "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG"
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Endpoint,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$AccessKey,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$SecretKey,
|
||||
|
||||
[Parameter()]
|
||||
[string]$TestBucket = "psminiotest-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
)
|
||||
|
||||
# Import the module
|
||||
Write-Host "Importing PSMinIO module..." -ForegroundColor Green
|
||||
Import-Module "$PSScriptRoot\..\Module\PSMinIO\PSMinIO.psd1" -Force
|
||||
|
||||
try {
|
||||
# Test 1: Connection
|
||||
Write-Host "`n=== Test 1: Connection ===" -ForegroundColor Yellow
|
||||
Write-Host "Connecting to MinIO server: $Endpoint" -ForegroundColor Cyan
|
||||
|
||||
$connection = Connect-MinIO -Endpoint $Endpoint -AccessKey $AccessKey -SecretKey $SecretKey -TestConnection -PassThru -Verbose
|
||||
Write-Host "✅ Connection successful!" -ForegroundColor Green
|
||||
Write-Host "Connection Status: $($connection.Status)" -ForegroundColor White
|
||||
|
||||
# Test 2: List Buckets
|
||||
Write-Host "`n=== Test 2: List Buckets ===" -ForegroundColor Yellow
|
||||
Write-Host "Listing existing buckets..." -ForegroundColor Cyan
|
||||
|
||||
$buckets = Get-MinIOBucket -Verbose
|
||||
Write-Host "✅ Found $($buckets.Count) buckets" -ForegroundColor Green
|
||||
|
||||
if ($buckets.Count -gt 0) {
|
||||
Write-Host "First few buckets:" -ForegroundColor White
|
||||
$buckets | Select-Object -First 3 | Format-Table Name, CreationDate, @{Name="Age"; Expression={(Get-Date) - $_.CreationDate}}
|
||||
}
|
||||
|
||||
# Test 3: Create Test Bucket
|
||||
Write-Host "`n=== Test 3: Create Test Bucket ===" -ForegroundColor Yellow
|
||||
Write-Host "Creating test bucket: $TestBucket" -ForegroundColor Cyan
|
||||
|
||||
$bucketResult = New-MinIOBucket -Name $TestBucket -PassThru -Verbose
|
||||
Write-Host "✅ Bucket created successfully!" -ForegroundColor Green
|
||||
Write-Host "Bucket: $($bucketResult.Name)" -ForegroundColor White
|
||||
|
||||
# Test 4: Test Bucket Exists
|
||||
Write-Host "`n=== Test 4: Test Bucket Exists ===" -ForegroundColor Yellow
|
||||
Write-Host "Testing if bucket exists..." -ForegroundColor Cyan
|
||||
|
||||
$exists = Test-MinIOBucketExists -Name $TestBucket -Verbose
|
||||
Write-Host "✅ Bucket exists: $exists" -ForegroundColor Green
|
||||
|
||||
# Test 5: Create Test File
|
||||
Write-Host "`n=== Test 5: Create and Upload Test File ===" -ForegroundColor Yellow
|
||||
$testFile = "$env:TEMP\psminiotest-$(Get-Date -Format 'yyyyMMddHHmmss').txt"
|
||||
$testContent = @"
|
||||
PSMinIO Test File
|
||||
================
|
||||
Created: $(Get-Date)
|
||||
Endpoint: $Endpoint
|
||||
Bucket: $TestBucket
|
||||
|
||||
This is a test file created by the PSMinIO test script.
|
||||
The new implementation uses a custom REST API client for better PowerShell compatibility.
|
||||
|
||||
Features demonstrated:
|
||||
- Real progress reporting
|
||||
- Performance metrics
|
||||
- Enhanced error handling
|
||||
- Synchronous operations optimized for PowerShell
|
||||
|
||||
Test data: $('A' * 100)
|
||||
"@
|
||||
|
||||
Write-Host "Creating test file: $testFile" -ForegroundColor Cyan
|
||||
$testContent | Out-File -FilePath $testFile -Encoding UTF8
|
||||
$fileInfo = Get-Item $testFile
|
||||
Write-Host "✅ Test file created: $($fileInfo.Length) bytes" -ForegroundColor Green
|
||||
|
||||
# Test 6: Upload File
|
||||
Write-Host "`n=== Test 6: Upload File with Progress ===" -ForegroundColor Yellow
|
||||
Write-Host "Uploading test file..." -ForegroundColor Cyan
|
||||
|
||||
$uploadResult = New-MinIOObject -BucketName $TestBucket -File $fileInfo -PassThru -Verbose
|
||||
Write-Host "✅ Upload completed!" -ForegroundColor Green
|
||||
Write-Host "Upload Result:" -ForegroundColor White
|
||||
$uploadResult | Format-List ObjectName, TotalSizeFormatted, DurationFormatted, AverageSpeedFormatted, Success
|
||||
|
||||
# Test 7: List Objects
|
||||
Write-Host "`n=== Test 7: List Objects ===" -ForegroundColor Yellow
|
||||
Write-Host "Listing objects in test bucket..." -ForegroundColor Cyan
|
||||
|
||||
$objects = Get-MinIOObject -BucketName $TestBucket -Verbose
|
||||
Write-Host "✅ Found $($objects.Count) objects" -ForegroundColor Green
|
||||
|
||||
if ($objects.Count -gt 0) {
|
||||
Write-Host "Objects in bucket:" -ForegroundColor White
|
||||
$objects | Format-Table Name, @{Name="Size"; Expression={$_.Size}}, LastModified
|
||||
}
|
||||
|
||||
# Test 8: Download File
|
||||
Write-Host "`n=== Test 8: Download File with Progress ===" -ForegroundColor Yellow
|
||||
$downloadFile = "$env:TEMP\psminiotest-download-$(Get-Date -Format 'yyyyMMddHHmmss').txt"
|
||||
Write-Host "Downloading file to: $downloadFile" -ForegroundColor Cyan
|
||||
|
||||
$downloadResult = Get-MinIOObjectContent -BucketName $TestBucket -ObjectName $fileInfo.Name -LocalPath $downloadFile -PassThru -Verbose
|
||||
Write-Host "✅ Download completed!" -ForegroundColor Green
|
||||
Write-Host "Download Result:" -ForegroundColor White
|
||||
$downloadResult | Format-List ObjectName, TotalSizeFormatted, DurationFormatted, AverageSpeedFormatted, Success
|
||||
|
||||
# Verify download
|
||||
$downloadedContent = Get-Content $downloadFile -Raw
|
||||
$originalContent = Get-Content $testFile -Raw
|
||||
if ($downloadedContent -eq $originalContent) {
|
||||
Write-Host "✅ File content verification passed!" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "❌ File content verification failed!" -ForegroundColor Red
|
||||
}
|
||||
|
||||
Write-Host "`n=== Test Summary ===" -ForegroundColor Yellow
|
||||
Write-Host "✅ All tests completed successfully!" -ForegroundColor Green
|
||||
Write-Host "New PSMinIO implementation is working correctly with:" -ForegroundColor White
|
||||
Write-Host " - Custom REST API client" -ForegroundColor White
|
||||
Write-Host " - Real progress reporting" -ForegroundColor White
|
||||
Write-Host " - Performance metrics" -ForegroundColor White
|
||||
Write-Host " - Enhanced error handling" -ForegroundColor White
|
||||
Write-Host " - PowerShell-optimized synchronous operations" -ForegroundColor White
|
||||
|
||||
} catch {
|
||||
Write-Host "❌ Test failed: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Write-Host "Stack trace:" -ForegroundColor Red
|
||||
Write-Host $_.ScriptStackTrace -ForegroundColor Red
|
||||
} finally {
|
||||
# Cleanup
|
||||
Write-Host "`n=== Cleanup ===" -ForegroundColor Yellow
|
||||
|
||||
# Remove test files
|
||||
if (Test-Path $testFile) {
|
||||
Remove-Item $testFile -Force
|
||||
Write-Host "Removed test file: $testFile" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
if (Test-Path $downloadFile) {
|
||||
Remove-Item $downloadFile -Force
|
||||
Write-Host "Removed download file: $downloadFile" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
# Note: We're not removing the test bucket to avoid issues with the test environment
|
||||
Write-Host "Note: Test bucket '$TestBucket' was left for manual cleanup" -ForegroundColor Gray
|
||||
|
||||
Write-Host "Cleanup completed." -ForegroundColor Gray
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
# PSMinIO Comprehensive Test Script
|
||||
# Tests all major functionality against Grace Solution S3 instance
|
||||
|
||||
param(
|
||||
[string]$TestDirectory = "C:\Temp\PSMinIOTest",
|
||||
[string]$TestBucket = "psminiotest-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
)
|
||||
|
||||
# Test configuration
|
||||
$S3Url = "https://api.s3.gracesolution.info"
|
||||
$AccessKey = "T34Wg85SAwezUa3sk3m4"
|
||||
$SecretKey = "PxEmnbQoQJTJsDocSEV6mSSscDpJMiJCayPv93xe"
|
||||
|
||||
Write-Verbose "=== PSMinIO Comprehensive Test Suite ==="
|
||||
Write-Verbose "S3 Endpoint: $S3Url"
|
||||
Write-Verbose "Test Bucket: $TestBucket"
|
||||
Write-Verbose "Test Directory: $TestDirectory"
|
||||
|
||||
# Create test directory and files
|
||||
Write-Verbose "Setting up test environment..."
|
||||
if (Test-Path $TestDirectory) {
|
||||
Remove-Item $TestDirectory -Recurse -Force
|
||||
}
|
||||
New-Item -ItemType Directory -Path $TestDirectory -Force | Out-Null
|
||||
|
||||
# Create test files of various sizes
|
||||
$SmallFile = Join-Path $TestDirectory "small-test.txt"
|
||||
$MediumFile = Join-Path $TestDirectory "medium-test.txt"
|
||||
$LargeFile = Join-Path $TestDirectory "large-test.txt"
|
||||
|
||||
"This is a small test file for PSMinIO testing." | Out-File $SmallFile -Encoding UTF8
|
||||
1..1000 | ForEach-Object { "Line $_ - Medium test file content for PSMinIO testing with more data." } | Out-File $MediumFile -Encoding UTF8
|
||||
1..10000 | ForEach-Object { "Line $_ - Large test file content for PSMinIO multipart testing with substantial data to trigger chunked operations." } | Out-File $LargeFile -Encoding UTF8
|
||||
|
||||
$testFiles = Get-ChildItem $TestDirectory
|
||||
Write-Verbose "Created test files: $($testFiles.Count) files, Total size: $([math]::Round(($testFiles | Measure-Object Length -Sum).Sum / 1KB, 2)) KB"
|
||||
|
||||
$testResults = @()
|
||||
|
||||
try {
|
||||
# Test 1: Connection
|
||||
Write-Verbose "Testing connection..."
|
||||
$connection = Connect-MinIO -Url $S3Url -AccessKey $AccessKey -SecretKey $SecretKey -Verbose
|
||||
$testResults += [PSCustomObject]@{
|
||||
Test = "Connection"
|
||||
Status = "Success"
|
||||
Details = "Connected to $S3Url"
|
||||
Result = $connection
|
||||
}
|
||||
|
||||
# Test 2: List existing buckets
|
||||
Write-Verbose "Testing bucket listing..."
|
||||
$buckets = Get-MinIOBucket -Verbose
|
||||
$testResults += [PSCustomObject]@{
|
||||
Test = "List Buckets"
|
||||
Status = "Success"
|
||||
Details = "Found $($buckets.Count) existing buckets"
|
||||
Result = $buckets
|
||||
}
|
||||
|
||||
# Test 3: Create test bucket
|
||||
Write-Verbose "Testing bucket creation..."
|
||||
$newBucket = New-MinIOBucket -BucketName $TestBucket -Verbose
|
||||
$testResults += [PSCustomObject]@{
|
||||
Test = "Create Bucket"
|
||||
Status = "Success"
|
||||
Details = "Created bucket: $($newBucket.Name)"
|
||||
Result = $newBucket
|
||||
}
|
||||
|
||||
# Test 4: Verify bucket exists
|
||||
Write-Verbose "Testing bucket existence check..."
|
||||
$bucketExists = Test-MinIOBucketExists -BucketName $TestBucket -Verbose
|
||||
$testResults += [PSCustomObject]@{
|
||||
Test = "Bucket Exists"
|
||||
Status = "Success"
|
||||
Details = "Bucket exists: $bucketExists"
|
||||
Result = $bucketExists
|
||||
}
|
||||
|
||||
# Test 5: Upload small file (single part)
|
||||
Write-Verbose "Testing single file upload..."
|
||||
$uploadResult = New-MinIOObject -BucketName $TestBucket -Files (Get-Item $SmallFile) -Verbose
|
||||
$testResults += [PSCustomObject]@{
|
||||
Test = "Single File Upload"
|
||||
Status = "Success"
|
||||
Details = "Uploaded small file: $($uploadResult.Count) objects"
|
||||
Result = $uploadResult
|
||||
}
|
||||
|
||||
# Test 6: Upload medium file (single part)
|
||||
Write-Verbose "Testing medium file upload..."
|
||||
$uploadResult2 = New-MinIOObject -BucketName $TestBucket -Files (Get-Item $MediumFile) -Verbose
|
||||
$testResults += [PSCustomObject]@{
|
||||
Test = "Medium File Upload"
|
||||
Status = "Success"
|
||||
Details = "Uploaded medium file: $($uploadResult2.Count) objects"
|
||||
Result = $uploadResult2
|
||||
}
|
||||
|
||||
# Test 7: Upload large file (multipart)
|
||||
Write-Verbose "Testing multipart upload..."
|
||||
$multipartResult = New-MinIOObjectMultipart -BucketName $TestBucket -FilePath (Get-Item $LargeFile) -Verbose
|
||||
$testResults += [PSCustomObject]@{
|
||||
Test = "Multipart Upload"
|
||||
Status = "Success"
|
||||
Details = "Multipart upload completed: $($multipartResult.Count) objects"
|
||||
Result = $multipartResult
|
||||
}
|
||||
|
||||
# Test 8: List objects in bucket
|
||||
Write-Verbose "Testing object listing..."
|
||||
$objects = Get-MinIOObject -BucketName $TestBucket -Verbose
|
||||
$testResults += [PSCustomObject]@{
|
||||
Test = "List Objects"
|
||||
Status = "Success"
|
||||
Details = "Found $($objects.Count) objects in bucket"
|
||||
Result = $objects
|
||||
}
|
||||
|
||||
# Test 9: Download small file
|
||||
Write-Verbose "Testing single file download..."
|
||||
$downloadPath = Join-Path $TestDirectory "downloaded-small.txt"
|
||||
$downloadResult = Get-MinIOObjectContent -BucketName $TestBucket -ObjectName "small-test.txt" -LocalPath $downloadPath -Verbose
|
||||
$testResults += [PSCustomObject]@{
|
||||
Test = "Single File Download"
|
||||
Status = "Success"
|
||||
Details = "Downloaded file: $($downloadResult.FilePath)"
|
||||
Result = $downloadResult
|
||||
}
|
||||
|
||||
# Test 10: Download large file (multipart)
|
||||
Write-Verbose "Testing multipart download..."
|
||||
$downloadPath2 = Join-Path $TestDirectory "downloaded-large.txt"
|
||||
$multipartDownload = Get-MinIOObjectContentMultipart -BucketName $TestBucket -ObjectName "large-test.txt" -DestinationPath (New-Object System.IO.FileInfo $downloadPath2) -Verbose
|
||||
$testResults += [PSCustomObject]@{
|
||||
Test = "Multipart Download"
|
||||
Status = "Success"
|
||||
Details = "Multipart download completed: $($multipartDownload.FilePath)"
|
||||
Result = $multipartDownload
|
||||
}
|
||||
|
||||
# Test 11: Generate presigned URL
|
||||
Write-Verbose "Testing presigned URL generation..."
|
||||
$presignedUrl = Get-MinIOPresignedUrl -BucketName $TestBucket -ObjectName "small-test.txt" -Expiration (New-TimeSpan -Hours 1) -Verbose
|
||||
$testResults += [PSCustomObject]@{
|
||||
Test = "Presigned URL"
|
||||
Status = "Success"
|
||||
Details = "Generated presigned URL"
|
||||
Result = $presignedUrl
|
||||
}
|
||||
|
||||
} catch {
|
||||
$testResults += [PSCustomObject]@{
|
||||
Test = "ERROR"
|
||||
Status = "Failed"
|
||||
Details = $_.Exception.Message
|
||||
Result = $_.ScriptStackTrace
|
||||
}
|
||||
} finally {
|
||||
# Cleanup
|
||||
Write-Verbose "Cleaning up test resources..."
|
||||
|
||||
try {
|
||||
# Remove local test directory
|
||||
if (Test-Path $TestDirectory) {
|
||||
Remove-Item $TestDirectory -Recurse -Force
|
||||
Write-Verbose "Removed local test directory"
|
||||
}
|
||||
} catch {
|
||||
Write-Warning "Cleanup warning: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
# Output test results
|
||||
Write-Output "PSMinIO Comprehensive Test Results:"
|
||||
Write-Output "=================================="
|
||||
$testResults | Format-Table Test, Status, Details -AutoSize
|
||||
Write-Output ""
|
||||
Write-Output "Test bucket '$TestBucket' left for manual cleanup"
|
||||
Write-Output "Total tests: $($testResults.Count)"
|
||||
Write-Output "Successful: $(($testResults | Where-Object Status -eq 'Success').Count)"
|
||||
Write-Output "Failed: $(($testResults | Where-Object Status -eq 'Failed').Count)"
|
||||
|
||||
# Return results for further processing
|
||||
return $testResults
|
||||
@@ -1,123 +0,0 @@
|
||||
# PSMinIO Individual Test Commands
|
||||
# Copy and paste these commands one by one to test functionality
|
||||
|
||||
# Test Configuration
|
||||
$S3Url = "https://api.s3.gracesolution.info"
|
||||
$AccessKey = "T34Wg85SAwezUa3sk3m4"
|
||||
$SecretKey = "PxEmnbQoQJTJsDocSEV6mSSscDpJMiJCayPv93xe"
|
||||
$TestBucket = "psminiotest-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
|
||||
Write-Output "Test Configuration:"
|
||||
Write-Output "S3 Endpoint: $S3Url"
|
||||
Write-Output "Test Bucket: $TestBucket"
|
||||
Write-Output ""
|
||||
|
||||
# ===== STEP 1: IMPORT MODULE =====
|
||||
Write-Output "1. Import PSMinIO Module:"
|
||||
Import-Module "..\Module\PSMinIO\PSMinIO.psd1" -Force -Verbose
|
||||
|
||||
# ===== STEP 2: CONNECT TO S3 =====
|
||||
Write-Output "`n2. Connect to S3:"
|
||||
$connection = Connect-MinIO -Url $S3Url -AccessKey $AccessKey -SecretKey $SecretKey -Verbose
|
||||
$connection
|
||||
|
||||
# ===== STEP 3: LIST EXISTING BUCKETS =====
|
||||
Write-Output "`n3. List existing buckets:"
|
||||
$buckets = Get-MinIOBucket -Verbose
|
||||
$buckets | Format-Table Name, CreationDate, Region -AutoSize
|
||||
|
||||
# ===== STEP 4: CREATE TEST BUCKET =====
|
||||
Write-Output "`n4. Create test bucket:"
|
||||
$newBucket = New-MinIOBucket -BucketName $TestBucket -Verbose
|
||||
$newBucket
|
||||
|
||||
# ===== STEP 5: VERIFY BUCKET EXISTS =====
|
||||
Write-Output "`n5. Verify bucket exists:"
|
||||
$bucketExists = Test-MinIOBucketExists -BucketName $TestBucket -Verbose
|
||||
Write-Output "Bucket exists: $bucketExists"
|
||||
|
||||
# ===== STEP 6: CREATE TEST FILES =====
|
||||
Write-Output "`n6. Create test files:"
|
||||
$TestDirectory = "C:\Temp\PSMinIOTest"
|
||||
if (Test-Path $TestDirectory) { Remove-Item $TestDirectory -Recurse -Force }
|
||||
New-Item -ItemType Directory -Path $TestDirectory -Force | Out-Null
|
||||
|
||||
# Small file (< 1KB)
|
||||
$SmallFile = Join-Path $TestDirectory "small-test.txt"
|
||||
"This is a small test file for PSMinIO testing." | Out-File $SmallFile -Encoding UTF8
|
||||
|
||||
# Medium file (~50KB)
|
||||
$MediumFile = Join-Path $TestDirectory "medium-test.txt"
|
||||
1..1000 | ForEach-Object { "Line $_ - Medium test file content for PSMinIO testing with more data." } | Out-File $MediumFile -Encoding UTF8
|
||||
|
||||
# Large file (~500KB)
|
||||
$LargeFile = Join-Path $TestDirectory "large-test.txt"
|
||||
1..10000 | ForEach-Object { "Line $_ - Large test file content for PSMinIO multipart testing with substantial data to trigger chunked operations." } | Out-File $LargeFile -Encoding UTF8
|
||||
|
||||
Get-ChildItem $TestDirectory | Select-Object Name, @{Name="Size(KB)";Expression={[math]::Round($_.Length/1KB,2)}}
|
||||
|
||||
# ===== STEP 7: UPLOAD SMALL FILE (SINGLE PART) =====
|
||||
Write-Output "`n7. Upload small file (single part):"
|
||||
$uploadResult1 = New-MinIOObject -BucketName $TestBucket -Files (Get-Item $SmallFile) -Verbose
|
||||
$uploadResult1
|
||||
|
||||
# ===== STEP 8: UPLOAD MEDIUM FILE (SINGLE PART) =====
|
||||
Write-Output "`n8. Upload medium file (single part):"
|
||||
$uploadResult2 = New-MinIOObject -BucketName $TestBucket -Files (Get-Item $MediumFile) -Verbose
|
||||
$uploadResult2
|
||||
|
||||
# ===== STEP 9: UPLOAD LARGE FILE (MULTIPART) =====
|
||||
Write-Output "`n9. Upload large file (multipart):"
|
||||
$multipartResult = New-MinIOObjectMultipart -BucketName $TestBucket -FilePath (Get-Item $LargeFile) -Verbose
|
||||
$multipartResult
|
||||
|
||||
# ===== STEP 10: LIST OBJECTS IN BUCKET =====
|
||||
Write-Output "`n10. List objects in bucket:"
|
||||
$objects = Get-MinIOObject -BucketName $TestBucket -Verbose
|
||||
$objects | Format-Table Key, @{Name="Size(KB)";Expression={[math]::Round($_.Size/1KB,2)}}, LastModified -AutoSize
|
||||
|
||||
# ===== STEP 11: DOWNLOAD SMALL FILE =====
|
||||
Write-Output "`n11. Download small file:"
|
||||
$downloadPath1 = Join-Path $TestDirectory "downloaded-small.txt"
|
||||
$downloadResult1 = Get-MinIOObjectContent -BucketName $TestBucket -ObjectName "small-test.txt" -LocalPath $downloadPath1 -Verbose
|
||||
$downloadResult1
|
||||
|
||||
# ===== STEP 12: DOWNLOAD LARGE FILE (MULTIPART) =====
|
||||
Write-Output "`n12. Download large file (multipart):"
|
||||
$downloadPath2 = Join-Path $TestDirectory "downloaded-large.txt"
|
||||
$multipartDownload = Get-MinIOObjectContentMultipart -BucketName $TestBucket -ObjectName "large-test.txt" -DestinationPath (New-Object System.IO.FileInfo $downloadPath2) -Verbose
|
||||
$multipartDownload
|
||||
|
||||
# ===== STEP 13: GENERATE PRESIGNED URL =====
|
||||
Write-Output "`n13. Generate presigned URL:"
|
||||
$presignedUrl = Get-MinIOPresignedUrl -BucketName $TestBucket -ObjectName "small-test.txt" -Expiration (New-TimeSpan -Hours 1) -Verbose
|
||||
$presignedUrl
|
||||
|
||||
# ===== STEP 14: VERIFY DOWNLOADED FILES =====
|
||||
Write-Output "`n14. Verify downloaded files:"
|
||||
Write-Output "Original files:"
|
||||
Get-ChildItem $TestDirectory -Filter "*test.txt" | Select-Object Name, @{Name="Size(KB)";Expression={[math]::Round($_.Length/1KB,2)}}
|
||||
|
||||
Write-Output "`nDownloaded files:"
|
||||
Get-ChildItem $TestDirectory -Filter "downloaded-*" | Select-Object Name, @{Name="Size(KB)";Expression={[math]::Round($_.Length/1KB,2)}}
|
||||
|
||||
# ===== STEP 15: COMPARE FILE CONTENTS =====
|
||||
Write-Output "`n15. Compare file contents:"
|
||||
$originalSmall = Get-Content $SmallFile
|
||||
$downloadedSmall = Get-Content $downloadPath1
|
||||
Write-Output "Small file content match: $(($originalSmall -join '') -eq ($downloadedSmall -join ''))"
|
||||
|
||||
$originalLarge = Get-Content $LargeFile
|
||||
$downloadedLarge = Get-Content $downloadPath2
|
||||
Write-Output "Large file content match: $(($originalLarge -join '') -eq ($downloadedLarge -join ''))"
|
||||
|
||||
# ===== CLEANUP INSTRUCTIONS =====
|
||||
Write-Output "`n16. Cleanup (manual):"
|
||||
Write-Output "Test bucket created: $TestBucket"
|
||||
Write-Output "Local test directory: $TestDirectory"
|
||||
Write-Output ""
|
||||
Write-Output "To clean up:"
|
||||
Write-Output "1. Remove local directory: Remove-Item '$TestDirectory' -Recurse -Force"
|
||||
Write-Output "2. Remove S3 bucket objects and bucket manually from S3 console"
|
||||
Write-Output ""
|
||||
Write-Output "=== ALL TESTS COMPLETED ==="
|
||||
@@ -1,104 +0,0 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Quick complete test of PSMinIO functionality
|
||||
|
||||
.DESCRIPTION
|
||||
Tests all core functionality quickly to verify the implementation works
|
||||
#>
|
||||
|
||||
# Import the module
|
||||
Import-Module "$PSScriptRoot\..\Module\PSMinIO\PSMinIO.psd1" -Force
|
||||
|
||||
Write-Output "=== PSMinIO Complete Functionality Test ==="
|
||||
|
||||
try {
|
||||
# Test 1: Connection
|
||||
Write-Output "1. Testing Connection..."
|
||||
Connect-MinIO -Endpoint "https://api.s3.gracesolution.info" -AccessKey "T34Wg85SAwezUa3sk3m4" -SecretKey "PxEmnbQoQJTJsDocSEV6mSSscDpJMiJCayPv93xe" -TestConnection
|
||||
Write-Output "✅ Connection successful!"
|
||||
|
||||
# Test 2: List Buckets
|
||||
Write-Output "2. Testing Bucket Listing..."
|
||||
$buckets = Get-MinIOBucket
|
||||
Write-Output "✅ Found $($buckets.Count) buckets"
|
||||
|
||||
# Test 3: Create Test Bucket
|
||||
Write-Output "3. Testing Bucket Creation..."
|
||||
$testBucket = "psminiotest-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
$bucketResult = New-MinIOBucket -BucketName $testBucket -PassThru
|
||||
Write-Output "✅ Bucket created: $($bucketResult.Name)"
|
||||
|
||||
# Test 4: Test Bucket Exists
|
||||
Write-Output "4. Testing Bucket Existence..."
|
||||
$exists = Test-MinIOBucketExists -BucketName $testBucket
|
||||
Write-Output "✅ Bucket exists: $exists"
|
||||
|
||||
# Test 5: Upload File
|
||||
Write-Output "5. Testing File Upload..."
|
||||
$testFile = Join-Path $env:TEMP "psminiotest-complete.txt"
|
||||
$testContent = @"
|
||||
PSMinIO Complete Test File
|
||||
=========================
|
||||
Created: $(Get-Date)
|
||||
Implementation: Custom REST API
|
||||
Test data: $('A' * 1000)
|
||||
"@
|
||||
$testContent | Out-File -FilePath $testFile -Encoding UTF8
|
||||
$fileInfo = Get-Item $testFile
|
||||
$uploadResult = New-MinIOObject -BucketName $testBucket -File $fileInfo -PassThru
|
||||
Write-Output "✅ Upload successful: $($uploadResult.ObjectName) ($($uploadResult.TotalSizeFormatted))"
|
||||
|
||||
# Test 6: List Objects
|
||||
Write-Output "6. Testing Object Listing..."
|
||||
$objects = Get-MinIOObject -BucketName $testBucket
|
||||
Write-Output "✅ Found $($objects.Count) objects"
|
||||
|
||||
# Test 7: Download File
|
||||
Write-Output "7. Testing File Download..."
|
||||
$downloadFile = Join-Path $env:TEMP "psminiotest-complete-download.txt"
|
||||
$downloadResult = Get-MinIOObjectContent -BucketName $testBucket -ObjectName $fileInfo.Name -LocalPath $downloadFile -PassThru
|
||||
Write-Output "✅ Download successful: $($downloadResult.TotalSizeFormatted)"
|
||||
|
||||
# Test 8: Verify Content
|
||||
Write-Output "8. Testing Content Verification..."
|
||||
$originalContent = Get-Content $testFile -Raw
|
||||
$downloadedContent = Get-Content $downloadFile -Raw
|
||||
if ($originalContent -eq $downloadedContent) {
|
||||
Write-Output "✅ Content verification PASSED!"
|
||||
} else {
|
||||
Write-Output "❌ Content verification FAILED!"
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
Write-Output "=== ALL TESTS PASSED! ==="
|
||||
Write-Output "🎉 PSMinIO Custom REST API Implementation is fully functional!"
|
||||
Write-Output ""
|
||||
Write-Output "Features Verified:"
|
||||
Write-Output " ✓ Connection management with AWS S3 signature v4"
|
||||
Write-Output " ✓ Bucket operations (create, list, exists)"
|
||||
Write-Output " ✓ Object upload with progress tracking"
|
||||
Write-Output " ✓ Object download with progress tracking"
|
||||
Write-Output " ✓ Object listing and filtering"
|
||||
Write-Output " ✓ Performance metrics and timing"
|
||||
Write-Output " ✓ Content integrity verification"
|
||||
Write-Output ""
|
||||
Write-Output "Architecture Benefits:"
|
||||
Write-Output " • No MinIO SDK dependency"
|
||||
Write-Output " • No async/await compatibility issues"
|
||||
Write-Output " • Real progress reporting from HTTP streams"
|
||||
Write-Output " • Built-in performance monitoring"
|
||||
Write-Output " • Reduced dependencies (3 DLLs vs 10+)"
|
||||
|
||||
} catch {
|
||||
Write-Output "❌ Test failed: $($_.Exception.Message)"
|
||||
exit 1
|
||||
} finally {
|
||||
# Cleanup
|
||||
if (Test-Path $testFile -ErrorAction SilentlyContinue) {
|
||||
Remove-Item $testFile -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
if (Test-Path $downloadFile -ErrorAction SilentlyContinue) {
|
||||
Remove-Item $downloadFile -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Quick test of PSMinIO upload and download functionality
|
||||
|
||||
.DESCRIPTION
|
||||
Tests the new PSMinIO implementation with file upload and download
|
||||
#>
|
||||
|
||||
# Import the module
|
||||
Import-Module "$PSScriptRoot\..\Module\PSMinIO\PSMinIO.psd1" -Force
|
||||
|
||||
# Connect to MinIO
|
||||
Write-Verbose "Connecting to MinIO..." -Verbose
|
||||
Connect-MinIO -Endpoint "https://api.s3.gracesolution.info" -AccessKey "T34Wg85SAwezUa3sk3m4" -SecretKey "PxEmnbQoQJTJsDocSEV6mSSscDpJMiJCayPv93xe" -Verbose
|
||||
|
||||
# Create test file
|
||||
$testFile = Join-Path $env:TEMP "psminiotest.txt"
|
||||
$testContent = @"
|
||||
PSMinIO Test File
|
||||
================
|
||||
Created: $(Get-Date)
|
||||
Test data: $('A' * 1000)
|
||||
"@
|
||||
|
||||
Write-Verbose "Creating test file: $testFile" -Verbose
|
||||
$testContent | Out-File -FilePath $testFile -Encoding UTF8
|
||||
$fileInfo = Get-Item $testFile
|
||||
Write-Verbose "Test file created: $($fileInfo.Length) bytes" -Verbose
|
||||
|
||||
# Upload file
|
||||
$testBucket = "psminiotest-20250711-142415"
|
||||
Write-Verbose "Uploading file to bucket: $testBucket" -Verbose
|
||||
$uploadResult = New-MinIOObject -BucketName $testBucket -File $fileInfo -PassThru -Verbose
|
||||
|
||||
Write-Output "Upload Result:"
|
||||
if ($uploadResult) {
|
||||
$uploadResult | Format-List ObjectName, TotalSizeFormatted, DurationFormatted, AverageSpeedFormatted, Success
|
||||
}
|
||||
|
||||
# List objects
|
||||
Write-Verbose "Listing objects in bucket..." -Verbose
|
||||
$objects = Get-MinIOObject -BucketName $testBucket -Verbose
|
||||
$objects | Format-Table Name, Size, LastModified
|
||||
|
||||
# Download file
|
||||
$downloadFile = Join-Path $env:TEMP "psminiotest-download.txt"
|
||||
Write-Verbose "Downloading file to: $downloadFile" -Verbose
|
||||
$downloadResult = Get-MinIOObjectContent -BucketName $testBucket -ObjectName $fileInfo.Name -LocalPath $downloadFile -PassThru -Verbose
|
||||
|
||||
Write-Output "Download Result:"
|
||||
if ($downloadResult) {
|
||||
$downloadResult | Format-List ObjectName, TotalSizeFormatted, DurationFormatted, AverageSpeedFormatted, Success
|
||||
}
|
||||
|
||||
# Verify content
|
||||
$originalContent = Get-Content $testFile -Raw -ErrorAction SilentlyContinue
|
||||
$downloadedContent = Get-Content $downloadFile -Raw -ErrorAction SilentlyContinue
|
||||
|
||||
if ($originalContent -and $downloadedContent -and ($originalContent -eq $downloadedContent)) {
|
||||
Write-Output "✅ File content verification PASSED!"
|
||||
} else {
|
||||
Write-Output "❌ File content verification FAILED!"
|
||||
}
|
||||
|
||||
# Cleanup
|
||||
Remove-Item $testFile -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item $downloadFile -Force -ErrorAction SilentlyContinue
|
||||
|
||||
Write-Output "Test completed!"
|
||||
@@ -1,74 +0,0 @@
|
||||
# Test XML Parsing for Multipart Upload Response
|
||||
# This script tests the XML parsing logic without modifying the codebase
|
||||
|
||||
# Sample XML response from your S3 server
|
||||
$xmlResponse = @'
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<InitiateMultipartUploadResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Bucket>xylem</Bucket><Key>Win10ISO.zip</Key><UploadId>MzBlZDdmNjUtZjNjYi00YzhhLThhMWQtNzViYTAyNWIzYjFhLmJiYjBmNzcxLWZiODEtNGFhYy1iYWQwLTk3M2EyNDIwMjRkM3gxNzUyNTQwMTc4NzE4NjczNjY1</UploadId></InitiateMultipartUploadResult>
|
||||
'@
|
||||
|
||||
Write-Output "=== XML Parsing Test ==="
|
||||
Write-Output "Testing XML response parsing logic"
|
||||
Write-Output ""
|
||||
|
||||
# Parse the XML
|
||||
$doc = [System.Xml.Linq.XDocument]::Parse($xmlResponse)
|
||||
|
||||
Write-Output "1. Basic XML parsing:"
|
||||
Write-Output " Root element: $($doc.Root.Name)"
|
||||
Write-Output " Root namespace: $($doc.Root.GetDefaultNamespace())"
|
||||
Write-Output ""
|
||||
|
||||
# Test method 1: Without namespace (current broken method)
|
||||
Write-Output "2. Method 1 - Without namespace (broken):"
|
||||
$uploadId1 = $doc.Descendants("UploadId") | Select-Object -First 1 | ForEach-Object { $_.Value }
|
||||
Write-Output " UploadId found: $($uploadId1 ?? 'NULL')"
|
||||
Write-Output ""
|
||||
|
||||
# Test method 2: With namespace (fixed method)
|
||||
Write-Output "3. Method 2 - With namespace (fixed):"
|
||||
$ns = $doc.Root.GetDefaultNamespace()
|
||||
if ($ns) {
|
||||
$uploadId2 = $doc.Descendants([System.Xml.Linq.XName]::Get("UploadId", $ns.NamespaceName)) | Select-Object -First 1 | ForEach-Object { $_.Value }
|
||||
} else {
|
||||
$uploadId2 = $doc.Descendants("UploadId") | Select-Object -First 1 | ForEach-Object { $_.Value }
|
||||
}
|
||||
Write-Output " Namespace: $($ns.NamespaceName)"
|
||||
Write-Output " UploadId found: $($uploadId2 ?? 'NULL')"
|
||||
Write-Output ""
|
||||
|
||||
# Test method 3: Alternative approach
|
||||
Write-Output "4. Method 3 - Alternative approach:"
|
||||
$uploadId3 = $doc.Descendants() | Where-Object { $_.Name.LocalName -eq "UploadId" } | Select-Object -First 1 | ForEach-Object { $_.Value }
|
||||
Write-Output " UploadId found: $($uploadId3 ?? 'NULL')"
|
||||
Write-Output ""
|
||||
|
||||
# Show all elements
|
||||
Write-Output "5. All elements in the XML:"
|
||||
$doc.Descendants() | ForEach-Object {
|
||||
Write-Output " Element: $($_.Name.LocalName) = $($_.Value)"
|
||||
}
|
||||
Write-Output ""
|
||||
|
||||
# Test the exact logic that should work
|
||||
Write-Output "6. Recommended fix logic:"
|
||||
$ns = $doc.Root.GetDefaultNamespace()
|
||||
if ($ns -and $ns.NamespaceName) {
|
||||
$uploadIdFinal = $doc.Descendants([System.Xml.Linq.XName]::Get("UploadId", $ns.NamespaceName)) | Select-Object -First 1 | ForEach-Object { $_.Value }
|
||||
} else {
|
||||
$uploadIdFinal = $doc.Descendants("UploadId") | Select-Object -First 1 | ForEach-Object { $_.Value }
|
||||
}
|
||||
|
||||
Write-Output " Final UploadId: $($uploadIdFinal ?? 'NULL')"
|
||||
Write-Output " Success: $($uploadIdFinal -ne $null -and $uploadIdFinal -ne '')"
|
||||
Write-Output ""
|
||||
|
||||
if ($uploadIdFinal) {
|
||||
Write-Output "✅ XML parsing would work with namespace handling!"
|
||||
Write-Output " The UploadId '$uploadIdFinal' was successfully extracted."
|
||||
} else {
|
||||
Write-Output "❌ XML parsing still has issues."
|
||||
}
|
||||
|
||||
Write-Output ""
|
||||
Write-Output "=== Test Complete ==="
|
||||
@@ -1,202 +0,0 @@
|
||||
# Test script for the new New-MinIOZipArchive cmdlet
|
||||
# Demonstrates comprehensive zip functionality with progress tracking
|
||||
|
||||
param(
|
||||
[string]$TestDirectory = "TestZipFiles",
|
||||
[switch]$Cleanup,
|
||||
[switch]$Verbose
|
||||
)
|
||||
|
||||
if ($Verbose) {
|
||||
$VerbosePreference = 'Continue'
|
||||
}
|
||||
|
||||
Write-Host "=== PSMinIO Zip Archive Test ===" -ForegroundColor Cyan
|
||||
Write-Host "Testing New-MinIOZipArchive cmdlet with comprehensive functionality" -ForegroundColor Green
|
||||
|
||||
try {
|
||||
# Import the module
|
||||
Write-Host "`n1. Loading PSMinIO module..." -ForegroundColor Yellow
|
||||
Import-Module ".\Module\PSMinIO\PSMinIO.psd1" -Force
|
||||
|
||||
# Create test directory and files
|
||||
Write-Host "2. Creating test files..." -ForegroundColor Yellow
|
||||
if (Test-Path $TestDirectory) {
|
||||
Remove-Item $TestDirectory -Recurse -Force
|
||||
}
|
||||
New-Item -ItemType Directory -Path $TestDirectory -Force | Out-Null
|
||||
|
||||
# Create main directory files
|
||||
for ($i = 1; $i -le 10; $i++) {
|
||||
$fileName = "document-{0:D2}.txt" -f $i
|
||||
$filePath = Join-Path $TestDirectory $fileName
|
||||
$content = "Document $i`n" + ("Sample content line $i`n" * (Get-Random -Minimum 5 -Maximum 20))
|
||||
Set-Content -Path $filePath -Value $content
|
||||
}
|
||||
|
||||
# Create subdirectories with different file types
|
||||
$subDir1 = Join-Path $TestDirectory "Reports"
|
||||
$subDir2 = Join-Path $TestDirectory "Data"
|
||||
$subDir3 = Join-Path $TestDirectory "Logs"
|
||||
New-Item -ItemType Directory -Path $subDir1, $subDir2, $subDir3 -Force | Out-Null
|
||||
|
||||
# Add files to subdirectories
|
||||
for ($i = 1; $i -le 5; $i++) {
|
||||
Set-Content -Path (Join-Path $subDir1 "report$i.txt") -Value "Report $i content"
|
||||
Set-Content -Path (Join-Path $subDir2 "data$i.csv") -Value "ID,Name,Value`n$i,Item$i,$(Get-Random -Minimum 100 -Maximum 1000)"
|
||||
Set-Content -Path (Join-Path $subDir3 "app$i.log") -Value "$(Get-Date) - Log entry $i"
|
||||
}
|
||||
|
||||
$allFiles = Get-ChildItem $TestDirectory -Recurse -File
|
||||
Write-Host "✅ Created test structure: $($allFiles.Count) files in multiple directories" -ForegroundColor Green
|
||||
|
||||
# Test 1: Create zip from FileInfo array
|
||||
Write-Host "`n3. Test 1: Creating zip from FileInfo array..." -ForegroundColor Yellow
|
||||
$mainFiles = Get-ChildItem $TestDirectory -File
|
||||
$zipFile1 = [System.IO.FileInfo]"test-files-array.zip"
|
||||
|
||||
Write-Host " Creating zip with $($mainFiles.Count) files using Files parameter set" -ForegroundColor Cyan
|
||||
$result1 = New-MinIOZipArchive -DestinationPath $zipFile1 -Path $mainFiles -CompressionLevel Optimal -Verbose
|
||||
|
||||
Write-Host "✅ Files array zip created:" -ForegroundColor Green
|
||||
Write-Host " Files: $($result1.FileCount)" -ForegroundColor White
|
||||
Write-Host " Original size: $([math]::Round($result1.TotalUncompressedSize / 1KB, 2)) KB" -ForegroundColor White
|
||||
Write-Host " Compressed size: $([math]::Round($result1.TotalCompressedSize / 1KB, 2)) KB" -ForegroundColor White
|
||||
Write-Host " Compression: $($result1.CompressionEfficiency.ToString('F1'))%" -ForegroundColor White
|
||||
Write-Host " Duration: $($result1.Duration.TotalSeconds.ToString('F2'))s" -ForegroundColor White
|
||||
|
||||
# Test 2: Create zip from directory (non-recursive)
|
||||
Write-Host "`n4. Test 2: Creating zip from directory (non-recursive)..." -ForegroundColor Yellow
|
||||
$zipFile2 = [System.IO.FileInfo]"test-directory-flat.zip"
|
||||
|
||||
Write-Host " Creating zip from directory (top-level files only)" -ForegroundColor Cyan
|
||||
$result2 = New-MinIOZipArchive -DestinationPath $zipFile2 -Directory (Get-Item $TestDirectory) -CompressionLevel Fastest -Verbose
|
||||
|
||||
Write-Host "✅ Directory flat zip created:" -ForegroundColor Green
|
||||
Write-Host " Files: $($result2.FileCount)" -ForegroundColor White
|
||||
Write-Host " Compression: $($result2.CompressionEfficiency.ToString('F1'))%" -ForegroundColor White
|
||||
|
||||
# Test 3: Create zip from directory (recursive)
|
||||
Write-Host "`n5. Test 3: Creating zip from directory (recursive)..." -ForegroundColor Yellow
|
||||
$zipFile3 = [System.IO.FileInfo]"test-directory-recursive.zip"
|
||||
|
||||
Write-Host " Creating zip from directory (recursive, all subdirectories)" -ForegroundColor Cyan
|
||||
$result3 = New-MinIOZipArchive -DestinationPath $zipFile3 -Directory (Get-Item $TestDirectory) -Recursive -IncludeBaseDirectory -CompressionLevel Optimal -Verbose
|
||||
|
||||
Write-Host "✅ Directory recursive zip created:" -ForegroundColor Green
|
||||
Write-Host " Files: $($result3.FileCount)" -ForegroundColor White
|
||||
Write-Host " Compression: $($result3.CompressionEfficiency.ToString('F1'))%" -ForegroundColor White
|
||||
|
||||
# Test 4: Create zip with file filtering
|
||||
Write-Host "`n6. Test 4: Creating zip with file filtering..." -ForegroundColor Yellow
|
||||
$zipFile4 = [System.IO.FileInfo]"test-filtered-logs.zip"
|
||||
|
||||
Write-Host " Creating zip with only .log files using InclusionFilter" -ForegroundColor Cyan
|
||||
$result4 = New-MinIOZipArchive -DestinationPath $zipFile4 -Directory (Get-Item $TestDirectory) -Recursive -InclusionFilter { $_.Extension -eq ".log" } -CompressionLevel Optimal -Verbose
|
||||
|
||||
Write-Host "✅ Filtered zip created:" -ForegroundColor Green
|
||||
Write-Host " Log files: $($result4.FileCount)" -ForegroundColor White
|
||||
Write-Host " Compression: $($result4.CompressionEfficiency.ToString('F1'))%" -ForegroundColor White
|
||||
|
||||
# Test 5: Append to existing zip (Update mode)
|
||||
Write-Host "`n7. Test 5: Appending to existing zip..." -ForegroundColor Yellow
|
||||
$csvFiles = Get-ChildItem $TestDirectory -Recurse -Filter "*.csv"
|
||||
|
||||
Write-Host " Appending $($csvFiles.Count) CSV files to existing zip" -ForegroundColor Cyan
|
||||
$result5 = New-MinIOZipArchive -DestinationPath $zipFile4 -Path $csvFiles -Mode Update -CompressionLevel Optimal -Verbose
|
||||
|
||||
Write-Host "✅ Files appended to zip:" -ForegroundColor Green
|
||||
Write-Host " Total files now: $($result5.FileCount)" -ForegroundColor White
|
||||
|
||||
# Test 6: Create zip with custom base path
|
||||
Write-Host "`n8. Test 6: Creating zip with custom base path..." -ForegroundColor Yellow
|
||||
$zipFile6 = [System.IO.FileInfo]"test-custom-basepath.zip"
|
||||
|
||||
Write-Host " Creating zip with custom base path (flattened structure)" -ForegroundColor Cyan
|
||||
$result6 = New-MinIOZipArchive -DestinationPath $zipFile6 -Directory (Get-Item $TestDirectory) -Recursive -BasePath $TestDirectory -CompressionLevel Optimal -Verbose
|
||||
|
||||
Write-Host "✅ Custom base path zip created:" -ForegroundColor Green
|
||||
Write-Host " Files: $($result6.FileCount)" -ForegroundColor White
|
||||
|
||||
# Test 7: Get zip archive information
|
||||
Write-Host "`n9. Test 7: Reading zip archive information..." -ForegroundColor Yellow
|
||||
$zipFiles = Get-ChildItem "*.zip"
|
||||
|
||||
foreach ($zipFile in $zipFiles) {
|
||||
Write-Host " Reading archive: $($zipFile.Name)" -ForegroundColor Cyan
|
||||
|
||||
# Basic archive info
|
||||
$archiveInfo = Get-MinIOZipArchive -ZipFile $zipFile -Verbose
|
||||
Write-Host " Entries: $($archiveInfo.EntryCount)" -ForegroundColor White
|
||||
Write-Host " Size: $([math]::Round($archiveInfo.TotalUncompressedSize / 1KB, 2)) KB -> $([math]::Round($archiveInfo.TotalCompressedSize / 1KB, 2)) KB" -ForegroundColor White
|
||||
Write-Host " Compression: $($archiveInfo.CompressionEfficiency.ToString('F1'))%" -ForegroundColor White
|
||||
|
||||
# Detailed entries for one archive
|
||||
if ($zipFile.Name -eq "test-directory-recursive.zip") {
|
||||
Write-Host " Getting detailed entries for recursive archive..." -ForegroundColor Cyan
|
||||
$detailedInfo = Get-MinIOZipArchive -ZipFile $zipFile -IncludeEntries -Verbose
|
||||
Write-Host " Entry details: $($detailedInfo.Entries.Count) entries" -ForegroundColor White
|
||||
|
||||
# Show first few entries
|
||||
$detailedInfo.Entries | Select-Object -First 3 | ForEach-Object {
|
||||
Write-Host " $($_.FullName) ($([math]::Round($_.Length / 1KB, 2)) KB)" -ForegroundColor Gray
|
||||
}
|
||||
}
|
||||
|
||||
# Validate integrity for one archive
|
||||
if ($zipFile.Name -eq "test-files-array.zip") {
|
||||
Write-Host " Validating archive integrity..." -ForegroundColor Cyan
|
||||
$validatedInfo = Get-MinIOZipArchive -ZipFile $zipFile -ValidateIntegrity -Verbose
|
||||
$validStatus = if ($validatedInfo.IsValid) { "✅ Valid" } else { "❌ Invalid" }
|
||||
Write-Host " Validation: $validStatus (took $($validatedInfo.ValidationDuration.TotalMilliseconds.ToString('F0'))ms)" -ForegroundColor White
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "✅ Archive reading tests completed!" -ForegroundColor Green
|
||||
|
||||
# Summary
|
||||
Write-Host "`n=== TEST SUMMARY ===" -ForegroundColor Cyan
|
||||
Write-Host "✅ All zip archive tests completed successfully!" -ForegroundColor Green
|
||||
Write-Host "New-MinIOZipArchive features tested:" -ForegroundColor Yellow
|
||||
Write-Host " • FileInfo destination path parameter" -ForegroundColor White
|
||||
Write-Host " • FileInfo[] parameter with Files parameter set" -ForegroundColor White
|
||||
Write-Host " • Directory parameter with recursive and non-recursive modes" -ForegroundColor White
|
||||
Write-Host " • File filtering with InclusionFilter ScriptBlock" -ForegroundColor White
|
||||
Write-Host " • Append mode (Update) for adding files to existing zips" -ForegroundColor White
|
||||
Write-Host " • Custom base path for entry name control" -ForegroundColor White
|
||||
Write-Host " • Multiple compression levels (Optimal, Fastest)" -ForegroundColor White
|
||||
Write-Host " • Comprehensive progress tracking and metrics" -ForegroundColor White
|
||||
Write-Host " • Always returns result objects (no PassThru needed)" -ForegroundColor White
|
||||
|
||||
Write-Host "Get-MinIOZipArchive features tested:" -ForegroundColor Yellow
|
||||
Write-Host " • Basic archive information reading" -ForegroundColor White
|
||||
Write-Host " • Detailed entry information with IncludeEntries" -ForegroundColor White
|
||||
Write-Host " • Archive integrity validation" -ForegroundColor White
|
||||
Write-Host " • Proper disposal handling with OpenRead" -ForegroundColor White
|
||||
Write-Host " • Comprehensive metrics and compression statistics" -ForegroundColor White
|
||||
|
||||
Write-Host "`nZip files created:" -ForegroundColor Yellow
|
||||
foreach ($zipFile in $zipFiles) {
|
||||
$sizeKB = [math]::Round($zipFile.Length / 1KB, 2)
|
||||
Write-Host " • $($zipFile.Name) ($sizeKB KB)" -ForegroundColor White
|
||||
}
|
||||
|
||||
if ($Cleanup) {
|
||||
Write-Host "`n10. Cleaning up..." -ForegroundColor Yellow
|
||||
Remove-Item "*.zip" -Force -ErrorAction SilentlyContinue
|
||||
Write-Host "✅ Cleanup completed!" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "`nZip files preserved for inspection. Use -Cleanup to remove them." -ForegroundColor Cyan
|
||||
}
|
||||
|
||||
} catch {
|
||||
Write-Host "❌ Test failed: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Write-Host "Stack trace: $($_.ScriptStackTrace)" -ForegroundColor Red
|
||||
} finally {
|
||||
# Clean up test directory
|
||||
if (Test-Path $TestDirectory) {
|
||||
Remove-Item $TestDirectory -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "`n=== Test Complete ===" -ForegroundColor Cyan
|
||||
@@ -1,71 +0,0 @@
|
||||
# PSMinIO Basic Operations Example
|
||||
# This script demonstrates fundamental MinIO operations using PSMinIO
|
||||
|
||||
# Import the module
|
||||
Import-Module ..\..\Module\PSMinIO\PSMinIO.psd1
|
||||
|
||||
# Example connection details (replace with your actual values)
|
||||
$endpoint = "https://minio.example.com"
|
||||
$accessKey = "your-access-key"
|
||||
$secretKey = "your-secret-key"
|
||||
|
||||
try {
|
||||
# Connect to MinIO server
|
||||
$connection = Connect-MinIO -Endpoint $endpoint -AccessKey $accessKey -SecretKey $secretKey
|
||||
"Connected to MinIO server: $endpoint"
|
||||
|
||||
# List all buckets
|
||||
"Listing all buckets..."
|
||||
$buckets = Get-MinIOBucket
|
||||
$buckets | Format-Table Name, CreationDate, @{Name="Objects";Expression={"N/A"}}
|
||||
|
||||
# Create a new bucket
|
||||
$bucketName = "example-bucket-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
"Creating bucket: $bucketName"
|
||||
New-MinIOBucket -BucketName $bucketName
|
||||
|
||||
# Verify bucket creation
|
||||
if (Test-MinIOBucketExists -BucketName $bucketName) {
|
||||
"✅ Bucket '$bucketName' created successfully"
|
||||
}
|
||||
|
||||
# Create a sample file for upload
|
||||
$sampleFile = "sample-document.txt"
|
||||
"This is a sample document created on $(Get-Date)" | Out-File -FilePath $sampleFile -Encoding UTF8
|
||||
|
||||
# Upload the file
|
||||
"Uploading file: $sampleFile"
|
||||
$uploadResult = New-MinIOObject -BucketName $bucketName -Files $sampleFile
|
||||
$uploadResult | Format-Table Name, @{Name="Duration";Expression={$_.Duration}}, @{Name="Speed";Expression={$_.AverageSpeedFormatted}}
|
||||
|
||||
# List objects in the bucket
|
||||
"Listing objects in bucket '$bucketName':"
|
||||
$objects = Get-MinIOObject -BucketName $bucketName
|
||||
$objects | Format-Table Name, @{Name="Size";Expression={"$($_.Size) bytes"}}, LastModified
|
||||
|
||||
# Download the file
|
||||
$downloadPath = "downloaded-$sampleFile"
|
||||
"Downloading file to: $downloadPath"
|
||||
$downloadResult = Get-MinIOObjectContent -BucketName $bucketName -ObjectName $sampleFile -FilePath $downloadPath
|
||||
$downloadResult | Format-Table @{Name="LocalFile";Expression={$_.FilePath.Name}}, @{Name="Duration";Expression={$_.Duration}}, @{Name="Speed";Expression={$_.AverageSpeedFormatted}}
|
||||
|
||||
# Verify download
|
||||
if (Test-Path $downloadPath) {
|
||||
"✅ File downloaded successfully"
|
||||
"Content: $(Get-Content $downloadPath)"
|
||||
}
|
||||
|
||||
# Clean up
|
||||
"Cleaning up..."
|
||||
Remove-MinIOObject -BucketName $bucketName -ObjectName $sampleFile -Force
|
||||
Remove-MinIOBucket -BucketName $bucketName -Force
|
||||
Remove-Item $sampleFile, $downloadPath -Force -ErrorAction SilentlyContinue
|
||||
|
||||
"✅ Basic operations completed successfully"
|
||||
|
||||
} catch {
|
||||
"❌ Error: $($_.Exception.Message)"
|
||||
} finally {
|
||||
# Clean up any remaining files
|
||||
Remove-Item "sample-document.txt", "downloaded-sample-document.txt" -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
# PSMinIO Advanced Object Listing Example
|
||||
# Demonstrates the powerful Get-MinIOObject cmdlet with filtering, sorting, and pagination
|
||||
|
||||
# Import the module
|
||||
Import-Module ..\..\Module\PSMinIO\PSMinIO.psd1
|
||||
|
||||
# Connection details (replace with your actual values)
|
||||
$endpoint = "https://minio.example.com"
|
||||
$accessKey = "your-access-key"
|
||||
$secretKey = "your-secret-key"
|
||||
|
||||
try {
|
||||
# Connect to MinIO
|
||||
$connection = Connect-MinIO -Endpoint $endpoint -AccessKey $accessKey -SecretKey $secretKey
|
||||
"Connected to MinIO server for advanced object listing demo"
|
||||
|
||||
# Create a demo bucket
|
||||
$bucketName = "demo-listing-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
New-MinIOBucket -BucketName $bucketName
|
||||
"Created demo bucket: $bucketName"
|
||||
|
||||
# Create sample files with different sizes and organize them in directories
|
||||
"Creating sample files..."
|
||||
|
||||
# Documents directory
|
||||
"Small document content" | Out-File -FilePath "small-doc.txt" -Encoding UTF8
|
||||
"Medium document content " * 50 | Out-File -FilePath "medium-doc.txt" -Encoding UTF8
|
||||
"Large document content " * 200 | Out-File -FilePath "large-doc.txt" -Encoding UTF8
|
||||
|
||||
# Images directory (simulated)
|
||||
"Image data " * 100 | Out-File -FilePath "image1.jpg" -Encoding UTF8
|
||||
"Image data " * 300 | Out-File -FilePath "image2.png" -Encoding UTF8
|
||||
|
||||
# Logs directory
|
||||
"Log entry " * 20 | Out-File -FilePath "app.log" -Encoding UTF8
|
||||
"Error log " * 80 | Out-File -FilePath "error.log" -Encoding UTF8
|
||||
|
||||
# Upload files to different directories
|
||||
New-MinIOObject -BucketName $bucketName -Files "small-doc.txt" -BucketDirectory "documents/2025"
|
||||
New-MinIOObject -BucketName $bucketName -Files "medium-doc.txt" -BucketDirectory "documents/2025"
|
||||
New-MinIOObject -BucketName $bucketName -Files "large-doc.txt" -BucketDirectory "documents/archive"
|
||||
New-MinIOObject -BucketName $bucketName -Files "image1.jpg" -BucketDirectory "media/images"
|
||||
New-MinIOObject -BucketName $bucketName -Files "image2.png" -BucketDirectory "media/images"
|
||||
New-MinIOObject -BucketName $bucketName -Files "app.log" -BucketDirectory "logs/application"
|
||||
New-MinIOObject -BucketName $bucketName -Files "error.log" -BucketDirectory "logs/system"
|
||||
|
||||
"Sample files uploaded to various directories"
|
||||
""
|
||||
|
||||
# Demonstrate different listing capabilities
|
||||
"=== 1. List All Objects ==="
|
||||
$allObjects = Get-MinIOObject -BucketName $bucketName
|
||||
$allObjects | Format-Table Name, @{Name="Size";Expression={"$($_.Size) B"}}, LastModified -AutoSize
|
||||
""
|
||||
|
||||
"=== 2. Filter by Prefix ==="
|
||||
$documentsObjects = Get-MinIOObject -BucketName $bucketName -Prefix "documents/"
|
||||
$documentsObjects | Format-Table Name, @{Name="Size";Expression={"$($_.Size) B"}}, LastModified -AutoSize
|
||||
""
|
||||
|
||||
"=== 3. Sort by Size (Descending) ==="
|
||||
$sortedBySize = Get-MinIOObject -BucketName $bucketName -SortBy "Size" -Descending
|
||||
$sortedBySize | Format-Table Name, @{Name="Size";Expression={"$($_.Size) B"}}, LastModified -AutoSize
|
||||
""
|
||||
|
||||
"=== 4. Sort by Name (Ascending) ==="
|
||||
$sortedByName = Get-MinIOObject -BucketName $bucketName -SortBy "Name"
|
||||
$sortedByName | Format-Table Name, @{Name="Size";Expression={"$($_.Size) B"}}, LastModified -AutoSize
|
||||
""
|
||||
|
||||
"=== 5. Limit Results ==="
|
||||
$limitedResults = Get-MinIOObject -BucketName $bucketName -MaxObjects 3 -SortBy "Size" -Descending
|
||||
$limitedResults | Format-Table Name, @{Name="Size";Expression={"$($_.Size) B"}}, LastModified -AutoSize
|
||||
""
|
||||
|
||||
"=== 6. Files Only (Exclude Directories) ==="
|
||||
$filesOnly = Get-MinIOObject -BucketName $bucketName -ObjectsOnly
|
||||
$filesOnly | Format-Table Name, @{Name="Size";Expression={"$($_.Size) B"}}, LastModified -AutoSize
|
||||
""
|
||||
|
||||
"=== 7. Specific Object Lookup ==="
|
||||
$specificObject = Get-MinIOObject -BucketName $bucketName -ObjectName "documents/2025/small-doc.txt"
|
||||
if ($specificObject) {
|
||||
$specificObject | Format-Table Name, @{Name="Size";Expression={"$($_.Size) B"}}, LastModified -AutoSize
|
||||
} else {
|
||||
"Object not found"
|
||||
}
|
||||
""
|
||||
|
||||
"=== 8. Complex Filtering Example ==="
|
||||
"Large files in media directory:"
|
||||
$largeMediaFiles = Get-MinIOObject -BucketName $bucketName -Prefix "media/" -SortBy "Size" -Descending | Where-Object { $_.Size -gt 1000 }
|
||||
$largeMediaFiles | Format-Table Name, @{Name="Size";Expression={"$($_.Size) B"}}, LastModified -AutoSize
|
||||
|
||||
# Clean up
|
||||
"Cleaning up demo files..."
|
||||
$allObjects = Get-MinIOObject -BucketName $bucketName
|
||||
foreach ($obj in $allObjects) {
|
||||
Remove-MinIOObject -BucketName $bucketName -ObjectName $obj.Name -Force
|
||||
}
|
||||
Remove-MinIOBucket -BucketName $bucketName -Force
|
||||
Remove-Item "small-doc.txt", "medium-doc.txt", "large-doc.txt", "image1.jpg", "image2.png", "app.log", "error.log" -Force -ErrorAction SilentlyContinue
|
||||
|
||||
"✅ Advanced object listing demo completed"
|
||||
|
||||
} catch {
|
||||
"❌ Error: $($_.Exception.Message)"
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
# PSMinIO Directory and Folder Management Example
|
||||
# Demonstrates creating nested directory structures and organizing files
|
||||
|
||||
# Import the module
|
||||
Import-Module ..\..\Module\PSMinIO\PSMinIO.psd1
|
||||
|
||||
# Connection details (replace with your actual values)
|
||||
$endpoint = "https://minio.example.com"
|
||||
$accessKey = "your-access-key"
|
||||
$secretKey = "your-secret-key"
|
||||
|
||||
try {
|
||||
# Connect to MinIO
|
||||
$connection = Connect-MinIO -Endpoint $endpoint -AccessKey $accessKey -SecretKey $secretKey
|
||||
"Connected to MinIO server for directory management demo"
|
||||
|
||||
# Create a demo bucket
|
||||
$bucketName = "directory-demo-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
New-MinIOBucket -BucketName $bucketName
|
||||
"Created demo bucket: $bucketName"
|
||||
|
||||
# Create sample files for different scenarios
|
||||
"Creating sample files..."
|
||||
"Project documentation" | Out-File -FilePath "README.md" -Encoding UTF8
|
||||
"Configuration settings" | Out-File -FilePath "config.json" -Encoding UTF8
|
||||
"Application source code" | Out-File -FilePath "app.py" -Encoding UTF8
|
||||
"Test data" | Out-File -FilePath "test-data.csv" -Encoding UTF8
|
||||
"Build output" | Out-File -FilePath "app.exe" -Encoding UTF8
|
||||
|
||||
"=== 1. Creating Explicit Folder Structures ==="
|
||||
# Create explicit folder structures using New-MinIOFolder
|
||||
New-MinIOFolder -BucketName $bucketName -FolderName "projects/web-app/src"
|
||||
New-MinIOFolder -BucketName $bucketName -FolderName "projects/web-app/tests"
|
||||
New-MinIOFolder -BucketName $bucketName -FolderName "projects/web-app/docs"
|
||||
New-MinIOFolder -BucketName $bucketName -FolderName "projects/api/v1"
|
||||
New-MinIOFolder -BucketName $bucketName -FolderName "projects/api/v2"
|
||||
"Created explicit folder structures"
|
||||
""
|
||||
|
||||
"=== 2. Automatic Directory Creation with BucketDirectory ==="
|
||||
# Upload files with automatic directory creation
|
||||
New-MinIOObject -BucketName $bucketName -Files "README.md" -BucketDirectory "projects/web-app/docs"
|
||||
New-MinIOObject -BucketName $bucketName -Files "config.json" -BucketDirectory "projects/web-app/config"
|
||||
New-MinIOObject -BucketName $bucketName -Files "app.py" -BucketDirectory "projects/web-app/src"
|
||||
New-MinIOObject -BucketName $bucketName -Files "test-data.csv" -BucketDirectory "projects/web-app/tests/data"
|
||||
New-MinIOObject -BucketName $bucketName -Files "app.exe" -BucketDirectory "releases/v1.0/binaries"
|
||||
"Uploaded files with automatic directory creation"
|
||||
""
|
||||
|
||||
"=== 3. Multi-Level Directory Structure ==="
|
||||
# Create a complex directory structure
|
||||
$complexStructure = @(
|
||||
"company/departments/engineering/teams/backend",
|
||||
"company/departments/engineering/teams/frontend",
|
||||
"company/departments/engineering/teams/devops",
|
||||
"company/departments/marketing/campaigns/2025",
|
||||
"company/departments/hr/policies/remote-work"
|
||||
)
|
||||
|
||||
foreach ($folder in $complexStructure) {
|
||||
New-MinIOFolder -BucketName $bucketName -FolderName $folder
|
||||
}
|
||||
"Created complex multi-level directory structure"
|
||||
""
|
||||
|
||||
"=== 4. Viewing Directory Structure ==="
|
||||
# List all objects to see the directory structure
|
||||
$allObjects = Get-MinIOObject -BucketName $bucketName
|
||||
"Complete directory and file structure:"
|
||||
$allObjects | Sort-Object Name | Format-Table Name, @{Name="Type";Expression={if($_.IsDirectory){"Directory"}else{"File"}}}, @{Name="Size";Expression={if($_.IsDirectory){"-"}else{"$($_.Size) B"}}} -AutoSize
|
||||
""
|
||||
|
||||
"=== 5. Filtering by Directory ==="
|
||||
# Show objects in specific directories
|
||||
"Files in projects/web-app/:"
|
||||
$webAppFiles = Get-MinIOObject -BucketName $bucketName -Prefix "projects/web-app/"
|
||||
$webAppFiles | Format-Table Name, @{Name="Type";Expression={if($_.IsDirectory){"Directory"}else{"File"}}}, @{Name="Size";Expression={if($_.IsDirectory){"-"}else{"$($_.Size) B"}}} -AutoSize
|
||||
""
|
||||
|
||||
"Engineering team directories:"
|
||||
$engineeringDirs = Get-MinIOObject -BucketName $bucketName -Prefix "company/departments/engineering/teams/"
|
||||
$engineeringDirs | Format-Table Name, @{Name="Type";Expression={if($_.IsDirectory){"Directory"}else{"File"}}} -AutoSize
|
||||
""
|
||||
|
||||
"=== 6. Directory-Only Listing ==="
|
||||
# Show only directories (folders)
|
||||
$directoriesOnly = Get-MinIOObject -BucketName $bucketName | Where-Object { $_.IsDirectory }
|
||||
"Directories only:"
|
||||
$directoriesOnly | Sort-Object Name | Format-Table Name -AutoSize
|
||||
""
|
||||
|
||||
"=== 7. Files-Only Listing ==="
|
||||
# Show only files (excluding directories)
|
||||
$filesOnly = Get-MinIOObject -BucketName $bucketName -ObjectsOnly
|
||||
"Files only:"
|
||||
$filesOnly | Format-Table Name, @{Name="Size";Expression={"$($_.Size) B"}}, LastModified -AutoSize
|
||||
""
|
||||
|
||||
"=== 8. Organizing Files by Date ==="
|
||||
# Create date-based directory structure
|
||||
$currentDate = Get-Date
|
||||
$yearMonth = $currentDate.ToString("yyyy/MM")
|
||||
$dailyFolder = $currentDate.ToString("yyyy/MM/dd")
|
||||
|
||||
# Upload files to date-based directories
|
||||
"Sample log entry" | Out-File -FilePath "daily.log" -Encoding UTF8
|
||||
"Backup data" | Out-File -FilePath "backup.zip" -Encoding UTF8
|
||||
|
||||
New-MinIOObject -BucketName $bucketName -Files "daily.log" -BucketDirectory "logs/$dailyFolder"
|
||||
New-MinIOObject -BucketName $bucketName -Files "backup.zip" -BucketDirectory "backups/$yearMonth"
|
||||
|
||||
"Created date-based directory structure and uploaded files"
|
||||
""
|
||||
|
||||
# Show the final structure
|
||||
"=== Final Directory Structure ==="
|
||||
$finalStructure = Get-MinIOObject -BucketName $bucketName | Sort-Object Name
|
||||
$finalStructure | Format-Table Name, @{Name="Type";Expression={if($_.IsDirectory){"Directory"}else{"File"}}}, @{Name="Size";Expression={if($_.IsDirectory){"-"}else{"$($_.Size) B"}}} -AutoSize
|
||||
|
||||
# Clean up
|
||||
"Cleaning up demo files..."
|
||||
$allObjects = Get-MinIOObject -BucketName $bucketName
|
||||
foreach ($obj in $allObjects) {
|
||||
if (-not $obj.IsDirectory) {
|
||||
Remove-MinIOObject -BucketName $bucketName -ObjectName $obj.Name -Force
|
||||
}
|
||||
}
|
||||
Remove-MinIOBucket -BucketName $bucketName -Force
|
||||
Remove-Item "README.md", "config.json", "app.py", "test-data.csv", "app.exe", "daily.log", "backup.zip" -Force -ErrorAction SilentlyContinue
|
||||
|
||||
"✅ Directory management demo completed"
|
||||
|
||||
} catch {
|
||||
"❌ Error: $($_.Exception.Message)"
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
# PSMinIO Chunked Operations Example
|
||||
# Demonstrates chunked uploads and downloads for large files with progress tracking
|
||||
|
||||
# Import the module
|
||||
Import-Module ..\..\Module\PSMinIO\PSMinIO.psd1
|
||||
|
||||
# Connection details (replace with your actual values)
|
||||
$endpoint = "https://minio.example.com"
|
||||
$accessKey = "your-access-key"
|
||||
$secretKey = "your-secret-key"
|
||||
|
||||
try {
|
||||
# Connect to MinIO
|
||||
$connection = Connect-MinIO -Endpoint $endpoint -AccessKey $accessKey -SecretKey $secretKey
|
||||
"Connected to MinIO server for chunked operations demo"
|
||||
|
||||
# Create a demo bucket
|
||||
$bucketName = "chunked-demo-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
New-MinIOBucket -BucketName $bucketName
|
||||
"Created demo bucket: $bucketName"
|
||||
|
||||
"=== 1. Creating Large Test Files ==="
|
||||
# Create files of different sizes for testing
|
||||
|
||||
# Small file (under chunk size)
|
||||
$smallContent = "Small file content " * 100 # ~2KB
|
||||
$smallContent | Out-File -FilePath "small-file.txt" -Encoding UTF8 -NoNewline
|
||||
|
||||
# Medium file (1-2 chunks)
|
||||
$mediumContent = "Medium file content " * 30000 # ~600KB
|
||||
$mediumContent | Out-File -FilePath "medium-file.txt" -Encoding UTF8 -NoNewline
|
||||
|
||||
# Large file (multiple chunks)
|
||||
$largeContent = "Large file content " * 100000 # ~2MB
|
||||
$largeContent | Out-File -FilePath "large-file.txt" -Encoding UTF8 -NoNewline
|
||||
|
||||
# Very large file (many chunks)
|
||||
$veryLargeContent = "Very large file content " * 250000 # ~6MB
|
||||
$veryLargeContent | Out-File -FilePath "very-large-file.txt" -Encoding UTF8 -NoNewline
|
||||
|
||||
"Created test files of various sizes"
|
||||
Get-ChildItem "*.txt" | Format-Table Name, @{Name="Size";Expression={"$([math]::Round($_.Length/1KB,2)) KB"}}
|
||||
""
|
||||
|
||||
"=== 2. Chunked Upload with Different Chunk Sizes ==="
|
||||
|
||||
# Upload with 1MB chunks (default)
|
||||
"Uploading medium file with 1MB chunks..."
|
||||
$result1 = New-MinIOObjectChunked -BucketName $bucketName -Files "medium-file.txt" -ChunkSize 1MB -BucketDirectory "uploads/1mb-chunks"
|
||||
$result1 | Format-Table Name, @{Name="SizeMB";Expression={[math]::Round($_.Size/1MB,2)}}, @{Name="Duration";Expression={$_.Duration}}, @{Name="Speed";Expression={$_.AverageSpeedFormatted}}
|
||||
""
|
||||
|
||||
# Upload with 512KB chunks
|
||||
"Uploading large file with 512KB chunks..."
|
||||
$result2 = New-MinIOObjectChunked -BucketName $bucketName -Files "large-file.txt" -ChunkSize 512KB -BucketDirectory "uploads/512kb-chunks"
|
||||
$result2 | Format-Table Name, @{Name="SizeMB";Expression={[math]::Round($_.Size/1MB,2)}}, @{Name="Duration";Expression={$_.Duration}}, @{Name="Speed";Expression={$_.AverageSpeedFormatted}}
|
||||
""
|
||||
|
||||
# Upload with 2MB chunks
|
||||
"Uploading very large file with 2MB chunks..."
|
||||
$result3 = New-MinIOObjectChunked -BucketName $bucketName -Files "very-large-file.txt" -ChunkSize 2MB -BucketDirectory "uploads/2mb-chunks"
|
||||
$result3 | Format-Table Name, @{Name="SizeMB";Expression={[math]::Round($_.Size/1MB,2)}}, @{Name="Duration";Expression={$_.Duration}}, @{Name="Speed";Expression={$_.AverageSpeedFormatted}}
|
||||
""
|
||||
|
||||
"=== 3. Multiple File Chunked Upload ==="
|
||||
# Upload multiple files in one operation
|
||||
"Uploading multiple files with chunked transfer..."
|
||||
$multiResult = New-MinIOObjectChunked -BucketName $bucketName -Files @("small-file.txt", "medium-file.txt") -ChunkSize 1MB -BucketDirectory "uploads/multi-file"
|
||||
$multiResult | Format-Table Name, @{Name="SizeMB";Expression={[math]::Round($_.Size/1MB,2)}}, @{Name="Duration";Expression={$_.Duration}}, @{Name="Speed";Expression={$_.AverageSpeedFormatted}}
|
||||
""
|
||||
|
||||
"=== 4. Chunked Download Operations ==="
|
||||
|
||||
# Download with chunked transfer
|
||||
"Downloading large file with chunked transfer..."
|
||||
$downloadResult = Get-MinIOObjectContentChunked -BucketName $bucketName -ObjectName "uploads/2mb-chunks/very-large-file.txt" -FilePath "downloaded-very-large.txt" -ChunkSize 1MB
|
||||
$downloadResult | Format-Table @{Name="LocalFile";Expression={$_.FilePath.Name}}, @{Name="SizeMB";Expression={[math]::Round($_.FilePath.Length/1MB,2)}}, @{Name="Duration";Expression={$_.Duration}}, @{Name="Speed";Expression={$_.AverageSpeedFormatted}}
|
||||
""
|
||||
|
||||
# Verify download integrity
|
||||
if (Test-Path "downloaded-very-large.txt") {
|
||||
$originalSize = (Get-Item "very-large-file.txt").Length
|
||||
$downloadedSize = (Get-Item "downloaded-very-large.txt").Length
|
||||
if ($originalSize -eq $downloadedSize) {
|
||||
"✅ Download integrity verified - sizes match ($originalSize bytes)"
|
||||
} else {
|
||||
"❌ Download integrity check failed - size mismatch"
|
||||
}
|
||||
}
|
||||
""
|
||||
|
||||
"=== 5. Performance Comparison ==="
|
||||
# Compare regular vs chunked upload for the same file
|
||||
"Comparing regular vs chunked upload performance..."
|
||||
|
||||
# Regular upload
|
||||
$regularStart = Get-Date
|
||||
$regularResult = New-MinIOObject -BucketName $bucketName -Files "large-file.txt" -BucketDirectory "comparison/regular"
|
||||
$regularEnd = Get-Date
|
||||
$regularDuration = $regularEnd - $regularStart
|
||||
|
||||
# Chunked upload
|
||||
$chunkedStart = Get-Date
|
||||
$chunkedResult = New-MinIOObjectChunked -BucketName $bucketName -Files "large-file.txt" -ChunkSize 1MB -BucketDirectory "comparison/chunked"
|
||||
$chunkedEnd = Get-Date
|
||||
$chunkedDuration = $chunkedEnd - $chunkedStart
|
||||
|
||||
"Performance Comparison for large-file.txt:"
|
||||
[PSCustomObject]@{
|
||||
Method = "Regular"
|
||||
Duration = $regularDuration.ToString("mm\:ss\.fff")
|
||||
Speed = $regularResult.AverageSpeedFormatted
|
||||
} | Format-Table
|
||||
|
||||
[PSCustomObject]@{
|
||||
Method = "Chunked"
|
||||
Duration = $chunkedDuration.ToString("mm\:ss\.fff")
|
||||
Speed = $chunkedResult.AverageSpeedFormatted
|
||||
} | Format-Table
|
||||
""
|
||||
|
||||
"=== 6. Listing Uploaded Files ==="
|
||||
# Show all uploaded files with their details
|
||||
$allUploads = Get-MinIOObject -BucketName $bucketName -Prefix "uploads/" -ObjectsOnly -SortBy "Size" -Descending
|
||||
"All uploaded files (sorted by size):"
|
||||
$allUploads | Format-Table Name, @{Name="SizeMB";Expression={[math]::Round($_.Size/1MB,2)}}, LastModified -AutoSize
|
||||
""
|
||||
|
||||
"=== 7. Chunk Size Recommendations ==="
|
||||
"Chunk Size Recommendations:"
|
||||
"• Files < 10MB: Use regular upload (New-MinIOObject)"
|
||||
"• Files 10MB - 100MB: Use 1-5MB chunks"
|
||||
"• Files 100MB - 1GB: Use 5-10MB chunks"
|
||||
"• Files > 1GB: Use 10-50MB chunks"
|
||||
"• Network considerations: Smaller chunks for unstable connections"
|
||||
""
|
||||
|
||||
# Clean up
|
||||
"Cleaning up demo files..."
|
||||
$allObjects = Get-MinIOObject -BucketName $bucketName
|
||||
foreach ($obj in $allObjects) {
|
||||
if (-not $obj.IsDirectory) {
|
||||
Remove-MinIOObject -BucketName $bucketName -ObjectName $obj.Name -Force
|
||||
}
|
||||
}
|
||||
Remove-MinIOBucket -BucketName $bucketName -Force
|
||||
Remove-Item "small-file.txt", "medium-file.txt", "large-file.txt", "very-large-file.txt", "downloaded-very-large.txt" -Force -ErrorAction SilentlyContinue
|
||||
|
||||
"✅ Chunked operations demo completed"
|
||||
|
||||
} catch {
|
||||
"❌ Error: $($_.Exception.Message)"
|
||||
}
|
||||
@@ -1,205 +0,0 @@
|
||||
# PSMinIO Bulk Operations Example
|
||||
# Demonstrates bulk file operations, batch processing, and automation scenarios
|
||||
|
||||
# Import the module
|
||||
Import-Module ..\..\Module\PSMinIO\PSMinIO.psd1
|
||||
|
||||
# Connection details (replace with your actual values)
|
||||
$endpoint = "https://minio.example.com"
|
||||
$accessKey = "your-access-key"
|
||||
$secretKey = "your-secret-key"
|
||||
|
||||
try {
|
||||
# Connect to MinIO
|
||||
$connection = Connect-MinIO -Endpoint $endpoint -AccessKey $accessKey -SecretKey $secretKey
|
||||
"Connected to MinIO server for bulk operations demo"
|
||||
|
||||
# Create a demo bucket
|
||||
$bucketName = "bulk-demo-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
New-MinIOBucket -BucketName $bucketName
|
||||
"Created demo bucket: $bucketName"
|
||||
|
||||
"=== 1. Creating Multiple Test Files ==="
|
||||
# Create a variety of files for bulk operations
|
||||
$testFiles = @()
|
||||
|
||||
# Create document files
|
||||
for ($i = 1; $i -le 5; $i++) {
|
||||
$fileName = "document-$i.txt"
|
||||
"Document $i content - $(Get-Date)" | Out-File -FilePath $fileName -Encoding UTF8
|
||||
$testFiles += $fileName
|
||||
}
|
||||
|
||||
# Create data files
|
||||
for ($i = 1; $i -le 3; $i++) {
|
||||
$fileName = "data-$i.csv"
|
||||
"Name,Value,Date`nItem$i,$(Get-Random -Minimum 100 -Maximum 1000),$(Get-Date)" | Out-File -FilePath $fileName -Encoding UTF8
|
||||
$testFiles += $fileName
|
||||
}
|
||||
|
||||
# Create log files
|
||||
for ($i = 1; $i -le 4; $i++) {
|
||||
$fileName = "log-$i.log"
|
||||
"$(Get-Date) - Log entry $i`n$(Get-Date) - Another log entry" | Out-File -FilePath $fileName -Encoding UTF8
|
||||
$testFiles += $fileName
|
||||
}
|
||||
|
||||
"Created $($testFiles.Count) test files"
|
||||
Get-ChildItem "*.txt", "*.csv", "*.log" | Format-Table Name, @{Name="Size";Expression={"$($_.Length) bytes"}} -AutoSize
|
||||
""
|
||||
|
||||
"=== 2. Bulk Upload to Different Directories ==="
|
||||
# Upload different file types to organized directories
|
||||
|
||||
# Upload documents
|
||||
$docFiles = Get-ChildItem "document-*.txt"
|
||||
if ($docFiles) {
|
||||
"Uploading $($docFiles.Count) document files..."
|
||||
$docResults = New-MinIOObject -BucketName $bucketName -Files $docFiles.Name -BucketDirectory "documents/$(Get-Date -Format 'yyyy/MM')"
|
||||
$docResults | Format-Table Name, @{Name="Duration";Expression={$_.Duration}}, @{Name="Speed";Expression={$_.AverageSpeedFormatted}}
|
||||
}
|
||||
""
|
||||
|
||||
# Upload data files
|
||||
$dataFiles = Get-ChildItem "data-*.csv"
|
||||
if ($dataFiles) {
|
||||
"Uploading $($dataFiles.Count) data files..."
|
||||
$dataResults = New-MinIOObject -BucketName $bucketName -Files $dataFiles.Name -BucketDirectory "data/exports"
|
||||
$dataResults | Format-Table Name, @{Name="Duration";Expression={$_.Duration}}, @{Name="Speed";Expression={$_.AverageSpeedFormatted}}
|
||||
}
|
||||
""
|
||||
|
||||
# Upload log files
|
||||
$logFiles = Get-ChildItem "log-*.log"
|
||||
if ($logFiles) {
|
||||
"Uploading $($logFiles.Count) log files..."
|
||||
$logResults = New-MinIOObject -BucketName $bucketName -Files $logFiles.Name -BucketDirectory "logs/application/$(Get-Date -Format 'yyyy-MM-dd')"
|
||||
$logResults | Format-Table Name, @{Name="Duration";Expression={$_.Duration}}, @{Name="Speed";Expression={$_.AverageSpeedFormatted}}
|
||||
}
|
||||
""
|
||||
|
||||
"=== 3. Bulk File Analysis ==="
|
||||
# Analyze uploaded files by type and location
|
||||
$allObjects = Get-MinIOObject -BucketName $bucketName -ObjectsOnly
|
||||
|
||||
"File distribution by directory:"
|
||||
$allObjects | Group-Object { ($_.Name -split '/')[0] } | Format-Table Name, Count -AutoSize
|
||||
""
|
||||
|
||||
"File distribution by extension:"
|
||||
$allObjects | Group-Object { [System.IO.Path]::GetExtension($_.Name) } | Format-Table Name, Count -AutoSize
|
||||
""
|
||||
|
||||
"Largest files:"
|
||||
$allObjects | Sort-Object Size -Descending | Select-Object -First 5 | Format-Table Name, @{Name="Size";Expression={"$($_.Size) bytes"}}, LastModified -AutoSize
|
||||
""
|
||||
|
||||
"=== 4. Batch Download Operations ==="
|
||||
# Download files by pattern/criteria
|
||||
|
||||
# Create download directory
|
||||
$downloadDir = "downloads"
|
||||
if (-not (Test-Path $downloadDir)) {
|
||||
New-Item -ItemType Directory -Path $downloadDir | Out-Null
|
||||
}
|
||||
|
||||
# Download all CSV files
|
||||
$csvObjects = Get-MinIOObject -BucketName $bucketName | Where-Object { $_.Name -like "*.csv" }
|
||||
"Downloading $($csvObjects.Count) CSV files..."
|
||||
foreach ($csvObj in $csvObjects) {
|
||||
$localFileName = [System.IO.Path]::GetFileName($csvObj.Name)
|
||||
$localPath = Join-Path $downloadDir $localFileName
|
||||
$downloadResult = Get-MinIOObjectContent -BucketName $bucketName -ObjectName $csvObj.Name -FilePath $localPath
|
||||
"Downloaded: $($csvObj.Name) -> $localPath"
|
||||
}
|
||||
""
|
||||
|
||||
# Download files from specific directory
|
||||
$docObjects = Get-MinIOObject -BucketName $bucketName -Prefix "documents/"
|
||||
"Downloading $($docObjects.Count) files from documents directory..."
|
||||
foreach ($docObj in $docObjects) {
|
||||
if (-not $docObj.IsDirectory) {
|
||||
$localFileName = [System.IO.Path]::GetFileName($docObj.Name)
|
||||
$localPath = Join-Path $downloadDir "doc-$localFileName"
|
||||
$downloadResult = Get-MinIOObjectContent -BucketName $bucketName -ObjectName $docObj.Name -FilePath $localPath
|
||||
"Downloaded: $($docObj.Name) -> $localPath"
|
||||
}
|
||||
}
|
||||
""
|
||||
|
||||
"=== 5. Bulk Operations with Filtering ==="
|
||||
# Demonstrate advanced bulk operations
|
||||
|
||||
# Find and process files by size
|
||||
$largeFiles = Get-MinIOObject -BucketName $bucketName -ObjectsOnly | Where-Object { $_.Size -gt 50 }
|
||||
"Processing $($largeFiles.Count) files larger than 50 bytes:"
|
||||
$largeFiles | Format-Table Name, @{Name="Size";Expression={"$($_.Size) bytes"}}, LastModified -AutoSize
|
||||
""
|
||||
|
||||
# Find files by date (last hour)
|
||||
$recentFiles = Get-MinIOObject -BucketName $bucketName -ObjectsOnly | Where-Object { $_.LastModified -gt (Get-Date).AddHours(-1) }
|
||||
"Files uploaded in the last hour: $($recentFiles.Count)"
|
||||
$recentFiles | Format-Table Name, LastModified -AutoSize
|
||||
""
|
||||
|
||||
"=== 6. Bulk Cleanup Operations ==="
|
||||
# Demonstrate selective cleanup
|
||||
|
||||
# Remove files by pattern
|
||||
$logObjects = Get-MinIOObject -BucketName $bucketName | Where-Object { $_.Name -like "*log*" -and -not $_.IsDirectory }
|
||||
"Removing $($logObjects.Count) log files..."
|
||||
foreach ($logObj in $logObjects) {
|
||||
Remove-MinIOObject -BucketName $bucketName -ObjectName $logObj.Name -Force
|
||||
"Removed: $($logObj.Name)"
|
||||
}
|
||||
""
|
||||
|
||||
# Remove files older than a certain date (simulated)
|
||||
$cutoffDate = (Get-Date).AddMinutes(-5) # 5 minutes ago for demo
|
||||
$oldFiles = Get-MinIOObject -BucketName $bucketName -ObjectsOnly | Where-Object { $_.LastModified -lt $cutoffDate }
|
||||
if ($oldFiles.Count -gt 0) {
|
||||
"Removing $($oldFiles.Count) files older than $cutoffDate..."
|
||||
foreach ($oldFile in $oldFiles) {
|
||||
Remove-MinIOObject -BucketName $bucketName -ObjectName $oldFile.Name -Force
|
||||
"Removed: $($oldFile.Name)"
|
||||
}
|
||||
} else {
|
||||
"No files older than $cutoffDate found"
|
||||
}
|
||||
""
|
||||
|
||||
"=== 7. Final Statistics ==="
|
||||
# Show final state
|
||||
$remainingObjects = Get-MinIOObject -BucketName $bucketName -ObjectsOnly
|
||||
"Remaining files after cleanup: $($remainingObjects.Count)"
|
||||
if ($remainingObjects.Count -gt 0) {
|
||||
$remainingObjects | Format-Table Name, @{Name="Size";Expression={"$($_.Size) bytes"}}, LastModified -AutoSize
|
||||
}
|
||||
""
|
||||
|
||||
"Downloaded files:"
|
||||
if (Test-Path $downloadDir) {
|
||||
Get-ChildItem $downloadDir | Format-Table Name, @{Name="Size";Expression={"$($_.Length) bytes"}}, LastWriteTime -AutoSize
|
||||
}
|
||||
|
||||
# Clean up
|
||||
"Cleaning up demo files..."
|
||||
$allObjects = Get-MinIOObject -BucketName $bucketName
|
||||
foreach ($obj in $allObjects) {
|
||||
if (-not $obj.IsDirectory) {
|
||||
Remove-MinIOObject -BucketName $bucketName -ObjectName $obj.Name -Force
|
||||
}
|
||||
}
|
||||
Remove-MinIOBucket -BucketName $bucketName -Force
|
||||
|
||||
# Clean up local files
|
||||
Remove-Item $testFiles -Force -ErrorAction SilentlyContinue
|
||||
if (Test-Path $downloadDir) {
|
||||
Remove-Item $downloadDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
"✅ Bulk operations demo completed"
|
||||
|
||||
} catch {
|
||||
"❌ Error: $($_.Exception.Message)"
|
||||
}
|
||||
@@ -1,291 +0,0 @@
|
||||
# PSMinIO Enterprise Automation Example
|
||||
# Demonstrates enterprise-grade automation scenarios including monitoring, policies, and scheduled operations
|
||||
|
||||
# Import the module
|
||||
Import-Module ..\..\Module\PSMinIO\PSMinIO.psd1
|
||||
|
||||
# Connection details (replace with your actual values)
|
||||
$endpoint = "https://minio.example.com"
|
||||
$accessKey = "your-access-key"
|
||||
$secretKey = "your-secret-key"
|
||||
|
||||
# Configuration
|
||||
$logFile = "minio-automation-$(Get-Date -Format 'yyyyMMdd').log"
|
||||
$reportFile = "minio-report-$(Get-Date -Format 'yyyyMMdd-HHmmss').html"
|
||||
|
||||
function Write-Log {
|
||||
param([string]$Message, [string]$Level = "INFO")
|
||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
$logEntry = "[$timestamp] [$Level] $Message"
|
||||
$logEntry | Out-File -FilePath $logFile -Append -Encoding UTF8
|
||||
$logEntry
|
||||
}
|
||||
|
||||
try {
|
||||
Write-Log "Starting MinIO enterprise automation demo"
|
||||
|
||||
# Connect to MinIO
|
||||
$connection = Connect-MinIO -Endpoint $endpoint -AccessKey $accessKey -SecretKey $secretKey
|
||||
Write-Log "Connected to MinIO server: $endpoint"
|
||||
|
||||
"=== 1. Infrastructure Health Check ==="
|
||||
# Perform comprehensive health checks
|
||||
Write-Log "Performing infrastructure health check"
|
||||
|
||||
# Check server connectivity and basic operations
|
||||
try {
|
||||
$buckets = Get-MinIOBucket
|
||||
Write-Log "✅ Server connectivity: OK ($($buckets.Count) buckets found)"
|
||||
"✅ Server connectivity: OK ($($buckets.Count) buckets found)"
|
||||
} catch {
|
||||
Write-Log "❌ Server connectivity: FAILED - $($_.Exception.Message)" "ERROR"
|
||||
"❌ Server connectivity: FAILED"
|
||||
throw
|
||||
}
|
||||
|
||||
# Test bucket operations
|
||||
$testBucketName = "health-check-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
try {
|
||||
New-MinIOBucket -BucketName $testBucketName
|
||||
$testExists = Test-MinIOBucketExists -BucketName $testBucketName
|
||||
Remove-MinIOBucket -BucketName $testBucketName -Force
|
||||
Write-Log "✅ Bucket operations: OK"
|
||||
"✅ Bucket operations: OK"
|
||||
} catch {
|
||||
Write-Log "❌ Bucket operations: FAILED - $($_.Exception.Message)" "ERROR"
|
||||
"❌ Bucket operations: FAILED"
|
||||
}
|
||||
""
|
||||
|
||||
"=== 2. Storage Statistics and Monitoring ==="
|
||||
# Collect comprehensive storage statistics
|
||||
Write-Log "Collecting storage statistics"
|
||||
|
||||
$stats = Get-MinIOStats -MaxObjectsToCount 1000
|
||||
Write-Log "Storage stats collected: $($stats.TotalBuckets) buckets, $($stats.TotalObjects) objects, $($stats.TotalSizeFormatted)"
|
||||
|
||||
"Storage Overview:"
|
||||
$stats | Format-List TotalBuckets, TotalObjects, TotalSizeFormatted, AverageObjectSizeFormatted
|
||||
""
|
||||
|
||||
# Detailed bucket analysis
|
||||
"Bucket Analysis:"
|
||||
$bucketStats = Get-MinIOBucket -IncludeStatistics
|
||||
$bucketStats | Format-Table Name, @{Name="Objects";Expression={$_.ObjectCount}}, @{Name="Size";Expression={$_.SizeFormatted}}, CreationDate -AutoSize
|
||||
""
|
||||
|
||||
"=== 3. Automated Backup Operations ==="
|
||||
# Simulate automated backup scenario
|
||||
Write-Log "Starting automated backup operations"
|
||||
|
||||
$backupBucket = "automated-backups-$(Get-Date -Format 'yyyyMMdd')"
|
||||
New-MinIOBucket -BucketName $backupBucket
|
||||
Write-Log "Created backup bucket: $backupBucket"
|
||||
|
||||
# Create sample data to backup
|
||||
$backupData = @{
|
||||
"config-backup.json" = @{
|
||||
timestamp = Get-Date
|
||||
server = $env:COMPUTERNAME
|
||||
version = "1.0"
|
||||
} | ConvertTo-Json
|
||||
|
||||
"database-backup.sql" = "-- Database backup generated on $(Get-Date)`nSELECT * FROM users;"
|
||||
|
||||
"logs-backup.txt" = "Application logs backup`n$(Get-Date) - System started`n$(Get-Date) - Backup initiated"
|
||||
}
|
||||
|
||||
foreach ($file in $backupData.Keys) {
|
||||
$backupData[$file] | Out-File -FilePath $file -Encoding UTF8
|
||||
}
|
||||
|
||||
# Perform backup with organized directory structure
|
||||
$backupDate = Get-Date -Format "yyyy/MM/dd"
|
||||
$backupTime = Get-Date -Format "HH-mm"
|
||||
|
||||
$backupResults = New-MinIOObject -BucketName $backupBucket -Files $backupData.Keys -BucketDirectory "daily-backups/$backupDate/$backupTime"
|
||||
Write-Log "Backup completed: $($backupResults.Count) files uploaded"
|
||||
|
||||
"Backup Results:"
|
||||
$backupResults | Format-Table Name, @{Name="Duration";Expression={$_.Duration}}, @{Name="Speed";Expression={$_.AverageSpeedFormatted}}
|
||||
""
|
||||
|
||||
"=== 4. Data Lifecycle Management ==="
|
||||
# Simulate data lifecycle management
|
||||
Write-Log "Performing data lifecycle management"
|
||||
|
||||
# Create lifecycle demo bucket
|
||||
$lifecycleBucket = "lifecycle-demo-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
New-MinIOBucket -BucketName $lifecycleBucket
|
||||
|
||||
# Upload files with different "ages" (simulated by different directories)
|
||||
$lifecycleFiles = @(
|
||||
@{ Name = "current-data.txt"; Content = "Current data"; Directory = "current" }
|
||||
@{ Name = "week-old-data.txt"; Content = "Week old data"; Directory = "archive/weekly" }
|
||||
@{ Name = "month-old-data.txt"; Content = "Month old data"; Directory = "archive/monthly" }
|
||||
@{ Name = "year-old-data.txt"; Content = "Year old data"; Directory = "archive/yearly" }
|
||||
)
|
||||
|
||||
foreach ($file in $lifecycleFiles) {
|
||||
$file.Content | Out-File -FilePath $file.Name -Encoding UTF8
|
||||
New-MinIOObject -BucketName $lifecycleBucket -Files $file.Name -BucketDirectory $file.Directory
|
||||
Remove-Item $file.Name -Force
|
||||
}
|
||||
|
||||
# Analyze data by lifecycle stage
|
||||
$allLifecycleObjects = Get-MinIOObject -BucketName $lifecycleBucket -ObjectsOnly
|
||||
"Data Lifecycle Analysis:"
|
||||
$allLifecycleObjects | Group-Object { ($_.Name -split '/')[0] } | Format-Table Name, Count -AutoSize
|
||||
""
|
||||
|
||||
"=== 5. Security and Compliance Audit ==="
|
||||
# Perform security audit
|
||||
Write-Log "Performing security and compliance audit"
|
||||
|
||||
$auditResults = @()
|
||||
|
||||
# Check bucket policies
|
||||
foreach ($bucket in $buckets) {
|
||||
try {
|
||||
$policy = Get-MinIOBucketPolicy -BucketName $bucket.Name
|
||||
$auditResults += [PSCustomObject]@{
|
||||
Bucket = $bucket.Name
|
||||
HasPolicy = $policy -ne $null
|
||||
PolicySize = if ($policy) { $policy.Length } else { 0 }
|
||||
Status = if ($policy) { "Policy Configured" } else { "No Policy" }
|
||||
}
|
||||
} catch {
|
||||
$auditResults += [PSCustomObject]@{
|
||||
Bucket = $bucket.Name
|
||||
HasPolicy = $false
|
||||
PolicySize = 0
|
||||
Status = "Policy Check Failed"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"Security Audit Results:"
|
||||
$auditResults | Format-Table Bucket, HasPolicy, Status -AutoSize
|
||||
Write-Log "Security audit completed: $($auditResults.Count) buckets audited"
|
||||
""
|
||||
|
||||
"=== 6. Performance Monitoring ==="
|
||||
# Monitor performance metrics
|
||||
Write-Log "Collecting performance metrics"
|
||||
|
||||
# Test upload/download performance
|
||||
$perfTestFile = "performance-test.txt"
|
||||
$perfTestContent = "Performance test data " * 1000 # ~20KB
|
||||
$perfTestContent | Out-File -FilePath $perfTestFile -Encoding UTF8 -NoNewline
|
||||
|
||||
$perfBucket = "performance-test-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
New-MinIOBucket -BucketName $perfBucket
|
||||
|
||||
# Measure upload performance
|
||||
$uploadStart = Get-Date
|
||||
$uploadResult = New-MinIOObject -BucketName $perfBucket -Files $perfTestFile
|
||||
$uploadEnd = Get-Date
|
||||
$uploadDuration = $uploadEnd - $uploadStart
|
||||
|
||||
# Measure download performance
|
||||
$downloadStart = Get-Date
|
||||
$downloadResult = Get-MinIOObjectContent -BucketName $perfBucket -ObjectName $perfTestFile -FilePath "downloaded-$perfTestFile"
|
||||
$downloadEnd = Get-Date
|
||||
$downloadDuration = $downloadEnd - $downloadStart
|
||||
|
||||
"Performance Metrics:"
|
||||
[PSCustomObject]@{
|
||||
Operation = "Upload"
|
||||
Duration = $uploadDuration.TotalMilliseconds
|
||||
Speed = $uploadResult.AverageSpeedFormatted
|
||||
FileSize = (Get-Item $perfTestFile).Length
|
||||
} | Format-Table
|
||||
|
||||
[PSCustomObject]@{
|
||||
Operation = "Download"
|
||||
Duration = $downloadDuration.TotalMilliseconds
|
||||
Speed = $downloadResult.AverageSpeedFormatted
|
||||
FileSize = (Get-Item "downloaded-$perfTestFile").Length
|
||||
} | Format-Table
|
||||
|
||||
Write-Log "Performance test completed - Upload: $($uploadDuration.TotalMilliseconds)ms, Download: $($downloadDuration.TotalMilliseconds)ms"
|
||||
""
|
||||
|
||||
"=== 7. Generating HTML Report ==="
|
||||
# Generate comprehensive HTML report
|
||||
Write-Log "Generating HTML report"
|
||||
|
||||
$htmlReport = @"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>MinIO Enterprise Report - $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 20px; }
|
||||
.header { background-color: #f0f0f0; padding: 10px; border-radius: 5px; }
|
||||
.section { margin: 20px 0; }
|
||||
.metric { background-color: #e8f4f8; padding: 10px; margin: 5px 0; border-radius: 3px; }
|
||||
table { border-collapse: collapse; width: 100%; }
|
||||
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
||||
th { background-color: #f2f2f2; }
|
||||
.success { color: green; }
|
||||
.warning { color: orange; }
|
||||
.error { color: red; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>MinIO Enterprise Automation Report</h1>
|
||||
<p>Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')</p>
|
||||
<p>Server: $endpoint</p>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>Storage Overview</h2>
|
||||
<div class="metric">Total Buckets: $($stats.TotalBuckets)</div>
|
||||
<div class="metric">Total Objects: $($stats.TotalObjects)</div>
|
||||
<div class="metric">Total Size: $($stats.TotalSizeFormatted)</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>Health Check Results</h2>
|
||||
<div class="metric success">✅ Server Connectivity: OK</div>
|
||||
<div class="metric success">✅ Bucket Operations: OK</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>Performance Metrics</h2>
|
||||
<div class="metric">Upload Performance: $($uploadResult.AverageSpeedFormatted)</div>
|
||||
<div class="metric">Download Performance: $($downloadResult.AverageSpeedFormatted)</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h2>Security Audit</h2>
|
||||
<p>$($auditResults.Count) buckets audited</p>
|
||||
<p>Buckets with policies: $(($auditResults | Where-Object HasPolicy).Count)</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"@
|
||||
|
||||
$htmlReport | Out-File -FilePath $reportFile -Encoding UTF8
|
||||
Write-Log "HTML report generated: $reportFile"
|
||||
"📊 HTML report generated: $reportFile"
|
||||
""
|
||||
|
||||
# Clean up demo resources
|
||||
Write-Log "Cleaning up demo resources"
|
||||
Remove-MinIOBucket -BucketName $backupBucket -Force
|
||||
Remove-MinIOBucket -BucketName $lifecycleBucket -Force
|
||||
Remove-MinIOBucket -BucketName $perfBucket -Force
|
||||
Remove-Item $backupData.Keys, $perfTestFile, "downloaded-$perfTestFile" -Force -ErrorAction SilentlyContinue
|
||||
|
||||
Write-Log "Enterprise automation demo completed successfully"
|
||||
"✅ Enterprise automation demo completed successfully"
|
||||
"📋 Check the log file: $logFile"
|
||||
"📊 View the report: $reportFile"
|
||||
|
||||
} catch {
|
||||
Write-Log "❌ Enterprise automation demo failed: $($_.Exception.Message)" "ERROR"
|
||||
"❌ Error: $($_.Exception.Message)"
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
# PSMinIO Examples
|
||||
|
||||
This directory contains comprehensive examples demonstrating various PSMinIO capabilities and usage patterns.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before running these examples:
|
||||
|
||||
1. **Install PSMinIO**: Import the module using `Import-Module ..\..\Module\PSMinIO\PSMinIO.psd1`
|
||||
2. **MinIO Server**: Have access to a MinIO server or compatible S3 service
|
||||
3. **Credentials**: Update the connection details in each script with your actual values:
|
||||
```powershell
|
||||
$endpoint = "https://your-minio-server.com"
|
||||
$accessKey = "your-access-key"
|
||||
$secretKey = "your-secret-key"
|
||||
```
|
||||
|
||||
## Example Scripts
|
||||
|
||||
### 01-Basic-Operations.ps1
|
||||
**Fundamental MinIO operations for beginners**
|
||||
|
||||
Demonstrates:
|
||||
- Connecting to MinIO server
|
||||
- Creating and managing buckets
|
||||
- Basic file upload and download
|
||||
- Object listing and verification
|
||||
- Clean resource management
|
||||
|
||||
**Best for**: First-time users, basic automation scripts
|
||||
|
||||
---
|
||||
|
||||
### 02-Advanced-Object-Listing.ps1
|
||||
**Comprehensive object listing and filtering capabilities**
|
||||
|
||||
Demonstrates:
|
||||
- Advanced filtering with prefixes
|
||||
- Sorting by multiple criteria (Name, Size, LastModified, ETag)
|
||||
- Result pagination with MaxObjects
|
||||
- Files-only filtering (excluding directories)
|
||||
- Complex query combinations
|
||||
|
||||
**Best for**: Data discovery, content management, reporting
|
||||
|
||||
---
|
||||
|
||||
### 03-Directory-Management.ps1
|
||||
**Creating and managing directory structures**
|
||||
|
||||
Demonstrates:
|
||||
- Explicit folder creation with New-MinIOFolder
|
||||
- Automatic directory creation with BucketDirectory
|
||||
- Multi-level nested directory structures
|
||||
- Directory-based file organization
|
||||
- Date-based directory patterns
|
||||
|
||||
**Best for**: Organized file storage, hierarchical data management
|
||||
|
||||
---
|
||||
|
||||
### 04-Chunked-Operations.ps1
|
||||
**Large file handling with chunked transfers**
|
||||
|
||||
Demonstrates:
|
||||
- Chunked uploads with configurable chunk sizes
|
||||
- Chunked downloads for large files
|
||||
- Multi-layer progress tracking
|
||||
- Performance comparison (regular vs chunked)
|
||||
- Chunk size optimization guidelines
|
||||
|
||||
**Best for**: Large file transfers, bandwidth optimization, resume capability
|
||||
|
||||
---
|
||||
|
||||
### 05-Bulk-Operations.ps1
|
||||
**Batch processing and bulk file operations**
|
||||
|
||||
Demonstrates:
|
||||
- Multiple file uploads to organized directories
|
||||
- Bulk download operations with filtering
|
||||
- File analysis and statistics
|
||||
- Pattern-based file processing
|
||||
- Selective cleanup operations
|
||||
|
||||
**Best for**: Data migration, batch processing, automated workflows
|
||||
|
||||
---
|
||||
|
||||
### 06-Enterprise-Automation.ps1
|
||||
**Enterprise-grade automation and monitoring**
|
||||
|
||||
Demonstrates:
|
||||
- Infrastructure health checks
|
||||
- Storage statistics and monitoring
|
||||
- Automated backup operations
|
||||
- Data lifecycle management
|
||||
- Security and compliance auditing
|
||||
- Performance monitoring
|
||||
- HTML report generation
|
||||
|
||||
**Best for**: Enterprise environments, monitoring systems, compliance reporting
|
||||
|
||||
## Usage Patterns
|
||||
|
||||
### Quick Start
|
||||
```powershell
|
||||
# Run a basic example
|
||||
.\01-Basic-Operations.ps1
|
||||
```
|
||||
|
||||
### Customization
|
||||
Each script includes configuration variables at the top. Modify these for your environment:
|
||||
|
||||
```powershell
|
||||
# Connection details
|
||||
$endpoint = "https://your-minio-server.com"
|
||||
$accessKey = "your-access-key"
|
||||
$secretKey = "your-secret-key"
|
||||
|
||||
# Optional: Bucket naming
|
||||
$bucketName = "your-custom-bucket-name"
|
||||
```
|
||||
|
||||
### Integration
|
||||
These examples can be integrated into larger automation workflows:
|
||||
|
||||
```powershell
|
||||
# Source common functions
|
||||
. .\examples\06-Enterprise-Automation.ps1
|
||||
|
||||
# Use specific functions in your scripts
|
||||
Write-Log "Starting custom automation"
|
||||
$stats = Get-MinIOStats
|
||||
```
|
||||
|
||||
## Common Scenarios
|
||||
|
||||
### Development Environment Setup
|
||||
```powershell
|
||||
# Local MinIO setup
|
||||
$endpoint = "http://localhost:9000"
|
||||
$accessKey = "minioadmin"
|
||||
$secretKey = "minioadmin"
|
||||
```
|
||||
|
||||
### Production Environment
|
||||
```powershell
|
||||
# Production setup with SSL
|
||||
$endpoint = "https://minio.company.com"
|
||||
$accessKey = $env:MINIO_ACCESS_KEY
|
||||
$secretKey = $env:MINIO_SECRET_KEY
|
||||
```
|
||||
|
||||
### AWS S3 Compatibility
|
||||
```powershell
|
||||
# AWS S3 setup
|
||||
$endpoint = "https://s3.amazonaws.com"
|
||||
$accessKey = $env:AWS_ACCESS_KEY_ID
|
||||
$secretKey = $env:AWS_SECRET_ACCESS_KEY
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Error Handling
|
||||
All examples include comprehensive error handling:
|
||||
```powershell
|
||||
try {
|
||||
# MinIO operations
|
||||
} catch {
|
||||
"❌ Error: $($_.Exception.Message)"
|
||||
} finally {
|
||||
# Cleanup operations
|
||||
}
|
||||
```
|
||||
|
||||
### Resource Cleanup
|
||||
Examples automatically clean up created resources:
|
||||
- Remove test buckets
|
||||
- Delete uploaded files
|
||||
- Clean local temporary files
|
||||
|
||||
### Logging
|
||||
Enterprise examples include structured logging:
|
||||
```powershell
|
||||
function Write-Log {
|
||||
param([string]$Message, [string]$Level = "INFO")
|
||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
"[$timestamp] [$Level] $Message"
|
||||
}
|
||||
```
|
||||
|
||||
### Performance Considerations
|
||||
- Use chunked operations for files > 10MB
|
||||
- Implement appropriate chunk sizes based on network conditions
|
||||
- Monitor transfer speeds and adjust accordingly
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Connection Issues
|
||||
- Verify endpoint URL and port
|
||||
- Check SSL/TLS configuration
|
||||
- Validate access credentials
|
||||
- Test network connectivity
|
||||
|
||||
### Permission Issues
|
||||
- Ensure proper bucket permissions
|
||||
- Verify access key has required privileges
|
||||
- Check bucket policies if applicable
|
||||
|
||||
### Performance Issues
|
||||
- Adjust chunk sizes for large files
|
||||
- Monitor network bandwidth
|
||||
- Consider parallel operations for bulk transfers
|
||||
|
||||
## Contributing
|
||||
|
||||
When adding new examples:
|
||||
1. Follow the existing naming convention
|
||||
2. Include comprehensive error handling
|
||||
3. Add resource cleanup
|
||||
4. Document the example purpose and usage
|
||||
5. Update this README with the new example
|
||||
|
||||
## Support
|
||||
|
||||
For issues with these examples:
|
||||
- Check the main [PSMinIO documentation](../docs/USAGE.md)
|
||||
- Review error messages and logs
|
||||
- Verify your MinIO server configuration
|
||||
- Test with basic operations first
|
||||
Reference in New Issue
Block a user