DFS-N: Folder and Folder Target Discovery Module

Microsoft.Windows.FileServer.DFSN.Library.NamespaceLinksDiscoveryDataSourceModuleType (DataSourceModuleType)

This module discovers all folders (links) and folder targets by running the dfsutil.exe command-line tool.

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityPublic
RunAsDefault
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Microsoft.Windows.TimedScript.DiscoveryProvider Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$IntervalSeconds
SyncTimestring$Config/SyncTime$SyncTime
TimeoutSecondsint$Config/TimeoutSeconds$TimeoutSeconds
DfsutilPathstring$Config/DfsutilPath$Path Of Dfsutil.exe

Source Code:

<DataSourceModuleType ID="Microsoft.Windows.FileServer.DFSN.Library.NamespaceLinksDiscoveryDataSourceModuleType" Accessibility="Public" Batching="false">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="IntervalSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="SyncTime" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="TimeoutSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="DfsutilPath" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" minOccurs="1" name="NamespaceName" type="xsd:string"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="SyncTime" Selector="$Config/SyncTime$" ParameterType="string"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
<OverrideableParameter ID="DfsutilPath" Selector="$Config/DfsutilPath$" ParameterType="string"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime>$Config/SyncTime$</SyncTime>
<ScriptName>DFSNNamespaceLinksDiscovery.vbs</ScriptName>
<Arguments>0 $MPElement$ $Target/Id$ $Config/NamespaceName$ $Config/DfsutilPath$</Arguments>
<ScriptBody><Script>
Option explicit
'-------------------------------------------------------------------
' &lt;company&gt;Microsoft Corporation&lt;/company&gt;
' &lt;copyright&gt;Copyright (c) Microsoft Corporation. All rights reserved.&lt;/copyright&gt;
' &lt;name&gt;
' Microsoft Windows DFS Namespace Links Discovery
' &lt;/name&gt;
' &lt;summary&gt;
'
' &lt;/summary&gt;
'-------------------------------------------------------------------

On Error Resume Next
SetLocale("en-us")
Dim SourceType, SourceID, ManagedEntityId, oArgs, oAPI, sDfsNamespaceName

Set oAPI = CreateObject("MOM.ScriptAPI")
If Err.Number &lt;&gt; 0 Then
Wscript.Quit -1
End if

On Error Goto 0
Set oArgs = WScript.Arguments
If oArgs.Count &lt; 4 Then
Wscript.Quit -1
End If

Dim oDiscData
Dim sDFSUtilPath

SourceType = oArgs(0)
SourceId = oArgs(1)
ManagedEntityId = oArgs(2)
sDfsNamespaceName = oArgs(3)

Dim WindowsVersion

If oArgs.Count &gt; 4 Then
sDFSUtilPath = oArgs(5) &amp; "\" &amp; "dfsutil.exe"
Else
WindowsVersion = OSVersion()
If (WindowsVersion = "5.2") Then
sDFSUtilPath = "%ProgramFiles%\Support Tools\dfsutil.exe"
Else
sDFSUtilPath = "dfsutil.exe"
End If
End If


Dim oRoot, oDFS
Set oRoot = New DFSRoot
oRoot.Initialize sDfsNamespaceName, sDFSUtilPath


Dim oNamespaceInst
On Error Resume Next
set oDiscData = oAPI.CreateDiscoveryData(SourceType, SourceId, ManagedEntityId)
If Err.Number &lt;&gt; 0 Then
Wscript.Quit -1
End if
On Error Goto 0

set oNamespaceInst = oDiscData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.FileServer.DFSN.Namespace']$")
call oNamespaceInst.AddProperty("$MPElement[Name='Microsoft.Windows.FileServer.DFSN.Namespace']/NamespaceName$", oRoot.Name)
call oDiscData.AddInstance(oNamespaceInst)

Dim oLink, oLinkInst, oTargetInst, oLinkTarget

For Each oLink In oRoot.Links
set oLinkInst = oDiscData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.FileServer.DFSN.Library.NamespaceLink']$")
call oLinkInst.AddProperty("$MPElement[Name='Microsoft.Windows.FileServer.DFSN.Library.NamespaceLink']/LinkName$", oRoot.Name &amp; "\" &amp; oLink.Name)
call oLinkInst.AddProperty("$MPElement[Name='Microsoft.Windows.FileServer.DFSN.Library.NamespaceLink']/State$", GetState(oLink.State, 0))
call oLinkInst.AddProperty("$MPElement[Name='Microsoft.Windows.FileServer.DFSN.Library.NamespaceLink']/Timeout$", oLink.Timeout)
call oLinkInst.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", oRoot.Name &amp; "\" &amp; oLink.Name)
call oLinkInst.AddProperty("$MPElement[Name='Microsoft.Windows.FileServer.DFSN.Namespace']/NamespaceName$", oRoot.Name)
call oDiscData.AddInstance(oLinkInst)


For Each oLinkTarget In oLink.Targets
set oTargetInst = oDiscData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.FileServer.DFSN.Library.LinkTarget']$")
call oTargetInst.AddProperty("$MPElement[Name='Microsoft.Windows.FileServer.DFSN.Library.LinkTarget']/TargetPath$", oLinkTarget.Name)
call oTargetInst.AddProperty("$MPElement[Name='Microsoft.Windows.FileServer.DFSN.Library.LinkTarget']/State$", GetState(oLinkTarget.State, 1))
call oTargetInst.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", oLinkTarget.Name)
call oTargetInst.AddProperty("$MPElement[Name='Microsoft.Windows.FileServer.DFSN.Library.NamespaceLink']/LinkName$", oRoot.Name &amp; "\" &amp; oLink.Name)
call oTargetInst.AddProperty("$MPElement[Name='Microsoft.Windows.FileServer.DFSN.Namespace']/NamespaceName$", oRoot.Name)
call oDiscData.AddInstance(oTargetInst)
Next

Next

oRoot.DeleteXMLFile

Call oAPI.Return(oDiscData)

Function GetState(ByVal iState, ByVal bIsTarget)
iState= iState AND 15
If bIsTarget =1 Then
Select Case iState
Case "1":
GetState = "OFFLINE"
Case "2":
GetState = "ONLINE"
Case "4":
GetState = "ACTIVE"
Case Else
GetState = iState
End Select
Else
Select Case iState
Case "1":
GetState = "OK"
Case "2":
GetState = "INCONSISTENT"
Case "3":
GetState = "OFFLINE"
Case "4":
GetState = "ONLINE"
Case Else
GetState = iState
End Select
End If
End Function

Function OSVersion()
Dim oError
Set oError = New Error
oError.Clear
On Error Resume Next
dim shell, strOS, strVerKey
OSVersion = ""
Set Shell = CreateObject("WScript.Shell")
oError.Save
On Error Goto 0
If oError.Number &lt;&gt; 0 then
Exit Function
End If
strVerKey = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\"
OSVersion = Shell.regread(strVerKey &amp; "CurrentVersion")
set Shell=nothing
End Function

Function IsValidObject(ByVal oObject)
IsValidObject = False

If IsObject(oObject) Then
If Not oObject Is Nothing Then
IsValidObject = True
End If
End If
End Function

Sub RunCommand (ByVal sCommand, ByRef iErrCode, ByRef sOutput, ByRef sError)

Dim oShell, oFSO, oOut

Set oShell = MomCreateObject("WScript.Shell")
Set oFSO = MomCreateObject("Scripting.FileSystemObject")

sError = ""
sOutput = ""
Dim sOutputFileName
sOutputFileName = GenerateGUID() &amp; ".out"
Dim sErrorFileName
sErrorFileName = GenerateGUID() &amp; ".err"
Dim sFullCommand
sFullCommand = "cmd /c " &amp; sCommand &amp; " &gt; " &amp; sOutputFileName &amp; " 2&gt; " &amp; sErrorFileName
iErrCode = oShell.run(sFullCommand, 2, true)
On Error Resume Next
Set oOut = oFSO.OpenTextFile(sOutputFileName)
On Error Goto 0
If IsValidObject(oOut) Then
On Error Resume Next
sOutput = oOut.ReadAll()
On Error Goto 0
oOut.Close
Else
WScript.Quit -1
End If

On Error Resume Next
oFSO.DeleteFile sOutputFileName
On Error Goto 0
If iErrCode &lt;&gt; 0 Then
Dim oErrorFile
On Error Resume Next
Set oErrorFile = oFSO.OpenTextFile(sErrorFileName)
On Error Goto 0
If IsValidObject(oErrorFile) Then
On Error Resume Next
sError = oErrorFile.ReadAll()
On Error Goto 0
oErrorFile.Close
End If
If sError = "" Then sError = sOutput
End If
On Error Resume Next
oFSO.DeleteFile sErrorFileName
On Error Goto 0
End Sub


Sub ParseForRoots (ByVal sDFSUtilOutput, ByRef oRootNames)
' Gets a string of the output from a successful run (error code = 0)
' of the DFS Util, parse out the list of roots and return the roots.

Dim rExp, sSearch, oMatches

Set rExp = new regexp
rExp.Global = True
rExp.IgnoreCase = True

' Match anything that starts with a tab and anything that's
' not a new line character. (till the end of the line)
rExp.Pattern = "\t[^(\n)]+"

' Parse for the roots...
Set oRootNames = rExp.Execute(sDFSUtilOutput)
End Sub

Function GenerateGUID()
Dim oTypeLib
Set oTypeLib = MomCreateObject("Scriptlet.TypeLib")

Dim sNewGUID
sNewGUID = oTypeLib.Guid

GenerateGUID = Left(sNewGUID, Len(sNewGUID)-2)
End Function


Function MomCreateObject(ByVal sProgramId)
Dim oError
Set oError = New Error

On Error Resume Next
Set MomCreateObject = CreateObject(sProgramId)
oError.Save
On Error Goto 0
If oError.Number &lt;&gt; 0 Then
WScript.Quit -1
End If
End Function

Class Error
Private m_lNumber
Private m_sSource
Private m_sDescription
Private m_sHelpContext
Private m_sHelpFile

Public Sub Save()
m_lNumber = Err.number
m_sSource = Err.Source
m_sDescription = Err.Description
m_sHelpContext = Err.HelpContext
m_sHelpFile = Err.helpfile
End Sub

Public Sub Raise()
Err.Raise m_lNumber, m_sSource, m_sDescription, m_sHelpFile, m_sHelpContext
End Sub

Public Sub Clear()
m_lNumber = 0
m_sSource = ""
m_sDescription = ""
m_sHelpContext = ""
m_sHelpFile = ""
End Sub

Public Default Property Get Number()
Number = m_lNumber
End Property

Public Property Get Source()
Source = m_sSource
End Property

Public Property Get Description()
Description = m_sDescription
End Property

Public Property Get HelpContext()
HelpContext = m_sHelpContext
End Property

Public Property Get HelpFile()
HelpFile = m_sHelpFile
End Property
End Class

Class DFSRoot
Private m_oXMLElement
Private m_sName
Private m_sXMLFileLocation

Public Sub DeleteXMLFile()
SetXMLElement Nothing
If m_sXMLFileLocation &lt;&gt; "" Then
Dim oFSO
Set oFSO = MomCreateObject("Scripting.FileSystemObject")
oFSO.DeleteFile m_sXMLFileLocation
End If
End Sub

Public Sub Initialize(ByVal sName, ByVal sDFSUtilPath)
m_sName = sName
DeleteXMLFile
m_sXMLFileLocation = GenerateGUID() &amp; ".xml"

Dim sDFSCommand
sDFSCommand = """""" &amp; sDFSUtilPath &amp; """ /root:""" &amp; sName &amp; """ /export:" &amp; m_sXMLFileLocation &amp; """"
Dim iErrorCode
Dim sOutput
Dim sError
RunCommand sDFSCommand, iErrorCode, sOutput, sError

If iErrorCode &lt;&gt; 0 Then

' Error occurred while running the dfsutil command
If iErrorCode = 1 Then
iErrorCode = 0
sDFSCommand = """""" &amp; "%ProgramFiles(x86)%\Support Tools\dfsutil.exe" &amp; """ /root:""" &amp; sName &amp; """ /export:" &amp; m_sXMLFileLocation &amp; """"
RunCommand sDFSCommand, iErrorCode, sOutput, sError
End If
If iErrorCode &lt;&gt; 0 Then
WScript.Quit -1
End If

End If

Dim oXDFSResults
Set oXDFSResults = MomCreateObject("MSXML2.DOMDocument")
oXDFSResults.validateOnParse = True

' Load the dfsutil result xml file
oXDFSResults.load(m_sXMLFileLocation)

If oXDFSResults.ParseError.ErrorCode &lt;&gt; 0 Then
DeleteXMLFile
WScript.Quit -1
End If

SetXMLElement oXDFSResults.SelectSingleNode("/Root")
End Sub


Public Property Get Name
Name = m_oXMLElement.SelectSingleNode("@Name").Value
End Property

Public Property Get State
State = CInt(m_oXMLElement.SelectSingleNode("@State").Value)
End Property

Public Property Get Timeout
Timeout = m_oXMLElement.SelectSingleNode("@Timeout").Value
End Property

Public Property Get Comment
Dim oCommentAttribute
Set oCommentAttribute = m_oXMLElement.SelectSingleNode("@Comment")
If oCommentAttribute Is Nothing Then
Comment = ""
Else
Comment = oCommentAttribute.Value
End If
End Property

Public Property Get Targets
Dim oTargetXMLElements
Set oTargetXMLElements = m_oXMLElement.SelectNodes("Target")
ReDim aTargets(oTargetXMLElements.length - 1)
Dim i
For i = 0 To oTargetXMLElements.length - 1
Set aTargets(i) = New DFSRootTarget
aTargets(i).SetXMLElement oTargetXMLElements.item(i)
Next
Targets = aTargets
End Property

Public Property Get TargetsCount
Dim oTargetXMLElements
Set oTargetXMLElements = m_oXMLElement.SelectNodes("Target")
TargetsCount = oTargetXMLElements.length
End Property

Public Property Get Links
Dim oLinkXMLElements
Set oLinkXMLElements = m_oXMLElement.SelectNodes("Link")
ReDim aLinks(oLinkXMLElements.length - 1)
Dim i
For i = 0 To oLinkXMLElements.length - 1
Set aLinks(i) = New DFSLink
aLinks(i).Initialize oLinkXMLElements.item(i), Name
Next
Links = aLinks
End Property

Public Property Get LinksCount
Dim oLinkXMLElements
Set oLinkXMLElements = m_oXMLElement.SelectNodes("Link")
LinksCount = oLinkXMLElements.length
End Property

Public Sub SetXMLElement(ByVal oXMLElement)
Set m_oXMLElement = oXMLElement
End Sub
End Class

Class DFSRootTarget
Private m_oXMLElement

Public Property Get Name
Name = "\\" &amp; Server &amp; "\" &amp; Folder
End Property

Public Property Get State
State = CInt(m_oXMLElement.SelectSingleNode("@State").Value)
End Property

Public Property Get Server
Server = m_oXMLElement.SelectSingleNode("@Server").Value
End Property

Public Property Get Folder
Folder = m_oXMLElement.SelectSingleNode("@Folder").Value
End Property

Public Sub SetXMLElement(ByVal oXMLElement)
Set m_oXMLElement = oXMLElement
End Sub
End Class

Class DFSLink
Private m_oXMLElement
Private m_sRootName

Public Property Get Name
Name = m_oXMLElement.SelectSingleNode("@Name").Value
End Property

Public Property Get State
State = CInt(m_oXMLElement.SelectSingleNode("@State").Value)
End Property

Public Property Get Timeout
Timeout = m_oXMLElement.SelectSingleNode("@Timeout").Value
End Property

Public Property Get Comment
Dim oCommentAttribute
Set oCommentAttribute = m_oXMLElement.SelectSingleNode("@Comment")
If oCommentAttribute Is Nothing Then
Comment = ""
Else
Comment = oCommentAttribute.Value
End If
End Property

Public Property Get Targets
Dim oTargetXMLElements
Set oTargetXMLElements = m_oXMLElement.SelectNodes("Target")
ReDim aTargets(oTargetXMLElements.length - 1)
Dim i
For i = 0 To oTargetXMLElements.length - 1
Set aTargets(i) = New DFSLinkTarget
aTargets(i).SetXMLElement oTargetXMLElements.item(i)
Next
Targets = aTargets
End Property

Public Property Get TargetsCount
Dim oTargetXMLElements
Set oTargetXMLElements = m_oXMLElement.SelectNodes("Target")
TargetsCount = oTargetXMLElements.length
End Property

Public Sub Initialize(ByVal oXMLElement, ByVal sRootName)
Set m_oXMLElement = oXMLElement
m_sRootName = sRootName
End Sub
End Class

Class DFSLinkTarget
Private m_oXMLElement

Public Property Get Name
Name = "\\" &amp; Server &amp; "\" &amp; Folder
End Property

Public Property Get State
State = CInt(m_oXMLElement.SelectSingleNode("@State").Value)
End Property

Public Property Get Server
Server = m_oXMLElement.SelectSingleNode("@Server").Value
End Property

Public Property Get Folder
Folder = m_oXMLElement.SelectSingleNode("@Folder").Value
End Property

Public Sub SetXMLElement(ByVal oXMLElement)
Set m_oXMLElement = oXMLElement
End Sub
End Class

</Script></ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DS"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>