weepingapps

App Packaging, App Deployment, Deployment Tools, OS Deployment

Mass manage FSRM quota with Powershell

For some reason in FSRM 2008 R2, Microsoft did not add any cmdlets to manage Quota’s
and templates.

For most organizations these tools are probably uncessecary as the GUI and
dirquota.exe provides the ways of creating Quota templates and auto templates.

But what happens when you need to mass modify qutoa’s? You will be spending alot of
time right clicking single folders and copying quota templates.

As with anything I do, I try to find ways to batch process or automate things. Where
I work we are migrating everyone’s home folder from a Novell file server to a Windows
based, FSRM quota managed file system.

We are migrating everyone as they migrate simultanioisly from Windows XP to Windows 7. The problem we have is we don’t have an automated method to migrate their quota limits.

What we are doing to get around this is we have 3 quota templates.
1. 2.5GB Soft Quota – Auto Apply
2. 2.5GB hard quota
3. 5GB hard quota

Now, as the migration of their home data occurs overnight and our migration process has no knowledge of disk usage we do not want a hard quota preventing the migration from being successfull, but we need SOME quota so that FSRM can do its job.

POWERSHELL FUNCTIONS
I’ve create two powershell functions that utilise the FSRM commandline tool dirquote.exe

Get-Quota
Description: Uses dirquota.exe and parses the output into a custom object
Parameters: Server (Remote FSRM Server), TemplateName (Return results on this template only), ListTemplates (Show a list of templates)
Returned object: A returned object might look like this:

PS> Get-Quota -Server sccm01 -TemplateName “Monitor 500 MB Share”

UserName    : sue_reg
Path        : E:\Homes\sue_reg
SharePath   : \\SCCM01\Homes\sue_reg
Template    : Monitor 500 MB Share (Matches template)
Status      : Enabled
Used        : 16.50 MB
PercentUsed : 3
Available   : 483.50 MB
Peak        : 16.50 MB

Set-Quota
Description: Uses dirquote.exe to apply a quota template to a path.
Parameters: Server (Remote FSRM Server), TemplateName (Template name to apply to path), Path (Folder path to apply template to)
Usage: Set-Quota’s path paramter can be accepted from the pipeline ie:

PS> Get-Quota | Set-Quota -TemplateName “250 MB Extended Limit”
Quota path E:\Homes\jessdazzlement modified to 250 MB Extended Limit successfully
Quota path E:\Homes\sue_it modified to 250 MB Extended Limit successfully
Quota path E:\Homes\sue_reg modified to 250 MB Extended Limit successfully

And finally, how I use these commands together:
PS> Get-Quota -TemplateName “2.5GB Soft Quota” | Where-Object {$_.PercentUsed -lt 100} | Set-Quota -TemplateName “2.5GB Hard Quota”

PS1 File (Written with some Powershell v3 CTP features used, I’ll post a v2 version later)

Update 2: New version of the script removes unnecessary delays in waiting for dirquota.exe parsing

Update: If you want this script to work on PowerShell v2, swap this line:

-[pscustomobject] @{
+New-Object -TypeName PSObject -Property @{
function Get-Quota {
<#
    .SYNOPSIS
    Retreive Quota information using dirqutoa with an FSRM Windows server.

    .DESCRIPTION
    Uses dirquota.exe and parses returned strings into a custom object usable in Powershell.

    .PARAMETER TemplateName
    The name of a quota template. Restricts query to return results from Quota's matching named template.

    .PARAMETER ListTemplates
    A switch which will simply output a list of templates configured on the FSRM server.

    .PARAMETER Server
    Accepts the name of the FSRM you are connecting to. Defaults to winfile02

    .EXAMPLE
    C:\PS>Get-Quota -ListTemplates

    Name                                    Limit                                   Type
    ----                                    -----                                   ----
    100 MB Limit                            100.00 MB                               Hard
    2.5GB Auto Soft Limit                   2.50 GB                                 Soft
    5GB Limit                               5.00 GB                                 Hard
    100GB Limit                             100.00 GB                               Soft
    2.5GB Hard Limit                        2.50 GB                                 Hard
    10GB Limit                              10.00 GB                                Hard
    30GB Limit                              30.00 GB                                Hard

    .EXAMPLE    
    C:\PS>Get-Quota -TemplateName "10GB Limit"

    UserName                                                    Available
    --------                                                    ---------
    PThindall                                                   3.44 GB
    WSmit                                                       1.02 GB
    ATinkert                                                    3.22 GB
    SFooi                                                       4.90 GB
    Wlions                                                      2.99 GB

    .EXAMPLE
    C:\PS>Get-Quota -TemplateName "2.5GB Auto Soft Limit" | Select-Object *

    UserName    : jdazzle
    Path        : J:\staffhome\jdazzle
    SharePath   : \\winfile02\staffhome\jdazzle
    Template    : 2.5GB Hard Limit (Matches template)
    Status      : Enabled
    Used        : 1.28 GB
    PercentUsed : 51
    Available   : 1.22 GB
    Peak        : 2.42 GB

    .NOTES
    Author: Jesse Harris
    For: University of Sunshine Coast
    Date Created: 30 March 2012        
    ChangeLog:
    1.0 - First Release
    1.1 - Changed to use the new [pscustomobject]
    1.2 - Changed to reduce lag and show data immediately
 #>
    Param([string[]]$TemplateName,$Server="winfile02",[Switch]$ListTemplates)
    If (! (Test-CurrentAdminRights) ) { Write-Host -ForegroundColor Red "Please run as Admin"; return }
    If ($ListTemplates) {
        $QuotaCMD = dirquota t l /remote:$($Server)
        $QuotaCMD | Select-String -Pattern "Template Name" -Context 0,6 | `
            %{$NewObj = "" | Select-Object Name,Limit,Type; 
                $NewObj.Name = $_.Line.Split(":")[1].TrimStart(" "); 
                $NewObj.Limit = $_.Context.PostContext[0].Split(":")[1].TrimStart(" ").Split("(")[0]; 
                $NewObj.Type = $_.Context.PostContext[0].Split("(")[1].Split(")")[0];
                $NewObj}
    } Else {
       $defaultProperties = @('UserName','Available')
        $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet',[string[]]$defaultProperties)
        $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet)
        If ( $TemplateName -ne $null ) {$SourceTemplate = "/sourcetemplate:$($TemplateName)"}
        $ErrorActionPreference = "SilentlyContinue"
        dirquota.exe q l /remote:$($Server) $SourceTemplate | Select-String -Pattern "Quota Path" -Context 0,12 |
            %{
                $Line = 0
                While ( ($_.Context.PostContext[$Line] -match "\\") ) { $Line++ }
                [pscustomobject] @{
                    'UserName' = $_.Line.Split("\") | Select-Object -Last 1;
                    'Path' = $_.Line.Split(":",2)[1].TrimStart(" ");
                    'SharePath' = $_.Context.PostContext[0].Split(":")[1].TrimStart(" ");
                    'Template' = $_.Context.PostContext[$Line].Split(":")[1].TrimStart(" ");
                    'Status' = $_.Context.PostContext[$Line+1].Split(":")[1].TrimStart(" ");
                    'Used' = $_.Context.PostContext[$Line+3].Split(":")[1].TrimStart(" ").Split("(")[0];
                    'PercentUsed' = [int]$_.Context.PostContext[$Line+3].Split("(")[1].Split("%")[0];
                    'Available' = $_.Context.PostContext[$Line+4].Split(":")[1].TrimStart(" ");
                    'Peak' = $_.Context.PostContext[$Line+5].Split(":")[1].TrimStart(" ").Split("(")[0];
                } | Add-Member MemberSet PSStandardMembers $PSStandardMembers -PassThru
            }
    }
            $ErrorActionPreference = "Continue"
}

function Set-Quota {
<#
    .SYNOPSIS
    Sets a quota template on a path using dirqutoa.exe with an FSRM Windows server.

    .DESCRIPTION
    Uses dirquota.exe and output from Get-Quota to modify a path quota to match that of a quota Template.

    .PARAMETER TemplateName
    The name of a quota template. Specifies the quota template to use on a path.

    .PARAMETER Path
    Specified the folder path to modify quota on.

    .PARAMETER Server
    Accepts the name of the FSRM you are connecting to. Defaults to winfile02

    .EXAMPLE
    C:\PS>Set-Quota -Path "J:\Staffhome\jdazzle" -TemplateName "2.5GB Hard Limit"

    Quota path J:\Staffhome\jdazzle modified to 2.5GB Hard Limit successfully

    .EXAMPLE    
    C:\PS>Get-Quota -TemplateName "2.5GB Auto Soft Limit" | Where-Object { $_.PercentUsed -lt 200 } | Set-Quota -TemplateName "5GB Limit"

    Quota path J:\staffhome\mmcallis modified to 5GB Limit successfully
    Quota path J:\staffhome\SDauk modified to 5GB Limit successfully
    Quota path J:\staffhome\vschriev modified to 5GB Limit successfully
    Quota path J:\staffhome\NKing modified to 5GB Limit successfully
    Quota path J:\staffhome\lcameron modified to 5GB Limit successfully
    Quota path J:\staffhome\jwatson modified to 5GB Limit successfully
    Quota path J:\staffhome\tlucke modified to 5GB Limit successfully
    Quota path J:\staffhome\msiddiqu modified to 5GB Limit successfully

    .EXAMPLE
    C:\PS>Get-Contents Paths.txt | Set-Quota -TemplateName "100 MB Limit"

    .NOTES
    Author: Jesse Harris
    For: University of Sunshine Coast
    Date Created: 30 March 2012        
    ChangeLog:
    1.0 - First Release
#>
    Param([Parameter(Mandatory = $true,
                     ValueFromPipeLine = $true,
                     ValueFromPipeLineByPropertyName = $false)]$Path,$TemplateName="2.5GB Hard Limit",$server="winfile02")
    BEGIN {
        If (! (Test-CurrentAdminRights) ) { Write-Host -ForegroundColor Red "Please run as Admin"; return }
    }

    PROCESS {

    function Set-QuotaWorker {
        Param($Path,$TemplateName)    
            $QuotaCMD = dirquota q m /remote:$($Server) /Path:$Path /sourcetemplate:$TemplateName
            If ( $QuotaCMD -match "successfully" ) { Write-Host "Quota path $Path modified to $TemplateName successfully" }
            Else { Write-Host $QuotaCMD }
        }

    #Verify Template
    $Templates = Get-Quota -ListTemplates
    If ( ! ($Templates | Where-Object { $_.Name -eq $TemplateName }) ) { 
        Write-Host "No such template exists"
        $Templates
        return
    }
    If ( $PSBoundParameters.ContainsKey('Path') ) {

        $Path | ForEach-Object {
            If ($_ | Get-Member -Name Path) {
                Set-QuotaWorker -Path $_.Path -TemplateName $TemplateName
            } Else {
                Set-QuotaWorker -Path $_ -TemplateName $TemplateName
            }
        } 
    } Else {

    Set-QuotaWorker -UserName $UserName -TemplateName $TemplateName
    }
    }
}

function Test-CurrentAdminRights {
    #Return $True if process has admin rights, otherwise $False
    $user = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $Role = [System.Security.Principal.WindowsBuiltinRole]::Administrator
    return (New-Object Security.Principal.WindowsPrincipal $User).IsInRole($Role)
 }

function Invoke-AsAdmin() {
    Param([System.String]$ArgumentString = "")
    $NewProcessInfo = new-object "Diagnostics.ProcessStartInfo"
    $NewProcessInfo.FileName = [System.Diagnostics.Process]::GetCurrentProcess().path
    $NewProcessInfo.Arguments = "-file " + $MyInvocation.MyCommand.Definition + " $ArgumentString"
    $NewProcessInfo.Verb = "runas"
    $NewProcess = [Diagnostics.Process]::Start($NewProcessInfo)
    $NewProcess.WaitForExit()
}
Advertisements

9 responses to “Mass manage FSRM quota with Powershell

  1. Jamie June 19, 2012 at 9:09 am

    Depending on exactly what you want to achieve, you could just create a vbscript.

  2. Ian H July 27, 2012 at 6:46 am

    Nice script… I’ve been browsing for something JUST like this 🙂

  3. Stephen Goudy October 10, 2012 at 1:27 pm

    How would you modify this PS script to check for an existing quota and ignore if one is present? For example, I have 7000 folders. 3600 have quotas set. I need to query the structure and apply quotas to any folder that does not have a quota at present.

    Thanks!

  4. Pingback: FSRM Powershell followup the II « weepingapps

  5. kc April 2, 2014 at 7:21 pm

    thank you for your blog. very helpful.

    quick query: where would I run dirquota or get qirquotas.exe? is it from the vnx gui, or from the SP ?

  6. KlassOne April 3, 2014 at 3:12 am

    How / where can I access FSRM? is it from the control station or Unisphere GUI?

    Any guidance is appreciated. thank you.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: