新しいオプションを追加して、-Exclude
で指定したフォルダとそのサブフォルダを完全に検索から除外する機能を実装するカスタマイズ例を説明します。新しいオプションを -ExcludeWithSubdirectories
と名付け、これを Get-ChildItem
コマンドレットに組み込みます。
https://github.com/PowerShell/PowerShell/blob/master/src/Microsoft.PowerShell.Commands.Management/commands/management/GetChildrenCommand.cs
まず、CustomizedGetChildItem
クラスに新しいパラメータ -ExcludeWithSubdirectories
を追加し、その動作を定義します。このパラメータは、-Exclude
パラメータが指定された場合にのみ意味を持ちます。
# CustomizedGetChildItemCmdlet.psm1
using namespace System.Management.Automation
using namespace System.IO
# Cmdletのカスタマイズ定義
[Cmdlet(VerbsCommon.Get, "ChildItem")]
Class CustomizedGetChildItem : Microsoft.PowerShell.Commands.GetChildItemCommand
{
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string[]] $Exclude
[Parameter(Mandatory = $false)]
[switch] $Recurse
[Parameter(Mandatory = $false)]
[switch] $Directory
[Parameter(Mandatory = $false)]
[switch] $ExcludeWithSubdirectories
protected override void BeginProcessing()
{
base.BeginProcessing();
if ($this.ExcludeWithSubdirectories -and $this.Exclude) {
# Excludeに指定された各パスに対して、サブディレクトリも含めて除外するリストを作成
$this.Exclude = $this.Exclude | ForEach-Object {
$currentPath = $_
$subDirs = Get-ChildItem -Path $_ -Recurse -Directory | Select-Object -ExpandProperty FullName
$subDirs += $currentPath
$subDirs
}
}
}
protected override void ProcessRecord()
{
if ($this.Directory) {
$this.InputObject = Get-ChildItem -Path $this.Path -Directory -Recurse:$this.Recurse -Exclude $this.Exclude
} else {
$this.InputObject = Get-ChildItem -Path $this.Path -Recurse:$this.Recurse -Exclude $this.Exclude
}
foreach ($item in $this.InputObject) {
Write-Output $item
}
}
}
Export-ModuleMember -Cmdlet CustomizedGetChildItem
ExcludeWithSubdirectories
スイッチパラメータは、Exclude
で指定されたディレクトリとそのすべてのサブディレクトリを除外する際に使用します。BeginProcessing
メソッドの拡張:
ExcludeWithSubdirectories
が指定された場合、Exclude
にリストされている各ディレクトリのサブディレクトリも動的に取得して除外リストに追加します。ProcessRecord
メソッドの変更:
このカスタマイズされたコマンドレットを使うと、-Exclude
に指定したディレクトリ及びその全てのサブディレクトリが検索結果から除外されます。これにより、より精密なファイルシステム操作が可能になります。
Get-ChildItem
コマンドレットに再帰的な除外機能を組み込みます。この関数は特定のフォルダとそのサブフォルダを除外しながらディレクトリ構造を再帰的に検索しています。同様のロジックをカスタム Cmdlet の実装に適用します。
# CustomizedGetChildItemCmdlet.psm1
using namespace System.Management.Automation
using namespace System.IO
# Cmdletのカスタマイズ定義
[Cmdlet(VerbsCommon.Get, "ChildItem")]
Class CustomizedGetChildItem : Microsoft.PowerShell.Commands.GetChildItemCommand
{
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[string[]] $Exclude
[Parameter(Mandatory = $false)]
[switch] $Recurse
[Parameter(Mandatory = $false)]
[switch] $Directory
[Parameter(Mandatory = $false)]
[switch] $ExcludeWithSubdirectories
# Cmdletの処理をオーバーライド
protected override void ProcessRecord()
{
Get-Folders -Path $this.Path -ExcludeFolders $this.Exclude
}
# 再帰的なフォルダ取得関数を定義
function Get-Folders {
param(
[string]$Path,
[string[]]$ExcludeFolders
)
# 現在のディレクトリ内のフォルダを取得
$folders = Get-ChildItem -Path $Path -Directory -Recurse:$this.Recurse -ErrorAction SilentlyContinue
foreach ($folder in $folders) {
# 除外するフォルダ名が含まれているかチェック
if ($ExcludeFolders -notcontains $folder.Name) {
# 除外フォルダではない場合、フォルダ情報を出力
Write-Output $folder
# `-Recurse` が指定されている場合、再帰的にこの関数を呼び出し
if ($this.Recurse) {
Get-Folders -Path $folder.FullName -ExcludeFolders $ExcludeFolders
}
}
}
}
}
Export-ModuleMember -Cmdlet CustomizedGetChildItem
Get-ChildItem
コマンドの ProcessRecord
メソッド内で新たに定義した Get-Folders
関数を呼び出しています。この関数は、指定されたパス内のすべてのフォルダを検索し、指定された除外リストに含まれるフォルダ名を持つディレクトリ(およびそれらのサブディレクトリ)を除外します。Recurse
スイッチが有効な場合にのみサブディレクトリを探索するように設定されています。