How much can I shrink recovery point volumes with DPM2010

The script shown below finds out how much recovery points volumes could be shrunk on DPM2010.
One word of caution though: use the shrink feature with common sense and not as a regular remedy! Repeated small shrinks cause free space fragmentation and increases the number of extents.


The shrink option can be useful if accidental gross over allocation occurred that certainly is not needed. Or if storage pool is depleted, no chance of rapid expansion and urgent need of raw space.


Sample output 


FindShrinkableSpace


#begin script


#—————-


param([string] $DPMServerName)


if(!$args[0])
{
    if(!$DPMServerName)
    {
        $DPMServerName = read-host “DPMServer:”
    }
}
else
{
    if((“-?”,”-help”) -contains $args[0])
    {
        write-host Usage::
        write-host FindShrinkableSpace.ps1 -DPMServerName [dpmserver]
        write-host Help::
        write-host Finds the shrinkable space for all volumes protected on the specified DPM server.
        write-host
        exit 0
    }
    else
    {
        write-host “Usage -? for Help”
        exit 1
    }
}


$dsListAfterCalculatingShrink = @{}


$dpmServer = Connect-DPMServer $DPMServerName
if (!$dpmServer)
{
    Write-Error “Unable to connect to $DpmServerName”
    exit 1
}


$pgList = Get-ProtectionGroup -DPMServerName $DPMServerName
if ($pgList -ne $null)
{
    foreach ($pg in $pgList)
    {
        $dsList = Get-Datasource -ProtectionGroup $pg
        foreach ($ds in $dsList)
        {
            # If we have already stored a datasource for this physical replica, skip this DS and continue (since it will be the same)
            if ($dsListAfterCalculatingShrink.ContainsKey($ds.AssociatedReplica.PhysicalReplicaId))
            {
                continue
            }


            $currentSizeInGb = [System.Math]::Round(($ds.ShadowCopyAreaSize * 1.0) / (1024.0 * 1024.0 * 1024.0), 2);
            $shrinkableSizeInGb = 0;


            #Clear errors, check for any exception during ‘CalculateShrinkThresholds’ operation
            $prevErrorActionPreference = $ErrorActionPreference;
            $ErrorActionPreference = “SilentlyContinue”;
            $Error.Clear()
            $ds2 = Get-DatasourceDiskAllocation -dataSource $ds -CalculateShrinkThresholds
            if ($?)
            {
                $shrinkableSizeInGb = [System.Math]::Round((($ds.ShadowCopyAreaSize – $ds2[0].ShadowCopySizeAfterMaxShrink) * 1.0 ) / (1024.0 * 1024.0 * 1024.0), 2);
            }
            $ErrorActionPreference = $prevErrorActionPreference;


            # Add details about this datasource to a hashmap;
            $dsListAfterCalculatingShrink[$ds.AssociatedReplica.PhysicalReplicaId] =
                @{Name = $ds.ToString(“s”, $null); ScSizeInGb = $currentSizeInGb; ShrinkableSizeInGb = $shrinkableSizeInGb }
        }
    }
}


# Sort the datasources in descending order of how much it can be shrunk
$dsListAfterCalculatingShrinkSorted = $dsListAfterCalculatingShrink.values | sort { $_.ShrinkableSizeInGb } -desc


# Print results
#write-output (” {0} {1} {2}” -f “Datasource”.PadRight(100),”SC-Size(GB)”.PadLeft(11),”CanBeShrunkBy(GB)”.PadLeft(11))
write-host -ForegroundColor Cyan (” {0} {1} {2}” -f “Datasource”.PadRight(100),”SC-Size(GB)”.PadLeft(11),”CanBeShrunkBy(GB)”.PadLeft(11))
write-host -ForegroundColor Cyan ————————————————————————————————————————————
foreach ($ds in $dsListAfterCalculatingShrinkSorted)
{
    write-output (” {0} {1} {2}” -f $ds.Name.PadRight(100), $ds.ScSizeInGb.ToString().PadLeft(11), $ds.ShrinkableSizeInGb.ToString().PadLeft(11))
}


#end script


#———–