TECHS 現地調査ツール
Invoke-TechsSiteSurvey.ps1

訪問時に、客先の TECHS 環境の情報を1回でまとめて取得します。設定不要・認証情報不要・読み取りのみ。

所要 約10秒 インストール不要 Windows認証で動作 USB不要(この場でダウンロード)
このページ: 2026-09-06 06:57 配信中のエージェント: 確認中… 実行すると1行目に agent v<版> が出ます。ここと一致していれば最新です

現場の構成(ここを取り違えると全部ずれます)

担当者PC あなたが座る場所 HV-HOST  /  Hyper-V ホスト  Windows Server 2025 TECHS も SQL Server も「ここには無い」 TECHS-SERVER (VM)  Windows Server 2019 ★ 実行するのはここ。24時間稼働・対話セッション0 SQL Server 2019 Windows認証のみ localhost で接続 TECHS6  1,388オブジェクト / 30.8M行 / 68.8GB TECHS6_TEST  605,126行 / 2.0GB EUCTOOL  帳票マート 受注は 020101_受注一覧情報(日本語名) techs-sync 15分ごとに起動 C:\techs-sync RDP PowerShell Direct(VMBus・ネットワーク設定不要) dev.fab-forward.co.jp 手順書・エージェント配布・更新 create.fab-forward.co.jp データの受け口・死活 到達OK × 18452 ホストからは入れない
読み方。 ホストで調査ツールを流しても TECHS も SQL も見つかりません — 実体は VM の中です。 ただし VM にログインする必要はありません。ホストに貼れば PowerShell Direct で中に届きます。
赤い×: ワークグループ構成のため、ホストから VM の SQL へ Windows 認証では入れません (エラー 18452)。SQL 認証も無効なので回避できず、エージェントは VM 内に置くしかありません
: VM から当社サーバーへは到達確認済み(TLS傍受なし)。だから遠隔で更新できます。

作業の順番

C4 VM を調査 環境を知る C17 常駐させる 帰る前に必ず C13 構造だけ取る 業務データ無し C8 量を確認 客先に見せる C14 絞って取込 後日でよい ここまで済めば、以降は全部リモートで足ります
C17 が分水嶺です。 ここを済ませずに現場を出ると、取得済みのファイルすら回収できず再訪問になります。 逆に C17 さえ入れば、C13 以降は帰ってからでも構いません。

どれを実行するか

コマンドの枠には左上に C1C15 の番号が付いています。 やりたいことから引いてください。

番号やること
C17 帰る前に必ず。スケジュールタスクとして常駐させる(同期は走りません)
C18常駐したか・動いたかを確認する
C1調査ツールを実行する(普通のPC・ネットに出られる)
C2同上。ただし客先PCがネットに出られない場合
C3Hyper-V ホストで VM の一覧を見る
C4Hyper-V の VM の中を調査する(ホストに貼るだけ。VMへのログイン不要)
C5ホストから VM の SQL に届くか確認する
C6PowerShell Direct が使えないときの代替
C12APIキーを手入力せずに取得する
C13 まずこれ。構造だけを持ち帰る(業務データは読みません)
C8取り込み対象と量を確認する(-Preflight・送信しません)
C14対象を絞って取り込む(-OnlyObjects
C10長時間の取り込みを切り離して起動する
C9出力をファイルに残してホストへ回収する
C11レポートやログを直接こちらへ送る(2万行まで)
C16取得済みの schema-report-*.json を送り直す(送信だけ失敗したとき)
C19 帳票ビューの小さい表を全件取る(区分名・分類マスタ・受注金額・製番別原価。約2.2万行)
C20大きい帳票ビューは先頭50行だけ取る(在庫入出庫履歴・払出実績・原価明細)
C7 / C15単体PC向けの取り込み(Hyper-V 構成では C8 を使ってください)

帰る前に必ず: 常駐させる(C17

これを入れずに現場を出ると、そのPCには二度と手が届きません 取得済みのファイルも回収できず、再訪問になります。スケジュールタスクとして 常駐させておけば、あとは全部リモートで済みます — エージェントは起動のたびに version.txt を見て自己更新し、 control.json で遠隔から停止・再開できます。
入れても同期は走りません 配信中の control.jsondisabled: true です。 エージェントは起動して更新を確認し、何もせず終了します。 お客様の SQL Server には触れません。足場だけ先に確保して、 中身は後からリモートで入れます。
C17
Invoke-Command -Session $s {
  [Net.ServicePointManager]::SecurityProtocol = 'Tls12'
  $root = 'C:\techs-sync'

  # 最新版を取得
  Invoke-WebRequest 'https://dev.fab-forward.co.jp/fab-forward-dev/srv/sites/techs6-agent/techs-sync.zip' -OutFile "$root\a.zip" -UseBasicParsing
  Expand-Archive "$root\a.zip" -DestinationPath "$root\current" -Force
  "installed version: " + (Get-Content "$root\current\VERSION" -Raw).Trim()

  # パスワードは画面に表示されます(schtasks が平文を要求するため)
  $pw = Read-Host "TECHS-SERVER\Administrator のパスワード"

  # /F で既存タスクを上書き。未登録でも、Interactive で登録済みでも、
  # どちらでもこれ1回で正しい状態になります
  schtasks /Create /TN "FabForward-TechsSync" /TR "cmd /c C:\techs-sync\run.cmd" `
           /SC MINUTE /MO 15 /RU "TECHS-SERVER\Administrator" /RP $pw /RL HIGHEST /F

  # すぐ1回動かして確認
  schtasks /Run /TN "FabForward-TechsSync"
  Start-Sleep -Seconds 20

  "--- 実行アカウント ---"
  (Get-ScheduledTask -TaskName 'FabForward-TechsSync').Principal | Format-List UserId, LogonType, RunLevel
  "--- 実行結果 ---"
  Get-ScheduledTask -TaskName 'FabForward-TechsSync' | Get-ScheduledTaskInfo |
    Format-List LastRunTime, LastTaskResult, NextRunTime
  "--- ログ ---"
  Get-ChildItem "$root\logs\agent-*.log" -ErrorAction SilentlyContinue |
    Sort-Object LastWriteTime | Select-Object -Last 1 | Get-Content -Tail 6
}

登録できたか、15分以内に1回動いたかを確認します。

C18
Invoke-Command -Session $s {
  Get-ScheduledTask -TaskName 'FabForward-TechsSync' | Get-ScheduledTaskInfo |
    Select-Object LastRunTime, LastTaskResult, NextRunTime
  Get-ChildItem 'C:\techs-sync\logs\agent-*.log' | Sort-Object LastWriteTime |
    Select-Object -Last 1 | Get-Content -Tail 8
}
揃うべき3つ
LogonTypePassword — これが Interactive だと、 ログオフした瞬間に動かなくなります
LastTaskResult0
ログ末尾STOOD DOWN remotely via control.json
LogonTypeInteractive ではいけない理由 このサーバーは調査時点で対話セッションが0でした。 Interactive は「そのユーザーがログオンしている間だけ」動く方式なので、 RDPを切った時点で二度と発火しません。 帰ったあとに気づく手段もありません。
Windows 標準の schtasks を使っています Install-ScheduledTask.ps1 ではなく schtasks を直接叩きます。 足場作りは一度きりのやり直しが効かない工程なので、こちらのコードを経由させません。 /F が付いているため、未登録でも登録済みでも同じコマンドで正しい状態になります。
なぜ Administrator で登録するのか ff_readonly はまだ存在せず、いま権限のあるアカウントが他にありません。 そして権限の高いアカウントで入れておかないと、後からタスクを組み替えられません — 低権限で入れると変更のために再訪問が必要になります。 権限を絞るのは、リモートで ff_readonly を作ってから行います。
本番DBを丸ごと取り込まないでください 実測で TECHS6 は 30,845,312 行 / 68.8GB ありました。 C13 で構造を持ち帰り、対象を決めてから C14 で絞って取り込みます。
この画面は訪問する担当者向けです お客様にお渡しするのは 読み取り専用ログインの作成手順SQL Server ネットワーク設定 の2本です。

いちばん簡単な使い方(コピーして貼るだけ)

調査したい Windows PC で PowerShell を開き、下を貼り付けて Enter。ダウンロードから実行まで一度に行います。USBメモリは不要です。

C1
# TLS1.2 を明示。Windows PowerShell 5.1 の既定は古く、これが無いと HTTPS に失敗します
[Net.ServicePointManager]::SecurityProtocol = 'Tls12'
$u = 'https://dev.fab-forward.co.jp/fab-forward-dev/srv/sites/techs6-survey/Invoke-TechsSiteSurvey.ps1.txt'
$p = "$env:TEMP\Invoke-TechsSiteSurvey.ps1"
Invoke-WebRequest $u -OutFile $p -UseBasicParsing
Unblock-File $p
powershell -NoProfile -ExecutionPolicy Bypass -File $p
なぜ拡張子が .ps1.txt なのか .ps1 のままだとメールの添付でもブラウザのダウンロードでも高確率でブロックされるためです。上のコマンドは保存時に .ps1 へ戻しています。

客先PCがインターネットに繋がらない場合

工場の端末は外に出られないことがあります。その場合は、繋がるPC(自分のノートなど)で下のリンクから保存し、ファイルを持ち込んでください。

⤓ Invoke-TechsSiteSurvey.ps1.txt をダウンロード

持ち込んだあと、客先PCの PowerShell で次を実行します。拡張子を手で変えようとしないでください — Windows は既定で拡張子を隠すため、.ps1.txt.ps1 のような名前になりがちです。下のコマンドが確実です。

C2
# 保存したファイルのある場所へ移動してから実行(例: ダウンロードフォルダ)
cd $env:USERPROFILE\Downloads

# .txt を外して .ps1 にし、ダウンロード由来のブロックを解除して実行
Copy-Item .\Invoke-TechsSiteSurvey.ps1.txt .\Invoke-TechsSiteSurvey.ps1 -Force
Unblock-File .\Invoke-TechsSiteSurvey.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File .\Invoke-TechsSiteSurvey.ps1

何を調べるか

項目内容
TECHSクライアントインストール先、バージョンTechs.ini
接続先SQLサーバー名・DB名・APサーバー・ポート(クライアント設定から)
SQL Serverバージョン、エディション、認証モード、TCP、ポート、照合順序
データベース一覧と状態
オブジェクト想定している22個が実在するか・読めるかTmStamp/UpdDt/DelFlg の有無、行数
ネットワーク疎通当社サーバーへ HTTPS が通るか(DNS/TCP/TLS/HTTP、証明書の発行者、所要時間)。下の「外部への通信」を参照
プロキシ設定WinHTTP/IE(WinINET)/環境変数/PAC の設定内容。認証情報は読みません
権限実行ユーザー、ローカル管理者かどうか、昇格しているか(後日タスクを登録できるかの判断用)
PCの使われ方連続稼働時間、電源プラン、スリープ/休止/画面オフまでの時間、ノートかデスクトップか、ログオン中の利用者の有無、TECHSクライアントが起動中か
タスクスケジューラサービスが動作しているか、タスクを列挙できるか。作成・変更・削除は一切しません
バージョンが 6.05 と違っても調査は成立します こちらのスキーマ地図は 0605.0002.0001.0000 から起こしたものです。客先が別バージョンなら警告を出しますが、22個のオブジェクトは1つずつ実測するので、何があって何が無いかは版に関係なく分かります。リバースエンジニアリングは仮説、この調査結果が答えです。

TECHS が Hyper-V の VM の中にある場合

ホストを調べても中身は分かりません ハイパーバイザ上で調査ツールを流すと、TECHS も SQL Server も「無い」という結果になります (Techs.ini not found / instance 見つからず)。調べるのは VM の中です。

まず VM を確認します。

C3
Get-VM | Select-Object Name, State, Uptime | Format-Table -AutoSize

VM にネットワーク設定は不要です。 Hyper-V ホストからは PowerShell Direct で VMBus 経由で入れます。下をホストで実行すると、ツールの取得・VMへの送り込み・ 実行・結果の回収まで一度に行います。1行目の VM 名だけ変えてください。

C4
# ★ここだけ書き換える(Get-VM で出た名前)
$vm = 'TECHS-SERVER'

# ホスト側でツールを取得
[Net.ServicePointManager]::SecurityProtocol = 'Tls12'
$p = "$env:TEMP\Invoke-TechsSiteSurvey.ps1"
Invoke-WebRequest 'https://dev.fab-forward.co.jp/fab-forward-dev/srv/sites/techs6-survey/Invoke-TechsSiteSurvey.ps1.txt' -OutFile $p -UseBasicParsing
Unblock-File $p

# VM の資格情報。Get-Credential は使わない(下の注意を参照)
$user = 'Administrator'
$pw = Read-Host "$vm の $user のパスワード" -AsSecureString
$c  = New-Object System.Management.Automation.PSCredential($user, $pw)

$s = New-PSSession -VMName $vm -Credential $c

# 送り込んで、VM の中で実行
Copy-Item $p -Destination 'C:\Users\Public\Invoke-TechsSiteSurvey.ps1' -ToSession $s
Invoke-Command -Session $s { powershell -NoProfile -ExecutionPolicy Bypass -File 'C:\Users\Public\Invoke-TechsSiteSurvey.ps1' -OutputDirectory 'C:\Users\Public' }

# 結果をホストへ回収
$out = "$env:USERPROFILE\Downloads\report"
New-Item -ItemType Directory -Force $out | Out-Null
Copy-Item -FromSession $s 'C:\Users\Public\techs-survey-*.json' -Destination $out
Copy-Item -FromSession $s 'C:\Users\Public\techs-survey-*.txt'  -Destination $out
Remove-PSSession $s
Write-Host "回収先: $out"
Get-Credential は使わないでください 管理者で起動した PowerShell でも 「次の1つ以上の必須パラメーターが指定されていません」で止まることがあります。 資格情報ダイアログを出せないコンソールセッションで起きるもので、権限の問題ではありません。 上のように Read-Host -AsSecureString で受け取れば確実に動きます(入力は画面に出ません)。
Administrator で弾かれる場合は 'TECHS-SERVER\Administrator' のように コンピューター名を付けてください。
ついでにこれも撃っておくと設置場所が一度で決まります ホストから VM の SQL に入れるなら、エージェントをホスト側に置く選択肢が生まれます (ホストは24時間稼働・管理者権限あり・外部到達も確認済みというケースが多い)。
C5
Test-NetConnection TECHS-SERVER -Port 1433

PowerShell Direct が使えないとき

VM の資格情報が無い、ホストが Hyper-V ではない等の場合。VM がインターネットに出られるなら、 VM の中で いちばん簡単な使い方 のコマンドをそのまま実行してください。

それも無理なら、ホストから SQL Server だけを対象にできます。ただし TECHS の設定ファイルは読めないため、得られる情報は半分になります (バージョン・DataSource・平文パスワードの有無が空欄のまま)。

C6
powershell -NoProfile -ExecutionPolicy Bypass -File .\Invoke-TechsSiteSurvey.ps1 -ServerInstance TECHS-SERVER

調査のあと: 実データを取り込む

APIキーはこのページに書きません この配布ページは URL を知っていれば誰でも見られます。鍵は別経路で受け取り、 下のブロックの $apiKey に貼ってください。

調査で SQL Server に接続できていることを確認してから実行します。 いきなり本番ではなく、まず TECHS6_TEST で通してください。 同じスキーマで件数が少ないため、失敗しても影響がありません。

C7
# ★書き換えるのはこの3行だけ
$server   = 'TECHS-SERVER'
$database = 'TECHS6_TEST'          # 通ったら 'TECHS6' に変える
$apiKey   = 'ここに鍵を貼る'          # または下の「鍵を打ち込まずに取る」を使う

# エージェントを取得
[Net.ServicePointManager]::SecurityProtocol = 'Tls12'
$root = 'C:\techs-sync'
New-Item -ItemType Directory -Force $root | Out-Null
Invoke-WebRequest 'https://dev.fab-forward.co.jp/fab-forward-dev/srv/sites/techs6-agent/techs-sync.zip' -OutFile "$root\a.zip" -UseBasicParsing
Expand-Archive "$root\a.zip" -DestinationPath "$root\current" -Force

# 設定を書く。SQL認証が無効なサーバーでは integratedSecurity が必須
$cfg = Get-Content "$root\current\config.example.json" -Raw | ConvertFrom-Json
$cfg.techs.server = $server
$cfg.techs.database = $database
$cfg.techs.integratedSecurity = $true
$cfg.api.baseUrl = 'https://create.fab-forward.co.jp'
$cfg.api.apiKey  = $apiKey
$cfg | ConvertTo-Json -Depth 10 | Set-Content "$root\config.json" -Encoding UTF8

# 何を送ることになるか一覧(★送信しません)
powershell -NoProfile -ExecutionPolicy Bypass -File "$root\current\Export-TechsAll.ps1" -ConfigPath "$root\config.json" -Preflight
ワークグループ構成では、ホストから VM の SQL には入れません ホスト側で実行して $server='TECHS-SERVER' を指すと、SQL Server が 「信頼されていないドメインからのログイン」(18452) で拒否します。 ホストのローカルアカウントは VM にとって存在しないアカウントで、SQL 認証も無効なため回避できません。
取り込みは VM の中で動かします。ただし VM にログインする必要はありません — 下のブロックはホストに貼るだけで、PowerShell Direct 経由で中で実行されます。
C8
# ★ホスト(Hyper-V)で実行。書き換えるのは3行
$vm   = 'TECHS-SERVER'
$user = 'Administrator'
$db   = 'TECHS6_TEST'          # 通ったら 'TECHS6'

# 既存セッションを再利用。無ければ作る
$s = Get-PSSession -VMName $vm -ErrorAction SilentlyContinue |
     Where-Object { $_.State -eq 'Opened' } | Select-Object -First 1
if (-not $s) {
  $pw = Read-Host "$vm の $user のパスワード" -AsSecureString
  $s  = New-PSSession -VMName $vm -Credential (New-Object System.Management.Automation.PSCredential($user, $pw))
}

Invoke-Command -Session $s -ArgumentList $db -ScriptBlock {
  param($db)
  [Net.ServicePointManager]::SecurityProtocol = 'Tls12'
  $apiKey = (Invoke-WebRequest '別途お伝えする鍵のURL' -UseBasicParsing).Content.Trim()

  $root = 'C:\techs-sync'
  New-Item -ItemType Directory -Force $root | Out-Null
  Invoke-WebRequest 'https://dev.fab-forward.co.jp/fab-forward-dev/srv/sites/techs6-agent/techs-sync.zip' -OutFile "$root\a.zip" -UseBasicParsing
  Expand-Archive "$root\a.zip" -DestinationPath "$root\current" -Force

  $cfg = Get-Content "$root\current\config.example.json" -Raw | ConvertFrom-Json
  $cfg.techs.server = 'localhost'        # 自ホスト名ではなく localhost
  $cfg.techs.database = $db
  $cfg.techs.integratedSecurity = $true
  $cfg.api.baseUrl = 'https://create.fab-forward.co.jp'
  $cfg.api.apiKey  = $apiKey
  $cfg | ConvertTo-Json -Depth 10 | Set-Content "$root\config.json" -Encoding UTF8

  powershell -NoProfile -ExecutionPolicy Bypass -File "$root\current\Export-TechsAll.ps1" -ConfigPath "$root\config.json" -Preflight
}

実行するときは末尾の -Preflight を外して同じブロックを貼り直します。 本番に切り替えるときは $db'TECHS6' にします。

一覧をファイルに残して持ち帰る

preflight の出力は長くなります。画面から拾うのではなく、ファイルに落としてホストへ回収してください。

C9
Invoke-Command -Session $s {
  powershell -NoProfile -ExecutionPolicy Bypass -File "C:\techs-sync\current\Export-TechsAll.ps1" `
    -ConfigPath "C:\techs-sync\config.json" -Preflight *>&1 |
    Out-File -FilePath 'C:\Users\Public\preflight.txt' -Encoding UTF8
}

# ホストへ回収
$out = "$env:USERPROFILE\Downloads\report"
New-Item -ItemType Directory -Force $out | Out-Null
Copy-Item -FromSession $s 'C:\Users\Public\preflight.txt' -Destination $out
Write-Host "回収先: $out\preflight.txt"

長時間の取り込みは「切り離して」起動する

セッションを閉じると取り込みも死にます 本番の取り込みは数十分〜数時間かかります。Invoke-Command の中で直接走らせると、 リモートセッションを閉じた時点で中断します。下のように Start-Process で 切り離して起動してください。VM が起動している限り走り続けます。
C10
Invoke-Command -Session $s {
  $a = '-NoProfile -ExecutionPolicy Bypass -File "C:\techs-sync\current\Export-TechsAll.ps1" -ConfigPath "C:\techs-sync\config.json"'
  Start-Process powershell.exe -ArgumentList $a -WindowStyle Hidden
  'started, detached'
}

レポートやログを直接こちらへ送る

ファイル転送サービスも個人PCも経由しません 客先PCから当社サーバーへ到達できることは調査で確認済みで、鍵もそのPCの config.json にあります。テキストファイルをそのまま送れます。 このブロックに鍵は書かれていません — 設定ファイルから読みます。

送りたいファイルとタグを1行目で指定します。preflight の一覧でも、取り込みの実行ログでも同じです。

C11
# ★送るファイルと、区別するためのタグ
Invoke-Command -Session $s -ArgumentList 'C:\Users\Public\preflight.txt','PREFLIGHT_TECHS6' -ScriptBlock {
  param($path, $tag)
  [Net.ServicePointManager]::SecurityProtocol = 'Tls12'
  $cfg   = Get-Content 'C:\techs-sync\config.json' -Raw | ConvertFrom-Json
  $lines = @(Get-Content $path -Encoding UTF8)

  $rows = New-Object System.Collections.ArrayList
  for ($i = 0; $i -lt $lines.Count; $i++) {
    [void]$rows.Add([pscustomobject]@{ n = $i + 1; text = [string]$lines[$i] })
  }

  $body = @{
    batchId        = "REPORT-$tag-" + (Get-Date -Format 'yyyyMMddHHmmss')
    sequenceNumber = 1
    isFinal        = $true
    source         = 'techs-s'
    entity         = "ZZ_$tag"
    sourceObject   = $path
    rowCount       = $rows.Count
    rows           = $rows
  } | ConvertTo-Json -Depth 6

  Invoke-RestMethod -Uri ($cfg.api.baseUrl + '/api/integrations/techs/batches') -Method Post `
    -Headers @{ 'x-api-key' = $cfg.api.apiKey } `
    -ContentType 'application/json; charset=utf-8' `
    -Body ([Text.Encoding]::UTF8.GetBytes($body))
}
送るものタグの例
preflight.txt(TECHS6)PREFLIGHT_TECHS6
preflight.txt(EUCTOOL)PREFLIGHT_EUCTOOL
C:\techs-sync\logs\export-*.logEXPORT_LOG
1回で送れるのは2万行までです preflight の一覧も実行ログも通常はこれに収まります。超える場合は分割が必要なので、 rowsStored が実際の行数と合っているか確認してください。
進捗は取り込み先で確認できます データは我々のサーバーに入るので、進み具合はそちら側から見えます。現地で見張る必要はありません。 途中で止まっても -Resume を付けて再実行すれば続きから再開します (完了済みのオブジェクトは飛ばします)。
エージェントの常駐先も VM 側になります SQL 認証が無効でワークグループ構成である以上、ホストに置く選択肢はありません。 VM からも配布ページ・受け口の両方に到達できることは調査で確認済みです。
鍵を打ち込まずに取る 76文字の鍵を客先PCで手入力するのは現実的ではありません。取得用の URL を 別途お伝えします(このページには載せません。ここに書けば公開されてしまうためです)。 受け取った URL を下に入れて実行すると、$apiKey に入ります。
C12
[Net.ServicePointManager]::SecurityProtocol = 'Tls12'
$keyUrl = '別途お伝えするURL'
$apiKey = (Invoke-WebRequest $keyUrl -UseBasicParsing).Content.Trim()
$apiKey.Length   # 72 と出れば取得成功
この配布用の鍵は使い捨てです 訪問当日限りで失効させます。常駐運用にはこの鍵を使わず、設置時に別の鍵を発行します。
この一覧をお客様に見せて了解を得てから次へ進んでください -Preflight は1行も送信しません。対象・行数・推定サイズだけを表示します。 実データを社外へ出すことは調査とは別の話なので、ここで必ず区切ってください。

先に「構造だけ」持ち帰る(-SchemaReport

本番DBは全部取るには大きすぎることがあります 実測例: TECHS6_TEST は 605,126 行 / 約2.0GB でしたが、本番 TECHS630,845,312 行 / 約68.8GB でした。 そのまま流すと転送だけで十数時間かかり、受け側のディスクも圧迫します。 30M行の大半は履歴系で、実際に必要なのは10万行のオーダーです。
まず構造だけ取り、対象を絞ってから取り込みます。
業務データは1行も読みません -SchemaReport が読むのはシステムカタログ(sys.columns)と 行数メタデータだけです。テーブルの中身には触れません。数分で終わります。
C13
Invoke-Command -Session $s {
  [Net.ServicePointManager]::SecurityProtocol = 'Tls12'

  # 最新版を取り直す
  Invoke-WebRequest 'https://dev.fab-forward.co.jp/fab-forward-dev/srv/sites/techs6-agent/techs-sync.zip' -OutFile 'C:\techs-sync\a.zip' -UseBasicParsing
  Expand-Archive 'C:\techs-sync\a.zip' -DestinationPath 'C:\techs-sync\current' -Force

  powershell -NoProfile -ExecutionPolicy Bypass -File "C:\techs-sync\current\Export-TechsAll.ps1" `
    -ConfigPath "C:\techs-sync\config.json" -SchemaReport
}

全オブジェクトの全列名・型・行数がそのまま送信されます。 ファイルの受け渡しは不要です。$db を変えて TECHS6 / EUCTOOL / TECHS6_TEST の それぞれで実行してください。

これで決まること

送信だけ失敗したとき(ローカルのJSONを送り直す)

取得は成功しているのに送信が落ちる場合があります 実例: 1300オブジェクトの環境で、ローカルの schema-report-*.json は書けたのに送信が「接続が閉じられました」で 6回とも失敗。再スキャンは不要です — 保存済みのJSONを送り直します。
なお C11(テキストとして送る方)は、この用途では 行数上限2万行を超えて 400 になります。整形JSONは数十万行あるためです。 下の C16 は構造のまま送るので行数が約1/8になり、1チャンクも小さくなります。
C16
# ★1つめ=送るJSON、2つめ=再開するチャンク番号(初回は 0)
Invoke-Command -Session $s -ArgumentList 'C:\techs-sync\logs\schema-report-日時.json',0 -ScriptBlock {
  param($path, $startChunk)

  [Net.ServicePointManager]::SecurityProtocol = 'Tls12'
  $cfg = Get-Content 'C:\techs-sync\config.json' -Raw | ConvertFrom-Json
  $uri = $cfg.api.baseUrl.TrimEnd('/') + '/api/integrations/techs/batches'
  $hdr = @{ 'x-api-key' = $cfg.api.apiKey }

  # PS 5.1 の ConvertTo-Json は [DBNull] を {} に直す。受け側は値を
  # 文字列/数値/真偽/null に限定しているので {} は 400 で弾かれる。
  function San($v) {
    if ($null -eq $v) { return $null }
    if ($v -is [System.DBNull]) { return $null }
    if ($v -is [string] -or $v -is [bool] -or $v -is [int] -or $v -is [long] `
        -or $v -is [double] -or $v -is [decimal]) { return $v }
    if ($v -is [System.Management.Automation.PSCustomObject]) { return $null }
    return [string]$v
  }

  Write-Host "reading $path ..."
  $all = @(Get-Content $path -Raw -Encoding UTF8 | ConvertFrom-Json)
  $size = 1000
  $total = [math]::Ceiling($all.Count / $size)
  Write-Host "$($all.Count) rows -> $total chunk(s)"

  $batchId = 'SCHEMA-' + (Get-Date -Format 'yyyyMMddHHmmss')
  for ($c = $startChunk; $c -lt $total; $c++) {
    $raw = $all[($c * $size)..([math]::Min(($c + 1) * $size, $all.Count) - 1)]

    $clean = New-Object System.Collections.ArrayList
    foreach ($r in $raw) {
      $h = @{}
      foreach ($pn in $r.PSObject.Properties.Name) { $h[$pn] = San $r.$pn }
      [void]$clean.Add([pscustomobject]$h)
    }

    $body = @{
      batchId = $batchId; sequenceNumber = $c + 1; isFinal = ($c -eq $total - 1)
      source = 'techs-s'; entity = 'ZZ_SCHEMA'; sourceObject = 'schema-report'
      rowCount = $clean.Count; rows = $clean
    } | ConvertTo-Json -Depth 6 -Compress

    $ok = $false
    for ($try = 1; $try -le 5 -and -not $ok; $try++) {
      try {
        Invoke-RestMethod -Uri $uri -Method Post -Headers $hdr `
          -ContentType 'application/json; charset=utf-8' `
          -Body ([Text.Encoding]::UTF8.GetBytes($body)) -TimeoutSec 120 | Out-Null
        $ok = $true
      }
      catch {
        # サーバーの本文を出す。どの項目が不正か details.fields に出る
        $detail = $_.Exception.Message
        try {
          $rs = $_.Exception.Response.GetResponseStream()
          $detail = (New-Object IO.StreamReader($rs)).ReadToEnd()
        } catch { }
        Write-Host "  chunk $($c+1)/$total attempt $try : $detail"
        Start-Sleep -Seconds (2 * $try)
      }
    }
    if (-not $ok) { throw "chunk $($c+1) failed. 再開は -ArgumentList の2番目を $c に" }
    Write-Host "  sent $($c+1)/$total"
  }
  Write-Host "done. batchId=$batchId"
}
400「要求が不適切です」が出たときの原因 Windows PowerShell 5.1 の ConvertTo-Json は、SQL の NULL ([DBNull]) を null ではなく {} に変換します。 受け側は値を「文字列・数値・真偽・null」に限定しているため、{} は弾かれます。 経路の問題ではないので、ホスト経由に変えても直りません。 上の San がこれを null に落とします。
失敗時はサーバーの応答本文をそのまま表示します (details.fields にどの項目が不正か出ます)。
途中で落ちても続きから送れます エラーに出たチャンク番号を -ArgumentList の2番目に入れて貼り直してください。 重複して送られても欠損は起きません(受け側で最新のバッチを採ります)。

対象が決まったら、-OnlyObjects で絞って取り込みます。

C14
Invoke-Command -Session $s {
  powershell -NoProfile -ExecutionPolicy Bypass -File "C:\techs-sync\current\Export-TechsAll.ps1" `
    -ConfigPath "C:\techs-sync\config.json" `
    -OnlyObjects 'MstItemNo','MstPartsCompose','TrnSOrderH','020101_受注一覧情報'
}

了解が取れたら、同じウィンドウで実行します。

C15
powershell -NoProfile -ExecutionPolicy Bypass -File "$root\current\Export-TechsAll.ps1" -ConfigPath "$root\config.json"

TECHS6_TEST で通ったら $database'TECHS6' に変えて、 設定を書き直すところから流し直してください。

状況対応
途中で止まった末尾に -Resume を付けて再実行。完了済みは飛ばします
思ったより件数が多い-MaxRowsPerObject 5000 で刻めます
業務時間中で負荷が心配-DelayMsBetweenBatches 1000 で緩めます。既定は200
図面などの巨大な列がある既定でスキップします。必要なら -IncludeBinary
お客様の業務を止めません READ UNCOMMITTED で読むため、TECHS 利用者をブロックしません。書き込みは一切行いません。

帳票ビューのサンプルを取る(C19 / C20

C13 の構造だけの取得で、020101_受注一覧情報 のような 番号付き日本語名のビューが 265 本あることが分かりました(すべてビュー、144 本に行あり)。 ここには客先が画面で見ている数字そのものが出ています。うち「小さい表」は全件、「大きいビュー」は 先頭 50 行だけを取り、残っている疑問(区分コードの名称・部品分類の名称・受注金額の所在・製番別原価)を 聞かずに済ませます。

やることは C14 と同じです 既存の Export-TechsAll.ps1-OnlyObjects で対象を指名し、 -MaxRowsPerObject で行数に上限を掛けて実行するだけです。 エージェント本体の変更はありません。READ UNCOMMITTED で読み、書き込みは一切しません。 C17 で常駐させたあとなら、$s のセッションを開いて貼るだけです。
C19 は業務データを読みます 区分名マスタ(SymKbn 928 行)、受注分類・部品分類マスタ(各 10 / 44 行)、 受注金額の計上履歴(TrnOrderMoneyRedBlack 4,643 行)、製番別の原価集計(1,228 行)など 19 オブジェクト・合計およそ 22,000 行です。各オブジェクト 5,000 行で頭打ちにしているので、 想定より大きくても止まります。数分で終わります。
C19
Invoke-Command -Session $s {
  [Net.ServicePointManager]::SecurityProtocol = 'Tls12'

  # 最新版を取り直す(C13/C17 と同じ)
  Invoke-WebRequest 'https://dev.fab-forward.co.jp/fab-forward-dev/srv/sites/techs6-agent/techs-sync.zip' -OutFile 'C:\techs-sync\a.zip' -UseBasicParsing
  Expand-Archive 'C:\techs-sync\a.zip' -DestinationPath 'C:\techs-sync\current' -Force

  # 小さい表は全件(1オブジェクト 5,000 行で頭打ち)
  powershell -NoProfile -ExecutionPolicy Bypass -File "C:\techs-sync\current\Export-TechsAll.ps1" `
    -ConfigPath "C:\techs-sync\config.json" -MaxRowsPerObject 5000 `
    -OnlyObjects 'SymKbnField','SymKbn','SymApKbn', `
      'MstOrderClass','120215_受注分類マスタ情報', `
      'MstPartsClass','120218_部品分類マスタ情報', `
      'CtlNumberCompose','120244_採番構成マスタ情報','120222_図番マスタ情報', `
      'TrnOrderMoneyRedBlack', `
      '020120_売上単位別売上原価情報','090209_受注別予実対比表情報','090220_受注原価情報', `
      '090224_製番別原価項目別原価情報','090231_受注別原価項目別原価情報', `
      '090214_製番別原価一覧情報','090223_製番別原価項目別原価予定情報','090210_部門別月別工場原価一覧情報'
}

ログに Discovered 19 object(s) to export と出て、各行が final chunk で閉じれば成功です。[n/19] の n が 19 まで進みます。

C20
Invoke-Command -Session $s {
  # 大きいビューは先頭 50 行だけ(形を見るため。全件は引きません)
  powershell -NoProfile -ExecutionPolicy Bypass -File "C:\techs-sync\current\Export-TechsAll.ps1" `
    -ConfigPath "C:\techs-sync\config.json" -MaxRowsPerObject 50 `
    -OnlyObjects '080105_在庫入出庫履歴一覧情報','080201_払出実績一覧情報','050101-2_払出指示書明細情報', `
      '090229_ユニット別原価項目別原価情報','090202_原価明細一覧情報','090225_部品別原価情報','ViwTrnBom'
}
全件を引かない理由 上の 7 本は 1.9 万〜26 万行あります。TOP 50 なので SQL Server 側の負荷はほぼゼロ、 送信も 350 行だけです。全件が必要になった場合は、こちらでエージェントの同期対象 (entities.json)に足して自己更新で配ります。お客様の作業はありません。
状況対応
Discovered 0 object(s)接続先 DB が TECHS6 か確認(config.jsontechs.database)。TECHS6_TEST にはこれらの行が無いことがあります
途中で止まったそのまま同じコマンドをもう一度。新しい run token で全オブジェクトを取り直します(-Resume は付けない)
送信で 400C16 の要領でこちらに知らせてください。ローカルの state\ にログが残ります

現地で確認すること

調査ツールが自動で記録するもの — 聞かなくてよい TECHSのバージョン・接続先・SQL Server の構成・22オブジェクトの実在・ 疎通可否とプロキシ設定・実行ユーザーの管理者権限・連続稼働時間・電源プラン (スリープ/休止までの時間)・ノートかデスクトップか・TECHSクライアントの起動有無。 これらは口頭で確認する必要はありません。

以下はツールでは分からず、人に聞くしかないものです。ここが埋まらないと、 持ち帰っても設計を確定できません。

聞くことなぜ必要か
同期を動かすPCはどれか
TECHSクライアント端末か、常時起動の別PCか
スリープ対策とタスクの実行方式が変わります。人が日中使う端末なら、画面に黒い窓が出ない設定(サービスアカウント実行)が必要です
そのPCは夜間も電源が入っているか
入替・初期化の予定はあるか
夜間に電源が落ちるなら深夜2時の実行は一度も走りません。実行時刻を昼休みへ寄せる判断になります
TECHSの日次データは何時に確定するか 締めより前に同期すると、毎日1日古いデータを取り続けます。今のところ誰も確認していません
読み取り専用ログインは誰が発行できるか
テクノアへの依頼が必要か
これが取れないと同期は1件も動きません。コード側の問題ではないので、こちらでは直せません
ウイルス対策ソフトの製品名 PowerShell スクリプトや zip を隔離する製品だと、自動更新が静かに失敗し続けます
PCの管理者は誰か
GPO・資産管理ソフトが入っているか
スケジュールタスクが管理ポリシーで消される・実行が禁止されることがあります。消されてもこちらからは気づけません
プロキシに認証が要るか
要るなら誰のアカウントか
調査ツールはプロキシの設定は読みますが、認証の要否までは判定できません
SQL Server を業務時間中に読んでよいか
避けるべき繁忙時間帯は
昼休みに実行する案の可否が決まります。全件取得はテーブル全体を読むため、TECHS利用者と競合し得ます
実データの提供をお願いできるか
いま手作業で出している 発注書・受注表・部品表 の Excel を数本いただけないか
こちらで実データに対して組み立てられます。お客様が普段出しているものと同じファイルなので新しい作業は発生しません。DBから直接抜くより先に、まずこれをお願いするのが筋です
PCに触れなくなったとき誰に連絡するか 設置後にこちらから直せるのはスクリプトだけです。PC・ネットワーク・権限は現地の人が必要です
設置前に必ず疎通結果を読んでください レポートの reachability が「出られない」なら、自動更新の前提が崩れます。 その場合は設置を進める前に方針を決め直してください(帰社後では手が出せません)。

安全性

業務データは1件も取得しません
客先PCに平文パスワードが置かれている可能性があります TECHS のクライアント設定 Technoa.Techs.ClientCommonLibrary.dll.configUserIdPassWord を平文で持ちます(参考インストールは UserId=sa)。
本ツールは「平文パスワードが存在するか」の真偽値だけを記録し、値はレポートに書きません。実機のセンチネル値で漏れないことを確認済みです。
お客様には別途お伝えすべき事項です。
外部への通信が発生します(GET 2回のみ) 将来の自動同期をこのPCから実行できるかを、その場で判断するためです。到達できたかどうかだけを記録します。 この2つの GET 以外に通信は行いません。客先のデータも調査結果も送信しません。社内ネットワークが外部へ出られない場合でも調査は成立し、「出られない」という結果が記録されます。

出力

実行したフォルダに2つ作られます。

techs-survey-<PC名>-<日時>.txt現地で目視する用。帰る前にこれを開いて確認してください
techs-survey-<PC名>-<日時>.json持ち帰り用。項目マッピングはこれを見て設計します

読み方

うまくいかないとき

症状対処
ダウンロードで止まる/SSLエラー1行目の Tls12 を飛ばしていませんか。PS 5.1 の既定は TLS1.0 で、いまの HTTPS には繋がりません
「スクリプトの実行がシステムで無効に…」-ExecutionPolicy Bypass を付けて実行してください(上のコマンドは付いています)
「発行元を確認できません」Unblock-File を実行してください。ダウンロード由来のマークが原因です
SQLサーバーに届かないレポートに NOT REACHABLE と理由が出ます。クライアント端末から見えない構成なら、サーバー機で実行し直してください
TECHSクライアントが見つからない-FindClientIni で全体を探索、または -ClientIniPath でパス直指定。サーバー機にいるなら不要です
SQLサーバーが別機で名前が分かる-ServerInstance SV01\TECHS で直接指定できます