タスクスケジューラでPowerShellを実行し、2147942401や0x80070001が表示された場合は、そのコードがどの履歴・アクションに出たかを先に確認します。「アクション完了」や終了コード0だけでは、ファイル出力やAD変更など目的の処理が完了した証明にはなりません。
2147942401は0x80070001の10進表示ですが、PowerShellの終了コード0x1と同じ値ではないため、履歴の失敗したアクションとログを併せて確認します。
2147942401・0x80070001・0x1の違い
| 値・表示 | 読み方と注意点 |
|---|---|
| 2147942401 | 0x80070001と同じ数値の10進表示 |
| 0x80070001 | Win32コード1をHRESULTへ変換した形式に対応。ERROR_INVALID_FUNCTIONは「関数が正しくありません」 |
| 0x1 | 数値1。PowerShellプロセス等の終了コードとして返った場合、その処理側の意味を確認する |
| 0x0/アクション完了 | 終了やタスクの状態。対象処理の業務結果まで保証する表示ではない |
下位のコードが1でも、0x80070001を「PowerShellがexit 1しただけ」と一律に解釈しないでください。タスクの最終結果、実行日時、履歴のイベント、操作したアクション、スクリプトログを対応させます。コードだけでTLS不足やAD権限不足が本命とは決められません。
'{0:X8}' -f [uint32]2147942401
# 期待する表示: 80070001
1. タスク履歴と本処理の開始を分ける
- タスク名、実行日時、最終実行結果、対象アクションを記録します。複数のアクションがあるなら、失敗したものを区別します。
- タスクの履歴、イベントビューアーのMicrosoft→Windows→TaskScheduler→Operationalを確認し、起動不能か、起動後の処理失敗かを調べます。履歴が無効なら、調査に必要な範囲で有効にして再現します。
- 本処理の最初にログが出たかを確認します。ログがない場合も、実行されなかったと即断せず、ログ保存先の作成・書き込み失敗を調べます。
- まず変更を伴わない診断用スクリプトを、意図する実行アカウント・設定で試します。削除処理を繰り返して切り分けないでください。
2. プログラム・引数・作業フォルダーを確認する
| 設定 | 確認例 |
|---|---|
| プログラム/スクリプト | Windows PowerShell 5.1なら通常C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe。実機のWindows保存先と必要な32/64bitを確認 |
| 引数 | -NoProfile -NonInteractive -File “C:\Scripts\TaskDiagnostic.ps1″。スクリプトのフルパスは引用符で囲む |
| 開始(作業)フォルダー | C:\Scripts等の実在する作業ディレクトリ。スクリプトのパスそのものを入れない |
| PowerShell 7を使う場合 | powershell.exeではなくインストールしたpwsh.exeを指定し、モジュールもその環境で確認 |
-NoProfileは対話ユーザーのプロファイルに依存しないための指定、-NonInteractiveは入力待ちを避ける指定です。モジュールの互換性や実行ポリシーを自動で解決する指定ではありません。実行ポリシーやAppLocker等は組織の方針を確認し、Bypassや一括ブロック解除を既定の対処にしないでください。
相対パスは作業ディレクトリで参照先が変わります。入力・出力にフルパスを使うか、スクリプト内でJoin-Path $PSScriptRootを使って基準を明示します。Z:等のマップドライブは別のログオン状態で見えないことがあるため、共有ならUNCパスも確認します。ただしUNCへ変えるだけで共有のアクセス権が付くわけではありません。
3. 同じユーザー名でもログオン方式を確認する
| 違い | 確認する点 |
|---|---|
| 実行アカウント | ファイル・共有・AD等に必要な権限があるか。ローカルの昇格とADへの委任権限は別 |
| ログオン方式 | 対話実行と非対話実行でトークン・入力可否・ネットワーク利用条件が違う |
| S4U/パスワードを保存しない構成 | MicrosoftはS4Uではネットワークや暗号化ファイルへアクセスできないと明記。必要な接続条件と照合 |
| 証明書・モジュール | そのユーザーに見えるストア、秘密鍵の権限、モジュール保存先・版を確認 |
「最上位の特権で実行」を有効にすれば、すべてのAD操作・共有・Graph認証が成功するわけではありません。必要な権限だけを確認します。同じアカウントで手動実行が成功しても、ログオン方式や対話認証が異なるため、タスク内の診断ログとの比較が必要です。
4. ログと終了コードを明示する診断例
次はWindows PowerShellで実行する診断用.ps1の例です。スクリプトと同じ場所にlogsフォルダーを作成できるアカウントで実行してください。AD変更・Graph接続は行わず、環境情報を記録するだけです。本番へ組み込む場合は、業務の成功条件を確認した後に0を返すよう設計します。
$ErrorActionPreference = 'Stop'
$taskExitCode = 1
$transcriptStarted = $false
try {
$diagnosticRoot = Join-Path $PSScriptRoot 'logs'
if (Test-Path -LiteralPath $diagnosticRoot) {
if (-not (Test-Path -LiteralPath $diagnosticRoot -PathType Container)) {
throw 'The log directory path is already used by a file.'
}
}
else {
New-Item -ItemType Directory -Path $diagnosticRoot | Out-Null
}
$diagnosticName = 'run_{0}_{1}.txt' -f (Get-Date -Format 'yyyyMMdd_HHmmss_fff'), $PID
$diagnosticPath = Join-Path $diagnosticRoot $diagnosticName
Start-Transcript -Path $diagnosticPath -NoClobber | Out-Null
$transcriptStarted = $true
if (-not (Test-Path -LiteralPath $diagnosticPath -PathType Leaf)) {
throw 'The expected transcript file was not created.'
}
Write-Output ('Identity: ' + [Security.Principal.WindowsIdentity]::GetCurrent().Name)
Write-Output ('PowerShell: ' + $PSVersionTable.PSVersion)
Write-Output ('Bitness: ' + ([IntPtr]::Size * 8))
Write-Output ('Script: ' + $PSCommandPath)
Write-Output ('WorkingDirectory: ' + (Get-Location).Path)
Write-Output 'STEP: diagnostic completed'
# この例は環境情報の確認だけ。AD変更やGraph接続は実行しない。
$taskExitCode = 0
}
catch {
$taskExitCode = 1
Write-Error -ErrorRecord $_ -ErrorAction Continue
}
finally {
if ($transcriptStarted) {
try { Stop-Transcript -ErrorAction Stop | Out-Null }
catch {
$taskExitCode = 1
Write-Error -ErrorRecord $_ -ErrorAction Continue
}
}
}
exit $taskExitCode
ログ保存先が既存ファイルと衝突していないか、開始後に想定したログファイルが実際に作られたかも確認します。フォルダー作成失敗もtryで扱い、開始できたときだけStop-Transcriptを呼びます。catchのWrite-ErrorにはContinueを明示し、そこで再び停止して終了コードの処理を飛ばさないようにしています。トランスクリプトの終了が失敗した場合も失敗を返します。
$ErrorActionPreferenceがStopなら、多くのPowerShellコマンドのエラーをcatchへ渡せますが、外部実行ファイルの非ゼロ終了を一律に例外へ変えるわけではありません。外部プログラムを呼ぶ処理では、直後に$LASTEXITCODEを保存し、そのツールの成功条件と照合します。ログへ認証情報・トークンや不要な業務データを出力しないでください。
5. モジュール・TLS・Graphは失敗した段階だけ調べる
| ログの失敗箇所 | 優先する確認 |
|---|---|
| コマンドが見つからない/Import-Module失敗 | 実行ユーザーとPowerShell版でGet-Module -ListAvailable。保存先・互換性・依存関係を照合 |
| Galleryの取得に失敗 | TLS 1.2以上、公式ネットワーク要件、プロキシと取得エラー。タスクごとにモジュールを再導入しない |
| Graph認証に失敗・入力待ち | 対話ログインのキャッシュへ依存していないか、必要なアプリ権限・同意・証明書・秘密鍵・有効期限を確認 |
| 入力ファイルがない/対象ゼロ | フルパス、実際の出力ファイル、件数・生成日時、前段の接続成功を確認 |
| AD変更が失敗 | 対象と委任権限、モジュール、ドメインへの接続。抽出成功と変更成功を別に記録 |
GalleryはTLS 1.2以上が必要です。該当するWindows PowerShellのGallery通信を調べる場合、Microsoftの案内はSecurityProtocolへTls12をビットORで追加する例です。これを入れれば、すべてのGraph SDK通信・サーバー全体のTLS・証明書が直るという意味ではありません。
[Net.ServicePointManager]::SecurityProtocol =
[Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
Graphの定期処理は、許可されたアプリ専用認証など非対話で成立する方法を確認します。証明書の拇印だけで十分とは限らず、実行ユーザーが証明書と秘密鍵を利用できること、アプリ権限が適切であることも必要です。ログでは接続、取得、出力の成功を別々に確認してください。
Entra抽出からオンプレAD変更へ進む場合
「90日チェックインがないから即削除」のような処理は、組織の端末管理方針と対象の照合が必要です。EntraのApproximateLastSignInDateTimeは概算の活動日時であり、正確な最終使用時刻ではありません。クラウドのデバイス識別子を、確認せずオンプレADのComputer識別子として扱わないでください。
まず取得・出力だけのレポートで端末、参加形態、対象と除外条件を確認します。Microsoftは古いデバイスを即削除せず猶予期間を設ける運用、ハイブリッド参加ではオンプレ管理方針と同期を踏まえることを案内しています。修復の再実行が削除を繰り返さないよう、対象リストと処理結果を残します。
完了を判定するチェック
- 目的のPowerShellが、想定したアカウント・版・作業フォルダーで起動した。
- ログに前段と後段の到達点があり、失敗を握りつぶして0へ置き換えていない。
- 出力の場所・生成日時・件数と、必要な業務結果を確認した。
- タスク履歴の日時・アクション・終了コードを、そのログと対応させた。
公式資料
- Microsoft:Win32エラー1の意味
- Microsoft:HRESULT_FROM_WIN32の変換
- Microsoft:powershell.exeの引数と終了コード
- Microsoft:タスクのログオン方式・S4U制限
- Microsoft:タスクの作業ディレクトリ
- Microsoft:PowerShellのtry・catch・finally
- Microsoft:トランスクリプトの記録
- Microsoft:終了コードとスクリプトパスの自動変数
- Microsoft:GalleryのTLS・ネットワーク要件
- Microsoft:Graphの非対話・証明書認証
- Microsoft:古いデバイスの判定とハイブリッド管理
- Microsoft:TaskScheduler Operationalログの確認位置

コメント