none
POWERSHELL3.0でファイル監視出来ないでしょうか? RRS feed

  • 質問

  • いつもお世話になっています。

    Windows Server 2012で特定の2つのフォルダにファイルが作成されたのを監視して、

    別サーバに移動させるというようなことは出来ないでしょうか?

    【 データファイル WIN2012 \\192.168.0.1\C$\TEMP 】

      data_20131113101600_0001.txt

      data_20131113101605_0002.txt

    【 コントロールファイル WIN2012 \\192.168.0.1\C$\TEMP 】

      ctrl_20131113101600.txt

    【 移動先 WIN2008 \\192.168.0.2\C$\TEMP 】

      ctrlの_以下の20131113101600が同じdata_20131113101600_0001.txt

      をctrlファイルと共に移動させたいです。

    TEMPフォルダには複数存在していて、タイムスタンプが同じものだけを移動できればと思います。

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




    • 編集済み qoo_man 2013年11月13日 2:42
    2013年11月13日 1:17

回答

  • こんにちは

    ちょっと興味があったので、監視部分だけサンプルを作ってみました。

    $fromPath = "F:\Desktop\wk\wk1"
    $toPath = "F:\Desktop\wk\wk2"
    
    $watcher = New-Object System.IO.FileSystemWatcher
    $watcher.Path = $fromPath
    Register-ObjectEvent -InputObject $watcher -SourceIdentifier mywatch -EventName Created -Action {
    	 Move-Item $EventArgs.FullPath $toPath
    }
    
    #Unregister-Event -SourceIdentifier mywatch

    いくらかでも参考になれば幸いです。
    • 回答としてマーク qoo_man 2013年11月26日 8:04
    2013年11月13日 8:01
  • こんにちは、

    当方の環境では、自PCで実行し、FileServer1のフォルダーを監視してFileServer2のフォルダーへ移動する処理が以下のような感じでうまくいっています。

    FileServer1のフォルダーへは適当な画像ファイル(jpg)をコピーして試しました。

    ファイルのコピーはエクスプローラで行っています。

    $fromPath = "\\FileServer1\FromFolder"
    $toPath = "\\FileServer2\ToFolder"
    
    $watcher = New-Object System.IO.FileSystemWatcher
    $watcher.Path = $fromPath
    Register-ObjectEvent -InputObject $watcher -SourceIdentifier mywatch -EventName Created -Action {
    	 Move-Item $EventArgs.FullPath $toPath
    }
    
    #Unregister-Event -SourceIdentifier mywatch
    ファイルサーバーはどちらもWindowsServer2008R2、自PCはWindows8です。

    • 回答としてマーク qoo_man 2013年11月26日 8:04
    2013年11月14日 5:30

すべての返信

  • こんにちは

    ちょっと興味があったので、監視部分だけサンプルを作ってみました。

    $fromPath = "F:\Desktop\wk\wk1"
    $toPath = "F:\Desktop\wk\wk2"
    
    $watcher = New-Object System.IO.FileSystemWatcher
    $watcher.Path = $fromPath
    Register-ObjectEvent -InputObject $watcher -SourceIdentifier mywatch -EventName Created -Action {
    	 Move-Item $EventArgs.FullPath $toPath
    }
    
    #Unregister-Event -SourceIdentifier mywatch

    いくらかでも参考になれば幸いです。
    • 回答としてマーク qoo_man 2013年11月26日 8:04
    2013年11月13日 8:01
  • minminnana_prof 様

    サンプルありがとうございます。

    実際にコピーしてPathを変えてみましたが、何も起こりませんでした。

    考えられる原因は何でしょうか?

    ご教授お願いいたします。

    2013年11月13日 8:38
  • 今晩は

    ん~、fromPathのフォルダに何かファイルを突っ込んでみてもtoPathに移動されないという事でしょうか?

    あれ、もしかしてそんな感じの処理がやりたいわけではなかったりしますか?

    2013年11月13日 14:01
  • minminnana_prof 様

    フォルダにファイルを置いてもtopath側に移動されませんでした。

    結果表示は

    Id              Name            State      HasMoreData     Location             Command                 
    --              ----            -----      -----------     --------             -------                 
    1               mywatch         NotStarted False                                ...                     

    のようになっていました。

    もう一回実行すると

    Register-ObjectEvent : イベントにサブスクライブできません。ソース ID が 'mywatch' のサブスクライバーは、既に存在しています。
    発生場所 行:1 文字:21
    + Register-ObjectEvent <<<<  -InputObject $watcher -SourceIdentifier mywatch -EventName Created -Action {
        + CategoryInfo          : InvalidArgument: (System.IO.FileSystemWatcher:FileSystemWatcher) [Register-ObjectEvent]、ArgumentException
        + FullyQualifiedErrorId : SUBSCRIBER_EXISTS,Microsoft.PowerShell.Commands.RegisterObjectEventCommand

     となりました。

    やりたいことは、そのとおりなのでこれが動作すればいいのですが、何が問題なのか分からないです。

    折角教えて頂いたのに、私の理解が足りずにご迷惑おかけします。

    2013年11月14日 1:54
  • こんにちは、

    何度も確認してすいません。

    スクリプト実行時に表示されるメッセージは良さそうなので、監視は出来ているように思います。

    手順としては、

    スクリプト実行した後(即ち監視を開始した後)、fromPathに指定したフォルダにファイルを作成で合っていますでしょうか?

    それでもうまくいかないとなると「Move-Item」に指定したパスが合っているかどうか・・・・。

    「Move-Item」単独で実行してうまくいきますかね?

    2013年11月14日 2:32
  • minminnana_prof 様

    何度も申し訳ありません。

    fromとtoのサーバーが違うのですが、それが原因になったりするでしょうか?

    Move-Item $fromPath $toPath

    としたときに

    Move-Item : ソースとターゲット パスは同一のルートを持たなければなりません。[移動] 操作はボリューム間で行えません。
    発生場所 行:1 文字:10

    というエラーが出てしまいました。

    コードのそのままを抜き出して

    Move-Item $EventArgs.FullPath $toPath としたときには

    Move-Item : 引数が null であるため、パラメーター 'Path' にバインドできません。

    となったので、move-itemの送り元は変更しました。

    Frompathにファイル名を追記して

    Move-Item -path $fromPath -destination $toPath

    としたらファイルが移動されましたが、関係ありますか?

    • 編集済み qoo_man 2013年11月14日 3:06
    2013年11月14日 3:01
  • こんにちは、

    当方の環境では、自PCで実行し、FileServer1のフォルダーを監視してFileServer2のフォルダーへ移動する処理が以下のような感じでうまくいっています。

    FileServer1のフォルダーへは適当な画像ファイル(jpg)をコピーして試しました。

    ファイルのコピーはエクスプローラで行っています。

    $fromPath = "\\FileServer1\FromFolder"
    $toPath = "\\FileServer2\ToFolder"
    
    $watcher = New-Object System.IO.FileSystemWatcher
    $watcher.Path = $fromPath
    Register-ObjectEvent -InputObject $watcher -SourceIdentifier mywatch -EventName Created -Action {
    	 Move-Item $EventArgs.FullPath $toPath
    }
    
    #Unregister-Event -SourceIdentifier mywatch
    ファイルサーバーはどちらもWindowsServer2008R2、自PCはWindows8です。

    • 回答としてマーク qoo_man 2013年11月26日 8:04
    2013年11月14日 5:30
  • minminnana_prof 様

    そちらの環境では実行できるのですね。

    何が原因かさっぱりです。

    今度は対象を変えてやってみようと思います。

    また結果を書きます。

    色々と教えて頂いてありがとうございます。

    貴重な時間を割いていただいて申し訳ありません。

    2013年11月15日 5:12
  • こんにちは、

    あまりお役に立たなかったようで申し訳ございません。

    ただ、お話からすると監視自体は出来ているようですから単純にファイル移動の問題のように感じます。

    「Move-Item : ソースとターゲット パスは同一のルートを持たなければなりません。[移動] 操作はボリューム間で行えません。」のメッセージを検索したところ、同じ問題が発生しているケースも見つかりました。

    http://stackoverflow.com/questions/6138849/how-do-you-move-files-folders-across-volumes-with-powershell

    プロバイダが異なっていると発生するような事が書いてありますのでサーバーOSの種類やバージョンの影響を受けたりするのかも、と思ったりしています。(NASなんかだったりすると怪しさいっぱい?)

    何にしても「Move-Item」だけの問題であれば、Copy-ItemとRemove-Itemの組み合わせに変更するとか、RoboCopyコマンドを使ったりとかで回避できるのではと思います。

    2013年11月15日 7:06
  • minminnana_prof様

    返信が出来ておらず申し訳ありません。

    色々と教えて頂きありがとうございました。

    Robocopyなんかも考えてみます。

    最後まで丁寧に教えて頂いて感謝しています。

    2013年11月25日 3:06
  • これ、本当に動作しますか?

    actionの処理中に、その外で定義した$toPathを利用していますが、参照できないと思います。

    2018年1月26日 15:12
  • これ、本当に動作しますか?

    actionの処理中に、その外で定義した$toPathを利用していますが、参照できないと思います。

    質問の便乗で申し訳ありません。

    外で定義した変数を参照する方法はあるのでしょうか?

    2018年5月21日 2:05
  • Register-ObjectEventの-Action内のスクリプトブロックは、Register-ObjectEventが実行されている環境(ExecutionContext)上で実行されるようです。

    なので、今回ご提示されているスクリプトでも、$toPathの値は-Action内で正しく参照できるはずです。

    2018年5月21日 6:02
    モデレータ