AD データベースとログ ファイル スクリプトのデータソース

AD_Database_and_Log.DataSource (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityPublic
RunAsDefault
OutputTypeSystem.PropertyBagData

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource System.CommandExecuterPropertyBagSource Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$間隔 (秒)
LogSuccessEventstring$Config/LogSuccessEvent$成功イベントのログ
Threshold_DITstring$Config/Threshold_DIT$Threshold_DIT
Boundary_DITstring$Config/Boundary_DIT$Boundary_DIT
Boundary_LOGstring$Config/Boundary_LOG$Boundary_LOG
Threshold_LOGstring$Config/Threshold_LOG$Threshold_LOG
TimeoutSecondsint$Config/TimeoutSeconds$タイムアウト (秒)

Source Code:

<DataSourceModuleType ID="AD_Database_and_Log.DataSource" Accessibility="Public" Batching="false">
<Configuration>
<xsd:element name="IntervalSeconds" type="xsd:int"/>
<xsd:element name="TargetComputerName" type="xsd:string"/>
<xsd:element name="TargetNetbiosDomain" type="xsd:string"/>
<xsd:element name="LogSuccessEvent" type="xsd:boolean"/>
<xsd:element name="ManagementGroupName" type="xsd:string"/>
<xsd:element name="Threshold_DIT" type="xsd:string"/>
<xsd:element name="Boundary_DIT" type="xsd:string"/>
<xsd:element name="Boundary_LOG" type="xsd:string"/>
<xsd:element name="Threshold_LOG" type="xsd:string"/>
<xsd:element name="TimeoutSeconds" type="xsd:int"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="LogSuccessEvent" Selector="$Config/LogSuccessEvent$" ParameterType="string"/>
<OverrideableParameter ID="Threshold_DIT" Selector="$Config/Threshold_DIT$" ParameterType="string"/>
<OverrideableParameter ID="Boundary_DIT" Selector="$Config/Boundary_DIT$" ParameterType="string"/>
<OverrideableParameter ID="Boundary_LOG" Selector="$Config/Boundary_LOG$" ParameterType="string"/>
<OverrideableParameter ID="Threshold_LOG" Selector="$Config/Threshold_LOG$" ParameterType="string"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="System!System.CommandExecuterPropertyBagSource">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<ApplicationName>%windir%\system32\cscript.exe</ApplicationName>
<WorkingDirectory/>
<CommandLine>//nologo $file/AD_Database_and_Log.vbs$ $Config/TargetComputerName$ $Config/TargetNetbiosDomain$ $Config/LogSuccessEvent$ $Config/ManagementGroupName$ $Config/Threshold_DIT$ $Config/Boundary_DIT$ $Config/Boundary_LOG$ $Config/Threshold_LOG$</CommandLine>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<RequireOutput>true</RequireOutput>
<Files>
<File>
<Name>AD_Database_and_Log.vbs</Name>
<Contents><Script>
'*************************************************************************
' Script Name - AD Database and Log
'
' Purpose - Determine the size and space available for the AD database
'
' Assumptions - Script is run by a timed event
'
' Parameters - LogSuccessEvent - True/False value to indicates to log an
' an event for script success
' (useful for demos and debugging)
'
' (c) Copyright 2001, Microsoft Corporation, All Rights Reserved
' Proprietary and confidential to Microsoft Corporation
'*************************************************************************

Option Explicit

SetLocale("en-us")

'Event Constants
Const EVENT_TYPE_SUCCESS = 0
Const EVENT_TYPE_ERROR = 1
Const EVENT_TYPE_WARNING = 2
Const EVENT_TYPE_INFORMATION = 4

' Event ID Constants
Const EVENTID_EVENT_RULE_ONLY = 2
Const EVENTID_SUCCESS = 99
Const EVENTID_SCRIPT_ERROR = 1000
Const EVENTID_SPACE_AVAILABLE_WARNING = 333
Const EVENTID_DIT_GROWTH_WARNING = 334
Const EVENTID_LOG_GROWTH_WARNING = 335
Const EVENT_ID_AGENTLESS = 98

'Other constants
Const SCRIPT_NAME = "AD Database and Log"

Const DIT_NAME = "DIT Database"
Const LOG_NAME = "DIT Log"

Const WARNING_TAG = "DriveSpaceWarning"

' Other Variables
Dim oParams, TargetFQDNComputer, TargetNetbiosDomain, bLogSuccessEvent, IsTargetAgentless
Set oParams = WScript.Arguments
if oParams.Count &lt; 8 then
Wscript.Quit -1
End if


Dim oAPI, objParams, objEvent, oBag, oBagState
Set oAPI = CreateObject("Mom.ScriptAPI")
Err.Clear

Dim sStateValuePath, DIT_THRESHOLD, DIT_BOUNDARY, LOG_BOUNDARY, LOG_THRESHOLD
sStateValuePath= "HKLM\" &amp; oAPI.GetScriptStateKeyPath(oParams(3))
' THRESHOLD and MINIMUM BOUNDARY for RESERVE SPACE
DIT_THRESHOLD = CDbl(oParams(4)) '%20
DIT_BOUNDARY = CDbl(oParams(5)) 'in KBytes
LOG_BOUNDARY = CDbl(oParams(6)) 'in KBytes
LOG_THRESHOLD = CDbl(oParams(7)) '%5 (NOTE: of the DIT size, not the log size)


' Registry Path to share data across scripts
Dim REG_Key
REG_Key = sStateValuePath &amp; "\AD Management Pack\AD Database and Log"

' TypedPropertyBag
const PerformanceDataType = 2
const StateDataType = 3

const DatabaseRegKey = "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters\DSA Database File"

const LogFileRegKey = "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters\Database log files path"
const LogFileName = "edb.log"

Dim oReg, oFileSystem
oReg = Null
oFileSystem = Null

Sub Main()
Dim dtStart
Dim lSizeDB, lFreeSpaceDB, lSizeLog, lFreeSpaceLog
Dim lReserveLog, lReserveDB
Dim strPathDB, strPathLog, strMessage, strComputer
Dim bSuccess


TargetFQDNComputer = oParams(0)
TargetNetbiosDomain = oParams(1)
IsTargetAgentless = False
Err.Clear

Set oBagState = oAPI.CreateTypedPropertyBag(StateDataType)

bSuccess = True

' Check this out TBD
If Not(IsTargetAgentless) Then
dtStart = Now
bLogSuccessEvent = CBool(oParams(2))'LogSuccessEvent
strComputer = TargetFQDNComputer

On Error Resume Next

If GetDatabaseInfo(strPathDB, lSizeDB, lFreeSpaceDB) Then
strPathDB = LCase(strPathDB)
Set oBag = oAPI.CreateTypedPropertyBag(PerformanceDataType)
oBag.AddValue "StatusCounter" , "Database Drive Free Space"
oBag.AddValue "StatusInstance" , strPathDB
oBag.AddValue "StatusValue", "" &amp; lFreeSpaceDB
oAPI.AddItem oBag

Set oBag = oAPI.CreateTypedPropertyBag(PerformanceDataType)
oBag.AddValue "StatusCounter" , "Database Size"
oBag.AddValue "StatusInstance" , strPathDB
oBag.AddValue "StatusValue", "" &amp; lSizeDB
oAPI.AddItem oBag

Else
bSuccess = False
End If

If GetLogFileInfo(strPathLog, lSizeLog, lFreeSpaceLog) Then

strPathLog = LCase(strPathLog)
Set oBag = oAPI.CreateTypedPropertyBag(PerformanceDataType)
oBag.AddValue "StatusCounter" , "Log File Drive Free Space"
oBag.AddValue "StatusInstance" , strPathLog
oBag.AddValue "StatusValue", "" &amp; lFreeSpaceLog
oAPI.AddItem oBag

Set oBag = oAPI.CreateTypedPropertyBag(PerformanceDataType)
oBag.AddValue "StatusCounter" , "Log File Size"
oBag.AddValue "StatusInstance" , strPathLog
oBag.AddValue "StatusValue", "" &amp; lSizeLog
oAPI.AddItem oBag

Else
bSuccess = False
End If

' If any of the previous code failed then we don't have enough information to
' complete the tests properly so don't do them.
If bSuccess Then
' calculate the reserve amount
lReserveLog = lSizeLog * CDbl(LOG_THRESHOLD)
If (lReserveLog &lt; LOG_BOUNDARY) Then
lReserveLog = LOG_BOUNDARY
End If
lReserveDB = lSizeDB * CDbl(DIT_THRESHOLD)
If (lReserveDB &lt; DIT_BOUNDARY) Then
lReserveDB = DIT_BOUNDARY
End If

' Get the old sizes
Dim lOldSizeDIT, lOldSizeLog, lOldFreeSpaceDB, lOldFreeSpaceLog, tempStr
tempStr = GetData("DITSize")
if tempStr &lt;&gt; "" Then
lOldSizeDIT = CDbl(tempStr)
Else
lOldSizeDIT = 0
End if

tempStr = GetData("LogSize")
if tempStr &lt;&gt; "" Then
lOldSizeLog = CDbl(tempStr)
Else
lOldSizeLog = 0
End if

tempStr = GetData("FreeDBSpace")
if tempStr &lt;&gt; "" Then
lOldFreeSpaceDB = CDbl(tempStr)
Else
lOldFreeSpaceDB = 0
End if

tempStr = GetData("FreeLogSpace")
if tempStr &lt;&gt; "" Then
lOldFreeSpaceLog = CDbl(tempStr)
Else
lOldFreeSpaceLog = 0
End if

' Update the old sizes
SetData "DITSize", lSizeDB
SetData "LogSize", lSizeLog
SetData "FreeDBSpace", lFreeSpaceDB
SetData "FreeLogSpace", lFreeSpaceLog
SetData "LastExecution", Now()

' Check the growth of the DIT and Logs, but only if first replication is not
' occurring

If Not InFirstReplication(strComputer) Then
Dim dtLastExec, deltaMinutes, deltaSize
dtLastExec = CDate(GetData("LastExecution"))
deltaMinutes = DateDiff("n", Now(), dtLastExec)
If 0 &lt; CLng(lOldSizeDIT) Then
deltaSize = (lSizeDB - lOldSizeDIT) / lOldSizeDIT
If 0.2 &lt; deltaSize Then
oBagState.AddValue "StateDBSIZE", "BAD"

CreateEvent EVENTID_DIT_GROWTH_WARNING, EVENT_TYPE_WARNING, _
"The size of the DIT file has grown " &amp; CLng(deltaSize * 100) &amp; _
"% in the last " &amp; deltaMinutes &amp; " minutes. If this is not " &amp; _
"expected, the reason for this growth should be investigated."
Else
oBagState.AddValue "StateDBSIZE", "GOOD"
End If

End If
If 0 &lt; CLng(lOldSizeLog) Then
deltaSize = (lSizeLog - lOldSizeLog) / lOldSizeLog
If 0.2 &lt; deltaSize Then
oBagState.AddValue "StateLOGSIZE", "BAD"

CreateEvent EVENTID_LOG_GROWTH_WARNING, EVENT_TYPE_WARNING, _
"The size of the log file has grown " &amp; CLng(deltaSize * 100) &amp; _
"% in the last " &amp; deltaMinutes &amp; " minutes. If this is not " &amp; _
"expected, the reason for this growth should be investigated."
Else
oBagState.AddValue "StateLOGSIZE", "GOOD"
End If
End If
End If

' check the size of log file and free space
Dim aComponents()
If Left(strPathDB, 2) = Left(strPathLog, 2) Then
'Log file and database file are on the same drive
If (lFreeSpaceDB &lt; (lReserveDB + lReserveLog)) Then
bSuccess = False
strMessage = "Free space (" &amp; lFreeSpaceDB &amp; "KB) on drive " &amp; UCase(Left(strPathDB, 2)) &amp; " is lower than the required reserved space for AD Database and Log file. It should be at least " &amp; (lReserveLog + lReserveDB) &amp; " KBytes."

oBagState.AddValue "StateDBFreeSpace", "BAD"

oBagState.AddValue "StateLOGFreeSpace", "BAD"

CreateEvent EVENTID_SPACE_AVAILABLE_WARNING, EVENT_TYPE_ERROR, strMessage
SetData WARNING_TAG, "True"
Else
oBagState.AddValue "StateDBFreeSpace", "GOOD"

oBagState.AddValue "StateLOGFreeSpace", "GOOD"
If GetData(WARNING_TAG) = "True" Then
SetData WARNING_TAG, "False"
CreateEvent EVENTID_SPACE_AVAILABLE_WARNING, EVENT_TYPE_SUCCESS, strMessage
End If
End If
Else
'Log File and database file are on separate drives
If (lFreeSpaceDB &lt; lReserveDB) Then
bSuccess = False
strMessage = "Free space (" &amp; lFreeSpaceDB &amp; "KB) on drive " &amp; UCase(Left(strPathDB, 2)) &amp; " is lower than the required reserved space for AD Database. It should be at least " &amp; (lReserveDB) &amp; " KBytes."

oBagState.AddValue "StateDBFreeSpace", "BAD"

CreateEvent EVENTID_SPACE_AVAILABLE_WARNING, EVENT_TYPE_ERROR, strMessage
SetData WARNING_TAG, "True"
Else
oBagState.AddValue "StateDBFreeSpace", "GOOD"
If GetData(WARNING_TAG) = "True" Then
SetData WARNING_TAG, "False"
CreateEvent EVENTID_SPACE_AVAILABLE_WARNING, EVENT_TYPE_SUCCESS, strMessage
End If
End If

If (lFreeSpaceLog &lt; lReserveLog) Then
bSuccess = False
bSuccess = False

strMessage = "Free space (" &amp; lFreeSpaceLog &amp; "KB) on drive " &amp; UCase(Left(strPathLog, 2)) &amp; " is lower than the required reserved space for AD Log file. It should be at least " &amp; (lReserveLog) &amp; " KBytes."

CreateEvent EVENTID_SPACE_AVAILABLE_WARNING, EVENT_TYPE_ERROR, strMessage
SetData WARNING_TAG, "True"

oBagState.AddValue "StateLOGFreeSpace", "BAD"
Else
oBagState.AddValue "StateLOGFreeSpace", "GOOD"
If GetData(WARNING_TAG) = "True" Then
SetData WARNING_TAG, "False"
CreateEvent EVENTID_SPACE_AVAILABLE_WARNING, EVENT_TYPE_SUCCESS, strMessage
End If
End If
End If

If bLogSuccessEvent And bSuccess Then
strMessage = "The script '" &amp; SCRIPT_NAME &amp; "' completed successfully in " &amp; _
DateDiff("s", dtStart, Now) &amp; " seconds."
CreateEvent EVENTID_SUCCESS, EVENT_TYPE_INFORMATION, strMessage
End If
End If
Else
CreateEvent EVENT_ID_AGENTLESS, EVENT_TYPE_ERROR, "The AD Management Pack does not support the agentless management mode." &amp; vbCrLf &amp; _
"The script '" &amp; SCRIPT_NAME &amp; "' will not execute." &amp; vbCrLf &amp; _
"To prevent this alert being generated again, either change the monitoring " &amp; _
"mode of the computer '" &amp; TargetFQDNComputer &amp; "' to agent-managed " &amp; _
"or disable the rule that generated this alert."
End If
oAPI.AddItem oBagState
oAPI.ReturnItems
'Else
'strMessage = "The script '" &amp; SCRIPT_NAME &amp; "' can only be executed by an event rule."
'CreateEvent EVENTID_EVENT_RULE_ONLY, EVENT_TYPE_WARNING, strMessage
'End If
End Sub

'******************************************************************************
' Name: GetDatabaseInfo
'
' Purpose: Read the size and path of the database file, and the amount of free space
' on the drive containing the database file.
'
' Parameters: None
'
Function GetDatabaseInfo(ByRef strPathDB, ByRef lSizeDB, ByRef lFreeSpaceDB)

Dim oDrive, strMessage

' Create the oReg object if it has not yet been created
If IsNull(oReg) Then
Set oReg = CreateObject("WScript.Shell")
End If

' Create the oFileSystem object if it has not yet been created
If IsNull(oFileSystem) Then
Set oFileSystem = CreateObject("Scripting.FileSystemObject")
End If

' Read the path to the database file from the registry
strPathDB = oReg.RegRead(DatabaseRegKey)

If strPathDB = "" Then
strMessage = "The script '" &amp; SCRIPT_NAME &amp; "' was unable to obtain Active Directory database information. " &amp; _
"Database path returned empty when reading from the registry." &amp; vbCrLf &amp; vbCrLf &amp; "DatabaseRegKey: " &amp; DatabaseRegKey
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, strMessage

GetDatabaseInfo = false
Else
' Get the object for the drive holding the database
Set oDrive = oFileSystem.GetDrive(oFileSystem.GetDriveName(strPathDB))

' Read the size of the database
lSizeDB = oFileSystem.GetFile(strPathDB).Size

' Read the amount of free space on the database drive
lFreeSpaceDB = oDrive.FreeSpace

oDrive = Null

GetDatabaseInfo = true
End If

End Function

'******************************************************************************
' Name: GetLogFileInfo
'
' Purpose: Read the size and path of the database log file, and the amount of free space
' on the drive containing the database log file.
'
' Parameters: None
'
Function GetLogFileInfo(ByRef strPathLog, ByRef lSizeLog, ByRef lFreeSpaceLog)

Dim oDrive, strMessage

' Create the oReg object if it has not yet been created
If IsNull(oReg) Then
Set oReg = CreateObject("WScript.Shell")
End If

' Create the oFileSystem object if it has not yet been created
If IsNull(oFileSystem) Then
Set oFileSystem = CreateObject("Scripting.FileSystemObject")
End If

' Read the path to the log file from the registry
strPathLog = oReg.RegRead(LogFileRegKey) &amp; "\" &amp; LogFileName

If strPathLog = "" Then
strMessage = "The script '" &amp; SCRIPT_NAME &amp; "' was unable to obtain Active Directory log file information. " &amp; _
"Logfile path returned empty when reading from the registry. " &amp; vbCrLf &amp; vbCrLf &amp; "LogFileRegKey: " &amp; LogFileRegKey
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, strMessage

GetLogFileInfo = false
Else
' Get the object for the drive holding the database
Set oDrive = oFileSystem.GetDrive(oFileSystem.GetDriveName(strPathLog))

' Read the size of the database
lSizeLog = oFileSystem.GetFile(strPathLog).Size

' Read the amount of free space on the database drive
lFreeSpaceLog = oDrive.FreeSpace

oDrive = Null

GetLogFileInfo = true
End If

End Function

'******************************************************************************
' Name: CreateEvent
'
' Purpose: Creates a MOM event
'
' Parameters: lEventID, the ID for the event
' lEventType, the severity for the event. See constants at head of file
' strMessage, the message for the event
'
Sub CreateEvent(lEventID, lEventType, strMessage)

oAPI.LogScriptEvent "AD Database and Log",lEventID, lEventType, strMessage

End Sub

'******************************************************************************
Function GetErrorString(oErr)
'
' Purpose: Attempts to find the description for an error if an error with
' no description is passed in.
'
' Parameters: oErr, the error object
'
' Return: String, the description for the error. (Includes the error code.)
'
Dim lErr, strErr
lErr = oErr
strErr = oErr.Description

On Error Resume Next
If 0 &gt;= Len(strErr) Then
' If we don't have an error description, then check to see if the error
' is a 0x8007xxxx error. If it is, then look it up.
Const ErrorMask = &amp;HFFFF0000
Const HiWord8007 = &amp;H80070000
Const LoWordMask = 65535 ' This is equivalent to 0x0000FFFF

If (lErr And ErrorMask) = HiWord8007 Then
' Attempt to use 'net helpmsg' to get a description for the error.
Dim oShell
Set oShell = CreateObject("WScript.Shell")
If Err = 0 Then
Dim oExec
Set oExec = oShell.Exec("net helpmsg " &amp; (lErr And LoWordMask))

Dim strMessage, i
Do
strMessage = oExec.stdout.ReadLine()
i = i + 1
Loop While (Len(strMessage) = 0) And (i &lt; 5)

strErr = strMessage
End If
End If
End If

GetErrorString = vbCrLf &amp; "The error returned was: '" &amp; strErr &amp; "' (0x" &amp; Hex(lErr) &amp; ")"
End Function

'******************************************************************************
Function GetData(strKey)
'
' Purpose: Retrieves data out of a varset. Uses the key to determine what
' data to retrieve.
'
' Arguments: strKey, the key of the data to retrieve
'
' Returns: String, the data to return or an empty string
'
On Error Resume Next
If IsNull(oReg) Then
Set oReg = CreateObject("WScript.Shell")
End If
Dim regData
regData = oReg.RegRead(REG_Key &amp; "\" &amp; strKey )
If IsNull(regData) or IsEmpty(regData) or regData = "" Then
GetData = ""
Else
GetData = regData
End If
Err.Clear
End Function

'******************************************************************************
Sub SetData(strKey, strData)
'
' Purpose: To store data in a varset. If the key exists then the data
' associated with that key is replaced, otherwise the key/data
' combination is added to the varset.
'
' Arguments: strKey, the key of the line to replace
' strData, the data to associate with the key
'
' Returns: Nothing
'
If IsNull(oReg) Then
Set oReg = CreateObject("WScript.Shell")
End If
Call oReg.RegWrite(REG_Key &amp; "\" &amp; strKey , strData )
Err.Clear
End Sub
'******************************************************************************
Function InFirstReplication(strDomainController)
'
' Purpose: To determine whether the domain controller is in a 'first
' replication' operation.
'
' Arguments: strDomainController - the name of the domain controller to be checked.
'
' Returns: Boolean - True if the DC is in First Replication, False otherwise.
'
' Remarks: The way to check to see if a naming context has succeeded following
' it's first replication is check if the attribute 'replUpToDateVector'
' exists. If it does exist then the naming context has completed it's
' first replication.
'
On Error Resume Next

Dim oRootDSE
Set oRootDSE = GetObject("LDAP://" &amp; strDomainController &amp; "/RootDSE")
If Err &lt;&gt; 0 Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, _
"The script '" &amp; SCRIPT_NAME &amp; "' encountered an error while trying " &amp; _
"to get the object 'LDAP://" &amp; strDomainController &amp; "/RootDSE'." &amp; _
GetErrorString(Err)
Else
Dim upToDateVector
upToDateVector = oRootDSE.Get("replUpToDateVector")
If Err &lt;&gt; 0 Then
If Err = &amp;H8000500d Then
' The attribute does not exist, we must be in first replication.
InFirstReplication = True
Else
' We could not get the vector. This should be because of a error.
CreateError EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, _
"The script '" &amp; SCRIPT_NAME &amp; "' encountered an error while trying " &amp; _
"to read 'replUpToDateVector' on the object 'LDAP://" &amp; strDomainController &amp; _
"/RootDSE'." &amp; GetErrorString(Err)
End If
End If
End If
End Function

Call Main()

</Script></Contents>
<Unicode>1</Unicode>
</File>
</Files>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DS"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.PropertyBagData</OutputType>
</DataSourceModuleType>