我正在尝试将IIS 6服务器上的网站列表添加到SQL-Server表中。我知道我可以使用WMI等获得它但是这需要在盒子上运行额外的服务,而我应该能够通过使用OPENXML获取proc来解析MetaBase.xml文件来找到信息。
对于那些不熟悉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')无济于事。
答案 0 :(得分:3)
您需要在路径中添加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)
答案 1 :(得分:3)
我将在这里扮演恶魔倡导者,并建议这是错误的做法。
元数据库文件并不总是最新的。 IIS缓存配置数据库更新并定期将其刷新到磁盘。我在使用ADSI或WMI更改属性与在服务器负载下刷新到磁盘之间经历了长达5分钟的延迟。
您说您需要额外的服务才能在计算机上运行以收集此数据。当然,您还需要某种过程来从元数据库文件中收集这些数据吗?
另一个非常重要的原因是,当您解析此文件时,您需要自己解析继承的属性。 IIS6配置数据库的主要技术设计方面之一是属性继承。
例如,如果您正在收集脚本地图,那么这是一个继承的属性。除非您在站点,虚拟目录或应用程序上显式设置ScriptMap
或DefaultDoc
(或其他一些继承的属性),否则您需要向后移动元数据库树以查找此内容值。
那是为你自己制作一根杆子。您应该使用API(ADSI,System.DirectoryServices
[最差阻力路径的API]或WMI)来查询元数据库,而不是直接读取此文件。相信我,我以前来过这里。