次の方法で共有


PowerShell スクリプトを使用して監査ログを検索する

今日の世界では、セキュリティ、コンプライアンス、および監査は、IT 管理者にとって最優先事項になっています。 Microsoft 365 には、組織がセキュリティ、コンプライアンス、および監査を管理するのに役立ついくつかの組み込みの機能があります。 特に、統合監査ログは、セキュリティ インシデントとコンプライアンスの問題を調査するのに役立ちます。 次の方法を使用して、監査ログを取得できます。

監査ログを定期的に取得する必要がある場合は、大規模な組織にスケーラビリティとパフォーマンスを提供して何百万もの監査レコードを継続的に取得できるため、Office 365 Management Activity API を使用するソリューションを検討する必要があります。 Microsoft Purview ポータルまたはコンプライアンス ポータルで監査ログ検索ツールを使用すると、短時間で発生する特定の操作の監査レコードをすばやく見つけることができます。 特に大規模な組織の場合、監査ログ検索ツールでより長い時間範囲を使用すると、返されるレコードが多すぎて簡単に管理またはエクスポートできない場合があります。

特定の調査またはインシデントの監査データを手動で取得する必要がある場合、特に大規模な組織で日付範囲が長い場合は、Search-UnifiedAuditLog コマンドレットを使用するのが最適なオプションです。 この記事には、(コマンドレットを実行するたびに、) そのコマンドレットを使用して最大 50,000 件の監査レコードを取得でき、それらを CSV ファイルにエクスポートする PowerShell スクリプトが含まれています。その CSV ファイルは、Excel の Power Query を使用して書式設定して、レビューに役立てることができます。 この記事のスクリプトを使用すると、大規模な監査ログ検索がそのサービスでタイムアウトになる可能性を最小限に抑えることもできます。

ヒント

E5 のお客様でない場合は、90 日間の Microsoft Purview ソリューション試用版を使用して、Purview の追加機能が組織のデータ セキュリティとコンプライアンスのニーズの管理にどのように役立つかを確認してください。 Microsoft Purview コンプライアンス ポータルのトライアル ハブで今すぐ開始してください。 サインアップと試用期間の詳細については、こちらをご覧ください。

スクリプトを実行する前に

  • スクリプトを正常に使用して監査レコードを返すようにするには、組織で監査ログを有効にする必要があります。 Microsoft 365 および Office 365 Enterprise 組織では、監査ログは既定でオンになっています。 組織で監査ログ検索が有効になっていることを確認するには、Exchange Online PowerShell で次のコマンドを実行します。

    Get-AdminAuditLogConfig | FL UnifiedAuditLogIngestionEnabled
    

    UnifiedAuditLogIngestionEnabled プロパティの値 Trueは、監査ログ検索が有効になっていることを示します。

  • スクリプトを正常に実行するには、Exchange Onlineの [監査ログの表示のみ] ロールまたは [監査ログ] ロールを割り当てる必要があります。 既定では、これらの役割は、Exchange 管理センターの [アクセス許可] ページで、コンプライアンス管理および組織管理の役割グループに割り当てられます。

  • スクリプトが完了するまでに長い時間がかかる場合があります。 実行にかかる時間は、スクリプトで監査レコードを取得するために構成する日付範囲と間隔のサイズによって異なります。 日付範囲が大きく、間隔が小さいと実行時間が長くなります。 日付範囲と間隔の詳細については、手順 2 の表を参照してください。

  • この記事で提供されるサンプル スクリプトは、Microsoft のいかなる標準サポート プログラムまたはサービスの下でもサポートされません。 サンプル スクリプトは現状のまま提供され、いかなる保証も伴いません。 さらに、Microsoft は、商品性、特定目的への適合性の黙示の保証を含む、一切の黙示の保証をいたしかねます。 本サンプル スクリプトおよびドキュメントの使用または性能に起因するすべてのリスクは、お客様が負うものとします。 Microsoft、本サンプル スクリプトの作成者、および本スクリプトの作成、製造、配布に関与する者は、いかなる場合においても、本サンプル スクリプトおよびドキュメントの使用または使用不能から生じる損害 (逸失利益、事業の中断、事業情報の喪失またはその他の金銭的損失を含みますがこれらに限定されません) に関して一切責任を負いません。たとえ、Microsoft がこのような損害の可能性について知らされていた場合でも同様です。

手順 1: Exchange Online PowerShell に接続する

最初の手順は、Exchange Online PowerShell へ接続することです。 最新の認証、多要素認証 (MFA) を使用して接続できます。 詳しい手順については、「Exchange Online PowerShell に接続する」を参照してください。

手順 2: スクリプトを変更して実行し、監査レコードを取得する

Exchange Online PowerShell に接続した後、次の手順は、スクリプトを作成、変更、および実行して、監査データを取得することです。 監査ログ検索スクリプトの最初の 7 行には、検索を構成するために変更できる次の変数が含まれています。 これらの変数の説明については、手順 2 の表を参照してください。

  1. ファイル名のサフィックスに ".ps1" を使って、次のテキストを Windows PowerShell スクリプト ファイルに保存します。 たとえば、SearchAuditLog.ps1 というファイル名です。

    #Modify the values for the following variables to configure the audit log search.
    $logFile = "d:\AuditLogSearch\AuditLogSearchLog.txt"
    $outputFile = "d:\AuditLogSearch\AuditLogRecords.csv"
    [DateTime]$start = [DateTime]::UtcNow.AddDays(-1)
    [DateTime]$end = [DateTime]::UtcNow
    $record = "AzureActiveDirectory"
    $resultSize = 5000
    $intervalMinutes = 60
    
    #Start script
    [DateTime]$currentStart = $start
    [DateTime]$currentEnd = $end
    
    Function Write-LogFile ([String]$Message)
    {
        $final = [DateTime]::Now.ToUniversalTime().ToString("s") + ":" + $Message
        $final | Out-File $logFile -Append
    }
    
    Write-LogFile "BEGIN: Retrieving audit records between $($start) and $($end), RecordType=$record, PageSize=$resultSize."
    Write-Host "Retrieving audit records for the date range between $($start) and $($end), RecordType=$record, ResultsSize=$resultSize"
    
    $totalCount = 0
    while ($true)
    {
        $currentEnd = $currentStart.AddMinutes($intervalMinutes)
        if ($currentEnd -gt $end)
        {
            $currentEnd = $end
        }
    
        if ($currentStart -eq $currentEnd)
        {
            break
        }
    
        $sessionID = [Guid]::NewGuid().ToString() + "_" +  "ExtractLogs" + (Get-Date).ToString("yyyyMMddHHmmssfff")
        Write-LogFile "INFO: Retrieving audit records for activities performed between $($currentStart) and $($currentEnd)"
        Write-Host "Retrieving audit records for activities performed between $($currentStart) and $($currentEnd)"
        $currentCount = 0
    
        $sw = [Diagnostics.StopWatch]::StartNew()
        do
        {
            $results = Search-UnifiedAuditLog -StartDate $currentStart -EndDate $currentEnd -RecordType $record -SessionId $sessionID -SessionCommand ReturnLargeSet -ResultSize $resultSize
    
            if (($results | Measure-Object).Count -ne 0)
            {
                $results | export-csv -Path $outputFile -Append -NoTypeInformation
    
                $currentTotal = $results[0].ResultCount
                $totalCount += $results.Count
                $currentCount += $results.Count
                Write-LogFile "INFO: Retrieved $($currentCount) audit records out of the total $($currentTotal)"
    
                if ($currentTotal -eq $results[$results.Count - 1].ResultIndex)
                {
                    $message = "INFO: Successfully retrieved $($currentTotal) audit records for the current time range. Moving on!"
                    Write-LogFile $message
                    Write-Host "Successfully retrieved $($currentTotal) audit records for the current time range. Moving on to the next interval." -foregroundColor Yellow
                    ""
                    break
                }
            }
        }
        while (($results | Measure-Object).Count -ne 0)
    
        $currentStart = $currentEnd
    }
    
    Write-LogFile "END: Retrieving audit records between $($start) and $($end), RecordType=$record, PageSize=$resultSize, total count: $totalCount."
    Write-Host "Script complete! Finished retrieving audit records for the date range between $($start) and $($end). Total count: $totalCount" -foregroundColor Green
    
  2. 次の表にリストされている変数を変更して、検索条件を構成します。 スクリプトにはこれらの変数のサンプル値が含まれていますが、ユーザーの特定の要件を満たすために (特に明記されていない限り) 変更する必要があります。



変数 サンプル値 説明
$logFile "d:\temp\AuditSearchLog.txt" スクリプトによって実行された監査ログ検索の進行状況に関する情報を含むログ ファイルの名前と場所を指定します。 スクリプトは UTC タイムスタンプをログ ファイルに書き込みます。
$outputFile "d:\temp\AuditRecords.csv" スクリプトによって返される監査レコードを含む CSV ファイルの名前と場所を指定します。
[DateTime]$start[DateTime]$end [DateTime]::UtcNow.AddDays(-1)
[DateTime]::UtcNow
監査ログ検索の日付範囲を指定します。 スクリプトは、指定された日付範囲内で発生した監査アクティビティのレコードを返します。 たとえば、2021 年 1 月に実行されたアクティビティを返すには、開始日を "2021-01-01"、終了日を "2021-01-31" と指定します (値は必ず二重引用符で囲んでください)。スクリプトのサンプル値は、24 時間前に実行されたアクティビティのレコードを返します。 値にタイムスタンプを含めない場合、既定のタイムスタンプは指定された日付の午前 0 時 (深夜) です。
$record "AzureActiveDirectory" 検索する監査アクティビティ (操作とも呼ばれます) のレコードの種類を指定します。 このプロパティは、アクティビティがトリガーされたサービスまたは機能を示します。 この変数に使用できるレコードの種類の一覧については、「監査ログ レコードの種類」を参照してください。 レコードの種類の名前または ENUM 値を使用できます。

ヒント: すべてのレコードの種類の監査レコードを返すには、値 $null (二重引用符なし) を使用します。
$resultSize 5000 Search-UnifiedAuditLog コマンドレットがスクリプトによって呼び出されるたびに返される結果の数を指定します (結果セットと呼ばれます)。 5,000 の値は、コマンドレットでサポートされている最大値です。 この値はそのままにしておきます。
$intervalMinutes 60 返される 5,000 レコードの制限を克服するために、この変数は指定したデータ範囲を受け取り、より小さな時間間隔にスライスします。 これで、日付範囲全体ではなく各間隔が、コマンドの 5000 レコード出力制限の対象になります。 日付範囲内の 60 分間隔あたり 5,000 レコードの既定値は、ほとんどの組織で十分です。 ただし、スクリプトが maximum results limitation reached (最大結果制限に達しました) というエラーを返した場合は、時間間隔を短くして (たとえば、30 分または 15 分にして) スクリプトを再実行します。

前の表にリストされている変数のほとんどは、Search-UnifiedAuditLog コマンドレットのパラメーターに対応しています。 これらのパラメーターの詳細については、「Search-UnifiedAuditLog」を参照してください。

  1. ローカル コンピューターで Windows PowerShell を開き、変更したスクリプトを保存したフォルダーに移動します。

  2. Exchange Online PowerShell でコマンドレットを実行します。以下に例を示します。

    .\SearchAuditLog.ps1
    

スクリプトの実行中は、進行状況メッセージが表示されます。 スクリプトの実行が終了すると、監査レコードを含むログ ファイルと CSV ファイルが作成され、$logFile 変数と $outputFile 変数で定義されたフォルダーに保存されます。

重要

スクリプトでコマンドレットを実行するたびに返される監査レコードの最大数には、50,000 の制限があります。 このスクリプトを実行して 50,000 件の結果が返される場合は、日付範囲内に発生したアクティビティの監査レコードが含まれていない可能性があります。 その場合は、日付範囲をより短い期間に分割してから、日付範囲ごとにスクリプトを再実行することをお勧めします。 たとえば、90 日間の日付範囲で 50,000 件の結果が返される場合、スクリプトを 2 回再実行できます。1 回目は日付範囲の最初の 45 日間、2 回目は残りの 45 日間です。

手順 3: 監査レコードを書式設定して表示する

スクリプトを実行して監査レコードを CSV ファイルにエクスポートした後、監査レコードの確認と分析を容易にするために CSV ファイルを書式設定することをお勧めします。 1 つの方法として、Excel の Power Query に含まれる JSON 変換機能を使用して、[AuditData] 列の JSON オブジェクトの各プロパティを、独自の列に分割することができます。 詳しい手順については、「監査ログ レコードをエクスポート、構成、表示する」の「手順 2: Power Query エディターを使用してエクスポートされた監査ログを書式設定する」を参照してください。