The log might not be matching because I stripped the script down by a lot. The full script has a lot of stuff that should be irrelevant to the issue but here it is:
#Make PSScriptRoot available in psISE
$PSScriptRootFix = $MyInvocation.MyCommand.Path | Split-Path -Parent
#Load WinSCP .NET assembly
$winSCPPath = if ($env:WINSCP_PATH) { $env:WINSCP_PATH } else { "$PSScriptRootFix\WinSCPNETAssembly" }
$tempSCPPath = "C:\temp\WinSCPNETAssembly"
$tempAssemblyPath = (Join-Path $tempSCPPath "WinSCPnet.dll")
Copy-Item -Path $winSCPPath -Destination $tempSCPPath -Recurse -Force
Add-Type -Path $tempAssemblyPath
[string]$script:sftpServer = "***.***.***.***"
[string]$script:username = "******"
[string]$script:password = "******"
[string]$script:fingerprint = "******"
[int]$script:port = 65535
$scplogpath = "$PSScriptRootFix\logs\script.log"
#region Functions
function Write-ConsoleLog {
param (
[string]$message,
[System.ConsoleColor]$foregroundColor = "White",
[switch]$noNewLine
)
$params = @{}
if ($noTime -eq 1) {
$params["Object"] = "$message"
$params["ForegroundColor"] = $foregroundColor
$script:noTime = 0
} else {
$params["Object"] = "$(Get-Date -Format 'yyyy-MM-ddThh:mm:ss') $message"
$params["ForegroundColor"] = $foregroundColor
}
if ($noNewLine) {
$params["NoNewLine"] = $true
$script:noTime = 1
}
Write-Host @params
}
function New-WinSCPSession {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string]$sftpServer,
[Parameter(Mandatory)]
[string]$username,
[string]$password = "",
[string]$fingerprint,
[int]$port,
[string]$logpath = ""
)
begin {
#PSCredential
$securePassword = ConvertTo-SecureString -String $password -AsPlainText -Force
#SFTP SessionParameters
if ($port) {
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
Protocol = [WinSCP.Protocol]::Sftp
HostName = $sftpServer
UserName = $username
SecurePassword = $securePassword
SshHostKeyFingerprint = $fingerprint
PortNumber = $port
}
}
else {
$sessionOptions = New-Object WinSCP.SessionOptions -Property @{
Protocol = [WinSCP.Protocol]::Sftp
Hostname = $sftpServer
Username = $username
SecurePassword = $securePassword
SshHostKeyFingerprint = $fingerprint
}
}
}
process {
$session = New-Object WinSCP.Session
$session.SessionLogPath = $logpath
$session.Open($sessionOptions)
}
end {
return $session
}
}
function Get-SFTPFiles {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[WinSCP.Session]$SCPsession,
[Parameter(Mandatory)]
[string]$remotePath
)
begin {
#Hashtable for the remote files
$remoteFilesHashTable = @{}
}
process {
Write-ConsoleLog "Getting SFTP Child-Item $remotePath" Cyan
$remoteFiles = $script:SCPsession.EnumerateRemoteFiles($remotePath, $null, [WinSCP.EnumerationOptions]::AllDirectories)
Write-ConsoleLog "Populating Hashtable... " Cyan -NoNewline
$filecounter = 1
foreach ($file in $remoteFiles) {
$remoteFilesHashTable["file_$filecounter"] = [PSCustomObject]@{
Name = $file.Name
Path = $file.FullName
Size = $file.Length
LastWriteTime = $file.LastWriteTime
Quartal = ""
}
$filecounter += 1
}
Write-ConsoleLog "Done" Green
}
end {
return $remoteFilesHashTable
}
}
function Get-LocalFiles {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
$localPath
)
begin {
#Hashtable for local Files
$localFilesHashTable = @{}
}
process {
Write-ConsoleLog "Getting Local Child-Item $localpath ... " Cyan -NoNewline
$localPath = $localPath.trimstart("\\")
$localFiles = Get-ChildItem -Path "\\?\UNC\$localPath" -Recurse | Where-Object { -not $_.PSIsContainer }
$filecounter = 1
foreach ($file in $localFiles) {
$localFilesHashTable["file_$filecounter"] = [PSCustomObject]@{
Name = $file.Name
Path = $file.FullName
Size = $file.Length
LastWriteTime = $file.LastWriteTime
Quartal = ""
}
$filecounter += 1
}
Write-ConsoleLog "Done" Green
}
end {
return $localFilesHashTable
}
}
#endregion
#region Main
#SFTP Session
$SCPsession = New-WinSCPSession -sftpServer $sftpServer -username $username -password $password -fingerprint $fingerprint -port $port -logpath $scplogpath
#Collect Files
$eFiles = Get-SFTPFiles -SCPsession $SCPsession -remotePath "/Downloads/"
$anKFiles = Get-SFTPFiles -SCPsession $SCPsession -remotePath "/anK/"
#Quartale setzen
$eQuartale = @()
foreach ($file in $eFiles.Keys) {
if ($eFiles[$file].Path -match "/Downloads/[\d]{4}-[1-4]/.*") {
$remoteQ = ($eFiles[$file].Path -split "/")[4]
$localQ = $remoteQ -replace "-", ""
$eFiles[$file].Quartal = $localQ
if ($eQuartale -notcontains $localQ) {
$eQuartale += $localQ
}
}
}
$eMissingFiles = @{}
#local files
$noQFolders = Get-LocalFiles -localPath "\\fileserver\noQ\" #Hashtable für Quartalsunabhängige Dateien
#$gQuartale = Get-ChildItem -Path "\\fileserver\dep\" | where { $_.Name -match "[\d]{4}[1-4]" } | Sort-Object Name #lokale Quartale
$gQuartale = Get-ChildItem -Path "\\fileserver\dep\" | where { $_.Name -match "2024[1-4]" } | Sort-Object Name #lokale Quartale nur 2024 (zum Test)
$gQuartalHashtables = @{}
#Get local Q Files
foreach ($q in $eQuartale) {
if (Test-Path "\\fileserver\dep\$q\G") {
$gQuartalHashtables = Get-LocalFiles -localPath "\\fileserver\dep\$q\G"
}
}
#Get missing/altered files
foreach ($file in $eFiles.Keys) {
Write-Host "$($eFiles[$file].Name)... "-NoNewline
if (($eFiles[$file].Quartal).length -gt 0) {
$localQ = $eFiles[$file].Quartal
if ($gQuartalHashtables.ContainsKey($localQ)) {
if ($gQuartalHashtables[$localQ].ContainsKey($file)) {
if ($gQuartalHashtables[$localQ][$file].Size -ne $eFiles[$file].Size -or $gQuartalHashtables[$localQ][$file].LastWriteTime -ne $eFiles[$file].LastWriteTime ) {
$eMissingFiles[$file] = $eFiles[$file]
Write-Host "found but different attributes"
}
else {
Write-Host "found"
}
}
else {
$eMissingFiles[$file] = $eFiles[$file]
Write-Host "missing"
}
}
else {
Write-Host "kein Quartal"
}
}
else {
$eFiles[$file].Quartal = "Quartalsunabhaengig"
if ($noQGFolders.ContainsKey($file)) {
if ($noQGFolders[$file].Size -ne $eFiles[$file].Size -or $noQGFolders[$file].LastWriteTime -ne $eFiles[$file].LastWriteTime ) {
$eMissingFiles[$file] = $eFiles[$file]
Write-Host "found but different attributes"
}
else {
Write-Host "found"
}
}
else {
$eMissingFiles[$file] = $eFiles[$file]
Write-Host "missing"
}
}
}
#Download missing/altered files
foreach ($file in $eMissingFiles.Keys) {
$remotepath = $eMissingFiles[$file].Path
if ($eMissingFiles[$file].Quartal -match "Quartalsunabhaengig") {
$remotePathRel = $remotepath -replace "/Downloads/noQ",""
$localpath = Join-Path "\\fileserver\noQ\" $remotePathRel | Split-Path -Parent
}
else {
$remoteQ = "$(($eMissingFiles[$file].Quartal).Substring(0,4))-$(($eMissingFiles[$file].Quartal).Substring(4,1))"
$remotePathRel = $remotepath -replace "/Downloads/$remoteQ",""
$localpath = Join-Path "\\fileserver\dep\$($eMissingFiles[$file].Quartal)\G" $remotePathRel | Split-Path -Parent
}
Write-ConsoleLog "Downloading $file to $localpath" Cyan
$SCPsession.GetFileToDirectory($remotepath,$localpath,$false,$null)
}
$SCPsession.Close()
Remove-Item -Path $tempAssemblyPath
Read-Host "Press Enter to Continue"
Now the log should match with the script. I have only renamed some paths so they might still be off.