getFTP_new.psm1
param( [string]$Destination = "c:\commit4.8" ) <# .SYNOPSIS . .DESCRIPTION Permet d'installer la dernière version "production" de commit et / ou d'effecter une mise à jour vers la dernière version .EXAMPLE Get-Commit -localpath 'c:\commit 4.7\' -force -install .NOTES Auteur : Yves Godart pour la REPF Date : 06/07/2023 #> class Frame { [char]$UL [char]$UR [char]$TOP [char]$LEFT [char]$RIGHT [char]$BL [char]$BR [char]$BOTTOM [char]$LEFTSPLIT [char]$RIGHTSPLIT Frame ( [bool]$Double ) { if ($Double) { $this.UL = "╔" $this.UR = "╗" $this.TOP = "═" $this.LEFT = "║" $this.RIGHT = "║" $this.BL = "╚" $this.BR = "╝" $this.BOTTOM = "═" $this.LEFTSPLIT = "⊫" } else { #$this.UL = "┌" $this.UL = [char]::ConvertFromUtf32(0x256d) #$this.UR = "┐" $this.UR = [char]::ConvertFromUtf32(0x256e) $this.TOP = "─" $this.LEFT = "│" $this.RIGHT = "│" $this.BL = [char]::ConvertFromUtf32(0x2570) #$this.BL = "└" $this.BR = [char]::ConvertFromUtf32(0x256f) #$this.BR = "┘" $this.BOTTOM = "─" $this.LEFTSPLIT = [char]::ConvertFromUtf32(0x2524) $this.RIGHTSPLIT = [char]::ConvertFromUtf32(0x251c) } } } class window { [int]$X [int]$Y [int]$W [int]$H [Frame]$frameStyle [System.ConsoleColor]$frameColor [string]$title = "" [System.ConsoleColor]$titleColor [string]$footer = "" [int]$page = 1 [int]$nbPages = 1 window( [int]$X, [int]$y, [int]$w, [int]$h, [bool]$Double, [System.ConsoleColor]$color = "White" ) { $this.X = $X $this.Y = $y $this.W = $W $this.H = $H $this.frameStyle = [Frame]::new($Double) $this.frameColor = $color } window( [int]$X, [int]$y, [int]$w, [int]$h, [bool]$Double, [System.ConsoleColor]$color = "White", [string]$title = "", [System.ConsoleColor]$titlecolor = "Blue" ) { $this.X = $X $this.Y = $y $this.W = $W $this.H = $H $this.frameStyle = [Frame]::new($Double) $this.frameColor = $color $this.title = $title $this.titleColor = $titlecolor } [void] setPosition( [int]$X, [int]$Y ) { [System.Console]::SetCursorPosition($X, $Y) } [void] drawWindow() { $esc = $([char]0x1b) [System.Console]::CursorVisible = $false $this.setPosition($this.X, $this.Y) $bloc1 = $this.frameStyle.UL, "".PadLeft($this.W - 2, $this.frameStyle.TOP), $this.frameStyle.UR -join "" $blank = $this.frameStyle.LEFT, "".PadLeft($this.W - 2, " "), $this.frameStyle.RIGHT -join "" Write-Host $bloc1 -ForegroundColor $this.frameColor -NoNewline for ($i = 1; $i -lt $this.H; $i++) { $Y2 = $this.Y + $i $X3 = $this.X $this.setPosition($X3, $Y2) Write-Host $blank -ForegroundColor $this.frameColor } $Y2 = $this.Y + $this.H $this.setPosition( $this.X, $Y2) $bloc1 = $this.frameStyle.BL, "".PadLeft($this.W - 2, $this.frameStyle.BOTTOM), $this.frameStyle.BR -join "" Write-Host $bloc1 -ForegroundColor $this.frameColor -NoNewline $this.drawTitle() $this.drawFooter() } [void] drawVersion() { $version = $this.frameStyle.LEFTSPLIT, [string]$(Get-InstalledModule -Name wingetposh -ErrorAction Ignore).version, $this.frameStyle.RIGHTSPLIT -join "" [System.Console]::setcursorposition($this.W - ($version.Length + 6), $this.Y ) [console]::write($version) } [void] drawTitle() { if ($this.title -ne "") { $local:X = $this.x + 2 $this.setPosition($local:X, $this.Y) Write-Host ($this.frameStyle.LEFTSPLIT, " " -join "") -NoNewline -ForegroundColor $this.frameColor $local:X = $local:X + 2 $this.setPosition($local:X, $this.Y) Write-Host $this.title -NoNewline -ForegroundColor $this.titleColor $local:X = $local:X + $this.title.Length $this.setPosition($local:X, $this.Y) Write-Host (" ", $this.frameStyle.RIGHTSPLIT -join "") -NoNewline -ForegroundColor $this.frameColor } } [void] drawFooter() { $Y2 = $this.Y + $this.H $this.setPosition( $this.X, $Y2) $bloc1 = $this.frameStyle.BL, "".PadLeft($this.W - 2, $this.frameStyle.BOTTOM), $this.frameStyle.BR -join "" Write-Host $bloc1 -ForegroundColor $this.frameColor -NoNewline if ($this.footer -ne "") { $local:x = $this.x + 2 $local:Y = $this.Y + $this.h $this.setPosition($local:X, $local:Y) $foot = $this.frameStyle.LEFTSPLIT, " ", $this.footer, " ", $this.frameStyle.RIGHTSPLIT -join "" [console]::write($foot) } } [void] drawPagination() { $sPages = ('Page {0}/{1}' -f ($this.page, $this.nbPages)) [System.Console]::setcursorposition($this.W - ($sPages.Length + 6), $this.Y + $this.H) [console]::write($sPages) } [void] clearWindow() { $local:blank = "".PadLeft($this.W, " ") for ($i = 1; $i -lt $this.H; $i++) { $this.setPosition(($this.X), ($this.Y + $i)) Write-Host $blank } } } function Get-Commit { param ( #Chemin de destination de l'installation / mise à jour de commit [Parameter(Mandatory = $true)][string]$localpath, #[optionnel] Flag qui indique si il faut installer une version "production" [switch]$install, #[optionnel] adresse du serveur FTP [string]$url, #[optionnel] utilisateur [string]$username, #Mot de passe. !! Obligatoire. DOIT être entré à la console. [Parameter(Mandatory = $true, ParameterSetName = 'Plain')][securestring]$pass, #[optionnel] Indique si il faut utiliser les paramètres FTP par défaut ou lire le commit.XML du répertoire de distination. [switch]$force ) $separator = "".PadLeft($Host.UI.RawUI.WindowSize.Width, '—') function Write-Separator { Write-Host $separator -ForegroundColor Blue #-BackgroundColor DarkGray } # Remove-Item 'C:\temp\v4.8' -Recurse -Force -ErrorAction Ignore $OriginalPref = $ProgressPreference $global:ProgressPreference = 'SilentlyContinue' $continue = $true #Clear-Host Write-Host "Paramètres :" Write-Separator Write-Host '$localpath : ' -NoNewline Write-Host $localpath Write-Host '$install : ' -NoNewline Write-Host $install Write-Host '$url : ' -NoNewline Write-Host $url if ($url.Trim() -eq "") { $url = "continentalcircus.ddns.net" Write-Host ' Using Default : ' -NoNewline -ForegroundColor Yellow Write-Host $url -ForegroundColor Yellow } Write-Host '$username : ' -NoNewline Write-Host $username if ($username.trim() -eq "") { $username = "commit" Write-Host ' Using Default : ' -NoNewline -ForegroundColor Yellow Write-Host $username -ForegroundColor Yellow } Write-Separator $localPath = Join-Path $localpath "" $exists = Test-Path $localpath if ($exists -and $install) { #[console]::Beep(1500, 200) $choices = New-Object Collections.ObjectModel.Collection[Management.Automation.Host.ChoiceDescription] $choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Abandonner')) $choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Supprimer')) $decision = $Host.UI.PromptForChoice("Le répertoire choisi existe déjà.", "Choisir une action :", $choices, 0) if ($decision -eq 0) { $continue = $false } else { Remove-Item -Recurse -Force $localpath } } if ((-not $exists) -and (-not $install)) { #[console]::Beep(1500, 200) $choices = New-Object Collections.ObjectModel.Collection[Management.Automation.Host.ChoiceDescription] $choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Abandonner')) $choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Continuer')) $choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Installer Commit')) $decision = $Host.UI.PromptForChoice("Le répertoire de destination n'existe pas.", "Choisir une action :", $choices, 2) if ($decision -eq 0) { $continue = $false } if ($decision -eq 2) { $install = $true } } function copyfile($path) { $destPath = Split-Path -Path $path $exists = Test-Path $destPath if (!$exists) { New-Item -ItemType Directory -Force -Path $destPath } Move-Item $file.FullName -Destination $path -Force } function installFresh { [System.Console]::CursorVisible = $false $statedata = [System.Collections.Hashtable]::Synchronized([System.Collections.Hashtable]::new()) $statedata.X = 0 $statedata.Y = $Host.UI.RawUI.CursorPosition.Y $statedata.width = $Host.UI.RawUI.BufferSize.Width $statedata.title = "⚡Installation de commit 4.8 production" $runspace = [runspacefactory]::CreateRunspace() $runspace.Open() $Runspace.SessionStateProxy.SetVariable("StateData", $StateData) $sb = { $x = $statedata.X $y = $statedata.Y $spinner = '{"aesthetic": { "interval": 80, "frames": [ "▰▱▱▱▱▱▱", "▰▰▱▱▱▱▱", "▰▰▰▱▱▱▱", "▰▰▰▰▱▱▱", "▰▰▰▰▰▱▱", "▰▰▰▰▰▰▱", "▰▰▰▰▰▰▰", "▰▱▱▱▱▱▱" ] }}' $spinners = $spinner | ConvertFrom-Json $frameCount = $spinners.aesthetic.frames.count $frameInterval = $spinners.aesthetic.interval $i = 1 while ($true) { $e = "$([char]27)" [System.Console]::setcursorposition($X, $Y) $frame = $spinners.aesthetic.frames[$i % $frameCount] $string = "$($e)[s", "$e[u$frame", " $($statedata.title)" -join "" [System.Console]::write($string.PadRight($statedata.width, " ")) Start-Sleep -Milliseconds $frameInterval $i++ } } $session = [powershell]::create() $null = $session.AddScript($sb) $session.Runspace = $runspace $handle = $session.BeginInvoke() $folder = "v4.8/distributions/" $credentials = New-Object System.Management.Automation.PSCredential($username, $pass) try { Set-FTPConnection -Credentials $credentials -Server $url -Session commitFTP -ignoreCert -UseBinary -KeepAlive -UsePassive | Out-Null $statedata.title = " 🔒 Connection au serveur FTP REPF" Start-Sleep -Milliseconds 750 $commitFTP = Get-FTPConnection -Session commitFTP $statedata.title = " ⏳Téléchargement du commit de production ..... " Get-FTPItem -Session $commitFTP -Path ( -join ($folder, 'Commit 4.8.7z')) -LocalPath C:\temp -Overwrite -RecreateFolders | Out-Null $statedata.title = " ⚡Installation de $localPath " Expand-7Zip -ArchiveFileName "C:\temp\v4.8\distributions\Commit 4.8.7z" -TargetPath 'C:\temp\decomp' -OutVariable test.txt #Remove-Item "C:\temp\v4.8\distributions\Commit 4.8.7z" -Force Move-Item 'C:\temp\decomp\commit 4.8' -Destination $localPath -Force } catch { Write-Host "Erreur " } $session.Stop() $runspace.Dispose() [System.Console]::setcursorposition($statedata.X, $statedata.Y) [System.Console]::write("".PadRight($Host.UI.RawUI.BufferSize.Width, " ")) [System.Console]::CursorVisible = $true } function majCommit { [System.Console]::CursorVisible = $false $statedata = [System.Collections.Hashtable]::Synchronized([System.Collections.Hashtable]::new()) $statedata.X = 0 $statedata.Y = $Host.UI.RawUI.CursorPosition.Y $statedata.width = $Host.UI.RawUI.BufferSize.Width $statedata.title = "⚡Mise à jour de commit 4.8" $runspace = [runspacefactory]::CreateRunspace() $runspace.Open() $Runspace.SessionStateProxy.SetVariable("StateData", $StateData) $sb = { $x = $statedata.X $y = $statedata.Y $spinner = '{"aesthetic": { "interval": 80, "frames": [ "▰▱▱▱▱▱▱", "▰▰▱▱▱▱▱", "▰▰▰▱▱▱▱", "▰▰▰▰▱▱▱", "▰▰▰▰▰▱▱", "▰▰▰▰▰▰▱", "▰▰▰▰▰▰▰", "▰▱▱▱▱▱▱" ] }}' $spinners = $spinner | ConvertFrom-Json $frameCount = $spinners.aesthetic.frames.count $frameInterval = $spinners.aesthetic.interval $i = 1 while ($true) { $e = "$([char]27)" [System.Console]::setcursorposition($X, $Y) $frame = $spinners.aesthetic.frames[$i % $frameCount] $string = "$($e)[s", "$e[u$frame", " $($statedata.title)" -join "" [System.Console]::write($string.PadRight($statedata.width, " ")) Start-Sleep -Milliseconds $frameInterval $i++ } } $session = [powershell]::create() $null = $session.AddScript($sb) $session.Runspace = $runspace $handle = $session.BeginInvoke() $nbMaj = 0 $nbNew = 0 $folder = "" if (! $force) { $xmlfile = -join ($localPath, "commit.xml") $xdoc = [xml] (Get-Content $xmlfile) $url = $xdoc.COMMIT.ServeursMAJ.ServeurMAJ.serveur $username = $xdoc.COMMIT.ServeursMAJ.ServeurMAJ.utilisateur $pass = $xdoc.COMMIT.ServeursMAJ.ServeurMAJ.mot_de_passe $password = $pass | ConvertTo-SecureString -AsPlainText -Force $folder = $xdoc.COMMIT.ServeursMAJ.ServeurMAJ.repertoire } else { $password = $pass } $credentials = New-Object System.Management.Automation.PSCredential($username, $password) $setcursortop = "$esc[0;0H" Write-Host $setcursortop Start-Sleep -Milliseconds 100 Clear-Host Write-Host "" Write-Separator Write-Host "" Write-Host "Mise à jour de commit" Write-Host "" Write-Separator Write-Host "" Write-Host "Connection au serveur FTP REPF en cours " Write-Host " Serveur : " -NoNewline Write-Host $url -ForegroundColor Blue # Write-Host " Utilisateur : " -NoNewline # Write-Host $username -ForegroundColor Blue # Write-Host " Mot de passe : " -NoNewline # Write-Host $pass -ForegroundColor Blue Write-Host " Répertoire : " -NoNewline Write-Host $folder -ForegroundColor Blue if ($folder.trim() -eq "") { $folder = "v4.8/mises_a_jour/" Write-Host ' Using Default : ' -NoNewline -ForegroundColor Yellow Write-Host $folder -ForegroundColor Yellow } Write-Host "" Write-Separator Write-Host "" # try { Set-FTPConnection -Credentials $credentials -Server $url -Session commitFTP -ignoreCert -UseBinary -KeepAlive -UsePassive | Out-Null $statedata.title = " 🔒 Connection au serveur FTP REPF" Start-Sleep -Milliseconds 750 $commitFTP = Get-FTPConnection -Session commitFTP $statedata.title = " ⏳ Connection au serveur FTP REPF" $files = Get-FTPChildItem -Session $commitFTP -Path $folder -Recurse Start-Sleep -Milliseconds 750 $statedata.title = " 💾 Mise en place de la mise à jour" foreach ($item in $files) { $bCopy = $false; if ($item.Dir -ne 'd') { $splitVar = "ftp://${url}/v4.8/mises_a_jour/" $realPath = [regex]::Split($item.FullName, $splitVar); $localFile = [regex]::Replace(( -join ($localPath, $realPath[1])), '/', '\') $isTMP = [regex]::Match($localFile, 'TMP\\'); if ($isTMP.Success) { $commitFile = [regex]::Split($localfile, 'TMP\\'); $localFile = -join ($localPath, $commitFile[1]) } $exists = Test-Path $localFile if ($exists) { $lf = Get-Item -Path $localFile if ($lf.LastWriteTime -lt $item.ModifiedDate) { $bCopy = $true # Write-Host '📝 Mise à jour | ' -NoNewline # Write-Host $lf.LastWriteTime.ToString().PadRight(20, " ") -ForegroundColor Blue -NoNewline $nbMaj++ } } else { # Write-Host "📦 Nouveau fichier | ".PadRight(20, " ") -NoNewline $nbNew++ $bCopy = $true } if ($bCopy) { Get-FTPItem -Session $commitFTP -Path $item.FullName -LocalPath C:\temp -Overwrite -RecreateFolders | Out-Null } } } $files = Get-ChildItem -Path C:\temp\v4.8 -Recurse foreach ($file in $files) { if ($file.Attributes -ne "Directory") { $realPath = [regex]::Split($file.FullName, 'C:\\temp\\v4.8\\mises_a_jour\\'); $isTMP = [regex]::Match($realPath[1], 'TMP\\'); if ($isTMP.Success) { #MAJ commit $commitFile = [regex]::Split($realPath, 'TMP\\'); $destination = -join ($localPath, $commitFile[1]) } else { # le reste $destination = -join ($localPath, $realPath[1]) } copyfile $destination | Out-Null } } Write-Host "" Write-Separator Write-Host "Mise à jour de ${localpath} effectuée" Write-Host " Nouveaux fichiers : ".PadRight(25, " ") -NoNewline Write-Host $nbNew -ForegroundColor Red Write-Host " Fichiers mis à jour : ".PadRight(25, " ") -NoNewline Write-Host $nbMaj -ForegroundColor Yellow Write-Separator Write-Host "" $session.Stop() $runspace.Dispose() [System.Console]::write("".PadRight($Host.UI.RawUI.BufferSize.Width, " ")) [System.Console]::CursorVisible = $true # } # catch { # Write-Host "Connection au serveur FTP REPF => " -NoNewline # Write-Host " KO " -BackgroundColor Red -ForegroundColor White # $Message = [regex]::Split($_.Exception.Message, '\s:\s'); # $Msg = $Message[1] # Write-Host " => ${Msg}" # } } if ($continue) { Import-Module PSFTP if ($install) { installFresh } majCommit } $Global:ProgressPreference = $OriginalPref } function color { param ( $Text, $ForegroundColor = 'default', $BackgroundColor = 'default' ) # Terminal Colors $Colors = @{ "default" = @(40, 50) "black" = @(30, 0) "lightgrey" = @(33, 43) "grey" = @(37, 47) "darkgrey" = @(90, 100) "red" = @(91, 101) "darkred" = @(31, 41) "green" = @(92, 102) "darkgreen" = @(32, 42) "yellow" = @(93, 103) "white" = @(97, 107) "brightblue" = @(94, 104) "darkblue" = @(34, 44) "indigo" = @(35, 45) "cyan" = @(96, 106) "darkcyan" = @(36, 46) } if ( $ForegroundColor -notin $Colors.Keys -or $BackgroundColor -notin $Colors.Keys) { Write-Error "Invalid color choice!" -ErrorAction Stop } "$([char]27)[$($colors[$ForegroundColor][0])m$([char]27)[$($colors[$BackgroundColor][1])m$($Text)$([char]27)[0m" } function getInstallPath { $WinWidth = [System.Console]::WindowWidth $X = 0 $Y = [System.Console]::WindowHeight - 6 $WinHeigt = 4 $win = [window]::new($X, $Y, $WinWidth, $WinHeigt, $false, "White"); $win.title = "Mise à jour Commit" $Win.titleColor = "Green" $win.footer = "$(color "[Enter]" "red") : Valider $(color "[Esc]" "red") : Abandonner" $win.drawWindow(); $win.setPosition($X + 2, $Y + 2); [System.Console]::Write('Chemin : ') [system.console]::CursorVisible = $true try { [Microsoft.PowerShell.PSConsoleReadLineOptions]$option = Get-PSReadLineOption $save = $option.PredictionSource Set-PSReadLineKeyHandler -key Escape -Function CancelLine Set-PSReadLineOption -PredictionSource None $pack = PSConsoleHostReadLine } finally { Remove-PSReadLineKeyHandler -Key Escape Set-PSReadLineOption -PredictionSource $save [console]::CursorVisible = $false } return $pack } [console]::clear() [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 $isadmin = [bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544") $okToRun = $true if (-not (Get-Module -ListAvailable -Name 7Zip4Powershell)) { if ($isadmin) { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 #Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force Write-Host "📡 Installation du module 7Zip" Set-PSRepository -Name 'PSGallery' -SourceLocation "https://www.powershellgallery.com/api/v2" -InstallationPolicy Trusted Install-Module -Name 7Zip4PowerShell -Force | Out-Null } else { $okToRun = $false } } if (-not (Get-Module -ListAvailable -Name PSFTP)) { if ($isadmin) { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 #Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force Write-Host "📡 Installation du module PSFTP" Set-PSRepository -Name 'PSGallery' -SourceLocation "https://www.powershellgallery.com/api/v2" -InstallationPolicy Trusted Install-Module -Name PSFTP -Force | Out-Null } else { $okToRun = $false } } if ($okToRun) { #Get-Commit -localpath $Destination -username admin_ftp -url repf.groupe.pharmagest.com -force Get-Commit -localpath $destination -username commit -url 192.168.50.92 -force } else { Write-Host "Doit être exécuté en mode Administrateur" } Export-ModuleMember -Function Get-Commit |