

表題の通りですが、以下のような感じで特定のフォルダだけ削除を実施したくないのですが  
上手くいきません。

なにか方法はないでしょうか？

[code]

    $filePath = 'C:\temp\'　 # 削除対象フォルダ
    $excludeItem = '処理済'　# 削除対象内で除外したいフォルダ
    
    Get-ChildItem -Path $filePath -Exclude $excludeItem -Recurse | Where-Object{$_.LastWriteTime -lt (Get-Date).AddDays(-2)} | Remove-Item -Force -WhatIf
    
[/code]


CC BY-SA 4.0
2022-02-21T06:45:08.103
86490
2022-02-21T23:10:23.813
2022-02-21T11:02:11.367
3060
51539
question
powershell
Powershellでフォルダ内のファイル削除を実施時に、特定のフォルダだけ除外したい


下記のスクリプトでできます。

[code]

    ls -Path $filePath -Recurse | ?{if($_.PSIsContainer){$_.Name -ne $excludeItem -and (ls $_.FullName -Directory -Filter $excludeItem).Count -eq 0}else{$_.FullName -notmatch $excludeItem}} | rm -Recurse  -Force -WhatIf
    
[/code]

**解説**

ご質問の通りフォルダの`-Exclude`はできないので、とりあえず全ファイルを再帰的に取得します。

[code]

    ls -Path $filePath -Recurse
    
[/code]

単純に次のWhere-Object(エイリアスは`?{}`)でできそうと思いますが、サブフォルダの`$excludeItem`を考慮してくれません。  
つまり`C:\temp\hoge\処理済\`が存在する場合でも、`C:\temp\hoge\`を削除しようとするためNGです。

[code]

    ls -Path $filePath -Recurse | ?{ $_.fullname -notmatch $excludeItem }
    
[/code]

これを回避するために、Where-Objectの中でフォルダとファイルに対する処理を分けました。

[code]

    ?{
        if($_.PSIsContainer){
            # フォルダの場合、フォルダ名が $excludeItem ではない、かつ子フォルダに $excludeItem が一つも存在しない
            $_.Name -ne $excludeItem -and
            (ls $_.FullName -Directory -Filter $excludeItem).Count -eq 0
        }else{
            # ファイルの場合、フルパスに $excludeItem を含まない
            $_.FullName -notmatch $excludeItem
        }
    }
    
[/code]

後は該当のファイルフォルダを削除します。(もちろん`-WhatIf`オプションがあるので実際には消えません)

[code]

     | rm -Recurse -Force -WhatIf
    
[/code]


CC BY-SA 4.0
2022-02-21T12:13:14.823
86496
2022-02-21T12:48:19.143
2022-02-21T12:48:19.143
9820
9820
86490
answer


質問の内容を整理すると、

[code]

    $filePath = 'C:\temp\'　 # 削除対象フォルダ
    $excludeItem = '処理済'　# 削除対象内で除外したいフォルダ
    
[/code]

を前提に

  * `$filePath` 配下を再帰的に削除を行いたい
  * ただし、`$filePath` 直下にある `$excludeItem` 配下は削除から除外したい

でしょうか。

[`Get-ChildItem`](https://docs.microsoft.com/en-
us/powershell/module/microsoft.powershell.management/get-
childitem?view=powershell-5.1) の `-Exclude` は 除外する名前を指定するもので、例えば `*.txt`
は削除しない、など個々のファイル名に対する除外指定に使えます。今回のように特定のディレクトリ以下全てを除外する機能は持ちません。

* * *

「`$filePath` 配下を再帰的に削除」という発想を転換して

  * `$filePath` 直下のディレクトリ（ただし`$excludeItem`を除く）を再帰的に削除
  * `$filePath` 直下のファイルを削除

と分けて考えれば、シンプルな記述ができそうです。具体的には

[code]

    Get-ChildItem $filePath -Directory -Exclude $excludeItem | Remove-Item -Recurse
    Get-ChildItem $filePath -File | Remove-Item
    
[/code]

でどうでしょうか？


CC BY-SA 4.0
2022-02-21T23:10:23.813
86502
2022-02-21T23:10:23.813
4236
86490
answer