dimanche 20 novembre 2011

Get-ChildItem un peu plus conviviale :)

Salut, je ne sais pas si quelqu'un d'autre a eu l'idée d'ajouter ces deux fonctionnalités à la cmdlet 'Get-ChildItem' et je n'ai pas aussi tester Powershell vNext pour voir s'il implémente l'une de ces deux fonctionnalités... alors, je me suis dit pourquoi attendre ?! j'ai tout ce qu'il me faut pour configurer mes 'cmdlets' .... alors la première chose qui m'ai venu à l'esprit c'est d'ajouter deux nouveaux paramètres: 'FileSizeInHumanReadableFormat' et 'Pattern' le premier est une implémentation du switch '-lh' de la commande lunix 'ls' qui signifie "Display File Size in Human Readable Format" et l'autre paramètre pour allez un cran au-dessus des simples wildcards utiliser par les "filter" et "include" ... 'pattern' va nous permette d'utiliser les RegExp dans nos recheches :) vous pouvez voir les nouveaux paramètres de la fonction 'Get-ChildItem' en écrivant ceci:
Get-Command Get-ChildItem -TotalCount 1 -Syntax  
en fait le méchanisme d'execution des commandes dans "Windows Powershell"
help Precedence
va nous permettre d'executer notre fonction avant le cmdlet 'Get-Childtem'

Function Get-ChildItem {
<#

.ForwardHelpTargetName Get-ChildItem
.ForwardHelpCategory Cmdlet

#>

[CmdletBinding(DefaultParameterSetName='Items', SupportsTransactions=$true)]
param(
    [Parameter(ParameterSetName='Items', Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
    [System.String[]]
    ${Path},

    [Parameter(ParameterSetName='LiteralItems', Mandatory=$true, Position=0, ValueFromPipelineByPropertyName=$true)]
    [Alias('PSPath')]
    [System.String[]]
    ${LiteralPath},

    [Parameter(Position=1)]
    [System.String]
    ${Filter},

    [System.String[]]
    ${Include},

    [System.String[]]
    ${Exclude},
    
    [System.String]
    ${Pattern},

    [Switch]
    ${Recurse},

    [Switch]
    ${FileSizeInHumanReadableFormat},

    [Switch]
    ${Force},

    [Switch]
    ${Name})

begin
{
    try {
        $outBuffer = $null
        if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
        {
            $PSBoundParameters['OutBuffer'] = 1
        }
        $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Microsoft.PowerShell.Management\Get-ChildItem', [System.Management.Automation.CommandTypes]::Cmdlet)
        $cmd = ""
        if($FileSizeInHumanReadableFormat) {
          $PSBoundParameters.Remove('FileSizeInHumanReadableFormat') | Out-Null
          $cmd = @"
            | ForEach-Object {
                `$_length=Switch(`$_.length) {
                  { `$_ -lt 1kb } 
                           {  '{0}B' -f (`$_) ;break }
                  { `$_ -lt 1MB }
                           {  '{0}KB' -f ([math]::round(`$(`$_/ 1kb)), 2) ;break }
                  { `$_ -lt 1gb }
                            { '{0}MB' -f ([math]::round(`$(`$_/ 1mb), 2)) ;break }
                  defaut { 
                            {  '{0}GB' -f ([math]::round(`$(`$_/ 1gb), 2)) ;break }
                   }
                }
                if(`$_.PSISContainer) { `$_length=`$null }
                New-Object PSObject -Property @{
                  Mode = `$_.Mode
                  LastWriteTime = `$_.LastWriteTime
                  Length = `$_length
                  Name = `$_.Name
                }
            }         
"@
        }
        if($PSBoundParameters['Pattern']) {
          if($Filter -or $Include) {
           throw "les paramètres Pattern et Filter/Include sont mutuellemnt exculsive"
          } else {
          $PSBoundParameters.Remove('Pattern') | Out-Null
          $scriptCmd = {& $wrappedCmd @PSBoundParameters | Where { $_.Name -imatch "$Pattern"  } }
          }
        } else {
          $scriptCmd = {& $wrappedCmd @PSBoundParameters } 
        }
        $scriptCmd = $ExecutionContext.InvokeCommand.NewScriptBlock(
                $scriptCmd.ToString() + $cmd
            )
        $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
        $steppablePipeline.Begin($PSCmdlet)
    } catch {
        throw
    }
}

process
{
    try {
        $steppablePipeline.Process($_)
    } catch {
        throw
    }
}

end
{
    try {
        $steppablePipeline.End()
    } catch {
        throw
    }
}

}



voici quelques utilisation de cette fonction:
Get-ChildItem  -Path $env:windir -Pattern "^\d{2}" -FileSizeInHumanReadableFormat
Get-ChildItem -path $env:windir -filter *.txt -FileSizeInHumanReadableFormat
 
la sortie de la commande est un objet:
System.Management.Automation.PSCustomObject 
 ou
System.IO.FileSystemInfo

Aucun commentaire: