Showing posts with label PowerShell. Show all posts
Showing posts with label PowerShell. Show all posts

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:









Tuesday, May 8, 2012

Powershell - Getting Folders Size

How many times did you just wish to not only list some files but also have the file's folder's size be displayed?
Today i setup a little script to give a hand at this.

The output is from the Get-ChildItem cmdlet (dir) but extending the System.IO.DirectoryInfo
Objects output with a ScriptProperty that display the folder size.

It will do the job for now, but it just can use the default behavior of  Get-ChildItem.

;)

Function Get-ExtendedChildItem {

[cmdletbinding()]

Param(
[Parameter(Mandatory=$false)]
[string]$FolderPath
)

if($FolderPath)
{$d = Get-ChildItem $FolderPath}
else
{$d = Get-ChildItem}

$d | Where-Object {$_.PSIsContainer} |
ForEach-Object{
Add-Member -InputObject $_ -MemberType ScriptProperty -Name Length -Value `
{#Get
$size = 0
Get-ChildItem -Recurse $this.FullName | Where-Object {!$_.PSIsContainer} |
ForEach-Object {$size += $_.Length}
$size
}
}
$d
}