Logical Disk Fragmentation Level Monitor Type

Microsoft.Windows.Server.10.0.LogicalDisk.DefragAnalysis.Monitortype (UnitMonitorType)

Element properties:

RunAsDefault
AccessibilityInternal
Support Monitor RecalculateFalse

Member Modules:

ID Module Type TypeId RunAs 
Scheduler DataSource System.Scheduler Default
Script ProbeAction Microsoft.Windows.Server.10.0.PowerShellPropertyBagProbe Default
ErrorFilter ConditionDetection System.ExpressionFilter Default
FilterDrive ConditionDetection System.ExpressionFilter Default
SuccessFilter ConditionDetection System.ExpressionFilter Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
SchedulerStartstring$Config/SchedulerStart$Start timeThe time of the day (HH:MM) that the fragmentation check should be run
SchedulerDaysOfWeekMaskint$Config/SchedulerDaysOfWeekMask$Days Of Week maskThe day(s) that the fragmentation check should be run. The values for the days are Sunday (1), Monday (2), Tuesday (4), Wednesday (8), Thursday (16), Friday (32) and Saturday (64). To specify multiple days, add the values for the days together. For example, for Monday, Wednesday, and Friday, specify 42 (2+8+32).
FilePercentFragmentationThresholddouble$Config/FilePercentFragmentationThreshold$File Percent Fragmentation ThresholdIf the "Use OS Recommendation" is set to "False" then this value will be used as the threshold for fragmentation levels.
UseOSRecommendationbool$Config/UseOSRecommendation$Use OS RecommendationThis parameter determines whether the fragmentation level check will use the default threshold determined by the operating system or not. If this parameter is set to "False" then the value from "File Percent Fragmentation Threshold" will be used.

Source Code:

<UnitMonitorType ID="Microsoft.Windows.Server.10.0.LogicalDisk.DefragAnalysis.Monitortype" Accessibility="Internal">
<MonitorTypeStates>
<MonitorTypeState ID="Warning" NoDetection="false"/>
<MonitorTypeState ID="Success" NoDetection="false"/>
</MonitorTypeStates>
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="SchedulerStart" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="SchedulerDaysOfWeekMask" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="FilePercentFragmentationThreshold" type="xsd:double"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="UseOSRecommendation" type="xsd:boolean"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="SchedulerStart" Selector="$Config/SchedulerStart$" ParameterType="string"/>
<OverrideableParameter ID="SchedulerDaysOfWeekMask" Selector="$Config/SchedulerDaysOfWeekMask$" ParameterType="int"/>
<OverrideableParameter ID="FilePercentFragmentationThreshold" Selector="$Config/FilePercentFragmentationThreshold$" ParameterType="double"/>
<OverrideableParameter ID="UseOSRecommendation" Selector="$Config/UseOSRecommendation$" ParameterType="bool"/>
</OverrideableParameters>
<MonitorImplementation>
<MemberModules>
<DataSource ID="Scheduler" TypeID="System!System.Scheduler">
<Scheduler>
<WeeklySchedule>
<Windows>
<Daily>
<Start>$Config/SchedulerStart$</Start>
<End>$Config/SchedulerStart$</End>
<DaysOfWeekMask>$Config/SchedulerDaysOfWeekMask$</DaysOfWeekMask>
</Daily>
</Windows>
</WeeklySchedule>
<ExcludeDates/>
</Scheduler>
</DataSource>
<ProbeAction ID="Script" TypeID="Microsoft.Windows.Server.10.0.PowerShellPropertyBagProbe">
<ScriptName>Microsoft.Windows.Server.LogicalDisk.DefragAnalysis.ps1</ScriptName>
<PSparam>param ($TargetComputer)</PSparam>
<ScriptBody><Script>
#Copyright (c) Microsoft Corporation. All rights reserved.

# Parameters that should be passed to this script
# 0 Computer (FQDN)

Function Main()
{
# Fragmentation analysis requires lots of time and consumes lots of CPU.
# So it is important to trace such activity in events log in order to be able
# to understand what is going on.
$g_DebugFlag = $true

$IsMsftVolumeSupported = Is_MSFT_Volume_Supported_On_NanoServer $TargetComputer
$IsVolumeInfoSupported = Is_Win32_Volume_Supported $TargetComputer

if ($IsMsftVolumeSupported -eq $true) # Win32_Volume is not supported on NanoServer
{
Start-DefragAnalysisOnNano -TargetComputer $TargetComputer -momAPI $momAPI
}
else
{
if ($false -eq $IsVolumeInfoSupported)
{
TraceLogMessage ("This Operating System doesn't support volumes WMI class.")
return
}

Start-DefragAnalysis -TargetComputer $TargetComputer -momAPI $momAPI
}

Unload-Module -ModuleName "CimCmdLets"

}

Function Is_MSFT_Volume_Supported_On_NanoServer($TargetComputer)
{
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()
$bRet = $false
$IsNano = Is_NanoServer
if ($true -eq $IsNano)
{
Load-CimModules
try
{
$cimSessionOption = New-CimSessionOption -Protocol DCOM
$cimsession = New-CimSession -SessionOption $cimSessionOption
$oWMI = Get-CimClass -CimSession $cimsession -NameSpace "root\microsoft\windows\storage" MSFT_Volume -ErrorAction SilentlyContinue
}
Finally
{
Get-CimSession | Remove-CimSession
$cimsession =$null
$cimSessionOption = $null
}
if ($oWMI -ne $null)
{
$bRet = $true
}
}

return $bRet
}

Function Start-DefragAnalysisOnNano($TargetComputer,$momAPI)
{
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()
$IsDiskFound = $false

$oWmiDiskSet = WMIGetInstanceNoAbort $TargetComputer "root\microsoft\windows\storage" "MSFT_Volume WHERE (DriveType=3 or DriveType=6) and FileSystem!=null"
foreach ($oWmiDisk in $oWmiDiskSet)
{
$sDriveLetter = $oWmiDisk.DriveLetter
if ([string]::IsNullOrEmpty($sDriveLetter))
{
$sDriveLetter = $oWmiDisk.UniqueId
}

if ([string]::IsNullOrEmpty($sDriveLetter))
{
continue
}

TraceLogMessage ("Running DefragAnalysis (disk: " + $sDriveLetter + "; computer: " + $TargetComputer + ").")
$error.Clear()
Load-CimModules
try
{
$cimSessionOption = New-CimSessionOption -Protocol DCOM
$cimsession = New-CimSession -SessionOption $cimSessionOption
$ret = Invoke-CimMethod -CimSession $cimsession -CimInstance $oWmiDisk -MethodName Optimize -Arguments @{ReTrim=$false;Analyze=$true;Defrag=$false;SlabConsolidate=$false;TierOptimize=$false} -ErrorAction SilentlyContinue
}
Finally
{
Get-CimSession | Remove-CimSession
$cimsession =$null
$cimSessionOption = $null
}
TraceLogMessage ("DefragAnalysis results (return code: " + $ret.ReturnValue + ")(disk: " + $sDriveLetter + "; computer: " + $TargetComputer + ")")

If ($ret.ReturnValue -ne 0 -or $error.Count -ne 0)
{
$pctFrag = 25
$DefragRecomend = $true
Add-BagData -sDriveLetter $sDriveLetter -pctFrag $pctFrag -DefragRecomend $DefragRecomend -objMomApi $momAPI
}


}

return

}

Function Start-DefragAnalysis($TargetComputer,$momAPI)
{
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()

$oWmiDiskSet = WMIGetInstanceNoAbort $TargetComputer "root\cimv2" "Win32_Volume WHERE (DriveType=3 or DriveType=6) and FileSystem!=null"

foreach ($oWmiDisk in $oWmiDiskSet)
{
$sDriveLetter = $oWmiDisk.DriveLetter
if ([string]::IsNullOrEmpty($sDriveLetter))
{
$sDriveLetter = $oWmiDisk.Name
$sDriveLetter = StripEndChar -sName $sDriveLetter
}

if ([string]::IsNullOrEmpty($sDriveLetter))
{
continue
}

TraceLogMessage ("Running DefragAnalysis (disk: " + $sDriveLetter + "; computer: " + $TargetComputer + ").")
$error.Clear()
Load-CimModules
try
{
$cimSessionOption = New-CimSessionOption -Protocol DCOM
$cimsession = New-CimSession -SessionOption $cimSessionOption
$ret = Invoke-CimMethod -CimSession $cimsession -CimInstance $oWmiDisk -MethodName DefragAnalysis -ErrorAction SilentlyContinue
}
Finally
{
Get-CimSession | Remove-CimSession
$cimsession =$null
$cimSessionOption = $null
}
TraceLogMessage ("DefragAnalysis results (return code: " + $ret.ReturnValue + ")(disk: " + $sDriveLetter + "; computer: " + $TargetComputer + "): OSRecommended = " + $ret.DefragRecommended + "; FilePercentFragmentation = " + $ret.DefragAnalysis.FilePercentFragmentation + ".")

$pctFrag = $ret.DefragAnalysis.FilePercentFragmentation
$DefragRecomend = $ret.DefragRecommended
Add-BagData -sDriveLetter $sDriveLetter -pctFrag $pctFrag -DefragRecomend $DefragRecomend -objMomApi $momAPI

}

return

}

Function Add-BagData($sDriveLetter,$pctFrag,$DefragRecomend,$objMomApi)
{
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()

if ($null -eq $sDriveLetterobjMomApi)
{
return
}

$oBag = $momAPI.CreatePropertyBag()

if ($Null -eq $oBag)
{
return
}

$oBag.AddValue("DiskLabel", $sDriveLetter)
$oBag.AddValue("OSRecommended", $DefragRecomend)
$oBag.AddValue("FilePercentFragmentation", $pctFrag )
$oBag

}

Function Load-CimModules
{
$error.Clear()

$CimModule = Get-Module CimCmdlets

if ($null -eq $CimModule)
{
Import-Module CimCmdlets
$error.Clear()
}
}
Main

</Script></ScriptBody>
<Parameters>
<Parameter>
<Name>TargetComputer</Name>
<Value>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>3600</TimeoutSeconds>
</ProbeAction>
<ConditionDetection ID="FilterDrive" TypeID="System!System.ExpressionFilter">
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='DiskLabel']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">$Target/Property[Type="Windows!Microsoft.Windows.LogicalDevice"]/DeviceID$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</ConditionDetection>
<ConditionDetection ID="ErrorFilter" TypeID="System!System.ExpressionFilter">
<Expression>
<Or>
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<Value Type="Boolean">$Config/UseOSRecommendation$</Value>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="Boolean">false</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Double">Property[@Name='FilePercentFragmentation']</XPathQuery>
</ValueExpression>
<Operator>Greater</Operator>
<ValueExpression>
<Value Type="Double">$Config/FilePercentFragmentationThreshold$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<Value Type="Boolean">$Config/UseOSRecommendation$</Value>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="Boolean">true</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Boolean">Property[@Name='OSRecommended']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="Boolean">true</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
</Or>
</Expression>
</ConditionDetection>
<ConditionDetection ID="SuccessFilter" TypeID="System!System.ExpressionFilter">
<Expression>
<Not>
<Expression>
<Or>
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<Value Type="Boolean">$Config/UseOSRecommendation$</Value>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="Boolean">false</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Double">Property[@Name='FilePercentFragmentation']</XPathQuery>
</ValueExpression>
<Operator>LessEqual</Operator>
<ValueExpression>
<Value Type="Double">$Config/FilePercentFragmentationThreshold$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<Value Type="Boolean">$Config/UseOSRecommendation$</Value>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="Boolean">true</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Boolean">Property[@Name='OSRecommended']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="Boolean">false</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
</Or>
</Expression>
</Not>
</Expression>
</ConditionDetection>
</MemberModules>
<RegularDetections>
<RegularDetection MonitorTypeStateID="Warning">
<Node ID="ErrorFilter">
<Node ID="FilterDrive">
<Node ID="Script">
<Node ID="Scheduler"/>
</Node>
</Node>
</Node>
</RegularDetection>
<RegularDetection MonitorTypeStateID="Success">
<Node ID="SuccessFilter">
<Node ID="FilterDrive">
<Node ID="Script">
<Node ID="Scheduler"/>
</Node>
</Node>
</Node>
</RegularDetection>
</RegularDetections>
</MonitorImplementation>
</UnitMonitorType>