(Follow-up set to microsoft.public.scripting.wsh).
Yet another script written in connection with the Windows Deployment
Resource Kit coming soon from Microsoft Press.
=====================================================================
One of the minor annoyances for WMI and other data into semi-persistent
variables that can be used easily from batch scripts. There are several ways
to do this type of thing; we were after something fairly simple to extend
and replicate by different people, with name scoping to make it easier to
see what goes where and avoid collisions with prior variables, and with
limited persistence to prevent possible problems with additions to the
environment.
A technique we're using is to read an XML file containing some instructions
about a WMI namespace, properties, and variable scope, and a special prefix
to make the variables "look" scoped. The following script does this and
creates VOLATILE variables from the items in the XML file. Feel free to use
this; and of course comments and ideas are appreciated.
Note that the script is followed by an example XML file.
===================================================
' note that you must supply the path to the xml file as an argument!
src = wscript.arguments(0)
' C:\data\windeploy\working\wmi2env\win32_operatingsystem.xml
set xmldoc = createobject("MSXML2.FreeThreadedDOMDocument")
die_if not xmldoc.load(src), "Could not load " & src, 3
set root = xmldoc.documentElement
die_if not ucase(root.nodeName) = "ENVIRONMENT", _
"Could not find Environment root in " & src, 4
wmiclass = GetAttributeOrDefault(root, "wmiclass", false)
die_if wmiclass = false, "could not find wmiclass attribute for " _
& root.nodeName & " in " & src, 5
set sh = createobject("WScript.Shell")
set Env = sh.Environment(GetAttributeOrDefault(root, "scope", "VOLATILE"))
prefix = GetAttributeOrDefault(root, "prefix", "_") _
& GetAttributeOrDefault(root, "delimiter", ".")
set properties = root.selectNodes("property")
computer = "."
set WmiSvc = GetObject("winmgmts:\\" & computer & "\root\CIMV2")
set instances = WmiSvc.ExecQuery("SELECT * FROM " & wmiclass, "WQL", 4
For Each instance in instances
For Each prop in properties
with instance.Properties_.Item(AttributeValue(prop, "name"))
Env.Item(ucase(prefix & .Name)) = .Value
end with
Next
wscript.quit
Next
function GetAttributeOrDefault(node, attributeName, defaultValue)
if hasAttribute(node, attributeName) then
GetAttributeOrDefault = AttributeValue(root, attributeName)
else
GetAttributeOrDefault = defaultValue
end if
end function
function hasAttribute(node, attributeName)
dim attribute: hasAttribute = false
for each attribute in node.attributes
if attributeName = attribute.baseName then
hasAttribute = true
exit function
end if
next
end function
function AttributeValue(node, attributeName)
AttributeValue = node.attributes.getNamedItem(attributeName).text
end function
sub die_if(expression, errorText, exitcode)
if expression then
WScript.StdErr.WriteLine errorText
WScript.Quit exitCode
end if
end sub
===================================================
<?xml version="1.0"?>
<Environment prefix="OS" wmiclass="Win32_OperatingSystem">
<property name="BootDevice"/>
<property name="Buildnumber"/>
<property name="BuildType"/>
<property name="CodeSet"/>
<property name="CSDVersion"/>
<property name="CurrentTimeZone"/>
<property name="Debug"/>
<property name="Distributed"/>
<property name="EncryptionLevel"/>
<property name="ForegroundApplicationBoost"/>
<property name="InstallDate"/>
<property name="LastBootUpTime"/>
<property name="Locale"/>
<property name="OSLanguage"/>
<property name="OSType"/>
<property name="ProductType"/>
<property name="SerialNumber"/>
<property name="ServicePackMajorVersion"/>
<property name="ServicePackMinorVersion"/>
<property name="SuiteMask"/>
<property name="Version"/>
</Environment>