none
CreationTimeを条件にファイルを取得できない RRS feed

  • 質問

  • お世話になります。

    ログファイルをCreationTimeを条件に取得したいのですが、うまく動作しません。

    他の日付属性および比較演算子でもダメでした。

    なお、イベントログの取得では日付属性を条件にしてもうまく動作します。

    ${DateTime} = "yyyy/mm/dd hh:mm:nn" -as [DateTime]

    NG:Get-ChildItem "C:\Log\Apache\*" -include access_log.* | Where-Object {$_.CreationTime -eq ${DateTime}}

    OK:Get-EventLog system | Where-Object {$_.TimeGenerated -eq ${DateTime}}

    よろしくお願い致します。

    2012年11月13日 6:30

回答

  • K. Takaokaさんのご回答の通り、やり方はいろいろあると思いますが、簡単にやるならこういうのもあるかと思います。

    where {(Get-Date $_.CreationTime.DateTime) -eq $DateTime}

    これも実際は文字列を経由してDateTime型に戻してるので、プログラム的にはあまりほめられたものでもないのですが、結果的には日付型で比較してますし、見た目的にはすっきりしていていいかもしれません。

    あるいは

    where {(Get-Date $_.CreationTime -Millisecond 0) -eq $DateTime}

    でもいけますね。こっちは文字列を経由しない分、よりよいかもしれません。

    2012年11月13日 9:01
    モデレータ
  • やりかたは色々あると思いますが、文字列にしてしまうのがお手軽じゃないでしょうか?

    where {
        $_.CreationTime.ToString("yyyyMMddHHmmss", 
            [Globalization.CultureInfo]::InvariantCulture) -eq "20121109102519" }

    みたいな。時間の比較でやりたければ、

    where {
         # 日付が同じ かつ
         $_.CreationTime.Date -eq $DateTime.Date -and
         # 00:00:00 からの経過秒数(切り捨て)が同じ
         [int] $_.CreationTime.TimeOfDay.TotalSeconds -eq
         [int] $DateTime.TimeOfDay.TotalSeconds
    }

     などなど。


    2012年11月13日 8:27

すべての返信

  • FileInfoオブジェクトのCreationTimeプロパティはミリ秒単位まで値が含まれているからなのではないでしょうか。

    返却されるDateTimeオブジェクトのMillisecondプロパティの値を確認してみてください。

    比較の際は、秒までで比較して、ミリ秒部分を切り捨てする処理が必要かと思います。

    2012年11月13日 6:58
    モデレータ
  • 牟田口大介様

    お世話になります。

    回答有難う御座いました。

    ${DateTime}への日付時間のセットで”2012/11/09 10:25:19.000”とミリ秒まで指定して比較演算子を-geに変更すると値が取得できました。

    しかし、目的の値が取得できたわけではないので、秒までで比較するようにしたいのですが、記述が分かりません。

    Where-Object {$_.TimeGenerated -eq ${DateTime}}の部分をどのように記述すればよろしいのでしょうか?

    よろしくお願い致します。

    2012年11月13日 8:00
  • やりかたは色々あると思いますが、文字列にしてしまうのがお手軽じゃないでしょうか?

    where {
        $_.CreationTime.ToString("yyyyMMddHHmmss", 
            [Globalization.CultureInfo]::InvariantCulture) -eq "20121109102519" }

    みたいな。時間の比較でやりたければ、

    where {
         # 日付が同じ かつ
         $_.CreationTime.Date -eq $DateTime.Date -and
         # 00:00:00 からの経過秒数(切り捨て)が同じ
         [int] $_.CreationTime.TimeOfDay.TotalSeconds -eq
         [int] $DateTime.TimeOfDay.TotalSeconds
    }

     などなど。


    2012年11月13日 8:27
  • K. Takaokaさんのご回答の通り、やり方はいろいろあると思いますが、簡単にやるならこういうのもあるかと思います。

    where {(Get-Date $_.CreationTime.DateTime) -eq $DateTime}

    これも実際は文字列を経由してDateTime型に戻してるので、プログラム的にはあまりほめられたものでもないのですが、結果的には日付型で比較してますし、見た目的にはすっきりしていていいかもしれません。

    あるいは

    where {(Get-Date $_.CreationTime -Millisecond 0) -eq $DateTime}

    でもいけますね。こっちは文字列を経由しない分、よりよいかもしれません。

    2012年11月13日 9:01
    モデレータ
  • K. Takaoka様

    牟田口大介様

    お世話になります。

    回答有難う御座いました。

    下記の二通りでうまくいきました。

    Where-Object {$_.CreationTime.ToString("yyyy/MM/dd hh:mm:ss") -eq ${DateTime}}

    Where-Object {(Get-Date $_.CreationTime.DateTime) -eq ${DateTime}}

    下記は「Get-Date : パラメーター名 'Millisecond' に一致するパラメーターが見つかりません。」とエラーが出てしまいうまくいきませんでした。

    Where-Object {(Get-Date $_.CreationTime -Millisecond 0) -eq ${DateTime}}

    うまく行った記述で進めていきたいと思います。

    有難うございました。

    2012年11月14日 2:09
  • Get-Dateコマンドレットの-MillisecondパラメータはPowerShell 3.0からの対応でした。よって2.0環境ではエラーになりますね。

    失礼しました。

    2012年11月14日 4:29
    モデレータ
  • Where-Object {$_.CreationTime.ToString("yyyy/MM/dd hh:mm:ss") -eq ${DateTime}}

    細かい話ですが、ToString に Culture を指定しない場合、コントロールパネルの設定が採用されます。

    たとえば、日本人の方で(お役所なんかではよく)地域の設定で年表記を和暦に設定されていることがあります。和暦になっていると "yyyy" は "  24" になりますので場合によっては期待しない値になることがあるので注意してください。

    2012年11月14日 7:13
  • where {(Get-Date $_.CreationTime.DateTime) -eq $DateTime}

    PowerShell では、こんなプロパティが追加されているんですね。こちらもコントロールパネルの設定に準拠するので、(まずないとは思いますが)時刻の表記を「秒なし」に設定されていると、「分までが一致した場合」という意味になっちゃうみたいですね。

    2012年11月14日 7:23
  • K. Takaoka様

    牟田口大介様

    お世話になります。

    ご指摘有難うございます。

    業務でPowerShellを使用するのが初めてなので、

    Bingってわからない場合は、また質問させて頂きます。

    2012年11月15日 0:34