Import-FSRMQuota.ps1

#Requires -Version 4
#Requires -RunasAdministrator

<#PSScriptInfo
 
.VERSION 1.0
 
.GUID 08b38133-e4e5-4320-a767-068dc059ba80
 
.AUTHOR samb@townsware.com
 
.COMPANYNAME Sam Boutros
 
.COPYRIGHT Public Domain
 
.TAGS FSRM Quota
 
.LICENSEURI https://opensource.org/licenses/MIT
 
.PROJECTURI https://superwidgets.wordpress.com/2016/06/09/powershell-script-to-migrate-fsrm-quota-settings/
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
 Republished from https://gallery.technet.microsoft.com/scriptcenter/Powershell-script-to-e159f521
 
.PRIVATEDATA
 
#>


<#
 
.DESCRIPTION
 Script to get FSRM Quota settings from remote server
 This includes Quota Templates, Admin Options, and Quotas applied to folders
 Using dirquota instead of the PS module fileserverresourcemanager to provide backward compatibility
 Tested with source server 2008 R2, 2012, and 2012 R2
 This script is designed to run on the destination server
 Assumes source and destination drive letters are the same
 Script by Sam Boutros - 9 June 2016 - v1.0
 For more information see https://superwidgets.wordpress.com/category/powershell/
 
#>
 

#region Input
Param(
    [Parameter(Mandatory=$false)]$SourceServer = 'FRMRFS02', # or $env:ComputerName for local computer..
    [Parameter(Mandatory=$false)]$LogFile      = "$((Get-Item .\).FullName)\logs\Import-FSRMQuota_$SourceServer-$(Get-Date -format yyyy-MM-dd_hh-mm-sstt).log"
)
#endregion


function Log {
<#
 .Synopsis
  Function to log input string to file and display it to screen
 
 .Description
  Function to log input string to file and display it to screen. Log entries in the log file are time stamped. Function allows for displaying text to screen in different colors.
 
 .Parameter String
  The string to be displayed to the screen and saved to the log file
 
 .Parameter Color
  The color in which to display the input string on the screen
  Default is White
  Valid options are
    Black
    Blue
    Cyan
    DarkBlue
    DarkCyan
    DarkGray
    DarkGreen
    DarkMagenta
    DarkRed
    DarkYellow
    Gray
    Green
    Magenta
    Red
    White
    Yellow
 
 .Parameter LogFile
  Path to the file where the input string should be saved.
  Example: c:\log.txt
  If absent, the input string will be displayed to the screen only and not saved to log file
 
 .Example
  Log -String "Hello World" -Color Yellow -LogFile c:\log.txt
  This example displays the "Hello World" string to the console in yellow, and adds it as a new line to the file c:\log.txt
  If c:\log.txt does not exist it will be created.
  Log entries in the log file are time stamped. Sample output:
    2014.08.06 06:52:17 AM: Hello World
 
 .Example
  Log "$((Get-Location).Path)" Cyan
  This example displays current path in Cyan, and does not log the displayed text to log file.
 
 .Example
  "$((Get-Process | select -First 1).name) process ID is $((Get-Process | select -First 1).id)" | log -color DarkYellow
  Sample output of this example:
    "MDM process ID is 4492" in dark yellow
 
 .Example
  log "Found",(Get-ChildItem -Path .\ -File).Count,"files in folder",(Get-Item .\).FullName Green,Yellow,Green,Cyan .\mylog.txt
  Sample output will look like:
    Found 520 files in folder D:\Sandbox - and will have the listed foreground colors
 
 .Link
  https://superwidgets.wordpress.com/category/powershell/
 
 .Notes
  Function by Sam Boutros
  v1.0 - 08/06/2014
  v1.1 - 12/01/2014 - added multi-color display in the same line
 
#>


    [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Low')] 
    Param(
        [Parameter(Mandatory=$true,
                   ValueFromPipeLine=$true,
                   ValueFromPipeLineByPropertyName=$true,
                   Position=0)]
            [String[]]$String, 
        [Parameter(Mandatory=$false,
                   Position=1)]
            [ValidateSet("Black","Blue","Cyan","DarkBlue","DarkCyan","DarkGray","DarkGreen","DarkMagenta","DarkRed","DarkYellow","Gray","Green","Magenta","Red","White","Yellow")]
            [String[]]$Color = "Green", 
        [Parameter(Mandatory=$false,
                   Position=2)]
            [String]$LogFile,
        [Parameter(Mandatory=$false,
                   Position=3)]
            [Switch]$NoNewLine
    )

    if ($String.Count -gt 1) {
        $i=0
        foreach ($item in $String) {
            if ($Color[$i]) { $col = $Color[$i] } else { $col = "White" }
            Write-Host "$item " -ForegroundColor $col -NoNewline
            $i++
        }
        if (-not ($NoNewLine)) { Write-Host " " }
    } else { 
        if ($NoNewLine) { Write-Host $String -ForegroundColor $Color[0] -NoNewline }
            else { Write-Host $String -ForegroundColor $Color[0] }
    }

    if ($LogFile.Length -gt 2) {
        "$(Get-Date -format "yyyy.MM.dd hh:mm:ss tt"): $($String -join " ")" | Out-File -Filepath $Logfile -Append 
    } else {
        Write-Verbose "Log: Missing -LogFile parameter. Will not save input string to log file.."
    }
}


#region Initialize

# Create logs subfolder if not exist
if (-not (Test-Path "$PSScriptRoot\logs")) { 
    New-Item "$PSScriptRoot\logs" -Type Directory -Force -Confirm:$false | Out-Null 
}

# Open PS session to remote server if one is not open already
log 'Connecting to source server',$SourceServer Green,Cyan $LogFile
$PwdFile = "$PSScriptRoot\$env:USERNAME.txt"
if (-not (Test-Path -Path $PwdFile)) { 
        Read-Host "Enter the pwd for '$env:USERNAME'" -AsSecureString | 
            ConvertFrom-SecureString | Out-File $PwdFile 
}
$Pwd  = Get-Content $PwdFile | ConvertTo-SecureString 
$Cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $env:USERNAME, $Pwd
Get-PSSession | Remove-PSSession # Close any old/open sessions
try { 
    $Session = New-PSSession -ComputerName $SourceServer -Credential $Cred -ErrorAction Stop
    log ($Session | Out-String) Green $LogFile
} catch {
    log 'Failed to set a remote PS session with computer', $SourceServer Magenta,Yellow $LogFile
    break
}
#endregion


#region Get Quota Templates from $SourceServer
$QTemplates = Invoke-Command -Session $Session -ScriptBlock {
    if (Test-Path   "$env:windir\Quota1.xml") {
        Remove-Item "$env:windir\Quota1.xml" -Force -Confirm:$false 
    }
    dirquota.exe template export /file:$env:windir\Quota1.xml
}
if ($QTemplates -match 'success') {
    $QTPath = Invoke-Command -Session $Session -ScriptBlock { "$env:windir\Quota1.xml" }
    $QTPath = "\\$SourceServer\$($QTPath.Replace(':','$'))"
    log 'Exported FSRM templates to',$QTPath Green,Cyan
} else {
    log 'Failed to export FSRM templates from', $SourceServer Magenta,Yellow $LogFile
    break
}
#endregion


#region Import Quota Templates to this computer
$Import = dirquota template import /file:$QTPath /overwrite 
if ($Import -match 'success') {
    log 'Imported FSRM templates to',$env:COMPUTERNAME Green,Cyan
} else {
    log 'Failed to export FSRM templates to', $env:COMPUTERNAME Magenta,Yellow $LogFile
    break
}
#endregion


#region Get Quota Admin Options from $SourceServer
$AdminOptions = Invoke-Command -Session $Session -ScriptBlock {
    dirquota.exe admin options 
}
log 'Got Quota Admin Options from',$SourceServer Green,Cyan
log ($AdminOptions | Out-String) Green $LogFile
#endregion


#region Import Quota Admin Options to this computer
dirquota.exe admin options /SMTP:"$(($AdminOptions -match 'SMTP Server:').Replace('SMTP Server:','').Trim())" | Out-Null
dirquota.exe admin options /From:"$(($AdminOptions -match 'Mail From:').Replace('Mail From:','').Trim())" | Out-Null
dirquota.exe admin options /AdminEmails:"$(($AdminOptions -match 'Admin E-mail Recipients:').Replace('Admin E-mail Recipients:','').Trim())" | Out-Null
dirquota.exe admin options /ScreenAudit:"$(($AdminOptions -match 'File Screen Auditing:').Replace('File Screen Auditing:','').Trim())" | Out-Null
dirquota.exe admin options /Command:"$(($AdminOptions -match 'Command Notifications:').Replace('Command Notifications:','').Trim())" | Out-Null
dirquota.exe admin options /RunLimitInterval:"M,"$(($AdminOptions -match 'E-mail:').Replace('E-mail:','').Replace('minutes','').Trim())"" | Out-Null
dirquota.exe admin options /RunLimitInterval:"E,"$(($AdminOptions -match 'Event Log:').Replace('Event Log:','').Replace('minutes','').Trim())"" | Out-Null
dirquota.exe admin options /RunLimitInterval:"C,"$(($AdminOptions -match 'Command:').Replace('Command:','').Replace('minutes','').Trim())"" | Out-Null
dirquota.exe admin options /RunLimitInterval:"R,"$(($AdminOptions -match 'Report:').Replace('Report:','').Replace('minutes','').Trim())"" | Out-Null
log 'Imported Quota Admin Options to',$env:COMPUTERNAME Green,Cyan
log (dirquota.exe admin options | Out-String) Green $LogFile
#endregion


#region Get Quotas applied to folders from $SourceServer
$QuotaFilePath = Invoke-Command -Session $Session -ScriptBlock {
    dirquota.exe quota list > $env:windir\Quota2.txt
    "$env:windir\Quota2.txt"
}
$QuotaFilePath = "\\$SourceServer\$($QuotaFilePath.Replace(':','$'))"
log 'Exported Quotas applied to folders - file',$QuotaFilePath Green,Cyan $LogFile
#endregion


#region Import Quotas/apply to folders on this computer
$NewQuota = $false
Get-Content $QuotaFilePath | % {
    $Line = $_
    if ($Line -match 'Quota Path:') { 
        $NewQuota = $true
        $QuotaPath = $Line.Replace('Quota Path:','').Trim()
    } 
    if ($NewQuota) {
        if ($Line -match 'Source Template:') { 
            $NewQuota = $false
            $SourceTemplate = $Line.Replace('Source Template:','').Replace('(Matches template)','').Trim()
            dirquota quota add /path:$QuotaPath /sourcetemplate:$SourceTemplate /overwrite | Out-Null
            log 'Imported Quota to folder',$QuotaPath,'based on Template',$SourceTemplate Green,Cyan,Green,Cyan $LogFile
        } 
    }
}
#endregion