diff --git a/Deploy-LoginMonitor.ps1 b/Deploy-LoginMonitor.ps1 index f2d9486..ca31e7e 100644 --- a/Deploy-LoginMonitor.ps1 +++ b/Deploy-LoginMonitor.ps1 @@ -973,12 +973,35 @@ function Stop-RdpLoginMonitorMainProcesses { } } +function Convert-RdpMonitorDeployTaskExecutionTimeLimitValue { + param($Limit) + + if ($null -eq $Limit) { return $null } + if ($Limit -is [TimeSpan]) { return $Limit } + + $text = [string]$Limit + if ([string]::IsNullOrWhiteSpace($text)) { return $null } + $t = $text.Trim() + if ($t -eq 'PT0S') { return [TimeSpan]::Zero } + + try { + return [System.Xml.XmlConvert]::ToTimeSpan($t) + } catch { } + + try { + return [TimeSpan]::Parse($t) + } catch { } + + return $null +} + function Test-RdpMonitorDeployTaskExecutionLimitUnlimitedValue { param($Limit) - if ($null -eq $Limit -or $Limit -isnot [TimeSpan]) { return $false } - if ($Limit.Ticks -le 0) { return $true } - if ($Limit.TotalDays -ge 999) { return $true } + $normalized = Convert-RdpMonitorDeployTaskExecutionTimeLimitValue -Limit $Limit + if ($null -eq $normalized) { return $false } + if ($normalized.Ticks -le 0) { return $true } + if ($normalized.TotalDays -ge 999) { return $true } return $false } @@ -987,9 +1010,9 @@ function Get-RdpMonitorDeployTaskExecutionTimeLimitLabelFromResolved { if ($null -eq $Resolved) { return '(null)' } if ($Resolved.Source -eq 'missing') { return '(task missing)' } - $limit = $Resolved.Limit + $limit = Convert-RdpMonitorDeployTaskExecutionTimeLimitValue -Limit $Resolved.Limit if ($null -eq $limit) { return '(null)' } - if ($limit -is [TimeSpan] -and $limit.Ticks -le 0) { return 'PT0S' } + if ($limit.Ticks -le 0) { return 'PT0S' } return $limit.ToString() } @@ -1019,33 +1042,63 @@ function Publish-RdpMonitorDeployTaskQueryFunctionsToScriptScope { } } -function Import-RdpMonitorDeployTaskQueryModule { - param([string]$ShareRoot = '') +function Import-RdpMonitorDeployTaskQueryModuleAtPath { + param( + [Parameter(Mandatory = $true)][string]$Candidate + ) - $candidates = [System.Collections.Generic.List[string]]::new() - if (-not [string]::IsNullOrWhiteSpace($ShareRoot)) { - $candidates.Add((Join-Path $ShareRoot 'RdpMonitor-TaskQuery.ps1')) | Out-Null - } - $deployScriptPath = $PSCommandPath - if ([string]::IsNullOrWhiteSpace($deployScriptPath)) { $deployScriptPath = $MyInvocation.MyCommand.Path } - if (-not [string]::IsNullOrWhiteSpace($deployScriptPath)) { - $candidates.Add((Join-Path (Split-Path -Parent $deployScriptPath) 'RdpMonitor-TaskQuery.ps1')) | Out-Null - } - $candidates.Add((Join-Path $InstallRoot 'RdpMonitor-TaskQuery.ps1')) | Out-Null + if (-not (Test-Path -LiteralPath $Candidate)) { return $false } - foreach ($candidate in @($candidates)) { - if (-not (Test-Path -LiteralPath $candidate)) { continue } - try { - . $candidate - } catch { - Write-DeployLog "Предупреждение: не удалось загрузить $candidate — $($_.Exception.Message)" - continue + $loadPath = $Candidate + $tempCopy = $null + try { + if ($Candidate.StartsWith('\\')) { + $tempCopy = Join-Path $env:TEMP ("rdp-taskquery-{0}.ps1" -f [guid]::NewGuid().ToString('N')) + Copy-Item -LiteralPath $Candidate -Destination $tempCopy -Force + $loadPath = $tempCopy } + . $loadPath if (Test-RdpMonitorDeployTaskQueryReady) { Publish-RdpMonitorDeployTaskQueryFunctionsToScriptScope return $true } - Write-DeployLog "Предупреждение: $candidate загружен, но функции TaskQuery недоступны — пробуем следующий источник." + Write-DeployLog "Предупреждение: $Candidate загружен, но функции TaskQuery недоступны — пробуем следующий источник." + } catch { + Write-DeployLog "Предупреждение: не удалось загрузить $Candidate — $($_.Exception.Message)" + } finally { + if ($null -ne $tempCopy -and (Test-Path -LiteralPath $tempCopy)) { + Remove-Item -LiteralPath $tempCopy -Force -ErrorAction SilentlyContinue + } + } + return $false +} + +function Import-RdpMonitorDeployTaskQueryModule { + param([string]$ShareRoot = '') + + $candidates = [System.Collections.Generic.List[string]]::new() + $installCandidate = Join-Path $InstallRoot 'RdpMonitor-TaskQuery.ps1' + $candidates.Add($installCandidate) | Out-Null + + $deployScriptPath = $PSCommandPath + if ([string]::IsNullOrWhiteSpace($deployScriptPath)) { $deployScriptPath = $MyInvocation.MyCommand.Path } + if (-not [string]::IsNullOrWhiteSpace($deployScriptPath)) { + $deployCandidate = Join-Path (Split-Path -Parent $deployScriptPath) 'RdpMonitor-TaskQuery.ps1' + if ($deployCandidate -ne $installCandidate) { + $candidates.Add($deployCandidate) | Out-Null + } + } + if (-not [string]::IsNullOrWhiteSpace($ShareRoot)) { + $shareCandidate = Join-Path $ShareRoot 'RdpMonitor-TaskQuery.ps1' + if ($shareCandidate -ne $installCandidate -and -not ($candidates -contains $shareCandidate)) { + $candidates.Add($shareCandidate) | Out-Null + } + } + + foreach ($candidate in @($candidates)) { + if (Import-RdpMonitorDeployTaskQueryModuleAtPath -Candidate $candidate) { + return $true + } } return $false } diff --git a/Login_Monitor.ps1 b/Login_Monitor.ps1 index 6f1e9cf..f9fc967 100644 --- a/Login_Monitor.ps1 +++ b/Login_Monitor.ps1 @@ -90,7 +90,7 @@ $script:SkipLogDetailLimit = 15 # строки ниже, если правки «мелкие» и вы не хотите менять отображаемую версию в логах). # Рекомендация: при значимых релизах меняйте и $ScriptVersion, и version.txt одинаково; при только # исправлениях на шаре — достаточно поднять patch в version.txt (например 1.3.0.1). -$ScriptVersion = "2.0.32-SAC" +$ScriptVersion = "2.0.33-SAC" # Логи (все под InstallRoot) $LogFile = Join-Path $script:InstallRoot "Logs\login_monitor.log" diff --git a/RdpMonitor-TaskQuery.ps1 b/RdpMonitor-TaskQuery.ps1 index bdb1904..5efd982 100644 --- a/RdpMonitor-TaskQuery.ps1 +++ b/RdpMonitor-TaskQuery.ps1 @@ -87,13 +87,21 @@ function Get-RdpMonitorScheduledTaskActionFromDocument { } } +function Convert-RdpMonitorScheduledTaskExecutionTimeLimitValue { + param($Limit) + + if ($null -eq $Limit) { return $null } + if ($Limit -is [TimeSpan]) { return $Limit } + return Convert-RdpMonitorScheduledTaskExecutionTimeLimitText -LimitText ([string]$Limit) +} + function Test-RdpMonitorScheduledTaskExecutionTimeLimitUnlimitedValue { param($Limit) - if ($null -eq $Limit) { return $false } - if ($Limit -isnot [TimeSpan]) { return $false } - if ($Limit.Ticks -le 0) { return $true } - if ($Limit.TotalDays -ge 999) { return $true } + $normalized = Convert-RdpMonitorScheduledTaskExecutionTimeLimitValue -Limit $Limit + if ($null -eq $normalized) { return $false } + if ($normalized.Ticks -le 0) { return $true } + if ($normalized.TotalDays -ge 999) { return $true } return $false } @@ -153,9 +161,9 @@ function Get-RdpMonitorScheduledTaskExecutionTimeLimitLabel { $resolved = Get-RdpMonitorScheduledTaskExecutionTimeLimitResolved -TaskName $TaskName if ($resolved.Source -eq 'missing') { return '(task missing)' } - $limit = $resolved.Limit + $limit = Convert-RdpMonitorScheduledTaskExecutionTimeLimitValue -Limit $resolved.Limit if ($null -eq $limit) { return '(null)' } - if ($limit -is [TimeSpan] -and $limit.Ticks -le 0) { return 'PT0S' } + if ($limit.Ticks -le 0) { return 'PT0S' } return $limit.ToString() } diff --git a/tools/tests/Test-DeployTaskLimit.ps1 b/tools/tests/Test-DeployTaskLimit.ps1 index 235a4fd..9777277 100644 --- a/tools/tests/Test-DeployTaskLimit.ps1 +++ b/tools/tests/Test-DeployTaskLimit.ps1 @@ -7,6 +7,17 @@ Invoke-RdpMonitorTestCase -Name 'Deploy functions load (RDP_DEPLOY_FUNCTIONS_ONL Assert-CommandExists -Name 'Test-RdpMonitorDeployMainTaskNeedsUnlimitedExecutionTime' Assert-CommandExists -Name 'Write-RdpMonitorDeployScheduledTaskVerification' Assert-CommandExists -Name 'Get-RdpMonitorDeployTaskExecutionTimeLimitLabelFromResolved' + Assert-CommandExists -Name 'Convert-RdpMonitorDeployTaskExecutionTimeLimitValue' +} + +Invoke-RdpMonitorTestCase -Name 'Deploy ExecutionTimeLimit accepts PT0S string (Get-ScheduledTask shape)' -Script { + Assert-True -Condition (Test-RdpMonitorDeployTaskExecutionLimitUnlimitedValue -Limit 'PT0S') ` + -Message 'PT0S string must be treated as unlimited' + $resolved = [pscustomobject]@{ Limit = 'PT0S'; Source = 'Get-ScheduledTask' } + $label = Get-RdpMonitorDeployTaskExecutionTimeLimitLabelFromResolved -Resolved $resolved + Assert-True -Condition ($label -eq 'PT0S') -Message "Expected PT0S label, got $label" + Assert-True -Condition (Test-RdpMonitorDeployTaskExecutionLimitUnlimitedValue -Limit $resolved.Limit) ` + -Message 'Resolved PT0S string must pass unlimited check' } Invoke-RdpMonitorTestCase -Name 'Deploy pre-check task limit (no throw on early path)' -Script { diff --git a/version.txt b/version.txt index 684bc8e..18bed85 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -2.0.32-SAC +2.0.33-SAC