a-ta3939
@a-ta3939

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

AWS CLIで一定時間内の新規アラートを取得したい

解決したいこと

AWS ClIで24時間以内に新規検出したアラートを取得するためにスクリプト作成をしているがコマンドがうまく通らないため、解決策をいただきたいです。

AWS CLI コマンド
aws guardduty list-findings --detector-id 環境のdetectorID --query "FindingIds" --finding-criteria "{"Criterion":{"updatedAt":{"Gte":"$startTime"}}}" --output json | ConvertFrom-Json

発生している問題・エラー

--finding-criteria "{"Criterion":{"updatedAt":{"Gte":"$startTime"}}}"

上記でUnknown optionsと出るため、こちらのコマンドが違うのかと思いますが、よくわかりません。

コマンドはPowershellで叩いてます。

※$startTimeは取得したい期間を定義してます。

お分かりの方どうぞ教えていただきたいです

0

2Answer

とりあえず引数に含まれるダブルクォートを \" のようにエスケープし、波括弧を全角から半角に直して再度試してください。また実行したコマンドと出たエラーは全文コピーして貼ってください。

0Like

Comments

  1. @a-ta3939

    Questioner

    コメントありがとうございます。
    指摘の通り修正してみましたが、同じエラーが表示されました。

    PCからこちらにペーストできないので画像での添付となってしまいますが、展開いたしますIMG_1572.jpeg

  2. 古いPowershellをお使いのようです.いずれにせよPowershellはオブジェクトを独自に解釈したりして色々面倒なので,まずはコマンドプロンプトを使ってください.

    一応ユーザーガイドにはPowershellも使えるとは書いてあるんですが,せめてPowershell 7を使うべきです.

  3. PowerShell の場合は \" でなく `" でエスケープするべきでした。そのように直して試してください。また、コマンドプロンプトを使うなら 多分 エスケープしないで当初のように書くのが正しいはずです(コマンドプロンプトはダブルクォートの扱いが特殊すぎて把握できていません)。

  4. @a-ta3939

    Questioner

    powershellでスクリプト作成を進めちゃってるので、今回はps1ファイルで作成しようと思ってます。
    ちなみに現在のバージョンが古いのは現場で使用してるため、バージョンをあげてしまうと使えなくなるツールが出てしまう可能性があるため、更新ができません。
    エスケープを使用するとエラーになってしまいますね。IMG_1578.jpeg

  5. `" でエスケープしたダブルクォートが消えているようですね。古い PowerShell の仕様なのかもしれませんが、詳しくないのでよく分かりません。以下によれば "" のように2つ重ねることでもエスケープできるようです。

    エラーの原因は相変わらず、引数中のダブルクォートが消えて JSON として不正な形式になっていることなので、エスケープがうまくいかないなら文字列結合などを使って引数を組み立てる方針でいくとよさそうです。

  6. @a-ta3939

    Questioner

    ご確認ありがとうございます。
    ""でかかってみましたがエスケープがうまくかかってないですね。
    powershellのバージョンのせいなんですかねー

  7. @a-ta3939

    Questioner

    バージョン7のpowershellで実行してみましたが、違ったエラーがでました。
    class部分がstringじゃなくて、intだよって記載ありますがGuardDutyの時間の取り方って形式からだと取れないんですかね?IMG_1579.jpeg

  8. エポックミリ秒で書けとのことです.

  9. 以下に書いてある通り、時間は Unix エポック秒をミリ秒単位の整数で与えてください。

    引数を ConvertTo-Json で組み立てるのはベストだと思います。

AIに修正を依頼すると次のような修正案が出てきたのですがいかがでしょうか。
上手くいかなかったらエラーコードごとAIに入れると何とかなるかもしれないと思います

$startTime = "2023-10-26T00:00:00Z" # 例:開始時間を設定

aws guardduty list-findings --detector-id 環境のdetectorID --query "FindingIds" --finding-criteria "{'Criterion':{'updatedAt':{'Gte':'$startTime'}}}" --output json | ConvertFrom-Json

0Like

Comments

  1. --finding-criteria オプションには JSON 形式の文字列を与えるべきですが、 JSON の中でシングルクォートは使えないので不正な形式としてエラーになると思います。

  2. すみません。上記生成コードの不備に気がつきませんでした。

    実行時エラー表示画像を貼っていただいていたので、そのままAIに与えてみました。
    まだ間違いはあるかもしれないのですが、Geminiで生成、GPTでチェックしています。
    参考情報として添付させていただきます。

    Google AI Studio生成回答

    PowerShellスクリプトのエラーは、aws guardduty list-findings コマンドに渡されるJSONペイロードのupdatedAt.Gteフィールドが、文字列ではなく整数である必要があるというパラメータ検証エラーです。GuardDuty APIがこのフィールドに整数型のタイムスタンプ(通常はUnixエポックからのミリ秒)を期待していることが原因です。

    修正するには、日付文字列をUnixエポックタイムスタンプに変換する必要があります。PowerShellでこれを行うには、以下のような手順が必要です。

    1. DateTimeオブジェクトに変換: まず、文字列をDateTimeオブジェクトに変換します。
    2. UnixエポックからのTicksを算出: 次に、そのDateTimeオブジェクトのTicksプロパティを取得し、Unixエポックからの差分を計算します。
    3. ミリ秒に変換: 最後に、Ticksをミリ秒に変換します。

    以下に修正されたスクリプトの例を示します。

    # startTimeを計算し、文字列としてフォーマット
    $startTime = (Get-Date).AddDays(-1).ToUniversalTime()
    
    # DateTimeオブジェクトをUnixエポックからのミリ秒に変換する関数
    function Get-UnixEpochMilliseconds {
        param (
            [Parameter(Mandatory = $true)]
            [DateTime]$DateTime
        )
        # UnixエポックのDateTimeオブジェクト
        $epoch = New-Object DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0, Utc
    
        # DateTimeオブジェクトとUnixエポックの差をTicksで計算
        $timeSpan = New-TimeSpan -Start $epoch -End $DateTime
    
        # Ticksをミリ秒に変換
        return [long]($timeSpan.TotalMilliseconds)
    }
    
    # startTimeをUnixエポックミリ秒に変換
    $startTimeEpoch = Get-UnixEpochMilliseconds -DateTime $startTime
    
    # criteriaObjectを作成
    $criteriaObject = @{
        Criterion = @{
            updatedAt = @{
                Gte = $startTimeEpoch
            }
        }
    }
    
    # JSONに変換
    $findingCriteria = $criteriaObject | ConvertTo-Json -Compress
    
    # 結果を出力 (デバッグ用)
    echo $findingCriteria
    
    # aws guardduty list-findingsコマンドを実行
    $findingIds = aws-vault exec  -- aws guardduty list-findings --detector-id  --query "FindingIds" --finding-criteria "$findingCriteria" --output json | ConvertFrom-Json
    
    #結果を表示
    Write-Host $findingIds
    

    重要な変更点:

    • Get-UnixEpochMilliseconds関数: この関数は、DateTimeオブジェクトをUnixエポックミリ秒に変換します。
    • $startTimeEpoch変数の作成: $startTimeEpoch 変数にミリ秒形式のタイムスタンプを格納します。
    • ToUniversalTime()の追加: $startTime の生成時に .ToUniversalTime() を呼び出すように変更しました。これにより、時刻がUTCで計算されるようになり、GuardDutyが予期する形式と一致するようになります。

    補足:

    • aws-vault exec の部分は、ご自身の環境に合わせて修正してください。
    • スクリプトをテストする際は、まず $findingCriteria の内容を出力して、意図したJSONが出力されていることを確認することをお勧めします。
    • GuardDuty APIのドキュメントをよく確認し、updatedAt.Gteフィールドのデータ型が本当に整数であることを確認してください。もし日付文字列を受け付けるのであれば、日付フォーマットが間違っている可能性があります。
    • エラーメッセージの詳細をよく読むと、問題の箇所を特定するのに役立ちます。

    この修正によって、aws guardduty list-findings コマンドが期待する形式でタイムスタンプを渡せるようになり、パラメータ検証エラーが解消されるはずです。

  3. エラーの指摘については合ってますね。提示されたコードは冗長です。エポック秒の取得は(下記でいくつかの方法が紹介されているように)1行で書けます。それを1000倍すればミリ秒が得られます。今回は小数点以下の精度はおそらく不要なのでこれで十分でしょう。

Your answer might help someone💌