2026-04-24 19:33:38 +02:00
|
|
|
param(
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[ValidateNotNullOrEmpty()]
|
|
|
|
|
[string]$RemoteUser,
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[ValidateNotNullOrEmpty()]
|
|
|
|
|
[string]$RemoteHost,
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[ValidateNotNullOrEmpty()]
|
|
|
|
|
[string]$RemotePort,
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[ValidateNotNullOrEmpty()]
|
|
|
|
|
[string]$SshExe,
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[ValidateNotNullOrEmpty()]
|
|
|
|
|
[string]$ScpExe
|
|
|
|
|
)
|
2026-04-19 11:05:30 +02:00
|
|
|
|
|
|
|
|
Add-Type -TypeDefinition @'
|
|
|
|
|
using System;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
|
|
|
|
|
public class ModernFolderPicker {
|
|
|
|
|
private const uint FOS_PICKFOLDERS = 0x00000020;
|
|
|
|
|
private const int SIGDN_FILESYSPATH = unchecked((int)0x80028000);
|
|
|
|
|
|
|
|
|
|
public static string Show(string title = "Select Folder") {
|
|
|
|
|
var dialog = (IFileOpenDialog)new FileOpenDialogClass();
|
|
|
|
|
try {
|
|
|
|
|
uint options;
|
|
|
|
|
dialog.GetOptions(out options);
|
|
|
|
|
dialog.SetOptions(options | FOS_PICKFOLDERS);
|
|
|
|
|
dialog.SetTitle(title);
|
|
|
|
|
if (dialog.Show(IntPtr.Zero) != 0) return null; // cancelled
|
|
|
|
|
IShellItem item;
|
|
|
|
|
dialog.GetResult(out item);
|
|
|
|
|
string path;
|
|
|
|
|
item.GetDisplayName(SIGDN_FILESYSPATH, out path);
|
|
|
|
|
Marshal.ReleaseComObject(item);
|
|
|
|
|
return path;
|
|
|
|
|
} finally {
|
|
|
|
|
Marshal.ReleaseComObject(dialog);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[ComImport, ClassInterface(ClassInterfaceType.None), Guid("DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7")]
|
|
|
|
|
private class FileOpenDialogClass {}
|
|
|
|
|
|
|
|
|
|
[ComImport, Guid("D57C7288-D4AD-4768-BE02-9D969532D960"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
|
|
|
private interface IFileOpenDialog {
|
|
|
|
|
[PreserveSig] int Show(IntPtr hwndOwner);
|
|
|
|
|
void SetFileTypes(uint cFileTypes, IntPtr rgFilterSpec);
|
|
|
|
|
void SetFileTypeIndex(uint iFileType);
|
|
|
|
|
void GetFileTypeIndex(out uint piFileType);
|
|
|
|
|
void Advise(IntPtr pfde, out uint pdwCookie);
|
|
|
|
|
void Unadvise(uint dwCookie);
|
|
|
|
|
void SetOptions(uint fos);
|
|
|
|
|
void GetOptions(out uint pfos);
|
|
|
|
|
void SetDefaultFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);
|
|
|
|
|
void SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi);
|
|
|
|
|
void GetFolder([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
|
|
|
|
|
void GetCurrentSelection([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
|
|
|
|
|
void SetFileName([MarshalAs(UnmanagedType.LPWStr)] string pszName);
|
|
|
|
|
void GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName);
|
|
|
|
|
void SetTitle([MarshalAs(UnmanagedType.LPWStr)] string pszTitle);
|
|
|
|
|
void SetOkButtonLabel([MarshalAs(UnmanagedType.LPWStr)] string pszText);
|
|
|
|
|
void SetFileNameLabel([MarshalAs(UnmanagedType.LPWStr)] string pszLabel);
|
|
|
|
|
void GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
|
|
|
|
|
void AddPlace([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, int fdap);
|
|
|
|
|
void SetDefaultExtension([MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension);
|
|
|
|
|
void Close(int hr);
|
|
|
|
|
void SetClientGuid([In] ref Guid guid);
|
|
|
|
|
void ClearClientData();
|
|
|
|
|
void SetFilter(IntPtr pFilter);
|
|
|
|
|
void GetResults(out IntPtr ppenum);
|
|
|
|
|
void GetSelectedItems(out IntPtr ppenum);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[ComImport, Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
|
|
|
private interface IShellItem {
|
|
|
|
|
void BindToHandler(IntPtr pbc, [In] ref Guid bhid, [In] ref Guid riid, out IntPtr ppv);
|
|
|
|
|
void GetParent(out IShellItem ppsi);
|
|
|
|
|
void GetDisplayName(int sigdnName, [MarshalAs(UnmanagedType.LPWStr)] out string ppszName);
|
|
|
|
|
void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);
|
|
|
|
|
void Compare(IShellItem psi, uint hint, out int piOrder);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
'@
|
|
|
|
|
|
2026-04-24 19:33:38 +02:00
|
|
|
Add-Type -AssemblyName System.Windows.Forms
|
|
|
|
|
$remoteRoots = @(
|
|
|
|
|
'/mnt/nas12/nas2/RUS',
|
|
|
|
|
'/mnt/da1/foto'
|
|
|
|
|
)
|
|
|
|
|
$encoderDir = Join-Path $PSScriptRoot 'face_encoder_cpu'
|
|
|
|
|
$outputDir = Join-Path $encoderDir 'output'
|
|
|
|
|
|
|
|
|
|
function ConvertTo-PosixSingleQuoted {
|
|
|
|
|
param(
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[string]$Value
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return "'" + $Value.Replace("'", "'`"'`"'") + "'"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Normalize-RemoteRelativePath {
|
|
|
|
|
param(
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[string]$InputPath
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
$normalized = $InputPath.Trim()
|
|
|
|
|
$normalized = $normalized -replace '\\', '/'
|
|
|
|
|
$normalized = $normalized -replace '^/mnt/nas12/nas2/RUS/?', ''
|
|
|
|
|
$normalized = $normalized -replace '^/mnt/da1/foto/?', ''
|
|
|
|
|
$normalized = $normalized -replace '/+', '/'
|
|
|
|
|
$normalized = $normalized.Trim('/')
|
|
|
|
|
|
|
|
|
|
if (-not $normalized) {
|
|
|
|
|
throw 'Il percorso remoto non puo essere vuoto.'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$segments = $normalized -split '/'
|
|
|
|
|
foreach ($segment in $segments) {
|
|
|
|
|
if ([string]::IsNullOrWhiteSpace($segment)) {
|
|
|
|
|
throw 'Il percorso remoto contiene segmenti vuoti non validi.'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($segment -in @('.', '..')) {
|
|
|
|
|
throw 'Il percorso remoto non puo contenere . o ...'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ($segments -join '/')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Join-RemotePath {
|
|
|
|
|
param(
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[string]$Root,
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[string]$RelativePath,
|
|
|
|
|
[string]$LeafName
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
$parts = @($Root.TrimEnd('/'))
|
|
|
|
|
if ($RelativePath) {
|
|
|
|
|
$parts += $RelativePath.Trim('/')
|
|
|
|
|
}
|
|
|
|
|
if ($LeafName) {
|
|
|
|
|
$parts += $LeafName
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ($parts -join '/')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Get-MulticoreSetting {
|
|
|
|
|
Write-Host ''
|
|
|
|
|
Write-Host "Seleziona il livello di multicore per l'elaborazione CPU:"
|
|
|
|
|
Write-Host ' 1 = 1/8 dei core'
|
|
|
|
|
Write-Host ' 2 = 1/4 dei core'
|
|
|
|
|
Write-Host ' 3 = 1/2 dei core (predefinito)'
|
|
|
|
|
Write-Host ' 4 = 3/4 dei core'
|
|
|
|
|
Write-Host ' 5 = n-2 core'
|
|
|
|
|
Write-Host ''
|
|
|
|
|
|
|
|
|
|
$multicoreChoice = Read-Host 'Inserisci il livello (1-5) oppure premi Invio per usare il predefinito (3)'
|
|
|
|
|
if ($multicoreChoice -match '^[1-5]$') {
|
|
|
|
|
return [int]$multicoreChoice
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Show-PklFilePicker {
|
|
|
|
|
param(
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[string]$InitialDirectory
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
$dialog = New-Object System.Windows.Forms.OpenFileDialog
|
|
|
|
|
$dialog.Title = 'Seleziona il file PKL da caricare'
|
|
|
|
|
$dialog.Filter = 'Pickle files (*.pkl)|*.pkl|Tutti i file (*.*)|*.*'
|
|
|
|
|
$dialog.CheckFileExists = $true
|
|
|
|
|
$dialog.Multiselect = $false
|
|
|
|
|
|
|
|
|
|
if (Test-Path -LiteralPath $InitialDirectory) {
|
|
|
|
|
$dialog.InitialDirectory = (Resolve-Path -LiteralPath $InitialDirectory).Path
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($dialog.ShowDialog() -ne [System.Windows.Forms.DialogResult]::OK) {
|
|
|
|
|
return $null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $dialog.FileName
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Invoke-RemoteShellCommand {
|
|
|
|
|
param(
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[string]$Payload,
|
|
|
|
|
[switch]$AllocateTty,
|
|
|
|
|
[switch]$Quiet
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
$remoteCommand = 'sh -c ' + (ConvertTo-PosixSingleQuoted $Payload)
|
|
|
|
|
$sshArgs = [System.Collections.Generic.List[string]]::new()
|
|
|
|
|
if ($AllocateTty) {
|
|
|
|
|
$sshArgs.Add('-tt')
|
|
|
|
|
}
|
|
|
|
|
$sshArgs.Add('-p')
|
|
|
|
|
$sshArgs.Add($remotePort)
|
|
|
|
|
$sshArgs.Add('-o')
|
|
|
|
|
$sshArgs.Add('PreferredAuthentications=password')
|
|
|
|
|
$sshArgs.Add('-o')
|
|
|
|
|
$sshArgs.Add('PubkeyAuthentication=no')
|
|
|
|
|
$sshArgs.Add('-o')
|
|
|
|
|
$sshArgs.Add('StrictHostKeyChecking=accept-new')
|
|
|
|
|
$sshArgs.Add("$remoteUser@$remoteHost")
|
|
|
|
|
$sshArgs.Add($remoteCommand)
|
|
|
|
|
|
|
|
|
|
if ($Quiet) {
|
|
|
|
|
& $sshExe @sshArgs | Out-Null
|
|
|
|
|
} else {
|
|
|
|
|
& $sshExe @sshArgs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $LASTEXITCODE
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Test-RemoteFileExists {
|
|
|
|
|
param(
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[string]$RemotePath
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
$payload = 'test -e ' + (ConvertTo-PosixSingleQuoted $RemotePath)
|
|
|
|
|
$exitCode = Invoke-RemoteShellCommand -Payload $payload -Quiet
|
|
|
|
|
|
|
|
|
|
if ($exitCode -eq 0) {
|
|
|
|
|
return $true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($exitCode -eq 1) {
|
|
|
|
|
return $false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw "Impossibile verificare l'esistenza del file remoto: $RemotePath"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Test-RemoteDirectoryExists {
|
|
|
|
|
param(
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[string]$RemotePath
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
$payload = 'test -d ' + (ConvertTo-PosixSingleQuoted $RemotePath)
|
|
|
|
|
$exitCode = Invoke-RemoteShellCommand -Payload $payload -Quiet
|
2026-04-19 11:05:30 +02:00
|
|
|
|
2026-04-24 19:33:38 +02:00
|
|
|
if ($exitCode -eq 0) {
|
|
|
|
|
return $true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($exitCode -eq 1) {
|
|
|
|
|
return $false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw "Impossibile verificare il percorso remoto: $RemotePath"
|
2026-04-19 11:05:30 +02:00
|
|
|
}
|
|
|
|
|
|
2026-04-24 19:33:38 +02:00
|
|
|
function Ensure-RemoteDirectory {
|
|
|
|
|
param(
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[string]$RemoteDirectory
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
$payload = 'mkdir -p ' + (ConvertTo-PosixSingleQuoted $RemoteDirectory)
|
|
|
|
|
$exitCode = Invoke-RemoteShellCommand -Payload $payload
|
|
|
|
|
if ($exitCode -ne 0) {
|
|
|
|
|
throw "Creazione cartella remota non riuscita: $RemoteDirectory"
|
|
|
|
|
}
|
2026-04-19 17:24:33 +02:00
|
|
|
}
|
|
|
|
|
|
2026-04-24 19:33:38 +02:00
|
|
|
function Upload-FileToRemoteTarget {
|
|
|
|
|
param(
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[string]$LocalFile,
|
|
|
|
|
[Parameter(Mandatory = $true)]
|
|
|
|
|
[string]$RemoteFile,
|
|
|
|
|
[bool]$Overwrite
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
$remoteDirectory = Split-Path -Path $RemoteFile -Parent
|
|
|
|
|
if ([string]::IsNullOrWhiteSpace($remoteDirectory) -or $remoteDirectory -eq '/') {
|
|
|
|
|
throw 'Il percorso remoto destinazione non e valido.'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Test-RemoteDirectoryExists -RemotePath $RemoteFile) {
|
|
|
|
|
throw "La destinazione remota e una cartella, non un file: $RemoteFile"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ensure-RemoteDirectory -RemoteDirectory $remoteDirectory
|
|
|
|
|
|
|
|
|
|
if ((-not $Overwrite) -and (Test-RemoteFileExists -RemotePath $RemoteFile)) {
|
|
|
|
|
Write-Host "Salto upload per file esistente: $RemoteFile"
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$scpArgs = @(
|
|
|
|
|
'-P', $remotePort,
|
|
|
|
|
'-o', 'PreferredAuthentications=password',
|
|
|
|
|
'-o', 'PubkeyAuthentication=no',
|
|
|
|
|
'-o', 'StrictHostKeyChecking=accept-new',
|
|
|
|
|
$LocalFile,
|
|
|
|
|
("{0}@{1}:{2}" -f $remoteUser, $remoteHost, (ConvertTo-PosixSingleQuoted $RemoteFile))
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
& $scpExe @scpArgs
|
|
|
|
|
if ($LASTEXITCODE -ne 0) {
|
|
|
|
|
throw "Caricamento non riuscito verso $RemoteFile"
|
|
|
|
|
}
|
2026-04-19 11:05:30 +02:00
|
|
|
}
|
|
|
|
|
|
2026-04-24 19:33:38 +02:00
|
|
|
function Invoke-FaceEncoding {
|
|
|
|
|
$multicore = Get-MulticoreSetting
|
|
|
|
|
$inputPath = [ModernFolderPicker]::Show('Select the folder containing images to encode')
|
|
|
|
|
|
|
|
|
|
if (-not $inputPath) {
|
|
|
|
|
Write-Host 'Nessuna cartella selezionata. Uscita.'
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$inputFolder = Get-Item -LiteralPath $inputPath -ErrorAction Stop
|
|
|
|
|
$raceName = $inputFolder.Name
|
|
|
|
|
$safeRaceName = ($raceName -replace '[<>:"/\\|?*]', ' ').Trim()
|
|
|
|
|
$safeRaceName = $safeRaceName -replace '\s+', '_'
|
|
|
|
|
if (-not $safeRaceName) {
|
|
|
|
|
$safeRaceName = 'race'
|
|
|
|
|
}
|
2026-04-19 11:05:30 +02:00
|
|
|
|
2026-04-24 19:33:38 +02:00
|
|
|
$timestamp = Get-Date -Format 'yyyyMMdd_HHmmss'
|
|
|
|
|
$outputFile = Join-Path $outputDir ("face_encodings_{0}_{1}.pkl" -f $timestamp, $safeRaceName)
|
|
|
|
|
$logFile = Join-Path $outputDir ("encoder_log_{0}_{1}.txt" -f $timestamp, $safeRaceName)
|
2026-04-19 17:24:33 +02:00
|
|
|
|
2026-04-24 19:33:38 +02:00
|
|
|
New-Item -ItemType Directory -Path $outputDir -Force | Out-Null
|
2026-04-19 17:24:33 +02:00
|
|
|
|
2026-04-24 19:33:38 +02:00
|
|
|
$encoderExe = Join-Path $encoderDir 'face_encoder_cpu.exe'
|
|
|
|
|
$encoderArgs = [System.Collections.Generic.List[string]]::new()
|
|
|
|
|
$encoderArgs.Add('-i')
|
|
|
|
|
$encoderArgs.Add($inputFolder.FullName)
|
|
|
|
|
$encoderArgs.Add('-r')
|
|
|
|
|
$encoderArgs.Add('-o')
|
|
|
|
|
$encoderArgs.Add($outputFile)
|
|
|
|
|
$encoderArgs.Add('-l')
|
|
|
|
|
$encoderArgs.Add($logFile)
|
|
|
|
|
|
|
|
|
|
if ($multicore -ge 0) {
|
|
|
|
|
$encoderArgs.Add('-m')
|
|
|
|
|
$encoderArgs.Add([string]$multicore)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Write-Host "Input folder : $($inputFolder.FullName)"
|
|
|
|
|
Write-Host "Race name : $raceName"
|
|
|
|
|
Write-Host "Multicore : $(if ($multicore -ge 0) { $multicore } else { 'default (3)' })"
|
|
|
|
|
Write-Host "Output file : $outputFile"
|
|
|
|
|
Write-Host "Log file : $logFile"
|
|
|
|
|
Write-Host "Command : $encoderExe $encoderArgs"
|
|
|
|
|
Write-Host ''
|
|
|
|
|
|
|
|
|
|
& $encoderExe @encoderArgs
|
|
|
|
|
$encoderExitCode = $LASTEXITCODE
|
|
|
|
|
|
|
|
|
|
if ($encoderExitCode -eq 0 -and (Test-Path -LiteralPath $outputFile)) {
|
|
|
|
|
Start-Process explorer.exe "/select,`"$outputFile`""
|
|
|
|
|
} elseif ($encoderExitCode -eq 0) {
|
|
|
|
|
Write-Warning "Encoding completed, but the expected output file was not found: $outputFile"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $encoderExitCode
|
2026-04-19 17:24:33 +02:00
|
|
|
}
|
|
|
|
|
|
2026-04-24 19:33:38 +02:00
|
|
|
function Invoke-PklUpload {
|
|
|
|
|
New-Item -ItemType Directory -Path $outputDir -Force | Out-Null
|
|
|
|
|
|
|
|
|
|
$selectedFile = Show-PklFilePicker -InitialDirectory $outputDir
|
|
|
|
|
if (-not $selectedFile) {
|
|
|
|
|
Write-Host 'Nessun file selezionato. Uscita.'
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$fileInfo = Get-Item -LiteralPath $selectedFile -ErrorAction Stop
|
|
|
|
|
$relativeInput = Read-Host 'Inserisci il percorso relativo sotto RUS/foto (esempio: 2026/04.APRILE/ISOLOTTO)'
|
|
|
|
|
$relativePath = Normalize-RemoteRelativePath -InputPath $relativeInput
|
|
|
|
|
|
|
|
|
|
$targets = foreach ($root in $remoteRoots) {
|
|
|
|
|
[pscustomobject]@{
|
|
|
|
|
Root = $root
|
|
|
|
|
RemoteFile = Join-RemotePath -Root $root -RelativePath $relativePath -LeafName $fileInfo.Name
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Write-Host ''
|
|
|
|
|
Write-Host 'Destinazioni remote:'
|
|
|
|
|
foreach ($target in $targets) {
|
|
|
|
|
Write-Host (" - {0}" -f $target.RemoteFile)
|
|
|
|
|
}
|
|
|
|
|
Write-Host ''
|
|
|
|
|
|
|
|
|
|
$existingTargets = @($targets | Where-Object { Test-RemoteFileExists -RemotePath $_.RemoteFile })
|
|
|
|
|
$overwrite = $false
|
|
|
|
|
if ($existingTargets.Count -gt 0) {
|
|
|
|
|
Write-Host 'Il file esiste gia nelle seguenti destinazioni:'
|
|
|
|
|
foreach ($target in $existingTargets) {
|
|
|
|
|
Write-Host (" - {0}" -f $target.RemoteFile)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$choice = Read-Host 'Vuoi sovrascrivere i file esistenti? (s/N)'
|
|
|
|
|
if ($choice -match '^(s|si|y|yes)$') {
|
|
|
|
|
$overwrite = $true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach ($target in $targets) {
|
|
|
|
|
Upload-FileToRemoteTarget -LocalFile $fileInfo.FullName -RemoteFile $target.RemoteFile -Overwrite:$overwrite
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Write-Host ''
|
|
|
|
|
Write-Host 'Caricamento completato.'
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Write-Host ''
|
|
|
|
|
Write-Host 'Seleziona un''opzione:'
|
|
|
|
|
Write-Host ' 1. Elaborazione riconoscimento facciale'
|
|
|
|
|
Write-Host ' 2. Caricamento'
|
|
|
|
|
Write-Host ''
|
|
|
|
|
|
|
|
|
|
$mode = $null
|
|
|
|
|
while ($mode -notin @('1', '2')) {
|
|
|
|
|
$mode = Read-Host 'Inserisci 1 o 2'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if ($mode -eq '1') {
|
|
|
|
|
$exitCode = Invoke-FaceEncoding
|
|
|
|
|
} else {
|
|
|
|
|
$exitCode = Invoke-PklUpload
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
exit $exitCode
|
|
|
|
|
} catch {
|
|
|
|
|
Write-Error $_
|
|
|
|
|
exit 1
|
|
|
|
|
}
|