#Requires -Version 3.0 <# app-client-utils — збір діагностики. Нічого не змінює. Паролі не читає і не записує. Результат: C:\tl-diag-.txt #> $ErrorActionPreference = 'SilentlyContinue' $TaskName = 'TerraLab app-client-utils' $DataDir = Join-Path $env:ProgramData 'app-client-utils' $Report = Join-Path $env:SystemDrive "tl-diag-$env:COMPUTERNAME.txt" $Lines = New-Object System.Collections.Generic.List[string] function W([string]$s = '') { $Lines.Add($s) } function Section([string]$t) { W ''; W ('=' * 72); W "== $t"; W ('=' * 72) } function Dump($o) { W (($o | Format-List * | Out-String).Trim()) } Section 'ЗАГАЛЬНЕ' W "час звіту : $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss K')" W "комп'ютер : $env:COMPUTERNAME" W "скрипт запущено як : $(whoami)" $isAdmin = ([Security.Principal.WindowsPrincipal] ` [Security.Principal.WindowsIdentity]::GetCurrent() ).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) W "права адміністратора: $isAdmin" if (-not $isAdmin) { W '!!! БЕЗ ПРАВ АДМІНА частина даних буде порожня. Запустіть tl-diag.cmd (він сам підніме права).' } $cs = Get-WmiObject Win32_ComputerSystem W "у домені : $($cs.PartOfDomain)" W "домен / робоча група: $($cs.Domain)" W "ОС : $((Get-WmiObject Win32_OperatingSystem).Caption) / $([Environment]::OSVersion.Version)" W "остання загрузка : $((Get-WmiObject Win32_OperatingSystem).ConvertToDateTime((Get-WmiObject Win32_OperatingSystem).LastBootUpTime))" # ---------------------------------------------------------------- задача Section 'ЗАДАЧА ПЛАНУВАЛЬНИКА — це найважливіший блок' $task = Get-ScheduledTask -TaskName $TaskName if (-not $task) { W 'ЗАДАЧУ НЕ ЗНАЙДЕНО. Інсталятор її не створив або її видалили.' $acct = $null } else { $acct = $task.Principal.UserId W "акаунт задачі (UserId): $acct" W "LogonType : $($task.Principal.LogonType)" W "RunLevel : $($task.Principal.RunLevel)" W "стан : $($task.State)" $info = $task | Get-ScheduledTaskInfo $rc = $info.LastTaskResult W "останній запуск : $($info.LastRunTime)" W ("КОД ОСТАННЬОГО ЗАПУСКУ: {0} (0x{1:X8})" -f $rc, $rc) switch ($rc) { 0x2147943785 { W ' -> ERROR_LOGON_TYPE_NOT_GRANTED: акаунту бракує права "Log on as a batch job".' } 0x8007052E { W ' -> невірний логін або пароль.' } 0x00041303 { W ' -> задача жодного разу не запускалась (тригер не спрацював).' } 0x00041301 { W ' -> задача зараз виконується.' } 0 { W ' -> запуск без помилки (0). Дивіться launcher.log нижче.' } 1 { W ' -> процес завершився з кодом 1: стартував run-agent.cmd і впав. Дивіться launcher.log.' } default { W ' -> див. таблицю кодів Task Scheduler.' } } W '' W '--- повний XML задачі (пароля тут немає, Windows тримає його в LSA) ---' W ((schtasks /Query /TN "$TaskName" /XML 2>&1 | Out-String).Trim()) } # ---------------------------------------------------------------- право batch logon Section 'ПРАВО "LOG ON AS A BATCH JOB" (SeBatchLogonRight)' if ($isAdmin) { $inf = Join-Path $env:TEMP 'tl-ur.inf' secedit /export /areas USER_RIGHTS /cfg $inf 2>&1 | Out-Null $line = (Select-String -Path $inf -Pattern '^SeBatchLogonRight').Line Remove-Item $inf -Force if (-not $line) { W 'SeBatchLogonRight у локальній політиці не заданий (діють дефолти: Administrators, Backup Operators).' } else { W "сирий рядок політики: $line" W '' W 'кому надано:' foreach ($t in ($line -split '=')[1] -split ',') { $t = $t.Trim() $name = $t if ($t.StartsWith('*')) { $name = (New-Object Security.Principal.SecurityIdentifier($t.TrimStart('*')) ).Translate([Security.Principal.NTAccount]).Value } W " $t -> $name" } } } else { W '(пропущено — потрібні права адміна)' } if ($acct) { W '' W "--- акаунт задачі '$acct' ---" $sid = $null try { $probe = if ($acct.StartsWith('.\')) { "$env:COMPUTERNAME\" + $acct.Substring(2) } else { $acct } $sid = (New-Object Security.Principal.NTAccount($probe) ).Translate([Security.Principal.SecurityIdentifier]).Value W "SID: $sid" } catch { W "SID: НЕ ВДАЛОСЯ РОЗІМЕНУВАТИ ('$acct' — такого акаунта не існує?)" } $short = $acct.Split('\')[-1] $isLocal = Get-WmiObject Win32_UserAccount -Filter "LocalAccount=True AND Name='$short'" W "локальний акаунт: $([bool]$isLocal)" if ($isLocal) { W " вимкнений : $($isLocal.Disabled)" W " пароль не спливає: $($isLocal.PasswordExpires -eq $false)" } W '' W 'net user (групи, стан пароля):' W ((net user $short 2>&1 | Out-String).Trim()) $adm = net localgroup Administrators 2>&1 W '' W "у локальній групі Administrators: $([bool]($adm | Select-String -SimpleMatch $short))" } # ---------------------------------------------------------------- журнали Section 'ЖУРНАЛ ПЛАНУВАЛЬНИКА (останні події про нашу задачу)' $ev = Get-WinEvent -LogName Microsoft-Windows-TaskScheduler/Operational -MaxEvents 300 | Where-Object { $_.Message -like '*app-client-utils*' } | Select-Object -First 25 if ($ev) { foreach ($e in $ev) { W "[$($e.TimeCreated)] id=$($e.Id) $($e.LevelDisplayName)"; W " $(($e.Message -split "`n")[0])" } } else { W '(подій немає; журнал Operational може бути вимкнений)' } Section 'ВІДМОВИ ЛОГОНУ (Security 4625) — шукаємо Logon Type 4' if ($isAdmin) { $f = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625} -MaxEvents 15 if ($f) { foreach ($e in $f) { W "[$($e.TimeCreated)]"; W (($e.Message -split "`n" | Select-String 'Logon Type|Account Name|Status|Sub Status|Failure Reason' | Out-String).Trim()); W '' } } else { W '(відмов логону не знайдено)' } } else { W '(пропущено — потрібні права адміна)' } # ---------------------------------------------------------------- наш процес Section 'ЧИ ПРАЦЮЄ АГЕНТ' $javaw = Get-WmiObject Win32_Process -Filter "Name='javaw.exe'" | Where-Object { $_.CommandLine -like '*app-client-utils*' } if ($javaw) { foreach ($p in $javaw) { $o = $p.GetOwner() W "javaw.exe pid=$($p.ProcessId) власник=$($o.Domain)\$($o.User)" W " cmdline: $($p.CommandLine)" } } else { W 'процесу javaw.exe з app-client-utils НЕМАЄ.' } W '' W 'слухачі порту 8089:' W ((netstat -ano | Select-String ':8089' | Out-String).Trim()) W '' W 'HTTP-перевірка http://127.0.0.1:8089/api/v1/client-utils/printers :' try { $r = Invoke-WebRequest -Uri 'http://127.0.0.1:8089/api/v1/client-utils/printers' -UseBasicParsing -TimeoutSec 5 W " HTTP $($r.StatusCode)" W " тіло: $($r.Content)" } catch { W " немає відповіді: $($_.Exception.Message)" } # ---------------------------------------------------------------- файли Section 'ФАЙЛИ ТА ПРАВА' foreach ($d in @("${env:ProgramFiles(x86)}\app-client-utils", "$env:ProgramFiles\app-client-utils")) { W "$d : $(if (Test-Path $d) {'Є'} else {'немає'})" if (Test-Path $d) { W ((Get-ChildItem $d | Select-Object Name,Length,LastWriteTime | Format-Table -Auto | Out-String).Trim()) } } W '' W "$DataDir : $(if (Test-Path $DataDir) {'Є'} else {'НЕМАЄ'})" if (Test-Path $DataDir) { W ((Get-ChildItem $DataDir -Recurse | Select-Object FullName,Length,LastWriteTime | Format-Table -Auto | Out-String).Trim()) W '' W 'ACL на каталог даних (акаунт задачі мусить мати Modify):' W ((icacls $DataDir 2>&1 | Out-String).Trim()) $ps = Join-Path $DataDir 'print_setting.json' W '' W "print_setting.json: $(if (Test-Path $ps) {'Є — принтери обрані'} else {'НЕМАЄ — принтери жодного разу не обиралися в UI'})" } Section 'LAUNCHER.LOG (останні 40 рядків)' $log = Join-Path $DataDir 'logs\launcher.log' if (Test-Path $log) { W ((Get-Content $log -Tail 40 | Out-String).TrimEnd()) } else { W 'launcher.log НЕМАЄ — run-agent.cmd не запускався жодного разу. Значить зламалось ДО нашого коду, на логоні задачі.' } Section 'ЗАЛИШКИ СТАРИХ ВЕРСІЙ' W "служба app-client-utils: $((sc.exe query app-client-utils 2>&1 | Out-String).Trim())" W '' W 'autorun-значення у профілях (era 2):' Get-ChildItem Registry::HKEY_USERS | ForEach-Object { $p = "Registry::$($_.Name)\Software\Microsoft\Windows\CurrentVersion\Run" $v = (Get-ItemProperty -Path $p -Name 'app-client-utils').'app-client-utils' if ($v) { W " $($_.Name) -> $v" } } # ---------------------------------------------------------------- підсумок Section 'КОРОТКИЙ ВИСНОВОК ДЛЯ ЛЮДИНИ' if (-not $task) { W 'Задачі немає — інсталяція не завершилась.' } elseif ($info.LastTaskResult -eq 0x2147943785) { W 'ПІДТВЕРДЖЕНО: акаунту бракує права "Log on as a batch job".' W 'Агент фізично не може стартувати. Це треба правити в інсталяторі.' } elseif (-not (Test-Path $log)) { W 'Задача є, але run-agent.cmd жодного разу не виконався -> проблема на логоні задачі, не в застосунку.' } elseif (-not $javaw) { W 'run-agent.cmd виконувався, але процес не живий. Дивіться launcher.log вище.' } else { W 'Процес живий. Якщо принтерів немає — питання до профілю акаунта або до принт-сервера, а не до запуску.' } # ---------------------------------------------------------------- запис $Lines | Out-File -FilePath $Report -Encoding UTF8 Write-Host '' Write-Host '========================================================' -ForegroundColor Green Write-Host " Звіт збережено: $Report" -ForegroundColor Green Write-Host ' Надішліть ЦЕЙ ФАЙЛ. Паролів у ньому немає.' -ForegroundColor Green Write-Host '========================================================' -ForegroundColor Green