Monday, May 14, 2012

Powershell - Proxy Functions


Last article, I made a powershell function to calculate folders size. Wrapping a Get-ChildItem cmdlet and adding a ScriptProperty that calculates the foldersize to the output of Get-ChildItem. But it has a major drawback, it only supports the default behavior of Get-ChildItem.  I couldn´t do nothing like Get-Childitem -Force because the function only execute Get-ChildItem without any switch. The best way to have the same behavior of Get-ChildItem but with extended functionality is to make a Proxy Command.  You can use the MetaProgramming Module by Jeffrey Snover to simplify the task. 


PS> Import-Module MetaProgramming
PS> New-ProxyCommand Get-ChildItem -AddParameter FolderSize > Get-ExtendedChildItem.ps1 . 


Add the Switch tag in Param section:

[Switch] ${FolderSize}


And add this piece of code in begin section:


begin
{
    try {
        $outBuffer = $null
        if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer))
        {
            $PSBoundParameters['OutBuffer'] = 1
        }
        $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Get-ChildItem', [System.Management.Automation.CommandTypes]::Cmdlet)
        if ($FolderSize)
        {
            [Void]$PSBoundParameters.Remove("FolderSize")
$scriptCmd = {& $wrappedCmd @PSBoundParameters |
ForEach-Object {
if ($_.PSIsContainer){
Add-Member -InputObject $_ -MemberType ScriptProperty -Name Length -Value `
{
$size = 0
Get-ChildItem -Recurse $this.FullName | Where-Object {!$_.PSIsContainer} |
ForEach-Object {$size += $_.Length}
$size
} -PassThru
}
else {
$_
}
}
        }
}
else {$scriptCmd = {& $wrappedCmd @PSBoundParameters }}
        $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
        $steppablePipeline.Begin($PSCmdlet)
    } catch {
        throw
    }
}


Wrap the code with Function Get-ExtendedChildItem{CODE} load it and  its done.
(You can also rename it Get-ChildItem, Powershell will search for the function first) 


Example:









No comments:

Post a Comment