• ベストアンサー

PowerShell try~catchについて

現在、Powershellでスクリプトを作成中ですが、動作がうまくいかず困っております。 スクリプトには以下のコードを記述しています。 簡単に書くと、対象のディレクトリにある作成から90日を超えたアイテムを削除、削除できたら"成功"、削除できなかったら"失敗"と表示します。 $log_dir #削除するファイルが入っているディレクトリ $message1 = "削除完了" $message2 = "削除失敗" try { #作成から90日経過したファイルを削除  Get-Childitem $log_dir | Where-Object [$_.LastWriteTime -lt (Get-Date).AddDays(-90)} | Remove-Item #削除完了メッセージ表示  Write-Host $message1 } catch { #削除失敗メッセージ表示 Write-Host $message2 } 現時点で$log_dirに90日を超えてないファイルがあったとします。 その際は削除されないのですが、上記のコードのままだと$message1が表示されてしまい、catchにいきません。 どう修正すれば、catchに行くでしょうか? Powershell初心者のため、申し訳ございませんが、ご教示をお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • dell_OK
  • ベストアンサー率13% (740/5645)
回答No.2

90日を超えていないファイルがひとつでもあった場合、と言うことでしたら、 例えば、以下のように、前もってそのファイルがあるかどうか確認して、あれば終了するとかになると思います。 if((Get-Childitem $log_dir | Where-Object {$_.LastWriteTime -ge (Get-Date).AddDays(-90)}).Count -ne 0){ Write-Host "90日を超えていないファイルがあります" exit } 余談 LastWriteTime は最終更新日時ですが大丈夫でしょうか。 作成日時は CreationTime です。 それと、90日と言っても、このままでは時刻も含まれているので、90日前の現在時刻との判定になっていると思います。

ptgapsokwave
質問者

お礼

ありがとうございました。

その他の回答 (1)

  • luka3
  • ベストアンサー率74% (299/401)
回答No.1

try~catch は処理を行おうとした時に、例外が発生した場合に対応するものです。 ですので、【ファイルを削除できた】場合には【処理が正常に動作した】ため例外は発生しません。 ここで例外が発生するには、ファイルがロックされているなどの理由で削除しようとしたが失敗した、などになります。 $message2の表示を確認したい場合は、例えば、90日前のOfficeファイルを開いた状態(ロックがかかる)でスクリプトを実行してみてください。 90日を超えてないファイルは、Where-Objectで【条件の対象外】となったことから次の処理(Remove-Item)へ渡されないだけで、これも正常な処理なので例外発生とはなりません。 $message2は"削除失敗"なんですよね? "90日以内のファイルです" ではないですね。 スクリプトは間違ってないです。

ptgapsokwave
質問者

お礼

ありがとうございました。

関連するQ&A

  • PowerShellでファイル存在確認するとき

    PowerShellについて勉強中です。 現在、日付を取得したものをファイル名にしてログファイルを作成し、そこに、その日の実行したスクリプトの結果が追記されていくようにしたいのですが、新規にファイルを作成した時には、当然問題がないのですが、new-itemを使用したため、すでにフォルダがありますとエラーになってしまいます。 ログファイルを作成する部分と、スクリプト実行の部分を分けずに、ひとつのps1にしなければなりません。 そのため、if文などで分岐をする必要があると思うのですが、ログのファイル名が日付を取得するので、このような場合、どう記述するものなのか、教えていただければと思います。 日付を取得してファイルを作成したところまでを、下に書きます。 よろしくお願いします。 Function GetFileName([ref]$fileName) #日付を取得してログファイル名に設定する { $invalidChars = [io.path]::GetInvalidFileNamechars() $date = Get-Date -format yyyy/MM/dd $fileName.value = ($date.ToString() -replace "[$invalidChars]","-") + ".log" } $fileName = $null #ログファイルをc:\shareに作成する GetFileName([ref]$fileName) new-item -path c:\share -name $filename -itemtype file この下に、実行するバッチの起動などのスクリプトが続きます。

  • PowerShellのスクリプト実行について

    PowerShellのスクリプト実行について PowerShellの勉強をしていますが、スクリプトを実行できません。。。 なんか、スクリプトの環境変数を設定するようですが、どこにも 設定方法がないです。。。。 もちろん、Set-ExecutionPolicy Unrestrictedは実行してあります。 以下日付と時間を表示するだけのスクリプトです。 ---------test.ps1--------- get-date get-time ---------------------------- スクリプトファイルの置き場所 ⇒ C:\script-test\test.ps1 ちなみに、スクリプトファイルを置いたディレクトリに移動して 実行しても、以下のようなメッセージが出て実行できませんでした。。 用語 'C:\script-test' は、コマンドレット、関数、スクリプト ファイル、または操作 可能なプログラムの名前として認識されません。名前が正しく記述されていることを確 認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試行してく ださい。 発生場所 行:1 文字:15 + C:\script-test <<<< .\test.ps1 + CategoryInfo : ObjectNotFound: (C:\script-test:String) []、Comma ndNotFoundException + FullyQualifiedErrorId : CommandNotFoundException どなたかご教授下さい。

  • 簡単なPowerShell

    Windows10のPowerShellで、ディレクトリを作りたいのですが、本日の日付の翌日の日付をyyyymmdd の形式で表した名前のフォルダを作りたいです。 例えば、本日が2022年5月25日であれば、c:\xxx\に、20220526 というフォルダを自動生成したいです。 最終的には、Windowsキー+R キーでファイル名を指定して実行から これが起動できればOKなのですが、何かスクリプトのようなものを作らなければなりませんか?(PowerShellド素人です) (Get-Date).AddDays(+1).ToString("yyyyMMdd") で翌日のyyyymmddを 取り出せることはわかったのですが、それを使って c:\xxxにフォルダはどう作るのかすらわかっていません。 mkdir c:\xxx\(Get-Date).AddDays(+1).ToString("yyyyMMdd") はやっても無駄でした。文法がわからず困ってます。

  • Powershellでzip圧縮が出来ない

    Powershellでzip圧縮しようとしているのですが、 ・Powershell ISEで実行すると正常に圧縮 ・コマンドプロンプトで実行すると、「圧縮(zip形式)フォルダーエラー」が発生し、圧縮できない という現象が発生しています。コマンドプロンプトで実行できるようにしたいのですが、原因がわからないので、御教示をお願いします。 ・環境 Windows XP SP3 Powershell 2.0 ・Powershellソース # 引数チェック # 引数の数が2以外の時は異常終了 if ($args.Length -ne 2 ) { write-host "引数エラー" exit 2; } # 圧縮zipファイル名 $ZipFilePath = $Args[0] # 圧縮対象ファイル名 $TargetItems = $Args[1] # 圧縮先パス存在チェック if((Test-Path (Split-Path $ZipFilePath -Parent)) -ne $True){ write-host "圧縮先パスエラー" exit 3; } # 圧縮対象ファイル存在チェック if((Test-Path ($TargetItems)) -ne $True){ write-host "圧縮対象ファイルエラー" exit 4; } # Zipファイルが存在する場合は削除 if(Test-Path -Path $ZipFilePath) { Remove-Item -Path $ZipFilePath } # Zipファイル作成 Set-Content $ZipFilePath ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18)) (dir $ZipFilePath).IsReadOnly = $false # Zipファイルにファイルを投入 $shell = New-Object -com Shell.Application $zipfile = $shell.NameSpace($ZipFilePath) $archivedItems = New-Object Collections.ArrayList # 圧縮対象ファイルの数だけループ foreach($item in ($TargetItems | %{Get-Item -Path $_})) { # ファイルをZipファイルに投入。圧縮処理は非同期なので、その終了を待つ。 $archivedItems.Add($item) | Out-Null $zipfile.CopyHere($item.FullName) while($true) { if($archivedItems.Count -eq $zipfile.Items().Count) { break } Start-Sleep -Seconds 1 } } write-host "処理終了" exit 0

  • PowerShellでフォルダを削除できない・・・

    [PowerShell]で作成されてから90日以降のフォルダとファイルを削除したいのですが・・・フォルダの削除がうまくいきません・・・ Script Guyを参考に、 $a = Get-ChildItem C:\Scripts foreach($x in $a) { $y = ((Get-Date) - $x.CreationTime).Days if ($y -gt 90 -and $x.PsISContainer -ne $True) {$x.Delete()} } これでC:\Scripts配下のファイルを消すことができることがわかったのですが、C:\Scripts配下のフォルダを削除する方法がわかりません。 なぜこれだとファイルしか消えないのでしょうか? 対象のフォルダにはいっぱいファイル数がありかつファイルサイズもそこそこあります。 PowerShellを動かした時にマシンにかかる負荷を極力抑えたいと思っています。 (なのでループで対象日付のファイルを拾い消し→次にフォルダと考えています。負荷低減になっていますでしょうか?) 詳しい方教えていただけませんでしょうか?

  • powershellとiniファイル

    ps1よりiniファイルを読み込むスクリプトを作成中です。 iniファイルには以下の記載をしています。 いわゆる連想配列です。 $info = @{} $info[0] = @{ host=testest1 ip=192.168.0.0 } $info[1] = [ host=testest2 ip=192.168.0.1 } 一方、ps1は以下の通り、コードを記述しています。 $INI_PATH = @(Split-Path $script:myInvocation.MyCommand.Path -Parent).Trim() $INI_FILE = "ini_test2.ini" $INI_FULLNAME = $INI_PATH + "\" + $INI_FILE $PARAMETER = @{} Get-Content $INI_FULLNAME | %{$PARAMETER += ConvertFrom-StringData $_} $host_info = $PARAMETER.info[0] #値格納 $host_info いざ、実行すると、 「ConvertFrom-StringData : データ行 '}' の形式が '名前=値' ではありません。」、「項目は既に追加されています。」とのエラーが出ます。 どのように変えればエラーがなくなりますでしょうか。 Powershellの初歩的な質問で申し訳ないのですが、ご回答をよろしくお願いいたします。

  • powershell 複数の文字列を連続で検索する

    サーバのログを検索一覧の内容(正規表現で複数のキーワードをAND検索する)から順番に検索して見つかったら”○”を表示させるスクリプトを作成しておりますが、うまく出来ずアドバイスを頂きたいです。よろしくお願いいたします。 ※環境としましては、サーバから取得したログを ローカルのPCで作業しております。 powershellのバージョンは5.1です。 (検索一覧:kensakulist.txt) ^(?=.*○)(?=.*△)(?=.*□).*$ ^(?=.*○○)(?=.*△△)(?=.*□□).*$ ^(?=.*○○○)(?=.*△△△)(?=.*□□□).*$ ...... (以下作成中のスクリプト内容) # 検索一覧を配列に格納 $Look = @(Get-Content -LiteralPath kensakulist.txt -Encoding UTF8) # サーバのログ内容を変数に格納 $Log = [IO.File]::ReadAllText("C:\Users\....\Documents\script\powershell\.findlog.txt") $Ok = "○" $NG = "×" # 検索処理する foreach( $a in $Look ){ #配列を順番に検索 if( $a -match $Log){ echo $Ok; } else{ echo $Ng; } }

  • powershellの配列について

    すみませんが、powershellの配列について、困っていることがあります。 下記に教えていただければと思います。 【やりたいこと】 スペースがバラバラに入っているファイルの中身を配列に格納したい。 その際、スペースを省いて数字のみ配列に入れたい 【今の状態】 > $test4 = $(Get-Content -path "C:\a.txt") > echo $test4 1 2 3 4 5 6 7 89 > write-host $test4[0] 1 > write-host $test4[1] (スペースが認識されてしまう) > write-host $test4[2] 2 【望む結果】 $test4にファイルの中身を格納する。 その後、以下の結果にしたい。 > write-host $test4[0] 1 > write-host $test4[1] 2 > write-host $test4[7] 89

  • Powershellでtsファイルをmp4に変換

    Powershellでtsファイルを無劣化でmp4に変換する事が出来そうなので 下記の記事を参考にスクリプト(test.ps1)を作成してみました。 http://pcsos.blog89.fc2.com/blog-entry-243.html '-------------------------------------------------- # MP4・MPG・WMV・TS ⇒ H.264 MP4 (PowerShell ファイル名スペース対応) $TARGET_DIR="C:\Users\ssd\Desktop\変換前\" $DEST_DIR="C:\Users\ssd\Desktop\変換後\" $FFMPEG="C:\ffmpeg-2022-12-11\bin\ffmpeg.exe" $FFMPEG_OPT_VIDEO="-c:v copy" $FFMPEG_OPT_AUDIO="-c:a copy" function h264enc { if ($args.count -ge 1) { $arg="-i '$args.mpg' -movflags faststart $FFMPEG_OPT_VIDEO $FFMPEG_OPT_AUDIO $DEST_DIR'$args.mp4'" powershell -Command "$FFMPEG $arg" } else { "エンコード対象のファイルを指定してください。" } } cd $TARGET_DIR Get-ChildItem | ForEach-Object { h264enc $_.Basename } pause '-------------------------------------------------- 変換されそうにはなりますが、   mpegを書き出し時に 「No such file or directory」とエラーになります。 エラーの修正をお願いします。

  • PowerShellからBATに制御を戻す方法

    【環境】 OS:Windows Server 2008 R2 SP1 【状況】 BATファイルにてメニューを作成しており、表示されたメニューの中からPowerShellで作成したテストイベントを送信するスクリプトを実行するための番号を入力後、Enterキーを押すとテストイベントが送信されるようになっております。 PowerShellが実行された後、呼び出し元のBATファイルに戻りメニューを表示させたいと考えておりますが、PowerShellが実行完了後、BATファイルに戻りません。 ※ JP1の動作定義ファイル(ntevent.conf)を修正しており、修正したフィルタが正常に動作することおよび既存のフィルタが影響がないかを確認するためにBATファイルからPowerShellでテストイベントを発行するためにBATおよびPowerShellでプログラムを作成しております。 【ご教示頂きたい点】 PowerShellが実行後、BATファイルに戻り、メニューを表示させるようにしたいと考えており、どのようにしたらBATに制御を戻すことができるかご教示頂けますでしょうか。