# # ------------- # CONSTANTS # ------------- # $DEDUP_FEATURE_NAME = "FS-Data-Deduplication" # # ------------------------ # RULE VIOLATION GENERATOR # ------------------------ # function RuleViolation # # FUNCTION DESCRIPTION: # Reports a BPA rule violation # NOTE: This function uses global variables defined in MAIN section # # PARAMETERS: # [varargs] List of violation descriptors # # RETURN VALUES: # None. # { $violation = $xdoc.createElement("violation",$tns) $id = $xdoc.createElement("ID",$tns) $id.InnerText = $args[0] $violation.appendChild($id) $xdoc.DocumentElement.appendChild($violation) if ($args.length -gt 1) { $args[1..($args.length-1)] | ` foreach ` { $context = $xdoc.createElement("context",$tns) $context.InnerText = $_ $violation.appendChild($context) } } } # # ------------------------ # RULE VIOLATION DETECTORS # ------------------------ # # These use the limits defined in the Global Limits section # $detectors = { #------------------------------ # Prerequisite Rules #------------------------------ # # A flag to indicate that we can import-module Dedup PS module to proceed # $dedupAvailable = $false # # Rule FeatureInstalled - Dedup feature should be installed # import-module ServerManager $feature = $null $feature = get-WindowsFeature | where { $_.Name -eq $DEDUP_FEATURE_NAME} if ($feature -eq $null -or $feature.Installed -eq $false) { RuleViolation FeatureInstalled } else { $dedupAvailable = $true import-module Deduplication } #------------------------------ # Non-Prerequisite Rules #------------------------------ if ($dedupAvailable) { # # Rule EnableDedup - Enable Dedup on the volumes that are big in size and low on free space # $notEnabledVolumes = "" $volumes = gwmi -namespace root\cimv2 win32_volume $dedupVolumes = Get-DedupVolume foreach($volume in $volumes) { # # If the volume looks promising to use Dedup # if( ( ($volume.Capacity -gt 100GB) -and ($volume.FileSystem -eq "NTFS") ) -and ( ($volume.FreeSpace/$volume.Capacity) -lt 0.2) ) { $enabled = $false foreach($dedupVol in $dedupVolumes) { # # Check if dedup is already enabled on this volume # if( ($volume.DeviceId -eq $dedupVol.VolumeId) -and $dedupVol.Enabled ) { $enabled = $true break } } if (!$enabled) { $notEnabledVolumes += ($volume.Name).TrimEnd("\") + "; " } } } if ($notEnabledVolumes.length -ne 0) { RuleViolation EnableDedup $notEnabledVolumes } # # Now check 3 rules about dedup schedules # $foundThroughputOptimization = $false $foundGCSchedule = $false $foundScrubbingSchedule = $false $dedupSchedules = Get-DedupSchedule foreach($schedule in $dedupSchedules) { if( $schedule.Enabled ) { # # Check if we have found any enabled Optimization schedule whose name is not "BackgroundOptimization" # if( ($schedule.Type -eq 1) -and ($schedule.Name -ne "BackgroundOptimization") ) { $foundThroughputOptimization = $true } # # Check if we have found any enabled GarbageCollection schedule # if( $schedule.Type -eq 2 ) { $foundGCSchedule = $true } # # Check if we have found any enabled Scrubbing schedule # if( $schedule.Type -eq 3 ) { $foundScrubbingSchedule = $true } } } # # Rule EnableThroughputSchedule - Enable Dedup throughput schedule # if( !$foundThroughputOptimization ) { RuleViolation EnableThroughputSchedule } # # Rule EnableGarbageCollectionSchedule - Enable Dedup GarbageCollection schedule # if( !$foundGCSchedule ) { RuleViolation EnableGarbageCollectionSchedule } # # Rule EnableScrubbingSchedule - Enable Dedup Scrubbing schedule # if( !$foundScrubbingSchedule ) { RuleViolation EnableScrubbingSchedule } # # Now check 4 rules about dedup volume status # $volumesNotKeepingUp = "" $volumesNotSaving = "" $volumesNotScrubbed = "" $volumesNotGCed = "" $dedupStatuses = Get-DedupStatus foreach($status in $dedupStatuses) { # # Check if optimization of each volume keeps up with the policy # if( ($status.InPolicyFilesSize -gt 0) -and ( ($status.OptimizedFilesSize/$status.InPolicyFilesSize) -lt 0.75) ) { $volumesNotKeepingUp += $status.Volume + "; " } # # Check if each volume saves enough # if( ($status.InPolicyFilesSize -gt 0) -and ( ( ($status.OptimizedFilesSize/$status.InPolicyFilesSize) -gt 0.9) -and ($status.SavingsRate -lt 15) ) ) { $volumesNotSaving += $status.Volume + "; " } # # Check if any volume's Scrubbing job did not run for a month or it failed/cancelled the last time it ran # if( ($status.LastScrubbingTime -ne $null) -and ( ($status.LastScrubbingResult -ne 0) -or ( ([System.DateTime]::now - $status.LastScrubbingTime).Days -gt 30 ) ) ) { $volumesNotScrubbed += $status.Volume + "; " } # # Check if any volume's GarbageCollection job did not run for a month or it failed/cancelled the last time it ran # if( ($status.LastGarbageCollectionTime -ne $null) -and ( ($status.LastGarbageCollectionResult -ne 0) -or ( ([System.DateTime]::now - $status.LastGarbageCollectionTime).Days -gt 30 ) ) ) { $volumesNotGCed += $status.Volume + "; " } } # # Rule OptimizationKeepUpWithPolicy - Ensure Optimization of each volume keeps up with the policy # if( $volumesNotKeepingUp.length -ne 0 ) { RuleViolation OptimizationKeepUpWithPolicy $volumesNotKeepingUp } # # Rule VolumeNotSavingMuch - Ensure Optimization of each volume keeps up with the policy # if( $volumesNotSaving.length -ne 0 ) { RuleViolation VolumeNotSavingMuch $volumesNotSaving } # # Rule VolumeNotScrubbedForAWhile - Ensure Dedup volumes get Scrubbed constantly # if( $volumesNotScrubbed.length -ne 0 ) { RuleViolation VolumeNotScrubbedForAWhile $volumesNotScrubbed } # # Rule VolumeNotGCedForAWhile - Ensure Optimization of each volume keeps up with the policy # if( $volumesNotGCed.length -ne 0 ) { RuleViolation VolumeNotGCedForAWhile $volumesNotGCed } # # Rule ByteLevelVerifyNotNeeded - Byte-by-byte verification should be disabled for each volume # $volumesVerified = "" foreach($volume in $dedupVolumes) { # # Find if Byte-by-byte verification is enabled for any volume # if( $volume.Verify ) { $volumesVerified += $volume.Volume + "; " } } if( $volumesVerified.length -ne 0 ) { RuleViolation ByteLevelVerifyNotNeeded $volumesVerified } }# if $dedupAvailable = $true } #end Violation Detectors # #------------------------------ # MAIN #------------------------------ # # # Custom namespace # $tns="http://schemas.microsoft.com/mbca/models/Dedup/2010/12" # # Create Rule violation XML document # $xdoc = [xml]"" # # Run violation detectors # .($detectors) | out-null # # Return the xml document # $xdoc