mirror of
https://github.com/Grace-Solutions/PSMinIO.git
synced 2026-07-26 06:48:13 +00:00
Major project reorganization: Centralized version management and improved structure
- Reorganized project structure with proper directory separation: * All scripts moved to scripts/ directory (including examples) * All documentation moved to docs/ directory (except README.md) * Centralized version management in Version.ps1 - Implemented centralized version management system: * Version.ps1 provides single source of truth for version information * Automatic yyyy.MM.dd.HHmm versioning based on build time * scripts/Update-Version.ps1 updates all version references * src/Properties/AssemblyInfo.cs for assembly version information - Enhanced build system: * scripts/Build.ps1 - Full build with validation and packaging * scripts/Quick-Build.ps1 - Fast build handling file locking issues * Removed automatic copy from project file to avoid locking * Integrated version updates into build process - Updated PowerShell Gallery publishing: * scripts/Publish-PSMinIOToGallery.ps1 updated for new structure * docs/POWERSHELL-GALLERY-RELEASE.md comprehensive publishing guide * Module manifest updated with proper metadata and release notes - Updated all documentation and examples: * README.md updated with PowerShell Gallery installation * All example scripts updated with correct import paths * scripts/examples/README.md updated for new location * docs/PROJECT-STRUCTURE.md documents new organization - Version updated to 2025.07.11.1151 with centralized management - All import paths corrected for new structure - Professional project organization following PowerShell best practices
This commit is contained in:
@@ -0,0 +1,295 @@
|
||||
#!/usr/bin/env pwsh
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Build script for PSMinIO PowerShell module
|
||||
|
||||
.DESCRIPTION
|
||||
This script builds the PSMinIO module, copies required files, and prepares the module for distribution.
|
||||
|
||||
.PARAMETER Configuration
|
||||
Build configuration (Debug or Release). Default: Release
|
||||
|
||||
.PARAMETER OutputPath
|
||||
Output path for the built module. Default: Module/PSMinIO
|
||||
|
||||
.PARAMETER Clean
|
||||
Clean the output directory before building
|
||||
|
||||
.PARAMETER Test
|
||||
Run tests after building (if test files exist)
|
||||
|
||||
.PARAMETER Package
|
||||
Create a distributable package after building
|
||||
|
||||
.EXAMPLE
|
||||
.\Build.ps1
|
||||
|
||||
.EXAMPLE
|
||||
.\Build.ps1 -Configuration Debug -Clean
|
||||
|
||||
.EXAMPLE
|
||||
.\Build.ps1 -Package
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[ValidateSet('Debug', 'Release')]
|
||||
[string]$Configuration = 'Release',
|
||||
|
||||
[string]$OutputPath = 'Artifacts\PSMinIO',
|
||||
|
||||
[switch]$Clean,
|
||||
|
||||
[switch]$Test,
|
||||
|
||||
[switch]$Package
|
||||
)
|
||||
|
||||
# Set error action preference
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# Get script directory and project root
|
||||
$ScriptRoot = $PSScriptRoot
|
||||
$ProjectRoot = Split-Path $ScriptRoot -Parent
|
||||
$ProjectFile = Join-Path $ProjectRoot 'PSMinIO.csproj'
|
||||
$ModuleManifest = Join-Path $ProjectRoot 'Module\PSMinIO\PSMinIO.psd1'
|
||||
|
||||
Write-Host "=== PSMinIO Build Script ===" -ForegroundColor Cyan
|
||||
Write-Host "Configuration: $Configuration" -ForegroundColor Gray
|
||||
Write-Host "Output Path: $OutputPath" -ForegroundColor Gray
|
||||
Write-Host "Script Root: $ScriptRoot" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
# Function to write status messages
|
||||
function Write-Status {
|
||||
param([string]$Message, [string]$Color = 'Yellow')
|
||||
Write-Host ">>> $Message" -ForegroundColor $Color
|
||||
}
|
||||
|
||||
# Function to check if command exists
|
||||
function Test-Command {
|
||||
param([string]$Command)
|
||||
$null -ne (Get-Command $Command -ErrorAction SilentlyContinue)
|
||||
}
|
||||
|
||||
try {
|
||||
# Update version information first
|
||||
Write-Status "Updating version information..."
|
||||
$updateVersionScript = Join-Path $ScriptRoot "Update-Version.ps1"
|
||||
if (Test-Path $updateVersionScript) {
|
||||
& $updateVersionScript
|
||||
Write-Host " ✓ Version information updated" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Warning "Update-Version.ps1 not found, skipping version update"
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
# Check prerequisites
|
||||
Write-Status "Checking prerequisites..."
|
||||
|
||||
if (!(Test-Command 'dotnet')) {
|
||||
throw ".NET SDK is required but not found. Please install .NET SDK 6.0 or later."
|
||||
}
|
||||
|
||||
$dotnetVersion = dotnet --version
|
||||
Write-Host " .NET SDK Version: $dotnetVersion" -ForegroundColor Green
|
||||
|
||||
if (!(Test-Path $ProjectFile)) {
|
||||
throw "Project file not found: $ProjectFile"
|
||||
}
|
||||
|
||||
if (!(Test-Path $ModuleManifest)) {
|
||||
throw "Module manifest not found: $ModuleManifest"
|
||||
}
|
||||
|
||||
Write-Host " ✓ Prerequisites check passed" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
# Clean output directory if requested
|
||||
if ($Clean -and (Test-Path $OutputPath)) {
|
||||
Write-Status "Cleaning output directory..."
|
||||
Remove-Item -Path $OutputPath -Recurse -Force
|
||||
Write-Host " ✓ Output directory cleaned" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
# Ensure output directory exists
|
||||
if (!(Test-Path $OutputPath)) {
|
||||
Write-Status "Creating output directory..."
|
||||
New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null
|
||||
Write-Host " ✓ Output directory created" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
# Build the project
|
||||
Write-Status "Building project..."
|
||||
$buildArgs = @(
|
||||
'build'
|
||||
$ProjectFile
|
||||
'--configuration', $Configuration
|
||||
'--verbosity', 'minimal'
|
||||
'--nologo'
|
||||
)
|
||||
|
||||
& dotnet @buildArgs
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Build failed with exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
Write-Host " ✓ Build completed successfully" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
# Copy built files to module directory
|
||||
Write-Status "Copying module files..."
|
||||
|
||||
$binPath = Join-Path $OutputPath 'bin'
|
||||
if (!(Test-Path $binPath)) {
|
||||
New-Item -ItemType Directory -Path $binPath -Force | Out-Null
|
||||
}
|
||||
|
||||
# Copy main assembly and dependencies
|
||||
$buildOutputPath = "bin\$Configuration\netstandard2.0"
|
||||
$filesToCopy = @(
|
||||
'PSMinIO.dll',
|
||||
'PSMinIO.pdb',
|
||||
'Minio.dll',
|
||||
'System.Text.Json.dll'
|
||||
)
|
||||
|
||||
foreach ($file in $filesToCopy) {
|
||||
$sourcePath = Join-Path $buildOutputPath $file
|
||||
$destPath = Join-Path $binPath $file
|
||||
|
||||
if (Test-Path $sourcePath) {
|
||||
Copy-Item -Path $sourcePath -Destination $destPath -Force
|
||||
Write-Host " ✓ Copied: $file" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Warning " File not found: $file"
|
||||
}
|
||||
}
|
||||
|
||||
# Copy module manifest
|
||||
$manifestDest = Join-Path $OutputPath 'PSMinIO.psd1'
|
||||
Copy-Item -Path $ModuleManifest -Destination $manifestDest -Force
|
||||
Write-Host " ✓ Copied: PSMinIO.psd1" -ForegroundColor Green
|
||||
|
||||
# Copy type and format files
|
||||
$typesPath = Join-Path $OutputPath 'types'
|
||||
if (!(Test-Path $typesPath)) {
|
||||
New-Item -ItemType Directory -Path $typesPath -Force | Out-Null
|
||||
}
|
||||
|
||||
$typeFiles = Get-ChildItem -Path 'Module\PSMinIO\types\*.ps1xml' -ErrorAction SilentlyContinue
|
||||
foreach ($typeFile in $typeFiles) {
|
||||
$destPath = Join-Path $typesPath $typeFile.Name
|
||||
Copy-Item -Path $typeFile.FullName -Destination $destPath -Force
|
||||
Write-Host " ✓ Copied: $($typeFile.Name)" -ForegroundColor Green
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
|
||||
# Validate module
|
||||
Write-Status "Validating module..."
|
||||
|
||||
try {
|
||||
$moduleInfo = Test-ModuleManifest -Path $manifestDest -ErrorAction Stop
|
||||
Write-Host " ✓ Module manifest is valid" -ForegroundColor Green
|
||||
Write-Host " Name: $($moduleInfo.Name)" -ForegroundColor Gray
|
||||
Write-Host " Version: $($moduleInfo.Version)" -ForegroundColor Gray
|
||||
Write-Host " Author: $($moduleInfo.Author)" -ForegroundColor Gray
|
||||
Write-Host " Cmdlets: $($moduleInfo.ExportedCmdlets.Count)" -ForegroundColor Gray
|
||||
} catch {
|
||||
Write-Warning "Module manifest validation failed: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
|
||||
# Run tests if requested
|
||||
if ($Test) {
|
||||
Write-Status "Running tests..."
|
||||
|
||||
# Check if Pester is available
|
||||
if (Test-Command 'Invoke-Pester') {
|
||||
$testPath = Join-Path $ScriptRoot 'Tests'
|
||||
if (Test-Path $testPath) {
|
||||
try {
|
||||
Invoke-Pester -Path $testPath -PassThru
|
||||
Write-Host " ✓ Tests completed" -ForegroundColor Green
|
||||
} catch {
|
||||
Write-Warning "Tests failed: $($_.Exception.Message)"
|
||||
}
|
||||
} else {
|
||||
Write-Warning "Test directory not found: $testPath"
|
||||
}
|
||||
} else {
|
||||
Write-Warning "Pester module not found. Install with: Install-Module -Name Pester"
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
# Create package if requested
|
||||
if ($Package) {
|
||||
Write-Status "Creating package..."
|
||||
|
||||
$timestamp = Get-Date -Format 'yyyy.MM.dd.HHmm'
|
||||
$packageDir = Join-Path 'Artifacts' "Release-$timestamp"
|
||||
|
||||
if (!(Test-Path $packageDir)) {
|
||||
New-Item -ItemType Directory -Path $packageDir -Force | Out-Null
|
||||
}
|
||||
|
||||
# Create ZIP package
|
||||
$packagePath = Join-Path $packageDir "PSMinIO-$timestamp.zip"
|
||||
Compress-Archive -Path $OutputPath -DestinationPath $packagePath -Force
|
||||
|
||||
Write-Host " ✓ Package created: $packagePath" -ForegroundColor Green
|
||||
|
||||
# Copy documentation
|
||||
$docsSource = Join-Path $ScriptRoot 'docs'
|
||||
if (Test-Path $docsSource) {
|
||||
$docsDest = Join-Path $packageDir 'docs'
|
||||
Copy-Item -Path $docsSource -Destination $docsDest -Recurse -Force
|
||||
Write-Host " ✓ Documentation copied" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Copy README and LICENSE
|
||||
$readmePath = Join-Path $ScriptRoot 'README.md'
|
||||
$licensePath = Join-Path $ScriptRoot 'LICENSE'
|
||||
|
||||
if (Test-Path $readmePath) {
|
||||
Copy-Item -Path $readmePath -Destination $packageDir -Force
|
||||
Write-Host " ✓ README copied" -ForegroundColor Green
|
||||
}
|
||||
|
||||
if (Test-Path $licensePath) {
|
||||
Copy-Item -Path $licensePath -Destination $packageDir -Force
|
||||
Write-Host " ✓ LICENSE copied" -ForegroundColor Green
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
# Build summary
|
||||
Write-Status "Build Summary" "Green"
|
||||
Write-Host " Configuration: $Configuration" -ForegroundColor Gray
|
||||
Write-Host " Output Path: $OutputPath" -ForegroundColor Gray
|
||||
Write-Host " Module Files: $(Get-ChildItem -Path $OutputPath -Recurse -File | Measure-Object | Select-Object -ExpandProperty Count)" -ForegroundColor Gray
|
||||
|
||||
if ($Package) {
|
||||
Write-Host " Package: $packagePath" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=== Build Completed Successfully ===" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "To import the module, run:" -ForegroundColor Cyan
|
||||
Write-Host " Import-Module '$OutputPath\PSMinIO.psd1'" -ForegroundColor White
|
||||
|
||||
} catch {
|
||||
Write-Host ""
|
||||
Write-Host "=== Build Failed ===" -ForegroundColor Red
|
||||
Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Write-Host ""
|
||||
exit 1
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
# PowerShell Gallery Release Script for PSMinIO
|
||||
# This script prepares and publishes the PSMinIO module to PowerShell Gallery
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[string]$NuGetApiKey,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$WhatIf,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$Force,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[string]$Repository = "PSGallery"
|
||||
)
|
||||
|
||||
# Set error action preference
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# Define paths
|
||||
$ProjectRoot = Split-Path $PSScriptRoot -Parent
|
||||
$ModulePath = Join-Path $ProjectRoot "Module\PSMinIO"
|
||||
$ManifestPath = Join-Path $ModulePath "PSMinIO.psd1"
|
||||
$PublishPath = Join-Path $ProjectRoot "Publish"
|
||||
|
||||
function Write-Status {
|
||||
param([string]$Message, [string]$Type = "Info")
|
||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
switch ($Type) {
|
||||
"Success" { Write-Host "[$timestamp] ✅ $Message" -ForegroundColor Green }
|
||||
"Warning" { Write-Host "[$timestamp] ⚠️ $Message" -ForegroundColor Yellow }
|
||||
"Error" { Write-Host "[$timestamp] ❌ $Message" -ForegroundColor Red }
|
||||
default { Write-Host "[$timestamp] ℹ️ $Message" -ForegroundColor Cyan }
|
||||
}
|
||||
}
|
||||
|
||||
function Test-ModuleStructure {
|
||||
Write-Status "Validating module structure..."
|
||||
|
||||
# Check if manifest exists
|
||||
if (-not (Test-Path $ManifestPath)) {
|
||||
throw "Module manifest not found at: $ManifestPath"
|
||||
}
|
||||
|
||||
# Test manifest
|
||||
try {
|
||||
$manifest = Test-ModuleManifest -Path $ManifestPath -ErrorAction Stop
|
||||
Write-Status "Module manifest is valid" "Success"
|
||||
Write-Status "Module: $($manifest.Name) v$($manifest.Version)"
|
||||
Write-Status "Author: $($manifest.Author)"
|
||||
Write-Status "Description: $($manifest.Description)"
|
||||
return $manifest
|
||||
} catch {
|
||||
throw "Module manifest validation failed: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
function Test-RequiredFiles {
|
||||
param($Manifest)
|
||||
|
||||
Write-Status "Checking required files..."
|
||||
|
||||
$requiredFiles = @(
|
||||
"bin\PSMinIO.dll",
|
||||
"bin\Minio.dll",
|
||||
"types\PSMinIO.Types.ps1xml",
|
||||
"types\PSMinIO.Format.ps1xml"
|
||||
)
|
||||
|
||||
foreach ($file in $requiredFiles) {
|
||||
$filePath = Join-Path $ModulePath $file
|
||||
if (-not (Test-Path $filePath)) {
|
||||
throw "Required file missing: $file"
|
||||
}
|
||||
Write-Status "✓ Found: $file"
|
||||
}
|
||||
|
||||
Write-Status "All required files present" "Success"
|
||||
}
|
||||
|
||||
function Test-ModuleFunctionality {
|
||||
Write-Status "Testing module functionality..."
|
||||
|
||||
try {
|
||||
# Import the module
|
||||
Import-Module $ManifestPath -Force -ErrorAction Stop
|
||||
Write-Status "✓ Module imported successfully"
|
||||
|
||||
# Test cmdlet availability
|
||||
$expectedCmdlets = @(
|
||||
'Connect-MinIO',
|
||||
'Get-MinIOBucket',
|
||||
'New-MinIOBucket',
|
||||
'Remove-MinIOBucket',
|
||||
'Test-MinIOBucketExists',
|
||||
'Get-MinIOObject',
|
||||
'New-MinIOObject',
|
||||
'New-MinIOObjectChunked',
|
||||
'New-MinIOFolder',
|
||||
'Get-MinIOObjectContent',
|
||||
'Get-MinIOObjectContentChunked',
|
||||
'Remove-MinIOObject',
|
||||
'Get-MinIOBucketPolicy',
|
||||
'Set-MinIOBucketPolicy',
|
||||
'Get-MinIOStats'
|
||||
)
|
||||
|
||||
$availableCmdlets = Get-Command -Module PSMinIO | Select-Object -ExpandProperty Name
|
||||
|
||||
foreach ($cmdlet in $expectedCmdlets) {
|
||||
if ($cmdlet -in $availableCmdlets) {
|
||||
Write-Status "✓ Cmdlet available: $cmdlet"
|
||||
} else {
|
||||
throw "Expected cmdlet not found: $cmdlet"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Status "All expected cmdlets are available" "Success"
|
||||
|
||||
# Remove module
|
||||
Remove-Module PSMinIO -Force -ErrorAction SilentlyContinue
|
||||
|
||||
} catch {
|
||||
throw "Module functionality test failed: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
function Prepare-PublishDirectory {
|
||||
param($Manifest)
|
||||
|
||||
Write-Status "Preparing publish directory..."
|
||||
|
||||
# Clean and create publish directory
|
||||
if (Test-Path $PublishPath) {
|
||||
Remove-Item $PublishPath -Recurse -Force
|
||||
}
|
||||
New-Item -ItemType Directory -Path $PublishPath -Force | Out-Null
|
||||
|
||||
# Create module directory in publish path
|
||||
$publishModulePath = Join-Path $PublishPath "PSMinIO"
|
||||
New-Item -ItemType Directory -Path $publishModulePath -Force | Out-Null
|
||||
|
||||
# Copy module files
|
||||
Copy-Item -Path "$ModulePath\*" -Destination $publishModulePath -Recurse -Force
|
||||
|
||||
Write-Status "Module prepared in: $publishModulePath" "Success"
|
||||
return $publishModulePath
|
||||
}
|
||||
|
||||
function Test-PowerShellGalleryConnection {
|
||||
Write-Status "Testing PowerShell Gallery connection..."
|
||||
|
||||
try {
|
||||
$repo = Get-PSRepository -Name $Repository -ErrorAction Stop
|
||||
Write-Status "✓ Repository '$Repository' is available"
|
||||
Write-Status " Source: $($repo.SourceLocation)"
|
||||
Write-Status " Publish: $($repo.PublishLocation)"
|
||||
|
||||
if ($repo.InstallationPolicy -eq "Untrusted") {
|
||||
Write-Status "Repository is marked as Untrusted - this is normal for PSGallery" "Warning"
|
||||
}
|
||||
|
||||
} catch {
|
||||
throw "Failed to connect to repository '$Repository': $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
function Publish-ModuleToGallery {
|
||||
param($PublishModulePath, $Manifest)
|
||||
|
||||
if ($WhatIf) {
|
||||
Write-Status "WhatIf: Would publish module to PowerShell Gallery" "Warning"
|
||||
Write-Status "Module: $($Manifest.Name) v$($Manifest.Version)"
|
||||
Write-Status "Path: $PublishModulePath"
|
||||
Write-Status "Repository: $Repository"
|
||||
return
|
||||
}
|
||||
|
||||
if (-not $NuGetApiKey) {
|
||||
Write-Status "NuGetApiKey not provided. Please provide your PowerShell Gallery API key." "Warning"
|
||||
$NuGetApiKey = Read-Host -Prompt "Enter your PowerShell Gallery API Key" -AsSecureString
|
||||
$NuGetApiKey = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($NuGetApiKey))
|
||||
}
|
||||
|
||||
Write-Status "Publishing module to PowerShell Gallery..."
|
||||
|
||||
try {
|
||||
$publishParams = @{
|
||||
Path = $PublishModulePath
|
||||
Repository = $Repository
|
||||
NuGetApiKey = $NuGetApiKey
|
||||
Force = $Force
|
||||
Verbose = $true
|
||||
}
|
||||
|
||||
Publish-Module @publishParams
|
||||
|
||||
Write-Status "Module published successfully!" "Success"
|
||||
Write-Status "It may take a few minutes to appear in search results"
|
||||
|
||||
} catch {
|
||||
throw "Failed to publish module: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
# Main execution
|
||||
try {
|
||||
Write-Status "Starting PowerShell Gallery release process for PSMinIO"
|
||||
Write-Status "Repository: $Repository"
|
||||
Write-Status "WhatIf: $WhatIf"
|
||||
|
||||
# Step 1: Validate module structure
|
||||
$manifest = Test-ModuleStructure
|
||||
|
||||
# Step 2: Check required files
|
||||
Test-RequiredFiles -Manifest $manifest
|
||||
|
||||
# Step 3: Test module functionality
|
||||
Test-ModuleFunctionality
|
||||
|
||||
# Step 4: Test PowerShell Gallery connection
|
||||
Test-PowerShellGalleryConnection
|
||||
|
||||
# Step 5: Prepare publish directory
|
||||
$publishModulePath = Prepare-PublishDirectory -Manifest $manifest
|
||||
|
||||
# Step 6: Final validation of prepared module
|
||||
Write-Status "Final validation of prepared module..."
|
||||
$finalManifest = Test-ModuleManifest -Path (Join-Path $publishModulePath "PSMinIO.psd1")
|
||||
Write-Status "Final validation successful" "Success"
|
||||
|
||||
# Step 7: Publish to gallery
|
||||
Publish-ModuleToGallery -PublishModulePath $publishModulePath -Manifest $finalManifest
|
||||
|
||||
Write-Status "PowerShell Gallery release process completed successfully!" "Success"
|
||||
Write-Status "Module: PSMinIO v$($finalManifest.Version)"
|
||||
Write-Status "Check status at: https://www.powershellgallery.com/packages/PSMinIO"
|
||||
|
||||
} catch {
|
||||
Write-Status "Release process failed: $($_.Exception.Message)" "Error"
|
||||
exit 1
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
# Quick-Build.ps1
|
||||
# Simple build script that handles file locking issues
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[ValidateSet('Debug', 'Release')]
|
||||
[string]$Configuration = 'Release'
|
||||
)
|
||||
|
||||
$ProjectRoot = Split-Path $PSScriptRoot -Parent
|
||||
|
||||
Write-Host "PSMinIO Quick Build" -ForegroundColor Cyan
|
||||
Write-Host "==================" -ForegroundColor Cyan
|
||||
|
||||
# Update version first
|
||||
Write-Host "Updating version..." -ForegroundColor Yellow
|
||||
& "$PSScriptRoot\Update-Version.ps1"
|
||||
|
||||
# Clean build
|
||||
Write-Host "Cleaning previous build..." -ForegroundColor Yellow
|
||||
dotnet clean "$ProjectRoot\PSMinIO.csproj" --configuration $Configuration --verbosity quiet
|
||||
|
||||
# Build without copying to avoid file locks
|
||||
Write-Host "Building project..." -ForegroundColor Yellow
|
||||
dotnet build "$ProjectRoot\PSMinIO.csproj" --configuration $Configuration --verbosity minimal --no-restore
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Error "Build failed"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Manual copy to avoid file locking issues
|
||||
Write-Host "Copying files manually..." -ForegroundColor Yellow
|
||||
|
||||
$buildOutput = "$ProjectRoot\bin\$Configuration\netstandard2.0"
|
||||
$moduleDir = "$ProjectRoot\Module\PSMinIO\bin"
|
||||
|
||||
# Ensure module directory exists
|
||||
if (!(Test-Path $moduleDir)) {
|
||||
New-Item -ItemType Directory -Path $moduleDir -Force | Out-Null
|
||||
}
|
||||
|
||||
# Copy files with retry logic
|
||||
$filesToCopy = @(
|
||||
@{ Source = "$buildOutput\PSMinIO.dll"; Dest = "$moduleDir\PSMinIO.dll" }
|
||||
@{ Source = "$buildOutput\PSMinIO.pdb"; Dest = "$moduleDir\PSMinIO.pdb" }
|
||||
@{ Source = "$buildOutput\Minio.dll"; Dest = "$moduleDir\Minio.dll" }
|
||||
)
|
||||
|
||||
foreach ($file in $filesToCopy) {
|
||||
$retryCount = 0
|
||||
$maxRetries = 3
|
||||
$copied = $false
|
||||
|
||||
while (-not $copied -and $retryCount -lt $maxRetries) {
|
||||
try {
|
||||
if (Test-Path $file.Dest) {
|
||||
Remove-Item $file.Dest -Force -ErrorAction Stop
|
||||
}
|
||||
Copy-Item $file.Source $file.Dest -Force -ErrorAction Stop
|
||||
Write-Host " ✓ Copied: $(Split-Path $file.Source -Leaf)" -ForegroundColor Green
|
||||
$copied = $true
|
||||
} catch {
|
||||
$retryCount++
|
||||
if ($retryCount -lt $maxRetries) {
|
||||
Write-Host " Retry $retryCount for $(Split-Path $file.Source -Leaf)..." -ForegroundColor Yellow
|
||||
Start-Sleep -Seconds 2
|
||||
} else {
|
||||
Write-Warning " Failed to copy $(Split-Path $file.Source -Leaf): $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Test the module
|
||||
Write-Host "Testing module..." -ForegroundColor Yellow
|
||||
try {
|
||||
$manifest = Test-ModuleManifest "$ProjectRoot\Module\PSMinIO\PSMinIO.psd1" -ErrorAction Stop
|
||||
Write-Host " ✓ Module is valid: $($manifest.Name) v$($manifest.Version)" -ForegroundColor Green
|
||||
} catch {
|
||||
Write-Warning " Module validation failed: $($_.Exception.Message)"
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "✅ Quick build completed!" -ForegroundColor Green
|
||||
Write-Host "To import: Import-Module .\Module\PSMinIO\PSMinIO.psd1" -ForegroundColor Cyan
|
||||
@@ -0,0 +1,178 @@
|
||||
# Update-Version.ps1
|
||||
# Updates version information across all PSMinIO project files
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$WhatIf
|
||||
)
|
||||
|
||||
# Import version configuration
|
||||
. "$PSScriptRoot\..\Version.ps1"
|
||||
|
||||
$ProjectRoot = Split-Path $PSScriptRoot -Parent
|
||||
$VersionInfo = Get-PSMinIOVersion
|
||||
|
||||
Write-Host "PSMinIO Version Update Script" -ForegroundColor Cyan
|
||||
Write-Host "=============================" -ForegroundColor Cyan
|
||||
Write-Host "Current Version: $($VersionInfo.Version)" -ForegroundColor Green
|
||||
Write-Host "Build Date: $($VersionInfo.BuildDateString)" -ForegroundColor Green
|
||||
Write-Host "Semantic Version: $($VersionInfo.SemanticVersion)" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
# Define file paths
|
||||
$FilesToUpdate = @{
|
||||
"Module Manifest" = @{
|
||||
Path = Join-Path $ProjectRoot "Module\PSMinIO\PSMinIO.psd1"
|
||||
Type = "ModuleManifest"
|
||||
}
|
||||
"Assembly Info" = @{
|
||||
Path = Join-Path $ProjectRoot "src\Properties\AssemblyInfo.cs"
|
||||
Type = "AssemblyInfo"
|
||||
}
|
||||
"Project File" = @{
|
||||
Path = Join-Path $ProjectRoot "PSMinIO.csproj"
|
||||
Type = "ProjectFile"
|
||||
}
|
||||
}
|
||||
|
||||
function Update-ModuleManifest {
|
||||
param($FilePath, $VersionInfo)
|
||||
|
||||
if (-not (Test-Path $FilePath)) {
|
||||
Write-Warning "Module manifest not found: $FilePath"
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "Updating Module Manifest: $FilePath" -ForegroundColor Yellow
|
||||
|
||||
if ($WhatIf) {
|
||||
Write-Host " [WhatIf] Would update ModuleVersion to: $($VersionInfo.Version)" -ForegroundColor Magenta
|
||||
Write-Host " [WhatIf] Would update Copyright to: $($VersionInfo.Copyright)" -ForegroundColor Magenta
|
||||
Write-Host " [WhatIf] Would update Description" -ForegroundColor Magenta
|
||||
Write-Host " [WhatIf] Would update ReleaseNotes" -ForegroundColor Magenta
|
||||
return
|
||||
}
|
||||
|
||||
$content = Get-Content $FilePath -Raw
|
||||
|
||||
# Update version
|
||||
$content = $content -replace "ModuleVersion\s*=\s*'[^']*'", "ModuleVersion = '$($VersionInfo.Version)'"
|
||||
|
||||
# Update copyright
|
||||
$content = $content -replace "Copyright\s*=\s*'[^']*'", "Copyright = '$($VersionInfo.Copyright)'"
|
||||
|
||||
# Update description
|
||||
$escapedDescription = $VersionInfo.Description -replace "'", "''"
|
||||
$content = $content -replace "Description\s*=\s*'[^']*'", "Description = '$escapedDescription'"
|
||||
|
||||
# Update author and company
|
||||
$content = $content -replace "Author\s*=\s*'[^']*'", "Author = '$($VersionInfo.Author)'"
|
||||
$content = $content -replace "CompanyName\s*=\s*'[^']*'", "CompanyName = '$($VersionInfo.CompanyName)'"
|
||||
|
||||
# Update URLs
|
||||
$content = $content -replace "ProjectUri\s*=\s*'[^']*'", "ProjectUri = '$($VersionInfo.ProjectUri)'"
|
||||
$content = $content -replace "LicenseUri\s*=\s*'[^']*'", "LicenseUri = '$($VersionInfo.LicenseUri)'"
|
||||
|
||||
# Update release notes (this is more complex due to multiline)
|
||||
$escapedReleaseNotes = $VersionInfo.ReleaseNotes -replace "'", "''" -replace "`r`n", "`n" -replace "`n", "``n"
|
||||
$content = $content -replace "ReleaseNotes\s*=\s*@'[^']*'@", "ReleaseNotes = @'`n$($VersionInfo.ReleaseNotes)`n'@"
|
||||
|
||||
$content | Set-Content $FilePath -Encoding UTF8
|
||||
Write-Host " ✅ Module manifest updated" -ForegroundColor Green
|
||||
}
|
||||
|
||||
function Update-AssemblyInfo {
|
||||
param($FilePath, $VersionInfo)
|
||||
|
||||
if (-not (Test-Path $FilePath)) {
|
||||
Write-Warning "Assembly info not found: $FilePath"
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "Updating Assembly Info: $FilePath" -ForegroundColor Yellow
|
||||
|
||||
if ($WhatIf) {
|
||||
Write-Host " [WhatIf] Would update AssemblyVersion to: $($VersionInfo.Version)" -ForegroundColor Magenta
|
||||
Write-Host " [WhatIf] Would update AssemblyFileVersion to: $($VersionInfo.Version)" -ForegroundColor Magenta
|
||||
Write-Host " [WhatIf] Would update AssemblyInformationalVersion to: $($VersionInfo.Version)" -ForegroundColor Magenta
|
||||
Write-Host " [WhatIf] Would update AssemblyCopyright to: $($VersionInfo.Copyright)" -ForegroundColor Magenta
|
||||
return
|
||||
}
|
||||
|
||||
$content = Get-Content $FilePath -Raw
|
||||
|
||||
# Update version attributes
|
||||
$content = $content -replace '\[assembly:\s*AssemblyVersion\("[^"]*"\)\]', "[assembly: AssemblyVersion(`"$($VersionInfo.Version)`")]"
|
||||
$content = $content -replace '\[assembly:\s*AssemblyFileVersion\("[^"]*"\)\]', "[assembly: AssemblyFileVersion(`"$($VersionInfo.Version)`")]"
|
||||
$content = $content -replace '\[assembly:\s*AssemblyInformationalVersion\("[^"]*"\)\]', "[assembly: AssemblyInformationalVersion(`"$($VersionInfo.Version)`")]"
|
||||
|
||||
# Update other attributes
|
||||
$content = $content -replace '\[assembly:\s*AssemblyCopyright\("[^"]*"\)\]', "[assembly: AssemblyCopyright(`"$($VersionInfo.Copyright)`")]"
|
||||
$content = $content -replace '\[assembly:\s*AssemblyCompany\("[^"]*"\)\]', "[assembly: AssemblyCompany(`"$($VersionInfo.CompanyName)`")]"
|
||||
$content = $content -replace '\[assembly:\s*AssemblyDescription\("[^"]*"\)\]', "[assembly: AssemblyDescription(`"$($VersionInfo.Description)`")]"
|
||||
|
||||
$content | Set-Content $FilePath -Encoding UTF8
|
||||
Write-Host " ✅ Assembly info updated" -ForegroundColor Green
|
||||
}
|
||||
|
||||
function Update-ProjectFile {
|
||||
param($FilePath, $VersionInfo)
|
||||
|
||||
if (-not (Test-Path $FilePath)) {
|
||||
Write-Warning "Project file not found: $FilePath"
|
||||
return
|
||||
}
|
||||
|
||||
Write-Host "Updating Project File: $FilePath" -ForegroundColor Yellow
|
||||
|
||||
if ($WhatIf) {
|
||||
Write-Host " [WhatIf] Project file uses AssemblyInfo.cs for version information" -ForegroundColor Magenta
|
||||
return
|
||||
}
|
||||
|
||||
# Project file now uses AssemblyInfo.cs, so no direct updates needed
|
||||
Write-Host " ✅ Project file uses AssemblyInfo.cs for version information" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Process each file
|
||||
foreach ($fileInfo in $FilesToUpdate.GetEnumerator()) {
|
||||
$fileName = $fileInfo.Key
|
||||
$fileData = $fileInfo.Value
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Processing: $fileName" -ForegroundColor Cyan
|
||||
|
||||
switch ($fileData.Type) {
|
||||
"ModuleManifest" {
|
||||
Update-ModuleManifest -FilePath $fileData.Path -VersionInfo $VersionInfo
|
||||
}
|
||||
"AssemblyInfo" {
|
||||
Update-AssemblyInfo -FilePath $fileData.Path -VersionInfo $VersionInfo
|
||||
}
|
||||
"ProjectFile" {
|
||||
Update-ProjectFile -FilePath $fileData.Path -VersionInfo $VersionInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Version Update Summary" -ForegroundColor Cyan
|
||||
Write-Host "=====================" -ForegroundColor Cyan
|
||||
Write-Host "Version: $($VersionInfo.Version)" -ForegroundColor Green
|
||||
Write-Host "Build Date: $($VersionInfo.BuildDateString)" -ForegroundColor Green
|
||||
Write-Host "Author: $($VersionInfo.Author)" -ForegroundColor Green
|
||||
Write-Host "Company: $($VersionInfo.CompanyName)" -ForegroundColor Green
|
||||
|
||||
if ($WhatIf) {
|
||||
Write-Host ""
|
||||
Write-Host "This was a WhatIf run - no files were actually modified" -ForegroundColor Yellow
|
||||
Write-Host "Run without -WhatIf to apply changes" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host ""
|
||||
Write-Host "✅ Version update completed successfully!" -ForegroundColor Green
|
||||
Write-Host "Next steps:" -ForegroundColor Yellow
|
||||
Write-Host " 1. Build the project: dotnet build --configuration Release" -ForegroundColor White
|
||||
Write-Host " 2. Test the module: Import-Module .\Module\PSMinIO\PSMinIO.psd1" -ForegroundColor White
|
||||
Write-Host " 3. Commit changes: git add . && git commit -m 'Update version to $($VersionInfo.Version)'" -ForegroundColor White
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
# 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
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
# 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)"
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
# 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)"
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
# 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)"
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
# 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)"
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
# 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)"
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
# 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