Install-O365Toolkit.ps1
|
param( [string]$Destination, [switch]$NoImport, [switch]$Force, [switch]$SkipDependencies, [switch]$InstallDependencies ) $moduleName = 'O365-Toolkit' $sourceRoot = Split-Path -Parent $PSCommandPath # Define required and optional dependencies $requiredModules = @( @{Name = 'ExchangeOnlineManagement'; MinVersion = '3.2.0'; Required = $true}, @{Name = 'PnP.PowerShell'; MinVersion = '1.12.0'; Required = $true} ) $optionalModules = @( @{Name = 'Microsoft.Graph'; MinVersion = '2.9.0'; Required = $false}, @{Name = 'Microsoft.Online.SharePoint.PowerShell'; MinVersion = '16.0.22601.12000'; Required = $false} ) function Get-DefaultModulePath { $paths = ($env:PSModulePath -split ';') | Where-Object { $_ -and (Test-Path $_) } $preferred = @( Join-Path $HOME 'Documents\PowerShell\Modules'), # PowerShell 6+ (Join-Path $HOME 'Documents\WindowsPowerShell\Modules') # Windows PowerShell foreach ($p in $preferred) { if (Test-Path $p) { return $p } } if ($paths) { return $paths[0] } $fallback = Join-Path $HOME 'Documents\PowerShell\Modules' New-Item -ItemType Directory -Path $fallback -Force | Out-Null return $fallback } function Test-ModuleInstalled { param([string]$ModuleName, [string]$MinVersion) $module = Get-Module $ModuleName -ListAvailable | Sort-Object Version -Descending | Select-Object -First 1 if (-not $module) { return $false } if ($MinVersion) { return [version]$module.Version -ge [version]$MinVersion } return $true } function Show-DependencyStatus { Write-Host "`n=== Dependency Check ===" -ForegroundColor Cyan foreach ($module in $requiredModules) { $installed = Test-ModuleInstalled -ModuleName $module.Name -MinVersion $module.MinVersion $status = if ($installed) { '✓ Installed' } else { '✗ Missing' } $color = if ($installed) { 'Green' } else { 'Red' } Write-Host " $($module.Name): $status" -ForegroundColor $color } Write-Host "`n Optional Dependencies:" -ForegroundColor Yellow foreach ($module in $optionalModules) { $installed = Test-ModuleInstalled -ModuleName $module.Name -MinVersion $module.MinVersion $status = if ($installed) { '✓ Installed' } else { '✗ Not Installed' } $color = if ($installed) { 'Green' } else { 'Yellow' } Write-Host " $($module.Name): $status" -ForegroundColor $color } } function Install-Dependencies { $allModules = $requiredModules + $optionalModules Write-Host "`n=== Installing Dependencies ===" -ForegroundColor Cyan foreach ($module in $allModules) { if (Test-ModuleInstalled -ModuleName $module.Name -MinVersion $module.MinVersion) { Write-Host " Skipping $($module.Name) - already installed" -ForegroundColor Gray continue } Write-Host " Installing $($module.Name)..." -ForegroundColor Yellow try { Install-Module -Name $module.Name -Repository PSGallery -AllowClobber -Force -Scope CurrentUser -ErrorAction Stop Write-Host " ✓ $($module.Name) installed" -ForegroundColor Green } catch { if ($module.Required) { Write-Host " ✗ Failed to install required module $($module.Name): $_" -ForegroundColor Red throw } else { Write-Host " ⚠ Failed to install optional module $($module.Name): $_" -ForegroundColor Yellow } } } } # Show dependency status Show-DependencyStatus # Handle dependency installation if ($InstallDependencies) { Install-Dependencies } elseif (-not $SkipDependencies) { Write-Host "`nInstall dependencies now? (Y/n) " -ForegroundColor Yellow -NoNewline $response = Read-Host if ($response -ne 'n' -and $response -ne 'N') { Install-Dependencies } } # Install the module $destRoot = if ($Destination) { $Destination } else { Get-DefaultModulePath } if (-not (Test-Path $destRoot)) { New-Item -ItemType Directory -Path $destRoot -Force | Out-Null } $targetPath = Join-Path $destRoot $moduleName if (Test-Path $targetPath) { Write-Host "Removing existing module installation at $targetPath..." -ForegroundColor Yellow Remove-Item -Recurse -Force $targetPath -ErrorAction SilentlyContinue Start-Sleep -Milliseconds 500 # Wait for filesystem to catch up } Copy-Item -Path $sourceRoot -Destination $targetPath -Recurse -Force -Exclude '.git','*.Tests.ps1','Tests' if (-not $NoImport) { Import-Module (Join-Path $targetPath "$moduleName.psd1") -Force } Write-Host "`nInstalled $moduleName to $targetPath" -ForegroundColor Green if (-not $NoImport) { Write-Host "Module imported. Try Get-Command -Module $moduleName to explore." -ForegroundColor Green } else { Write-Host "Import manually with: Import-Module '$targetPath\$moduleName.psd1'" -ForegroundColor Yellow } |