DSCResources/BMD_cFSRMQuotaTemplateAction/BMD_cFSRMQuotaTemplateAction.psm1
data LocalizedData { # culture="en-US" ConvertFrom-StringData -StringData @' GettingActionMessage=Getting FSRM Quota Template Action for {2} "{0}" threshold {1}. ActionExistsMessage=FSRM Quota Template Action for {2} "{0}" threshold {1} exists. ActionNotExistMessage=FSRM Quota Template Action for {2} "{0}" threshold {1} does not exist. SettingActionMessage=Setting FSRM Quota Template Action for {2} "{0}" threshold {1}. EnsureActionExistsMessage=Ensuring FSRM Quota Template Action for {2} "{0}" threshold {1} exists. EnsureActionDoesNotExistMessage=Ensuring FSRM Quota Template Action for {2} "{0}" threshold {1} does not exist. ActionCreatedMessage=FSRM Quota Template Action for {2} "{0}" threshold {1} has been created. ActionUpdatedMessage=FSRM Quota Template Action for {2} "{0}" threshold {1} has been updated. ActionRemovedMessage=FSRM Quota Template Action for {2} "{0}" threshold {1} has been removed. ActionNoChangeMessage=FSRM Quota Template Action for {2} "{0}" threshold {1} required not changes. ActionWrittenMessage=FSRM Quota Template Action for {2} "{0}" threshold {1} has been written. TestingActionMessage=Testing FSRM Quota Template Action for {2} "{0}" threshold {1}. ActionPropertyNeedsUpdateMessage=FSRM Quota Template Action for {2} "{0}" threshold {1} {3} is different. Change required. ActionDoesNotExistButShouldMessage=FSRM Quota Template Action for {2} "{0}" threshold {1} does not exist but should. Change required. ActionExistsAndShouldNotMessage=FSRM Quota Template Action for {2} "{0}" threshold {1} exists but should not. Change required. ActionDoesNotExistAndShouldNotMessage=FSRM Quota Template Action for {2} "{0}" threshold {1} does not exist and should not. Change not required. QuotaTemplateNotFoundError=FSRM Quota Template "{0}" not found. QuotaTemplateThresholdNotFoundError=FSRM Quota Template "{0}" threshold {1} not found. '@ } function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [parameter(Mandatory = $true)] [System.String] $Name, [parameter(Mandatory = $true)] [ValidateRange(0,100)] [System.Uint32] $Percentage, [parameter(Mandatory = $true)] [ValidateSet('Email','Event','Command','Report')] [System.String] $Type ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.GettingActionMessage) ` -f $Name,$Percentage,$Type ) -join '' ) $Result = Get-Action ` -Name $Name ` -Percentage $Percentage ` -Type $Type $returnValue = @{ Name = $Name Percentage = $Percentage Type = $Type } if ($Result.ActionIndex -eq $null) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionDoesNotExistMessage) ` -f $Name,$Percentage,$Type ) -join '' ) $returnValue += @{ Ensure = 'Absent' } } else { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionExistsMessage) ` -f $Name,$Percentage,$Type ) -join '' ) $Action = $Result.SourceObjects[$Result.SourceIndex].Action[$Result.ActionIndex] $returnValue += @{ Ensure = 'Present' Subject = $Action.Subject Body = $Action.Body MailBCC = $Action.MailBCC MailCC = $Action.MailCC MailTo = $Action.MailTo Command = $Action.Command CommandParameters = $Action.CommandParameters KillTimeOut = [System.Int32] $Action.KillTimeOut RunLimitInterval = [System.Int32] $Action.RunLimitInterval SecurityLevel = $Action.SecurityLevel ShouldLogError = $Action.ShouldLogError WorkingDirectory = $Action.WorkingDirectory EventType = $Action.EventType ReportTypes = [System.String[]] $Action.ReportTypes } } $returnValue } # Get-TargetResource function Set-TargetResource { [CmdletBinding()] param ( [parameter(Mandatory = $true)] [System.String] $Name, [parameter(Mandatory = $true)] [ValidateRange(0,100)] [System.Uint32] $Percentage, [parameter(Mandatory = $true)] [ValidateSet('Email','Event','Command','Report')] [System.String] $Type, [ValidateSet('Present','Absent')] [System.String] $Ensure = 'Present', [System.String]$Subject, [System.String]$Body, [System.String]$MailTo, [System.String]$MailCC, [System.String]$MailBCC, [ValidateSet('None','Information','Warning','Error')] [System.String]$EventType, [System.String]$Command, [System.String]$CommandParameters, [System.Int32]$KillTimeOut, [System.Int32]$RunLimitInterval, [ValidateSet('None','LocalService','NetworkService','LocalSystem')] [System.String]$SecurityLevel, [System.Boolean]$ShouldLogError, [System.String]$WorkingDirectory, [System.String[]]$ReportTypes ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.SettingActionMessage) ` -f $Name,$Percentage,$Type ) -join '' ) # Remove any parameters that can't be splatted. $PSBoundParameters.Remove('Name') $PSBoundParameters.Remove('Percentage') $PSBoundParameters.Remove('Ensure') # Lookup the existing action and related objects $Result = Get-Action ` -Name $Name ` -Percentage $Percentage ` -Type $Type if ($Ensure -eq 'Present') { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.EnsureActionExistsMessage) ` -f $Name,$Percentage,$Type ) -join '' ) $NewAction = New-FSRMAction @PSBoundParameters -ErrorAction Stop if ($Result.ActionIndex -eq $null) { # Create the action Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionCreatedMessage) ` -f $Name,$Percentage,$Type ) -join '' ) } else { # The action exists, remove it then update it $Result.SourceObjects[$Result.SourceIndex].Action.RemoveAt($Result.ActionIndex) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionUpdatedMessage) ` -f $Name,$Percentage,$Type ) -join '' ) } $Result.SourceObjects[$Result.SourceIndex].Action.Add($NewAction) } else { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.EnsureActionDoesNotExistMessage) ` -f $Name,$Percentage,$Type ) -join '' ) if ($Result.ActionIndex -eq $null) { # The action doesn't exist and should not Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionNoChangeMessage) ` -f $Name,$Percentage,$Type ) -join '' ) return } else { # The Action exists, but shouldn't remove it $Result.SourceObjects[$Result.SourceIndex].Action.RemoveAt($Result.ActionIndex) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionRemovedMessage) ` -f $Name,$Percentage,$Type ) -join '' ) } # if } # if # Now write the actual change to the appropriate place Set-Action ` -Name $Name ` -ResultObject $Result Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionWrittenMessage) ` -f $Name,$Percentage,$Type ) -join '' ) } # Set-TargetResource function Test-TargetResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [parameter(Mandatory = $true)] [System.String] $Name, [parameter(Mandatory = $true)] [ValidateRange(0,100)] [System.Uint32] $Percentage, [parameter(Mandatory = $true)] [ValidateSet('Email','Event','Command','Report')] [System.String] $Type, [ValidateSet('Present','Absent')] [System.String] $Ensure = 'Present', [System.String]$Subject, [System.String]$Body, [System.String]$MailTo, [System.String]$MailCC, [System.String]$MailBCC, [ValidateSet('None','Information','Warning','Error')] [System.String]$EventType, [System.String]$Command, [System.String]$CommandParameters, [System.Int32]$KillTimeOut, [System.Int32]$RunLimitInterval, [ValidateSet('None','LocalService','NetworkService','LocalSystem')] [System.String]$SecurityLevel, [System.Boolean]$ShouldLogError, [System.String]$WorkingDirectory, [System.String[]]$ReportTypes ) # Could check report types here # @('DuplicateFiles','FilesByFileGroup','FilesByOwner','FilesByProperty','LargeFiles','LeastRecentlyAccessed','MostRecentlyAccessed','QuotaUsage') # Flag to signal whether settings are correct [Boolean] $desiredConfigurationMatch = $true Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.SettingActionMessage) ` -f $Name,$Percentage,$Type ) -join '' ) # Lookup the existing action and related objects $Result = Get-Action ` -Name $Name ` -Percentage $Percentage ` -Type $Type if ($Ensure -eq 'Present') { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.EnsureActionExistsMessage) ` -f $Name,$Percentage,$Type ) -join '' ) if ($Result.ActionIndex -eq $null) { # The action does not exist but should Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionDoesNotExistButShouldMessage) ` -f $Name,$Percentage,$Type ) -join '' ) $desiredConfigurationMatch = $false } else { # The action exists - check it $Action = $Result.SourceObjects[$Result.SourceIndex].Action[$Result.ActionIndex] #region Parameter Checks if (($PSBoundParameters.ContainsKey('Subject')) ` -and ($Action.Subject -ne $Subject)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionPropertyNeedsUpdateMessage) ` -f $Name,$Percentage,$Type,'Subject' ) -join '' ) $desiredConfigurationMatch = $false } if (($PSBoundParameters.ContainsKey('Body')) ` -and ($Action.Body -ne $Body)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionPropertyNeedsUpdateMessage) ` -f $Name,$Percentage,$Type,'Body' ) -join '' ) $desiredConfigurationMatch = $false } if (($PSBoundParameters.ContainsKey('MailBCC')) ` -and ($Action.MailBCC -ne $MailBCC)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionPropertyNeedsUpdateMessage) ` -f $Name,$Percentage,$Type,'MailBCC' ) -join '' ) $desiredConfigurationMatch = $false } if (($PSBoundParameters.ContainsKey('MailCC')) ` -and ($Action.MailCC -ne $MailCC)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionPropertyNeedsUpdateMessage) ` -f $Name,$Percentage,$Type,'MailCC' ) -join '' ) $desiredConfigurationMatch = $false } if (($PSBoundParameters.ContainsKey('MailTo')) ` -and ($Action.MailTo -ne $MailTo)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionPropertyNeedsUpdateMessage) ` -f $Name,$Percentage,$Type,'MailTo' ) -join '' ) $desiredConfigurationMatch = $false } if (($PSBoundParameters.ContainsKey('Command')) ` -and ($Action.Command -ne $Command)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionPropertyNeedsUpdateMessage) ` -f $Name,$Percentage,$Type,'Command' ) -join '' ) $desiredConfigurationMatch = $false } if (($PSBoundParameters.ContainsKey('CommandParameters')) ` -and ($Action.CommandParameters -ne $CommandParameters)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionPropertyNeedsUpdateMessage) ` -f $Name,$Percentage,$Type,'CommandParameters' ) -join '' ) $desiredConfigurationMatch = $false } if (($PSBoundParameters.ContainsKey('KillTimeOut')) ` -and ($Action.KillTimeOut -ne $KillTimeOut)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionPropertyNeedsUpdateMessage) ` -f $Name,$Percentage,$Type,'KillTimeOut' ) -join '' ) $desiredConfigurationMatch = $false } if (($PSBoundParameters.ContainsKey('RunLimitInterval')) ` -and ($Action.RunLimitInterval -ne $RunLimitInterval)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionPropertyNeedsUpdateMessage) ` -f $Name,$Percentage,$Type,'RunLimitInterval' ) -join '' ) $desiredConfigurationMatch = $false } if (($PSBoundParameters.ContainsKey('SecurityLevel')) ` -and ($Action.SecurityLevel -ne $SecurityLevel)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionPropertyNeedsUpdateMessage) ` -f $Name,$Percentage,$Type,'SecurityLevel' ) -join '' ) $desiredConfigurationMatch = $false } if (($PSBoundParameters.ContainsKey('ShouldLogError')) ` -and ($Action.ShouldLogError -ne $ShouldLogError)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionPropertyNeedsUpdateMessage) ` -f $Name,$Percentage,$Type,'ShouldLogError' ) -join '' ) $desiredConfigurationMatch = $false } if (($PSBoundParameters.ContainsKey('WorkingDirectory')) ` -and ($Action.WorkingDirectory -ne $WorkingDirectory)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionPropertyNeedsUpdateMessage) ` -f $Name,$Percentage,$Type,'WorkingDirectory' ) -join '' ) $desiredConfigurationMatch = $false } if (($PSBoundParameters.ContainsKey('EventType')) ` -and ($Action.EventType -ne $EventType)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionPropertyNeedsUpdateMessage) ` -f $Name,$Percentage,$Type,'EventType' ) -join '' ) $desiredConfigurationMatch = $false } if (($PSBoundParameters.ContainsKey('ReportTypes')) ` -and ($Action.ReportTypes -ne $ReportTypes)) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionPropertyNeedsUpdateMessage) ` -f $Name,$Percentage,$Type,'ReportTypes' ) -join '' ) $desiredConfigurationMatch = $false } #endregion } } else { if ($Result.ActionIndex -eq $null) { # The action doesn't exist and should not Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionDoesNotExistAndShouldNotMessage) ` -f $Name,$Percentage,$Type ) -join '' ) } else { # The Action exists, but it should be removed Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($LocalizedData.ActionExistsAndShouldNotMessage) ` -f $Name,$Percentage,$Type ) -join '' ) $desiredConfigurationMatch = $false } # if } # if return $desiredConfigurationMatch } # Test-TargetResource # Helper Functions <# .Synopsis This function tries to find a matching Quota Template and threshold object If found, it assembles all threshold and action objects into modifiable arrays So that they can be worked with and then later saved back into the Quota Template Using Set-Action. #> Function Get-Action { param ( [parameter(Mandatory = $true)] [System.String] $Name, [parameter(Mandatory = $true)] [ValidateRange(0,100)] [System.Int32] $Percentage, [parameter(Mandatory = $true)] [ValidateSet('Email','Event','Command','Report')] [System.String] $Type ) $ResultObject = [PSObject] @{ SourceObjects = [System.Collections.ArrayList]@() SourceIndex = $null ActionIndex = $null } # Lookup the Quota Template try { $QuotaTemplate = Get-FSRMQuotaTemplate -Name $Name -ErrorAction Stop } catch [Microsoft.PowerShell.Cmdletization.Cim.CimJobException] { $errorId = 'QuotaTemplateNotFound' $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidArgument $errorMessage = $($LocalizedData.QuotaTemplateNotFoundError) ` -f $Name,$Percentage,$Type $exception = New-Object -TypeName System.InvalidOperationException ` -ArgumentList $errorMessage $errorRecord = New-Object -TypeName System.Management.Automation.ErrorRecord ` -ArgumentList $exception, $errorId, $errorCategory, $null $PSCmdlet.ThrowTerminatingError($errorRecord) } # Assemble the Result Object # This object is created from copies of the CIM classes returned in the threshold objects # but put into ArrayLists so that they can be manipulated. # DO NOT change this behavior unless you are sure you know what you're doing. for ($t=0; $t -ilt $QuotaTemplate.Threshold.Count; $t++) { $NewActions = New-Object -TypeName 'System.Collections.ArrayList' if ($QuotaTemplate.Threshold[$t].Percentage -eq $Percentage) { $ResultObject.SourceIndex = $t } for ($a=0; $a -ilt $QuotaTemplate.Threshold[$t].Action.Count; $a++) { $NewActions.Add($QuotaTemplate.Threshold[$t].Action[$a]) if (($QuotaTemplate.Threshold[$t].Action[$a].Type -eq $Type) ` -and ($ResultObject.SourceIndex -eq $t)) { $ResultObject.ActionIndex = $a } } $properties = @{'Percentage' = $QuotaTemplate.Threshold[$t].Percentage; 'Action' = $NewActions;} $NewSourceObject = New-Object -TypeName 'PSObject' -Property $properties $ResultObject.SourceObjects += @($NewSourceObject) } if ($ResultObject.SourceIndex -eq $null) { $errorId = 'QuotaTemplateThresholdNotFound' $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidArgument $errorMessage = $($LocalizedData.QuotaTemplateThresholdNotFoundError) ` -f $Name,$Percentage,$Type $exception = New-Object -TypeName System.InvalidOperationException ` -ArgumentList $errorMessage $errorRecord = New-Object -TypeName System.Management.Automation.ErrorRecord ` -ArgumentList $exception, $errorId, $errorCategory, $null $PSCmdlet.ThrowTerminatingError($errorRecord) } # Return the result Return $ResultObject } <# .Synopsis This function converts the result object that was created by Get-Action back Into a form that can be saved into the Quota Template. #> Function Set-Action { param ( [parameter(Mandatory = $true)] [System.String] $Name, [parameter(Mandatory = $true)] $ResultObject ) $Threshold = @() foreach ($o in $ResultObject.SourceObjects) { $Threshold += New-CimInstance ` -ClassName 'MSFT_FSRMQuotaThreshold' ` -Namespace Root/Microsoft/Windows/FSRM ` -ClientOnly ` -Property @{ Percentage = $o.Percentage Action = [Microsoft.Management.Infrastructure.CimInstance[]]($o.Action) } } Set-FSRMQuotaTemplate ` -Name $Name ` -Threshold $Threshold ` -ErrorAction Stop } Export-ModuleMember -Function *-TargetResource |