Installed C:\ProgramData\dataforth-uploader\ on AD2 with: - credentials.json (SYSTEM+Administrators ACL only) - run-pipeline.ps1 (DFWDS-process -> enumerate For_Web -> upload-delta) - dfwds-process.js + upload-delta.js (copied from prior install dir) - logs/ with 60-day retention Scheduled Task 'DataforthTestDatasheetUploader' registered as SYSTEM, hourly trigger, 30-min execution limit. First SYSTEM-context run verified: received=7061 unchanged=7061 errors=0 in 8.7s. Initial registration via inline base64 mangled the backslashes in the -File argument (resulted in ERROR_DIRECTORY 0x8007010B). Fixed by running the registration PowerShell from a file rather than an encoded command string. Also deleted throwaway tmp/list_amtransit.py + tmp/reset_cansley.py which had hardcoded ACG admin password. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
68 lines
3.3 KiB
Python
68 lines
3.3 KiB
Python
"""Re-register scheduled task with clean argument escaping.
|
|
|
|
Uses an external file for the PowerShell registration script rather than
|
|
inline base64 (which was mangling backslashes).
|
|
"""
|
|
import base64, paramiko, subprocess, time, yaml
|
|
|
|
pwd_raw = yaml.safe_load(subprocess.run(['sops','-d','D:/vault/clients/dataforth/ad2.sops.yaml'],
|
|
capture_output=True, text=True, timeout=30, check=True).stdout)['credentials']['password']
|
|
PWD = pwd_raw.replace('\\', '')
|
|
|
|
REG_SCRIPT = r'''# register-task.ps1 — re-register DataforthTestDatasheetUploader cleanly
|
|
$taskName = 'DataforthTestDatasheetUploader'
|
|
$scriptPath = 'C:\ProgramData\dataforth-uploader\run-pipeline.ps1'
|
|
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue | Out-Null
|
|
|
|
# Argument uses single quotes inside to avoid double-quote escaping issues
|
|
$argStr = '-NoProfile -ExecutionPolicy Bypass -File ' + '"' + $scriptPath + '"'
|
|
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument $argStr -WorkingDirectory 'C:\ProgramData\dataforth-uploader'
|
|
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).Date.AddHours(1) -RepetitionInterval (New-TimeSpan -Hours 1)
|
|
$principal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -LogonType ServiceAccount -RunLevel Highest
|
|
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -ExecutionTimeLimit (New-TimeSpan -Minutes 30)
|
|
Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Description 'Dataforth Test Datasheet Uploader (DFWDS port + Hoffman API)' | Out-Null
|
|
|
|
Write-Host '=== registered task definition ==='
|
|
(Get-ScheduledTask -TaskName $taskName).Actions | Format-List
|
|
|
|
Write-Host '=== run it now ==='
|
|
Start-ScheduledTask -TaskName $taskName
|
|
Start-Sleep -Seconds 20
|
|
Get-ScheduledTaskInfo -TaskName $taskName | Select LastRunTime,LastTaskResult,NextRunTime | Format-List
|
|
'''
|
|
|
|
c = paramiko.SSHClient(); c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
c.connect('192.168.0.6', username='sysadmin', password=PWD,
|
|
timeout=30, banner_timeout=45, look_for_keys=False, allow_agent=False)
|
|
|
|
print('[1] SFTP register-task.ps1 to AD2')
|
|
remote_reg = 'C:/ProgramData/dataforth-uploader/register-task.ps1'
|
|
sftp = c.open_sftp()
|
|
with sftp.open(remote_reg, 'w') as fh:
|
|
fh.write(REG_SCRIPT)
|
|
sftp.close()
|
|
|
|
print('\n[2] run register-task.ps1 (elevated)')
|
|
# Use cmd to launch powershell so we avoid the quote-escape chain
|
|
_, o, e = c.exec_command(
|
|
r'powershell -NoProfile -ExecutionPolicy Bypass -File "C:\ProgramData\dataforth-uploader\register-task.ps1"',
|
|
timeout=120
|
|
)
|
|
print(o.read().decode('utf-8','replace'))
|
|
err = e.read().decode('utf-8','replace')
|
|
if err.strip() and 'CLIXML' not in err: print('[stderr]', err[:500])
|
|
|
|
print('\n[3] tail latest pipeline log (post-SYSTEM-run)')
|
|
def psb64(cmd, to=60):
|
|
enc = base64.b64encode(cmd.encode('utf-16-le')).decode()
|
|
_, o, _ = c.exec_command(f'powershell -NoProfile -EncodedCommand {enc}', timeout=to)
|
|
return o.read().decode('utf-8','replace')
|
|
out = psb64(
|
|
r'$latest = Get-ChildItem "C:\ProgramData\dataforth-uploader\logs" -Filter "pipeline-*.log" | '
|
|
r'Sort-Object LastWriteTime -Descending | Select -First 1; '
|
|
r'"Log: $($latest.FullName)"; "---"; Get-Content $latest.FullName -Tail 20'
|
|
)
|
|
print(out)
|
|
|
|
c.close()
|