Synchronizing Quotas - Part 2/3: Quotas-Acquire.ps1

Note: Did this in a bit of a rush...

########################
## Quotas-Acquire.ps1 ##
########################

Param($User,$Pass,$Cluster,$SVM)
Import-Module DataONTAP

"";"<<<<< Quotas-Acquire.ps1 >>>>>";""
"The script is designed to store Quota Policy Rule information in special hidden CIFS shares and their comments field.";""

If(!$User)   {$User    = Read-Host ">>> Enter Admin User "}
If(!$Pass)   {$Pass    = Read-Host ">>> Enter Password " -AsSecureString}
else {$Pass = $Pass | ConvertTo-SecureString  -AsPlainText -Force}
$Cred = New-Object System.Management.Automation.PsCredential($User,$Pass)
If(!$Cluster){$Cluster = Read-Host ">>> Enter Source Cluster "}
If(!$SVM)    {$SVM     = Read-Host ">>> Enter Source SVM "}

"";"STEP 1: CONNECTING TO SOURCE CLUSTER $Cluster AND FOCUSING ON SVM $SVM <<<"
[Void](Connect-NcController -Name $Cluster -Credential $Cred)
$Global:CurrentNcController.Vserver = $SVM

"";"STEP 2: GET THE APPLIED QUOTA POLICY"
$SVM_Attrs = Get-NcVserver -Template
$SVM_Attrs.QuotaPolicy = ""
$Quota_Pol = (Get-NcVserver -Attributes $SVM_Attrs).QuotaPolicy

"";"STEP 3: GET THE LIST OF VOLUMES WITH QUOTA ENABLED (ON)"
$QUOTA_Status_Attrs = Get-NcQuotaStatus -Template
$QUOTA_Status_Attrs.Volume = ""
$QUOTA_Status_Query = Get-NcQuotaStatus -Template
$QUOTA_Status_Query.Status = "on"
$QUOTA_On_Vols = (Get-NcQuotaStatus -Attributes $QUOTA_Status_Attrs -Query $QUOTA_Status_Query).Volume
$QUOTA_Vols = @{}
$QUOTA_On_Vols | foreach { $QUOTA_Vols.$_ = $true }

"";"STEP 4: GET THE VOLUME SIZES (for Tracking Quotas)"
$VOL_Attrs = Get-NcVol -Template
Initialize-NcObjectProperty -object $VOL_Attrs -name VolumeSpaceAttributes
$VOL_Attrs.VolumeSpaceAttributes.Size = ""
$VOL_Sizes = Get-NcVol -Attributes $VOL_Attrs -Vserver $SVM
$VOL_Size = @{}
$VOL_Sizes | foreach { $VOL_Size.($_.Name) = $_.TotalSize }

"";"STEP 5: GET THE QUOTA POLICY RULES PER VOLUME PER QTREE (Belonging to the Active Policy)"
$QUOTA_Query = Get-NcQuota -Template
$QUOTA_Query.Policy = $Quota_Pol
$QUOTA_Query.Vserver = $SVM
$QUOTA_Rules = Get-NcQuota -Query $Quota_Query
$VOL_Attrs = Get-NcVol -Template
$VOL_List = (Get-NcVol -Attributes $VOL_Attrs -Vserver $SVM).Name
$VOL_Hash = @{} # HASH gives true for .VolName is VolName exists!
$QTREE_Attrs = Get-NcQtree -Template
$QTREE_Attrs.Qtree = ""
$QTREE_V_Q = @{} # HASH gives true for .VolName.Qtree if Qtree exists!
$QUOTA_V_Q = @{} # HASH gives Disk Limit for .VolName.Qtree if it exists or null!

Foreach ($VolName in $VOL_List) {
$VOL_Hash.$VolName = $true
$QTREE_V_Q.$VolName = @{}
$QUOTA_V_Q.$VolName = @{}
$QTREE_List = (Get-NcQtree -Attributes $QTREE_Attrs -Volume $VolName -Vserver $SVM).Qtree

Foreach ($QtreeName in $QTREE_List){

If ($QtreeName){
$QTREE_V_Q.$VolName.$QtreeName = $true
$QUOTA_V_Q.$VolName.$QtreeName = $null
}
}
}

Foreach ($QUOTA_Rule in $QUOTA_Rules){
$VolName = $QUOTA_Rule.Volume
$QtreeName = (($QUOTA_Rule.QuotaTarget).Split("/"))[3]
# Get-NcQuota returns the Qtree in the QuotaTarget fields as /vol/VOLNAME/QTREENAME, even if the volume is mounted to /. So the split is always on 3 as in 0/1/2/3. It does not return the Qtree in .Qtree! #
$DiskLimit = $QUOTA_Rule.DiskLimit
If ($QtreeName){ $QUOTA_V_Q.$VolName.$QtreeName = $DiskLimit }
# A tracking quota with no defined DiskLimit gives $DiskLimit -eq "-" #
}

"";"STEP 6: CHECK EXISTING QUOTA.RULE.* SHARES"
$Shares = Get-NcCifsShare -ShareName "QUOTA.RULE.*"
$QR_Shares_V = @{} # HASH records if volumes already have a share
$QR_Shares_V_Q = @{} # HASH records if qtrees already have a share
$VOL_List | foreach { $QR_Shares_V_Q.$_ = @{} }

Foreach ($Share in $Shares){
$ShareName = $Share.ShareName
$ShareNameSplit = $ShareName.Split(".")
$SplitCount = $ShareNameSplit.Count
$VolName = $ShareNameSplit[2]
$QtreeName = $ShareNameSplit[3]

If (!$ShareName.EndsWith(".$")){
Write-Host "Invalid Quota Rule share - $ShareName (does not end with .$) - removing!" -ForegroundColor Red
Remove-NcCifsShare $ShareName -Confirm:$false  

} elseif(!$VolName){
Write-Host "Invalid Quota Rule share - $ShareName - removing!" -ForegroundColor Red
Remove-NcCifsShare $ShareName -Confirm:$false

} elseif (!$VOL_Hash.$VolName){
Write-Host "Invalid Quota Rule share - $ShareName ($VolName does not exist) - removing!" -ForegroundColor Red
Remove-NcCifsShare $ShareName -Confirm:$false

} elseif (!$QUOTA_Vols.$VolName){
Write-Host "Invalid Quota Rule share - $ShareName ($VolName Quota off) - removing!" -ForegroundColor Red
Remove-NcCifsShare $ShareName -Confirm:$false         

} elseif ($SplitCount -eq 5){

If (!$QTREE_V_Q.$VolName.$QtreeName){
Write-Host "Invalid Quota Rule share - $ShareName ($QtreeName does exist) - removing!" -ForegroundColor Red
Remove-NcCifsShare $ShareName -Confirm:$false

} elseif (!$QUOTA_V_Q.$VolName.$QtreeName -or ($QUOTA_V_Q.$VolName.$QtreeName -eq "-")) {
Write-Host "Invalid Quota Rule share - $ShareName ($QtreeName has a tracking quota) - removing!" -ForegroundColor Red
Remove-NcCifsShare $ShareName -Confirm:$false                

} else {
$QR_Shares_V_Q.$VolName.$QtreeName = $true
}

} else {
$QR_Shares_V.$VolName = $true
}
}

"";"STEP 7: CREATE/SET QUOTA.RULE.* SHARES"
$VOL_Attrs = Get-NcVol -Template
Initialize-NcObjectProperty -object $VOL_Attrs -name VolumeIdAttributes
$VOL_Attrs.VolumeIdAttributes.JunctionPath = ""
$SHARE_Prefix = "QUOTA.RULE."
$Resize_Required = @{}

Foreach ($VolName in $QUOTA_On_Vols){
$SHARE = $SHARE_Prefix + $VolName + ".$"
$JunctionPath = (Get-NcVol -Volume $VolName -Attributes $VOL_Attrs -Vserver $SVM).JunctionPath

If ($QR_Shares_V.$VolName){
[Void](Set-NcCifsShare -Name $SHARE -Path $JunctionPath)

} else {
Write-Host "Creating the new CIFS Share $SHARE!" -ForegroundColor Red
Add-NcCifsShare -Name $SHARE -Path $JunctionPath
}

$QTREE_List = (Get-NcQtree -Attributes $QTREE_Attrs -Volume $VolName -Vserver $SVM).Qtree

Foreach ($QtreeName in $QTREE_List){
$SHARE = $SHARE_Prefix + $VolName + "." + $QtreeName + ".$"
$Path = $JunctionPath + "/" + $QtreeName

If ($QtreeName){

If($QR_Shares_V_Q.$VolName.$QtreeName){
[Void](Set-NcCifsShare -Name $SHARE -Path $Path -Comment $QUOTA_V_Q.$VolName.$QtreeName)

} elseif ($QUOTA_V_Q.$VolName.$QtreeName -and ($QUOTA_V_Q.$VolName.$QtreeName -ne "-")) {
Write-Host "Creating the new CIFS Share $SHARE!" -ForegroundColor Red
Add-NcCifsShare -Name $SHARE -Path $Path -Comment $QUOTA_V_Q.$VolName.$QtreeName

} elseif ($QUOTA_V_Q.$VolName.$QtreeName -eq "-") {
$QUOTA_Query.QuotaTarget = "/vol/$VolName/$QtreeName"
$CurrentSoftDiskLimit = (Get-NcQuota -Query $QUOTA_Query).SoftDiskLimit
$SoftDiskLimitSetting = $VOL_Size.$VolName*4

If (([Int64]$CurrentSoftDiskLimit)*1024 -ne $SoftDiskLimitSetting){
[Void](Set-NcQuota -Path "/vol/$VolName/$QtreeName" -SoftDiskLimit $SoftDiskLimitSetting -Policy $Quota_Pol)
$Resize_Required.$VolName = $true
}

} else {
Write-Host "No tracking quota defined, setting on /vol/$VolName/$QtreeName!" -ForegroundColor Red
Add-NcQuota -Path "/vol/$VolName/$QtreeName" -SoftDiskLimit $SoftDiskLimitSetting -Policy $Quota_Pol
$Resize_Required.$VolName = $true
}
}
}
}

"";"STEP 8: RUN QUOTA RESIZE TO APPLY SET/ADD-ed QUOTA RULES APPLIED IN 7"
Foreach ($VolName in $QUOTA_On_Vols){
If ($Resize_Required.$VolName){
Start-NcQuotaResize -Volume $VolName
}
}

## THE END ##

Comments