SecurityMonitoringMP.Discoveries.DiscoverWriteableFileLocations (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityPublic
RunAsDefault
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
Discovery DataSource Microsoft.Windows.TimedPowerShell.DiscoveryProvider Default

Overrideable Parameters:

IDParameterTypeSelector
FrequencyInSecondsint$Config/FrequencyInSeconds$
AdditionalLocationsstring$Config/AdditionalLocations$
TimeOutSecondsint$Config/TimeOutSeconds$

Source Code:

<DataSourceModuleType ID="SecurityMonitoringMP.Discoveries.DiscoverWriteableFileLocations" Accessibility="Public" Batching="false">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="FrequencyInSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="AdditionalLocations" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="0" name="TimeOutSeconds" type="xsd:integer"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="FrequencyInSeconds" Selector="$Config/FrequencyInSeconds$" ParameterType="int"/>
<OverrideableParameter ID="AdditionalLocations" Selector="$Config/AdditionalLocations$" ParameterType="string"/>
<OverrideableParameter ID="TimeOutSeconds" Selector="$Config/TimeOutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="Discovery" TypeID="Windows!Microsoft.Windows.TimedPowerShell.DiscoveryProvider">
<IntervalSeconds>$Config/FrequencyInSeconds$</IntervalSeconds>
<SyncTime/>
<ScriptName>DiscoverWriteableLocations.PS1</ScriptName>
<ScriptBody><Script>param($sourceId,$managedEntityId,$computerName,$debug,$additionallocations)

#Constants used for event logging
$SCRIPT_NAME = 'DiscoverWriteableLocations.ps1'
$EVENT_LEVEL_ERROR = 1
$EVENT_LEVEL_WARNING = 2
$EVENT_LEVEL_INFO = 4

$SCRIPT_STARTED = 811 #These are event IDs you are creating for logging.
$CLASS_CREATED = 812
$SCRIPT_ENDED = 815

function Log-DebugEvent
{
param($eventNo,$message)

$message = "`n" + $message
if ($debug = $true)
{
$api.LogScriptEvent($SCRIPT_NAME,$eventNo,$EVENT_LEVEL_INFO,$message)
}
}
$api = New-Object -comObject 'MOM.ScriptAPI'
$discoveryData = $api.CreateDiscoveryData(0, $sourceId, $managedEntityId)

$message = 'Script started' + "`n" + `
'Source ID: ' + $sourceId + "`n" + `
'Managed Entity ID: ' + $managedEntityId + "`n" + `
'Computer Name: ' + $computerName
Log-DebugEvent $SCRIPT_STARTED $message #Will run whether there's a debug or not

$OutputXML = $false
$DontFilterNTService = $false
$ShowGrantees = $false
$KnownAdmins
$RootDirectory = "%windir%"

# If RootDirectory has a trailing backslash, remove it (AccessChk doesn't handle it correctly).


# Entities for which to ignore write permissions.
# TrustedInstaller is always ignored; other NT SERVICE\ accounts are filtered
# out later (too many to list and too many unknown).
# The Package SIDs below (S-1-15-2-*) are associated with microsoft.windows.fontdrvhost and
# are not a problem. AppContainers never grant additional access; they only reduce access.
$FilterOut0 = @"
S-1-3-0
S-1-5-18
S-1-5-19
S-1-5-20
S-1-5-32-544
S-1-5-32-549
S-1-5-32-550
S-1-5-32-551
S-1-5-32-577
S-1-5-32-559
S-1-5-32-568
NT SERVICE\TrustedInstaller
S-1-15-2-1430448594-2639229838-973813799-439329657-1197984847-4069167804-1277922394
S-1-15-2-95739096-486727260-2033287795-3853587803-1685597119-444378811-2746676523
"@

# Filter all the above plus caller-supplied "known admins"
$FilterOut = ($FilterOut0.Split("`n`r") + $KnownAdmins | Where-Object { $_.Length -gt 0 }) -join ","
# Add all members of the local Administrators group, as the Effective Permissions
# APIs consider them to be administrators also.
# For some reason, Get-LocalGroup/Get-LocalGroupMember aren't available on WMFv5.0 on Win7;
# Verify whether command exists before using it. The commands are available on Win7 in v5.1.
if ($null -ne (Get-Command Get-LocalGroupMember -ErrorAction SilentlyContinue))
{
#TODO: Detect and handle case where this cmdlet fails - disconnected and the admins group contains domain SIDs that can't be resolved.
#FWIW, NET LOCALGROUP Administrators doesn't report these entries either.
#Also fails on AAD-joined, with unresolved SIDs beginning with S-1-12-1-...
Get-LocalGroupMember -SID S-1-5-32-544 -ErrorAction SilentlyContinue | ForEach-Object { $FilterOut += "," + $_.SID.Value }

}

$currfile = ""

#if ($OutputXML) { "&lt;root&gt;" }

$bInElem = $false
[System.Collections.ArrayList]$path = @()
if ($additionallocations -ne $null)
{
$path = @($additionallocations.split(','))
}
$path.add("%windir%")
$path.add("%programfiles%")
$path.add("%ProgramFiles% (x86)")

foreach ($item in $path)
{
if ($item.EndsWith("\")) { $item = $item.Substring(0, $item.Length - 1) }
AccessChk.exe /accepteula -nobanner -w -d -s -f $FilterOut $item | ForEach-Object {


if ($_.StartsWith(" ") -or $_.Length -eq 0)
{
if ($_.StartsWith(" RW ") -or $_.StartsWith(" W "))
{
$grantee = $_.Substring(5).Trim()

if ($DontFilterNTService -or (!$grantee.StartsWith("NT SERVICE\") -and !$grantee.StartsWith("S-1-5-80-")))
{

if ($currfile.Length -gt 0)
{
$instance = $discoveryData.CreateClassInstance("$MPElement[Name='Security.Monitoring.WriteableLocations']$")
$instance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $computerName)
$instance.AddProperty("$MPElement[Name='Security.Monitoring.WriteableLocations']/FolderPath$", $currfile)
$discoveryData.AddInstance($instance)
$message = 'Created' + $currfile + 'Service class' + "`n" + `
'Computer Name: ' + $computerName + "`n"
Log-DebugEvent $CLASS_CREATED $message
$currfile = ""
$bInElem = $true
}
}
}
}
else
{
if ($bInElem -and $OutputXML) { "&lt;/dir&gt;" }
$currfile = $_
$bInElem = $false
}

}
}
Log-DebugEvent -eventNo $SCRIPT_ENDED -$message
#Return the discovery data.
$discoveryData

# if ($bInElem -and $OutputXML) { "&lt;/dir&gt;" }
# if ($OutputXML) { "&lt;/root&gt;" }


</Script></ScriptBody>
<Parameters>
<Parameter>
<Name>sourceID</Name>
<Value>$MPElement$</Value>
</Parameter>
<Parameter>
<Name>managedEntityID</Name>
<Value>$Target/Id$</Value>
</Parameter>
<Parameter>
<Name>computerName</Name>
<Value>$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Value>
</Parameter>
<Parameter>
<Name>debug</Name>
<Value>$false</Value>
</Parameter>
<Parameter>
<Name>additionallocations</Name>
<Value>$Config/AdditionalLocations$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>$Config/TimeOutSeconds$</TimeoutSeconds>
</DataSource>
</MemberModules>
<Composition>
<Node ID="Discovery"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>