PowerShellスキャンを使用すると、PowerShell スクリプトを実行してデバイスから追加情報を収集し、その結果を保存できます。
標準スキャナーでは取得できないデータを利用した、高度な端末管理、カスタムレポート作成、条件に応じたデバイスの自動選定が可能になります。
この記事は以下の 2 部構成です。
- Part 1: PowerShellスキャンの作成、設定、および使用方法
- Part 2:PowerShellスキャンの動作概要と、高度なトラブルシューティング向けオプションラッパーについて(上級者向け)
【Part 1】 PowerShellスキャンの作成、設定、および使用方法
新しい PowerShellスキャンを作成する
- 左側のナビゲーションバーから「Scanners」をクリックします。
- 右上の[Create Scanner]をクリックします。
- スキャナー名を入力します。
- 「Type」ドロップダウンから「PowerShell」を選択します。PowerShellスキャンの設定ページが表示されます。
PowerShell スクリプトを追加する
「Script」セクションでは、各デバイス上で実行する PowerShell コードを定義します。
以下のいずれかの方法で追加できます。
- .ps1 ファイルをインポートする
- エディターへ直接スクリプトを貼り付ける
スクリプトは、データ収集と、PDQ Connect が処理可能な形式で結果を返すことのみに集中させることを推奨します。
PowerShellスキャンでは、デバイスごとに最大 100 行・36 列まで結果を返せます。
いずれかの制限を超えた場合、PDQ Connect は上限を超えた分を自動的に切り捨てます。
スクリプト出力要件
PowerShellスキャンは、コンソール出力ではなく、PowerShell のオブジェクトストリームを処理します。
PDQ Connect と互換性を持たせるには、スクリプトは構造化された PowerShell オブジェクト(例: PSCustomObject)のみを出力する必要があります。
✅ 正しい出力例
- [PSCustomObject]@{
- AntivirusEnabled = $true
- AntispywareEnabled = "Antispyware is enabled"
- Timestamp = Get-Date
- }
❌ 誤った出力例
- Write-Host "Antivirus is enabled"
- Write-Output "Antispyware is enabled"
- Get-Date
スクリプトが単なる文字列や整形済みテキストを出力した場合、PDQ Connect がデータを受け取る前にオブジェクト構造が失われます。
その結果、列や値を正しく検出・保存できなくなります。
出力整形用 Cmdlet を使用しない
PowerShellスキャンでは、以下のような出力整形用またはコンソール専用の Cmdlet を使用しないでください。
- Write-Host
- Format-Table
- Format-List
- Out-String
これらの Cmdlet は、構造化オブジェクトを、対話型 PowerShell セッション向けの表示専用テキストへ変換します。
一度変換されると、元のオブジェクトプロパティは失われ、PDQ Connect で処理できなくなります。
ベストプラクティス
構造化された生オブジェクトのみを返してください。表示形式や整形は、PDQ Connect 側で自動的に処理されます。
テキスト出力とオブジェクト出力を混在させない
スクリプトがプレーンテキストと構造化オブジェクトの両方を出力すると、PDQ Connect は結果を正しく処理できません。
Write-Host や文字列リテラルを含むテキストベースの出力が存在すると、PDQ Connect はオブジェクトスキーマを無視し、すべての出力を非構造化データとして扱います。
この問題を防ぐには、ステータスや情報メッセージを含むすべての値を PSCustomObject のプロパティとして返し、テキストを直接出力ストリームへ書き込まないようにしてください。
ログやステータスメッセージを出力しない
以下のような情報メッセージも、オブジェクト処理に影響する場合があります。
- "Starting scan..."
- "Completed scan."
有効なオブジェクトを返している場合でも、これらのメッセージが混在すると問題になる可能性があります。
スクリプトは、構造化オブジェクトのみを出力し、ログ出力や進捗表示を抑制するようにしてください。
PowerShellスキャンスクリプト テンプレート
以下のテンプレートは、スキャナー互換スクリプトを作成する際の基本例です。
- # PowerShell Scanner Script Template
- # ---------------------------------
- # Purpose:
- # Collect data for use in a PDQ Connect PowerShell scanner.
- #
- # Requirements:
- # - Output structured objects only
- # - Do not write to the console
- # - Do not use formatting or ConvertTo-Json
- # Collect data
- $osInfo = Get-CimInstance -ClassName Win32_OperatingSystem
- # Return structured output
- [PSCustomObject]@{
- ComputerName = $env:COMPUTERNAME
- OSName = $osInfo.Caption
- OSVersion = $osInfo.Version
- InstallDate = $osInfo.InstallDate
- LastBootTime = $osInfo.LastBootUpTime
- }
新しいスキャナー作成時や、既存スクリプトを PDQ Connect 向けに調整する際に利用してください。
テストデバイスの選択と出力確認
スキャナーを環境全体へ展開する前に、必ずテストデバイスで動作確認を行ってください。
- 「Select test device」セクションでオンライン状態のデバイスを選択します。
- [Run script]をクリックします。
検証を行うことで、以下を確認できます。
- スクリプトが正常に実行されるか
- 検出された列とデータ型
- 他デバイスへスキャンを展開する前に、期待通りの構造で出力されているか
列情報は検証時に確定され、その後スキャンされるすべてのデバイスへ共通適用されます。
一部デバイスが他より多くのプロパティを返した場合でも同様です。
別デバイスで追加プロパティや追加オブジェクトが返された場合でも、そのプロパティが検証時に存在していなければ、スキャナー結果には表示されません。
追加列を含めるには、それらのプロパティを返すデバイスで再度検証を実行する必要があります。
最適な結果を得るためには、できるだけ多くのデータセットを返すテストデバイスを選択し、追加デバイスをスキャンする前に必要な列をすべて検出させることを推奨します。
出力内容とデータ型について
検証後、PDQ Connect はスクリプト出力を表形式で表示します。
- 各オブジェクトは 1 行として扱われます
- 各オブジェクトプロパティは 1 列として扱われます
- PDQ Connect は各列のデータ型を自動判定します。
サポートされる型は以下の通りです。
- String
- Integer
- Float
- Boolean
- Date Date 型は、表示用に統一フォーマットへ変換されます。
各列には UI 上でデータ型セレクターが表示されます。
これはスクリプトが返す元データ自体には影響しませんが、PDQ Connect が Filters や Groups 用にデータをどのように保存するかを制御します。
たとえば、PowerShell が Boolean 値を 0 や 1 として返した場合でも、数値ではなく true / false として扱いたい場合に便利です。
スキャナーの有効化と保存
PowerShellスキャンは、有効化しない限りデバイスのスキャンを開始しません。
スキャナーは以下のいずれかの方法で有効化できます。
- 作成時に設定ページ右下の「Enabled」トグルを使用して有効化する
- 後から「Scanners」画面の一覧から有効化する
スクリプトと検証結果に問題がなければ、[Save]をクリックします。
有効化されたスキャナーは、PDQ Connect の通常のスキャン動作に従ってデバイスをスキャンします。
デバイス上で結果を確認する
PowerShellスキャンの結果は、各デバイス単位で確認できます。
- PDQ Connect で対象デバイスを開きます。
- 「Scanners」を開きます。
- 「PowerShell」を選択します。
この画面では、そのデバイスで最後に収集された結果を確認できます。インベントリ確認、フィルタリング、ターゲティングにも利用できます。
スキャンが上手くいかない場合は、
こちらをご参照ください。
【Part 2】 PowerShellスキャンの動作概要と、高度なトラブルシューティング向けオプションラッパーについて(上級者向け)
PowerShellスキャンは、非対話型コンテキストでスクリプトを実行し、コンソール出力ではなく「データ」として結果を評価します。
PDQ Connect で表示・フィルター・ターゲティングを行うため、スキャナーの出力は最終的に、整形された予測可能な JSON 形式へ変換される必要があります。
PDQ Connect は、一貫した構造とデータ型を維持するため、この JSON 変換をバックエンドで自動的に実施します。
そのため、以下の点に注意してください。
- スキャナースクリプトは、ネイティブの PowerShell オブジェクトを返してください
- スクリプト側で JSON シリアライズを制御しないでください
- Format 系コマンドレットなどの整形処理や、コンソール向け出力はサポートされません
PDQ Connect は、PowerShellスキャン実行時に内部ロジック(「ラッパー」)を使用して、Connect アプリケーションで利用できるように、スクリプト出力の処理および正規化を行います。
ラッパーでは、主に以下の処理が行われます。
- ユーザーのスクリプトを実行する
- PowerShell の出力ストリームへ書き込まれた内容を収集する
- 結果を予測可能なフラット構造へ正規化する
- 最終的な出力を適切な JSON に変換する
ユーザーが作成したスクリプトに ConvertTo-Json が含まれている場合、その部分は実行前に自動的に削除されます。
これは二重シリアライズを防ぎ、PDQ Connect 側でスキャナー結果の処理および保存方法を一元管理するためです。
スクリプトはオブジェクトのみを返してください。JSON への変換は PDQ Connect が自動的に処理します。
スキャナーラッパーを使用したローカルテスト
対話型 PowerShell セッションでは正常に動作するスクリプトでも、スキャナー実行時には異なる動作となる場合があります。
高度なトラブルシューティングを支援するため、以下にスキャナーラッパーの改変版をご用意しています。
このラッパーは PowerShell プロンプト上で実行できるよう調整されていますが、PDQ Connect が PowerShellスキャン実行時にバックエンドで使用しているロジックを再現しています。このラッパーは、診断用途としてのみ提供されています。ほとんどのお客様は使用する必要はありません。
ローカルテスト用ラッパー(高度なトラブルシューティング用)
このラッパーで期待通りの結果が得られる場合、PDQ Connect の PowerShellスキャンでも同様に動作します。
- # Load and sanitize external script, stripping any trailing ConvertTo-Json
- param (
- [Parameter(Mandatory)]
- [ValidateScript({ Test-Path $_ -PathType Leaf })]
- [string]$ScriptPath
- )
- $originalScript = Get-Content -Path $ScriptPath -Raw
- $convertToJsonPattern = '\|\s*ConvertTo-Json\b[^\r\n]*\s*$'
- $cleanedScript = [regex]::Replace(
- $originalScript.TrimEnd(),
- $convertToJsonPattern,
- '',
- 'IgnoreCase'
- ).TrimEnd()
- $scriptBlock = [scriptblock]::Create($cleanedScript)
- & $scriptBlock |
- ForEach-Object {
- if ($null -eq $_) { return }
- if ($_ -is [hashtable] -or $_ -is [System.Collections.Specialized.OrderedDictionary]) {
- $_ = [pscustomobject]$_
- }
- $out = [ordered]@{}
- foreach ($p in $_.PSObject.Properties) {
- $value = $p.Value
- if ($value -is [datetime]) {
- $value = $value.ToString('o')
- }
- $out[$p.Name] = $value
- }
- [pscustomobject]$out
- } | ConvertTo-Json -Depth 1 -Compress
関連情報
PowerShellスキャンは構造化出力を前提としているため、スキャナー結果の整形に使用する PSCustomObject に関する以下の記事もあわせてご参照ください。