sync: auto-sync from HOWARD-HOME at 2026-07-07 21:05:08

Author: Howard Enos
Machine: HOWARD-HOME
Timestamp: 2026-07-07 21:05:08
This commit is contained in:
2026-07-07 21:05:37 -07:00
parent 19edfc45c0
commit 4e148b6dc5
14 changed files with 4 additions and 341 deletions

View File

@@ -19,6 +19,10 @@ Categories (the `[type]` tag): _(none)_ = skill/command execution failure ·
<!-- Append entries below this line -->
2026-07-08 | Howard-Home | rmm/ps-encoded.sh | [friction] iconv not found on HOWARD-HOME Git-Bash -> ps-encoded.sh fails 'encoding produced nothing'; fell back to jq --rawfile direct dispatch [ctx: ref=ps-encoded.sh]
2026-07-08 | Howard-Home | ps-encoded | encode produced empty output [ctx: src=C:UsersHowardAppDataLocalTempclaudeC--claudetools<6C>88c32-7d31-4efa-b061-8d4521258192scratchpadcheck-sqlmem.ps1]
2026-07-08 | Howard-Home | bash/background-task | [friction] added shell '& ... disown' on top of run_in_background:true -> shell forks the long-running wait and exits 0 immediately, orphaning it; the blocking read never notifies. Twice this session. Fix: with run_in_background:true, run the command in the FOREGROUND of that shell (no trailing &, no disown) - the harness does the backgrounding. [ctx: ref=discord ask-forum.sh --wait]
2026-07-08 | Howard-Home | rmm/deploy-beast | [friction] cannot git-fetch Gitea submodule as SYSTEM via RMM: credential.helper=manager (GCM) fails with 'Must specify at least one OAuthAuthenticationModes' when no guru desktop session is logged on; new commit not fetchable, so remote SYSTEM deploy of the discord-bot is blocked. Restart-Service works as SYSTEM, but pull must run in guru context (interactive /sync on BEAST) first. [ctx: host=GURU-BEAST-ROG repo=acg-discord-bot]

View File

@@ -1,18 +0,0 @@
$ErrorActionPreference='SilentlyContinue'
"==== WINDOWS SERVER BACKUP FEATURE ===="
(Get-WindowsFeature Windows-Server-Backup | Select-Object Name,Installed | Out-String)
"==== ALL DISKS (spot a USB/backup disk) ===="
Get-Disk | Select-Object Number,FriendlyName,BusType,@{n='SizeGB';e={[math]::Round($_.Size/1GB,0)}},OperationalStatus,PartitionStyle | Format-Table -Auto | Out-String
"==== VOLUMES ===="
Get-Volume | Where-Object {$_.DriveType -ne 'CD-ROM'} | Select-Object DriveLetter,FileSystemLabel,DriveType,@{n='SizeGB';e={[math]::Round($_.Size/1GB,1)}},@{n='FreeGB';e={[math]::Round($_.SizeRemaining/1GB,1)}} | Format-Table -Auto | Out-String
"==== C: USED (what we must protect) ===="
$c=Get-CimInstance Win32_LogicalDisk -Filter "DeviceID='C:'"
"Used GB: $([math]::Round(($c.Size-$c.FreeSpace)/1GB,1)) Free GB: $([math]::Round($c.FreeSpace/1GB,1))"
"==== VSS WRITER HEALTH (must be stable/no-error before backup) ===="
$w = vssadmin list writers 2>$null
($w | Select-String -Pattern 'Writer name:|State:|Last error:' | Out-String)
"==== EXISTING WBADMIN BACKUP HISTORY ===="
wbadmin get versions 2>&1 | Out-String
"==== REACH NEW SERVER? ===="
Test-NetConnection -ComputerName TPS-SVR -Port 445 -InformationLevel Quiet 2>$null
"==== DONE ===="

View File

@@ -1,20 +0,0 @@
$ErrorActionPreference='SilentlyContinue'
"== CA service + identity =="
Get-Service CertSvc | Select-Object Name,Status,StartType | Format-Table -Auto | Out-String
certutil -cainfo 2>&1 | Select-String 'CA name|CA type|Subject|Expires|Provider|hash' | Out-String
"== CA database + log files (backup sizing) =="
Get-ChildItem 'C:\Windows\System32\CertLog' -File 2>$null | Select-Object Name,@{n='MB';e={[math]::Round($_.Length/1MB,2)}} | Format-Table -Auto | Out-String
"== Private-key provider / exportability (determines backupKey method) =="
certutil -store My 2>&1 | Select-String 'TPS-TPS-SERVER-CA|Provider =|Private key is NOT exportable|Signature test|Key Container' | Out-String
"== Config to reproduce on the rebuilt CA =="
"-- Validity period --"
certutil -getreg CA\ValidityPeriodUnits 2>&1 | Select-String 'Values|=' | Out-String
certutil -getreg CA\ValidityPeriod 2>&1 | Select-String 'Values|=' | Out-String
"-- CRL publication URLs --"
certutil -getreg CA\CRLPublicationURLs 2>&1 | Out-String
"-- AIA publication URLs --"
certutil -getreg CA\CACertPublicationURLs 2>&1 | Out-String
"-- CRL period --"
certutil -getreg CA\CRLPeriodUnits 2>&1 | Select-String 'Values|=' | Out-String
certutil -getreg CA\CRLPeriod 2>&1 | Select-String 'Values|=' | Out-String
"== DONE =="

View File

@@ -1,22 +0,0 @@
$ErrorActionPreference='SilentlyContinue'
Import-Module ActiveDirectory -ErrorAction SilentlyContinue
"== OS / edition (must be Std/DC-capable) =="
$os=Get-CimInstance Win32_OperatingSystem; "$($os.Caption) $($os.Version)"
"== AD DS deployment module (needed to promote + to run Test-ADDSDomainControllerInstallation) =="
Get-Module -ListAvailable ADDSDeployment | Select-Object Name,Version | Format-Table -Auto | Out-String
"== Secure channel to domain =="
nltest /sc_query:TPS.local 2>&1 | Out-String
"== Locate a DC for the domain =="
nltest /dsgetdc:TPS.local 2>&1 | Out-String
"== Port reachability to current DC 192.168.1.125 (need all OPEN) =="
foreach($p in 53,88,135,389,445,3268,636){ $r=Test-NetConnection -ComputerName 192.168.1.125 -Port $p -WarningAction SilentlyContinue; "{0,-6} {1}" -f $p, $(if($r.TcpTestSucceeded){'OPEN'}else{'CLOSED'}) }
"== Time offset vs DC (Kerberos needs < 5 min) =="
w32tm /stripchart /computer:192.168.1.125 /samples:1 /dataonly 2>&1 | Select-Object -Last 3 | Out-String
"== Schema objectVersion (87=2016, 88=2019 -> promotion auto-adpreps if 87) =="
$sch=(Get-ADRootDSE).schemaNamingContext
"objectVersion: $((Get-ADObject $sch -Property objectVersion).objectVersion)"
"== Free space C: (NTDS + SYSVOL target) =="
$v=Get-Volume -DriveLetter C; "Free GB: $([math]::Round($v.SizeRemaining/1GB,1))"
"== This box's current DNS (post-promo it should point to itself) =="
Get-DnsClientServerAddress -AddressFamily IPv4 | Where-Object {$_.ServerAddresses} | Select-Object InterfaceAlias,@{n='DNS';e={$_.ServerAddresses -join ','}} | Format-Table -Auto | Out-String
"== DONE =="

View File

@@ -1,13 +0,0 @@
$ErrorActionPreference='SilentlyContinue'
function DryCopy($src){
if(-not (Test-Path $src)){ "### $src`nMISSING`n"; return }
$out = robocopy $src 'C:\__dryrun_nul__' /L /E /NFL /NDL /NP /R:0 /W:0 /BYTES /XJ 2>&1
"### $src"
($out | Select-String 'Dirs :|Files :|Bytes :|ERROR|Access is denied') | Out-String
}
DryCopy 'C:\Share\Quickbooks'
DryCopy 'C:\ServerFolders\Users'
DryCopy 'C:\ServerFolders\Company'
DryCopy 'C:\ServerFolders\Folder Redirection'
DryCopy 'C:\Share\Deployment'
"== DONE =="

View File

@@ -1,28 +0,0 @@
$ErrorActionPreference='Stop'
$path='C:\Backups\TPS-SERVER'
New-Item -ItemType Directory -Path $path -Force | Out-Null
# SMB share granting the old server's machine account + Domain Admins
if(Get-SmbShare -Name 'TPSBackup' -ErrorAction SilentlyContinue){
Write-Host "share TPSBackup already exists"
} else {
New-SmbShare -Name 'TPSBackup' -Path $path -FullAccess 'TPS\Domain Admins','TPS\TPS-SERVER$' -CachingMode None | Out-Null
Write-Host "created share TPSBackup"
}
# NTFS ACL: SYSTEM, Administrators, Domain Admins, TPS-SERVER$ full control
$acl = Get-Acl $path
foreach($id in @('TPS\Domain Admins','TPS\TPS-SERVER$','BUILTIN\Administrators','NT AUTHORITY\SYSTEM')){
try {
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($id,'FullControl','ContainerInherit,ObjectInherit','None','Allow')
$acl.AddAccessRule($rule)
} catch { Write-Host "acl skip $id : $_" }
}
Set-Acl -Path $path -AclObject $acl
"==== RESULT ===="
Get-SmbShare -Name TPSBackup | Format-List Name,Path,FullAccess | Out-String
"UNC: \\TPS-SVR\TPSBackup"
$v=Get-Volume -DriveLetter C
"Target free space GB: $([math]::Round($v.SizeRemaining/1GB,1))"
"==== DONE ===="

View File

@@ -1,22 +0,0 @@
$ErrorActionPreference='Stop'
"== post-reboot state =="
$pfro=(Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name PendingFileRenameOperations -ErrorAction SilentlyContinue).PendingFileRenameOperations
"PendingFileRenameOperations now: $([bool]$pfro)"
$os=Get-CimInstance Win32_OperatingSystem
"Last boot: $($os.LastBootUpTime) Uptime min: $([math]::Round(((Get-Date)-$os.LastBootUpTime).TotalMinutes,0))"
"Activation: $((Get-CimInstance SoftwareLicensingProduct -Filter "ApplicationID='55c92734-d682-4d71-983e-d6ec3f16059f' AND LicenseStatus=1" | Select-Object -First 1 -Expand LicenseStatus) ) (1 = Licensed)"
"== create staging root + share (push target for pre-seed) =="
New-Item -ItemType Directory -Path 'C:\Share' -Force | Out-Null
if(Get-SmbShare -Name 'Share' -ErrorAction SilentlyContinue){ "share 'Share' already exists" } else {
New-SmbShare -Name 'Share' -Path 'C:\Share' -FullAccess 'TPS\Domain Admins','TPS\TPS-SERVER$' -CachingMode None | Out-Null
"created share 'Share'"
}
$acl=Get-Acl 'C:\Share'
foreach($id in @('TPS\Domain Admins','TPS\TPS-SERVER$','BUILTIN\Administrators','NT AUTHORITY\SYSTEM')){
$r=New-Object System.Security.AccessControl.FileSystemAccessRule($id,'FullControl','ContainerInherit,ObjectInherit','None','Allow'); $acl.AddAccessRule($r)
}
Set-Acl 'C:\Share' $acl
Get-SmbShareAccess -Name Share | Select-Object AccountName,AccessRight,AccessControlType | Format-Table -Auto | Out-String
"UNC ready: \\TPS-SVR\Share -> C:\Share"
"== DONE =="

View File

@@ -1,50 +0,0 @@
$ErrorActionPreference='SilentlyContinue'
Import-Module ActiveDirectory -ErrorAction SilentlyContinue
"==== FUNCTIONAL LEVELS + DOMAIN ===="
$f=Get-ADForest; $d=Get-ADDomain
"Forest mode: $($f.ForestMode) Domain mode: $($d.DomainMode)"
"Domain: $($d.DNSRoot) NetBIOS: $($d.NetBIOSName) PDC: $($d.PDCEmulator)"
"`n==== CURRENT DOMAIN CONTROLLERS ===="
Get-ADDomainController -Filter * | Select-Object Name,IPv4Address,IsGlobalCatalog,OperatingSystem,Site | Format-Table -Auto | Out-String
"==== FSMO HOLDERS ===="
netdom query fsmo 2>&1 | Out-String
"==== LINGERING TPS-SVR DC METADATA (must be clean before promo) ===="
$cfg=(Get-ADRootDSE).configurationNamingContext
"-- computer object(s) matching TPS-SVR --"
Get-ADComputer -Filter 'Name -like "*SVR*"' -Properties operatingSystem,whenCreated | Select-Object Name,DistinguishedName,operatingSystem,whenCreated | Format-Table -Auto | Out-String
"-- 'server' objects in config Sites (each real/former DC has one) --"
Get-ADObject -SearchBase "CN=Sites,$cfg" -Filter "objectClass -eq 'server'" -Properties dNSHostName | Select-Object Name,dNSHostName | Format-Table -Auto | Out-String
"-- nTDSDSA (NTDS Settings) objects = active DC replicas --"
Get-ADObject -SearchBase "CN=Sites,$cfg" -Filter "objectClass -eq 'nTDSDSA'" | Select-Object DistinguishedName | Format-Table -Auto | Out-String
"-- Domain Controllers OU members --"
Get-ADComputer -SearchBase "OU=Domain Controllers,$($d.DistinguishedName)" -Filter * | Select-Object Name | Format-Table -Auto | Out-String
"==== AD REPLICATION HEALTH ===="
repadmin /replsummary 2>&1 | Out-String
"==== DHCP AUTHORIZED IN AD (empty => MS DHCP not authoritative) ===="
Get-DhcpServerInDC 2>&1 | Out-String
"==== CERTIFICATE AUTHORITY (assess if in use) ===="
certutil -cainfo 2>&1 | Select-String 'CA type|CA name|Subject|Expires|Provider' | Out-String
"-- issued (non-revoked, non-expired-status) cert rows, first 30 --"
certutil -view -restrict "Disposition=20" -out "RequestID,CommonName,CertificateTemplate,NotAfter" csv 2>&1 | Select-Object -First 30 | Out-String
"-- total issued rows --"
$rows = certutil -view -restrict "Disposition=20" -out "RequestID" csv 2>&1
"issued cert rows (incl header): $(($rows | Measure-Object -Line).Lines)"
"==== OLD SERVER IP CONFIG (plan Option B swap) ===="
Get-NetIPConfiguration | ForEach-Object {
"IF: $($_.InterfaceAlias) IP: $($_.IPv4Address.IPAddress) GW: $($_.IPv4DefaultGateway.NextHop) DNS: $($_.DNSServer.ServerAddresses -join ',')"
}
"-- all IPv4 addrs --"
Get-NetIPAddress -AddressFamily IPv4 | Where-Object {$_.IPAddress -notlike '169.*' -and $_.IPAddress -ne '127.0.0.1'} | Select-Object IPAddress,PrefixLength,InterfaceAlias | Format-Table -Auto | Out-String
"==== DFS NAMESPACES (Folder Redirection / Shared Folders use these) ===="
Get-DfsnRoot 2>&1 | Out-String
"==== DONE ===="

View File

@@ -1,29 +0,0 @@
$ErrorActionPreference='SilentlyContinue'
"==== A. WHAT USES EACH SERVER IP ===="
"-- DNS A records pointing at the server's IPs --"
$targets = '192.168.1.120','192.168.1.125','10.10.10.5'
Get-DnsServerResourceRecord -ZoneName 'TPS.local' -RRType A 2>$null |
Where-Object { $_.RecordData.IPv4Address.IPAddressToString -in $targets } |
Select-Object HostName,@{n='IP';e={$_.RecordData.IPv4Address.IPAddressToString}} |
Sort-Object IP | Format-Table -Auto | Out-String
"-- TCP listeners bound to a SPECIFIC IP (reveals services pinned to .120/.125/10.x) --"
Get-NetTCPConnection -State Listen 2>$null |
Where-Object { $_.LocalAddress -notin '0.0.0.0','::','127.0.0.1','::1' } |
Select-Object LocalAddress,LocalPort,@{n='Process';e={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName}} |
Sort-Object LocalAddress,LocalPort | Format-Table -Auto | Out-String
"-- IIS websites + bindings (Essentials Remote Web Access, etc.) --"
Import-Module WebAdministration -ErrorAction SilentlyContinue
Get-Website 2>$null | Select-Object Name,State,@{n='Bindings';e={ ($_.bindings.Collection | ForEach-Object { $_.protocol + ':' + $_.bindingInformation }) -join ' | ' }} | Format-Table -Auto -Wrap | Out-String
"==== B. IS THE CA STILL ACTIVELY ISSUING? ===="
"-- Templates the CA is currently published to issue --"
certutil -CATemplates 2>&1 | Out-String
"-- MOST RECENT issued certs (highest RequestIDs = newest) --"
certutil -view -restrict "Disposition=20" -out "RequestID,CommonName,CertificateTemplate,NotAfter" csv 2>&1 | Select-Object -Last 15 | Out-String
"-- Any GPO that might drive cert autoenrollment --"
Get-GPO -All 2>$null | Select-Object DisplayName,ModificationTime | Sort-Object DisplayName | Format-Table -Auto | Out-String
"==== DONE ===="

View File

@@ -1,27 +0,0 @@
$ErrorActionPreference='SilentlyContinue'
"== PENDING REBOOT CHECKS (all should be False) =="
"CBS RebootPending: $([bool](Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending'))"
"WindowsUpdate RebootRequired: $([bool](Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired'))"
$pfro = (Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name PendingFileRenameOperations -ErrorAction SilentlyContinue).PendingFileRenameOperations
"PendingFileRenameOperations: $([bool]$pfro)"
$cn1=(Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName').ComputerName
$cn2=(Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName').ComputerName
"Rename pending: $($cn1 -ne $cn2) (active=$cn1 / configured=$cn2)"
"== ROLE / SERVICE STATE (is AD DS ready to promote?) =="
Get-WindowsFeature AD-Domain-Services,RSAT-ADDS,DNS,DHCP | Select-Object Name,InstallState | Format-Table -Auto | Out-String
Get-Service NTDS,DNS,DHCPServer,Netlogon,W32Time | Select-Object Name,Status,StartType | Format-Table -Auto | Out-String
"== EXISTING TARGET PATHS (for data pre-seed) =="
foreach($p in 'C:\Share','C:\Share\Quickbooks','C:\Share\Deployment'){ "$p exists: $(Test-Path $p)" }
"== DISK C: =="
Get-Volume -DriveLetter C | Select-Object @{n='FreeGB';e={[math]::Round($_.SizeRemaining/1GB,1)}},@{n='SizeGB';e={[math]::Round($_.Size/1GB,1)}} | Format-Table -Auto | Out-String
"== UPTIME / LAST BOOT =="
$os=Get-CimInstance Win32_OperatingSystem
"Last boot: $($os.LastBootUpTime) Uptime days: $([math]::Round(((Get-Date)-$os.LastBootUpTime).TotalDays,1))"
"== PENDING WINDOWS UPDATES (a big backlog = reboot churn) =="
try { $s=(New-Object -ComObject Microsoft.Update.Session).CreateUpdateSearcher(); $r=$s.Search("IsInstalled=0 and IsHidden=0"); "Pending updates: $($r.Updates.Count)" } catch { "update query n/a: $_" }
"== DONE =="

View File

@@ -1,15 +0,0 @@
$ErrorActionPreference='Stop'
$log='C:\Windows\Temp\tps-preseed.log'
# Pre-seed: data+attributes+timestamps only (ACLs re-applied fresh at cutover, avoids remote-privilege issues).
# /B backup mode reads open/locked files where possible; locked live QB .QBW skips fast (/R:1) and is recopied clean at cutover.
$rc = 'robocopy "C:\Share" "\\TPS-SVR\Share" /E /COPY:DAT /DCOPY:DAT /B /R:1 /W:2 /Z /XJ /MT:16 /NFL /NDL /NP /LOG:' + $log
$action = New-ScheduledTaskAction -Execute 'cmd.exe' -Argument ('/c ' + $rc)
$principal = New-ScheduledTaskPrincipal -UserId 'NT AUTHORITY\SYSTEM' -LogonType ServiceAccount -RunLevel Highest
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Hours 12) -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
$task = New-ScheduledTask -Action $action -Principal $principal -Settings $settings
Register-ScheduledTask -TaskName 'TPS-Preseed-Copy' -InputObject $task -Force | Out-Null
Start-ScheduledTask -TaskName 'TPS-Preseed-Copy'
Start-Sleep -Seconds 12
"Task state: $((Get-ScheduledTask -TaskName 'TPS-Preseed-Copy').State)"
"-- log head --"
if(Test-Path $log){ Get-Content $log -TotalCount 14 } else { "(log not created yet)" }

View File

@@ -1,30 +0,0 @@
$ErrorActionPreference='Continue'
$src='C:\Share\Quickbooks'
$dst='\\TPS-SVR\Share\Quickbooks'
$qbw='schoonerQB2025.QBW'
$tlg='schoonerQB2025.QBW.TLG'
"== stop QB hosting services (prevents re-lock during copy) =="
foreach($s in 'QuickBooksDB34','QBCFMonitorService'){ Stop-Service $s -Force -ErrorAction SilentlyContinue; Start-Sleep 1; "$s -> $((Get-Service $s -ErrorAction SilentlyContinue).Status)" }
Start-Sleep 3
try {
"== confirm company file is unlocked =="
try { $fs=[System.IO.File]::Open((Join-Path $src $qbw),'Open','Read','None'); $fs.Close(); "UNLOCKED - copying" }
catch { "STILL LOCKED: $($_.Exception.Message)" }
"== copy clean company file + transaction log =="
$out = robocopy $src $dst $qbw $tlg /COPY:DAT /R:2 /W:3 /NP /NJH
($out | Select-String 'schoonerQB2025|Bytes :|ERROR|New File') | Out-String
"robocopy exit code: $LASTEXITCODE (0-7 = success)"
}
finally {
"== restart QB services (users resume on OLD server) =="
foreach($s in 'QBCFMonitorService','QuickBooksDB34'){ Start-Service $s -ErrorAction SilentlyContinue; Start-Sleep 1; "$s -> $((Get-Service $s -ErrorAction SilentlyContinue).Status)" }
}
"== verify copied file matches source =="
$s=(Get-Item (Join-Path $src $qbw) -ErrorAction SilentlyContinue).Length
$d=(Get-Item (Join-Path $dst $qbw) -ErrorAction SilentlyContinue).Length
"SRC: $([math]::Round($s/1MB,1)) MB DST: $([math]::Round($d/1MB,1)) MB MATCH: $($s -eq $d -and $s -gt 0)"
"== DONE =="

View File

@@ -1,41 +0,0 @@
$ErrorActionPreference='SilentlyContinue'
"===== .QWC application files (define the connected app) ====="
$roots = @('C:\Share\Quickbooks','C:\ProgramData\Intuit','C:\Program Files\Common Files\Intuit','C:\Program Files (x86)\Common Files\Intuit','C:\Program Files (x86)\Intuit','C:\Program Files\Intuit')
$qwc = @()
# top-level of the QB data folder (where apps usually drop the .qwc)
$qwc += Get-ChildItem 'C:\Share\Quickbooks' -Filter *.qwc -ErrorAction SilentlyContinue
# recursive in the (small) profile + program locations
foreach($r in @('C:\Users','C:\ProgramData\Intuit','C:\Program Files\Common Files\Intuit','C:\Program Files (x86)\Common Files\Intuit')){
if(Test-Path $r){ $qwc += Get-ChildItem $r -Recurse -Filter *.qwc -ErrorAction SilentlyContinue }
}
$qwc = $qwc | Sort-Object FullName -Unique
if(-not $qwc){ "(no .qwc files in searched locations)" }
foreach($f in $qwc){
"### $($f.FullName) (modified $($f.LastWriteTime))"
try { [xml]$x = Get-Content $f.FullName -Raw
" AppName : $($x.QBWCXML.AppName)"
" AppURL : $($x.QBWCXML.AppURL)"
" AppSupport : $($x.QBWCXML.AppSupport)"
" AppDescription: $($x.QBWCXML.AppDescription)"
" UserName : $($x.QBWCXML.UserName)"
} catch { " raw:"; (Get-Content $f.FullName -Raw) }
}
"`n===== Web Connector data dirs (per-user) ====="
Get-ChildItem 'C:\Users\*\AppData\Local\Intuit\QBWebConnector' -Directory -ErrorAction SilentlyContinue | ForEach-Object {
"-- $($_.FullName) --"
Get-ChildItem $_.FullName -Recurse -ErrorAction SilentlyContinue | Select-Object @{n='KB';e={[math]::Round($_.Length/1KB,1)}},FullName,LastWriteTime | Format-Table -Auto -Wrap | Out-String
}
"`n===== Web Connector LOG - app names / URLs it talks to ====="
$logs = Get-ChildItem 'C:\Users\*\AppData\Local\Intuit\QBWebConnector','C:\ProgramData\Intuit\QBWebConnector' -Recurse -Include *.txt,*.log -ErrorAction SilentlyContinue
foreach($l in $logs){
"### $($l.FullName)"
Select-String -Path $l.FullName -Pattern 'AppName|App Name|AppURL|Connecting|http' -ErrorAction SilentlyContinue | ForEach-Object { $_.Line.Trim() } | Sort-Object -Unique | Select-Object -Last 25 | Out-String
}
"`n===== registry-registered Web Connector apps ====="
reg query "HKLM\SOFTWARE\Intuit\QBWebConnector" /s 2>$null
reg query "HKLM\SOFTWARE\WOW6432Node\Intuit\QBWebConnector" /s 2>$null
"===== DONE ====="

View File

@@ -1,26 +0,0 @@
$ErrorActionPreference='Stop'
$target='\\TPS-SVR\TPSBackup'
# Pre-flight: confirm we can write to the target as the machine account
$probe = Join-Path $target ("_probe_{0}.txt" -f $env:COMPUTERNAME)
try { Set-Content -Path $probe -Value 'ok' -ErrorAction Stop; Remove-Item $probe -Force; Write-Host "target writable: YES" }
catch { Write-Host "target writable: NO -> $_"; throw }
# Detached one-time scheduled task so the backup outlives this RMM command
$log = 'C:\Windows\Temp\tps-bmr.log'
$cmd = "wbadmin start backup -backupTarget:$target -allCritical -vssCopy -quiet"
$action = New-ScheduledTaskAction -Execute 'cmd.exe' -Argument "/c $cmd > `"$log`" 2>&1"
$principal = New-ScheduledTaskPrincipal -UserId 'NT AUTHORITY\SYSTEM' -LogonType ServiceAccount -RunLevel Highest
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit (New-TimeSpan -Hours 12)
$task = New-ScheduledTask -Action $action -Principal $principal -Settings $settings
Register-ScheduledTask -TaskName 'TPS-BMR-Backup' -InputObject $task -Force | Out-Null
Start-ScheduledTask -TaskName 'TPS-BMR-Backup'
Start-Sleep -Seconds 12
"==== TASK STATE ===="
Get-ScheduledTask -TaskName 'TPS-BMR-Backup' | Select-Object TaskName,State | Format-Table -Auto | Out-String
"==== WBADMIN STATUS ===="
wbadmin get status 2>&1 | Out-String
"==== LOG HEAD ===="
if(Test-Path $log){ Get-Content $log -TotalCount 15 | Out-String } else { "(log not created yet)" }
"==== DONE ===="