#Requires -Version 3.0 <# app-client-utils — діагностика, крок 3. Read-only. Єдина мета: дістати Status / SubStatus невдалих batch-логонів. У кроці 2 я читав поля події за числовими індексами — імена й LogonType зчитались, а Status/SubStatus вийшли порожні. Тут поля беруться за ІМЕНАМИ з XML події, тож ні локаль, ні порядок полів більше не впливають. Результат: C:\tl-diag3-.txt #> $ErrorActionPreference = 'SilentlyContinue' $TaskName = 'TerraLab app-client-utils' $Report = Join-Path $env:SystemDrive "tl-diag3-$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) } # Поля події за іменами: 0xc000015b function Get-EventData($e) { $h = @{} foreach ($n in ([xml]$e.ToXml()).Event.EventData.Data) { $h[$n.Name] = $n.'#text' } $h } function Explain([string]$code) { switch -Regex ($code) { '0xc000015b' { 'LOGON_TYPE_NOT_GRANTED — акаунту не дозволено batch-логон. ЦЕ НАШ ДІАГНОЗ.' } '0xc000006a' { 'WRONG_PASSWORD — невірний пароль.' } '0xc0000064' { 'NO_SUCH_USER — такого акаунта немає.' } '0xc0000072' { 'ACCOUNT_DISABLED' } '0xc0000070' { 'INVALID_WORKSTATION — обмеження "Разрешенные рабочие станции".' } '0xc0000071' { 'PASSWORD_EXPIRED' } '0xc0000234' { 'ACCOUNT_LOCKED_OUT' } '0xc000006d' { '(загальний STATUS_LOGON_FAILURE — дивись SubStatus)' } '0x0' { '-' } default { '(код не з нашого списку)' } } } $PrintAcct = $env:TL_PRINT_ACCOUNT if (-not $PrintAcct) { Write-Host '' Write-Host 'Введіть назву облікового запису друку (той, що вводили в інсталяторі).' -ForegroundColor Cyan $PrintAcct = Read-Host 'Акаунт' } $short = $PrintAcct.Split('\')[-1] 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 '!!! ЗАПУСТІТЬ ВІД ІМЕНІ АДМІНІСТРАТОРА.' } # WMI на цій станції двічі повернув порожнечу — беремо з реєстру та змінних. $cv = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' W "ОС : $($cv.ProductName) $($cv.DisplayVersion) build $($cv.CurrentBuild)" W "домен (DNS) : $env:USERDNSDOMAIN" W "акаунт друку: $PrintAcct" # ---------------------------------------------------------------- ГОЛОВНЕ Section 'НЕВДАЛІ ВХОДИ 4625 — Status / SubStatus за іменами полів' if ($isAdmin) { $ev = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625} -MaxEvents 60 $batch = @() foreach ($e in $ev) { $d = Get-EventData $e $lt = $d['LogonType'] $row = [pscustomobject]@{ Час = $e.TimeCreated Акаунт = "$($d['TargetDomainName'])\$($d['TargetUserName'])" LogonType = $lt Status = $d['Status'] SubStatus = $d['SubStatus'] Процес = $d['LogonProcessName'] Викликав = "$($d['SubjectDomainName'])\$($d['SubjectUserName'])" } if ($lt -eq '4') { $batch += $row } } W '--- ЛИШЕ batch (LogonType=4). Це запуски нашої задачі. ---' if (-not $batch) { W '(жодного batch-логону в межах вибірки)' } foreach ($r in $batch) { W '' W "час : $($r.Час)" W "акаунт : $($r.Акаунт)" W "викликав : $($r.Викликав)" W "процес : $($r.Процес)" W "Status : $($r.Status) $(Explain $r.Status)" W "SubStatus: $($r.SubStatus) $(Explain $r.SubStatus)" } W '' W '--- усі 4625 таблицею (для контексту) ---' W ((($ev | ForEach-Object { $d = Get-EventData $_ [pscustomobject]@{ Час=$_.TimeCreated; Акаунт="$($d['TargetDomainName'])\$($d['TargetUserName'])" Type=$d['LogonType']; Status=$d['Status']; SubStatus=$d['SubStatus']; Процес=$d['LogonProcessName'] } }) | Format-Table -AutoSize | Out-String).Trim()) } else { W '(пропущено)' } Section 'УСПІШНІ BATCH-ЛОГОНИ 4624 LogonType=4 (шукаємо ширше — 800 подій)' if ($isAdmin) { $ok = @() foreach ($e in (Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} -MaxEvents 800)) { $d = Get-EventData $e if ($d['LogonType'] -eq '4') { $ok += "[$($e.TimeCreated)] $($d['TargetDomainName'])\$($d['TargetUserName']) proc=$($d['LogonProcessName'])" } } if ($ok) { $ok | Select-Object -First 20 | ForEach-Object { W $_ } } else { W '(жодного успішного batch-логону -> задача не стартувала НІ РАЗУ)' } } else { W '(пропущено)' } # ---------------------------------------------------------------- політика Section 'ПОЛІТИКА' if ($isAdmin) { $inf = Join-Path $env:TEMP 'tl-ur3.inf' secedit /export /areas USER_RIGHTS /cfg $inf 2>&1 | Out-Null W "надано : $((Select-String -Path $inf -Pattern '^SeBatchLogonRight').Line)" W "заборона: $((Select-String -Path $inf -Pattern '^SeDenyBatchLogonRight').Line)" Remove-Item $inf -Force W '' try { $sid = (New-Object Security.Principal.NTAccount($PrintAcct)).Translate([Security.Principal.SecurityIdentifier]).Value W "SID акаунта: $sid" } catch { W 'SID: не розіменовано' } } Section 'ЧИ ЗАСТОСОВУЄ GPO РОЗДІЛ SECURITY (User Rights Assignment)' W 'Якщо так — локальний грант Планувальника живе лише до наступного refresh.' W '' W '--- gpresult (правильний синтаксис: /scope computer, через пробіл) ---' W ((gpresult /r /scope computer 2>&1 | Out-String).Trim()) W '' W '--- журнал застосування Group Policy: CSE "Security" ---' $gp = Get-WinEvent -LogName 'Microsoft-Windows-GroupPolicy/Operational' -MaxEvents 200 | Where-Object { $_.Id -in 4016,5016,6016,7016 -and $_.Message -like '*Security*' } | Select-Object -First 10 if ($gp) { foreach ($e in $gp) { W "[$($e.TimeCreated)] id=$($e.Id) $(($e.Message -split "`r?`n")[0])" } } else { W '(подій немає)' } W '' W '--- scesrv.log: коли політика безпеки востаннє перезаписувалась ---' $sce = Join-Path $env:SystemRoot 'security\logs\scesrv.log' if (Test-Path $sce) { W ((Get-Content $sce -Tail 25 | Out-String).TrimEnd()) } else { W '(немає)' } # ---------------------------------------------------------------- сміття Section 'СЛІДИ РУЧНИХ ЕКСПЕРИМЕНТІВ' W 'У launcher.log видно запуски з C:\TerraLabPrintUtils — наш інсталятор такого каталогу не створює.' foreach ($d in @('C:\TerraLabPrintUtils', "${env:ProgramFiles(x86)}\app-client-utils")) { W '' W "$d : $(if (Test-Path $d) {'Є'} else {'немає'})" if (Test-Path $d) { W ((Get-ChildItem $d | Select-Object Name,LastWriteTime | Format-Table -AutoSize | Out-String).Trim()) } } W '' W 'усі задачі Планувальника зі словом TerraLab або client-utils:' W ((Get-ScheduledTask | Where-Object { $_.TaskName -like '*TerraLab*' -or $_.TaskName -like '*client-utils*' } | Select-Object TaskName,TaskPath,State | Format-Table -AutoSize | Out-String).Trim()) W '' W 'autorun у всіх профілях:' Get-ChildItem Registry::HKEY_USERS | ForEach-Object { $p = "Registry::$($_.Name)\Software\Microsoft\Windows\CurrentVersion\Run" $v = (Get-ItemProperty -Path $p).PSObject.Properties | Where-Object { $_.Name -like '*client-utils*' -or $_.Value -like '*client-utils*' -or $_.Value -like '*TerraLab*' } foreach ($x in $v) { W " $($_.Name) : $($x.Name) = $($x.Value)" } } Section 'ЖУРНАЛ ПЛАНУВАЛЬНИКА — за TaskName, без фільтра по тексту' $te = Get-WinEvent -LogName 'Microsoft-Windows-TaskScheduler/Operational' -MaxEvents 500 | Where-Object { $_.Properties.Value -join ' ' -like '*app-client-utils*' } | Select-Object -First 30 if ($te) { foreach ($e in $te) { W "[$($e.TimeCreated)] id=$($e.Id) $(($e.Message -split "`r?`n")[0])" } } else { W '(нічого; задачу видалено, події могли витіснитись)' } Section 'ЯК ЧИТАТИ' W 'Дивіться секцію "НЕВДАЛІ ВХОДИ 4625" -> рядок SubStatus:' W ' 0xc000015b -> права batch logon немає. Фікс: видати право (локально або доменним GPO).' W ' 0xc000006a -> пароль. Фікс: ввести правильний, жодних змін у коді не треба.' W ' 0xc0000070 -> обмеження "Разрешенные рабочие станции" на акаунті.' $Lines | Out-File -FilePath $Report -Encoding UTF8 Write-Host '' Write-Host " Звіт: $Report" -ForegroundColor Green Write-Host ' Надішліть цей файл.' -ForegroundColor Green