Использование OPENXML для анализа IIS MetaBase.xml - PullRequest
1 голос
/ 19 апреля 2011

Я пытаюсь получить список веб-сайтов на сервере IIS 6 в таблицу SQL-Server.Я знаю, что могу получить его с помощью WMI и т. Д., Но для этого потребуется дополнительная служба, работающая на коробке, в то время как я смогу найти информацию, получив процедуру анализа файла MetaBase.xml с использованием OPENXML.

Для тех из вас, кто не знаком с MetaBase.xml, соответствующие разделы выглядят примерно так:

<configuration xmlns="urn:microsoft-catalog:XML_Metabase_V64_0">
  <MBProperty>
    <IIsWebDirectory Location="/LM/W3SVC/1/ROOT/MySite1" AppFriendlyName="MySite1" AppIsolated="2" AppPoolId="MySite1" AppRoot="/LM/W3SVC/1/ROOT/MySite1" DontLog="TRUE">     
    </IIsWebDirectory>
    <IIsWebDirectory Location="/LM/W3SVC/1/ROOT/MySite2" AppFriendlyName="MySite2" AppIsolated="2" AppPoolId="MySite2" AppRoot="/LM/W3SVC/1/ROOT/MySite2" DontLog="TRUE">     
    </IIsWebDirectory>
  </MBProperty>
</configuration>

Я использую следующий SQL, чтобы попытаться разобрать его:

DECLARE @XMLPath VARCHAR(MAX)
SELECT @XMLPath = 'C:\Temp\MetaBase.xml'

DECLARE @RawXML XML, @sql NVARCHAR(4000), @params NVARCHAR(4000), @handle INT
SELECT @sql = N'SELECT @res = (SELECT * FROM OPENROWSET (BULK '''+ @XMLPath +''', SINGLE_BLOB)x)'
SELECT @params = N'@res XML OUTPUT'
EXEC sp_executesql @sql, @params, @res = @RawXML OUTPUT

SELECT @RawXML

EXEC sp_xml_preparedocument @handle OUTPUT, @RawXML
SELECT * 
FROM OPENXML(@handle, 'MBProperty/IISWebDirectory', 3) WITH (AppFriendlyName VARCHAR(800), Location VARCHAR(800), AppRoot VARCHAR(800), AppPoolId VARCHAR(800), DefaultDoc VARCHAR(800))
EXEC sp_xml_removedocument @handle

Я вижу, что XML правильно загружен в @RawXML, но ничего не получает из запроса OPENXML.Я предполагаю, что это как-то связано с путем, но я пробовал несколько комбинаций (например, «configuration / MBProperty / IISWebDirectory») безрезультатно.

Ответы [ 2 ]

3 голосов
/ 19 апреля 2011

Я собираюсь сыграть здесь адвоката дьяволов и предположить, что это неправильный подход.

Файл метабазы ​​не всегда актуален. IIS кэширует обновления метабазы ​​и периодически сбрасывает их на диск. У меня возникали задержки до 5 минут между изменением свойства с помощью ADSI или WMI и его сбросом на диск, когда сервер находится под нагрузкой.

Вы говорите, что для сбора этих данных вам понадобится дополнительная служба на компьютере. Конечно, вам все равно нужен какой-то процесс для сбора этих данных из файла метабазы?

Другая очень важная причина, по которой это также является плохой идеей, заключается в том, что при анализе этого файла вам нужно будет самостоятельно разрешать унаследованные свойства. Одним из основных аспектов технического проектирования метабазы ​​IIS6 является наследование свойств.

Например, если вы собираете Script Maps, это наследуемое свойство. Если вы явно не задали ScriptMap или, возможно, DefaultDoc (или какое-либо другое унаследованное свойство) на сайте, в виртуальном каталоге или приложении, вам придется вернуться к дереву метабазы, чтобы найти это значение.

Это делает удочку для своей спины. Вы должны использовать API (ADSI, System.DirectoryServices [API, который является путем наименьшего сопротивления] или WMI) для запроса метабазы, а не для чтения этого файла напрямую. Поверь мне, я был здесь раньше.

3 голосов
/ 19 апреля 2011

Вам необходимо добавить configuration к пути и изменить IISWebDirectory на IIsWebDirectory, поскольку XML чувствителен к регистру и вам необходимо добавить параметр xpath_namespaces.

EXEC sp_xml_preparedocument @handle OUTPUT, @RawXML, '<root xmlns:ns="urn:microsoft-catalog:XML_Metabase_V64_0" />'

SELECT * 
FROM OPENXML(@handle, 'ns:configuration/ns:MBProperty/ns:IIsWebDirectory', 3) WITH
  (AppFriendlyName VARCHAR(800),
   Location VARCHAR(800),
   AppRoot VARCHAR(800),
   AppPoolId VARCHAR(800),
   DefaultDoc VARCHAR(800))
EXEC sp_xml_removedocument @handle

Или вы можете запросить переменную XML напрямую.

;with xmlnamespaces ('urn:microsoft-catalog:XML_Metabase_V64_0' as ns)
select
  n.i.value('@AppFriendlyName', 'varchar(800)') as AppFriendlyName,
  n.i.value('@Location', 'varchar(800)') as Location,
  n.i.value('@AppRoot', 'varchar(800)') as AppRoot,
  n.i.value('@AppPoolId', 'varchar(800)') as AppPoolId,
  n.i.value('@DefaultDoc', 'varchar(800)') as DefaultDoc
from @RawXML.nodes('ns:configuration/ns:MBProperty/ns:IIsWebDirectory') as n(i)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...