Allow me to preface this by saying I am not an expert on IIS, but this is how I think the setup works based on reverse-engineering one of my own setups with multiple Sites/Applications, and I’ll step through my assumptions as I explain this query.
First I don’t want to assume the Sites are located as c:\inetpub\wwwroot or its subdirectories. I know for a fact IIS sites can be in other paths, as I have many instances of that myself. So instead of assuming c:\Inetpub\wwwroot, I’ll look up the application server path from the Registry:
q: value "InstallPath" of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp" of native registry
A: %25windir%25\system32\inetsrv%00
That directory, based on the environment variable %windir%, cannot be used as a folder directly, but we can use the ‘expand environment string’ to resolve the variable and find that path:
q: (expand environment string of (it as string) of value "InstallPath" of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp" of native registry)
A: C:\windows\system32\inetsrv
Next, I know that path will have an ‘applicationHost.config’ file, which is an XML document describing all the IIS Sites on the host. I can use the XML inspectors and xpaths to pull data from the XML file.
Here, I assume that we only need to find the web.config files from the root directory of each Site. Some of my sites have multiple virtual directories, if we expect web.config files in each virtual directory we would modify this query, but for now I’m assuming we only need the root directory of each Site.
You should run this query on some of your test machines to determine whether this retrieves all the Sites you expect:
// Root folders of all Sites
q: node values of attributes "physicalPath" of xpaths "/configuration/*/sites/site/application/virtualDirectory[@path='/']" of xml documents of files "applicationHost.config" of folders "config" of native folder (expand environment string of (it as string) of value "InstallPath" of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp" of native registry)
A: %25SystemDrive%25\inetpub\wwwroot
A: C:\Program Files\Microsoft Configuration Manager\Client
A: C:\Program Files\Microsoft Configuration Manager\CCM\Incoming
A: C:\Program Files\SMS_CCM\ServiceData\System
A: C:\Program Files\SMS_CCM\ServiceData\System
A: C:\Program Files\SMS_CCM\ServiceData\System
A: C:\Program Files\SMS_CCM\CCM_STS
A: C:\Program Files\SMS_CCM\CMUserService
A: C:\Program Files\SMS_CCM\CMUserServiceWindowsAuth
A: C:\Program Files\SMS_CCM\SMS_MP
A: C:\Program Files\SMS_CCM\SMS_MP
A: C:\Program Files\SMS_CCM\SMS_BGB
A: C:\SCCMContentLib
A: C:\SMSSIG$
A: C:\Program Files\Update Services\WebServices\Root\
A: C:\Program Files\Update Services\WebServices\ReportingWebService
A: C:\Program Files\Update Services\WebServices\ClientWebService
A: C:\Program Files\Update Services\WebServices\SimpleAuthWebService
A: C:\Program Files\Update Services\WebServices\ServerSyncWebService
A: C:\Program Files\Update Services\WebServices\DssAuthWebService
A: C:\Program Files\Update Services\Inventory
A: C:\Program Files\Update Services\WebServices\ApiRemoting30
A: C:\inetpub\wwwroot\test
Notice again my first result references an environment variable in the result A: %25SystemDrive%25\inetpub\wwwroot
, so we’ll again use the folders (expand environment string of it) inspector to resolve that variable to a physical path:
q: (native folders (expand environment string of it)) of node values of attributes "physicalPath" of xpaths "/configuration/*/sites/site/application/virtualDirectory[@path='/']" of xml documents of files "applicationHost.config" of folders "config" of native folder (expand environment string of (it as string) of value "InstallPath" of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp" of native registry)
A: C:\inetpub\wwwroot
A: C:\Program Files\Microsoft Configuration Manager\Client
A: C:\Program Files\Microsoft Configuration Manager\CCM\Incoming
...
Next is to check for each case in those root folders -
- Does a web.config exist ?
- Is the web.config a valid XML document ?
- Does the web.config define Forms-Based Authentication?
- Does the web.config require SSL for Forms-Based Authentication?
Again this is a series of XML xpath queries
q: (it, exists files "web.config" of it, exists xml documents of files "web.config" of it, exists xpaths "/configuration/system.web/authentication[@mode='Forms']" of xml documents of files "web.config" of it, exists xpaths "/configuration/system.web/authentication[@mode='Forms']/forms[@requireSSL='true']" of xml documents of files "web.config" of it) of (folders (it)) of (expand environment string of (it as string) ) of node values of attributes "physicalPath" of xpaths "/configuration/*/sites/site/application/virtualDirectory[@path='/']" of xml documents of files "applicationHost.config" of folders "config" of native folder (expand environment string of (it as string) of value "InstallPath" of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp" of native registry)
A: C:\inetpub\wwwroot, True, True, False, False
A: C:\Program Files\Microsoft Configuration Manager\Client, False, False, False, False
A: C:\Program Files\Microsoft Configuration Manager\CCM\Incoming, False, False, False, False
A: C:\Program Files\SMS_CCM\ServiceData\System, False, False, False, False
A: C:\Program Files\SMS_CCM\ServiceData\System, False, False, False, False
A: C:\Program Files\SMS_CCM\ServiceData\System, False, False, False, False
A: C:\Program Files\SMS_CCM\CCM_STS, True, True, False, False
A: C:\Program Files\SMS_CCM\CMUserService, True, True, False, False
A: C:\Program Files\SMS_CCM\CMUserServiceWindowsAuth, True, True, False, False
A: C:\Program Files\SMS_CCM\SMS_MP, False, False, False, False
A: C:\Program Files\SMS_CCM\SMS_MP, False, False, False, False
A: C:\Program Files\SMS_CCM\SMS_BGB, False, False, False, False
A: C:\SCCMContentLib, False, False, False, False
A: C:\SMSSIG$, False, False, False, False
A: C:\Program Files\Update Services\WebServices\Root, False, False, False, False
A: C:\Program Files\Update Services\WebServices\ReportingWebService, True, True, False, False
A: C:\Program Files\Update Services\WebServices\ClientWebService, True, True, False, False
A: C:\Program Files\Update Services\WebServices\SimpleAuthWebService, True, True, False, False
A: C:\Program Files\Update Services\WebServices\ServerSyncWebService, True, True, False, False
A: C:\Program Files\Update Services\WebServices\DssAuthWebService, True, True, False, False
A: C:\Program Files\Update Services\Inventory, False, False, False, False
A: C:\Program Files\Update Services\WebServices\ApiRemoting30, True, True, False, False
A: C:\inetpub\wwwroot\test, True, True, True, True
In my system, only the ‘test’ site (the last result) allows Forms-Based Authentication, and that site has requireSSL set on it. Several (but not all) of my sites even have a web.config. I’m not sure what happens with the Sites that have no web.config, but I assume they must inherit from the top-level web.config of the default site? Not sure…
In any case, now that all the data is retrieved I can use the values of each of these items to print a result. I think you can just change the messages here to be whatever you like for reporting
q: (item 0 of it, (if not item 1 of it then "No web.config" else if not item 2 of it then "web.config not readable" else if not item 3 of it then "No Forms Auth Configured" else if item 4 of it then "SSL Enabled for Forms auth" else "SSL Disabled for Forms auth") ) of (it, exists files "web.config" of it, exists xml documents of files "web.config" of it, exists xpaths "/configuration/system.web/authentication[@mode='Forms']" of xml documents of files "web.config" of it, exists xpaths "/configuration/system.web/authentication[@mode='Forms']/forms[@requireSSL='true']" of xml documents of files "web.config" of it) of (folders (it)) of (expand environment string of (it as string) ) of node values of attributes "physicalPath" of xpaths "/configuration/*/sites/site/application/virtualDirectory[@path='/']" of xml documents of files "applicationHost.config" of folders "config" of native folder (expand environment string of (it as string) of value "InstallPath" of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp" of native registry)
A: C:\inetpub\wwwroot, No Forms Auth Configured
A: C:\Program Files\Microsoft Configuration Manager\Client, No web.config
A: C:\Program Files\Microsoft Configuration Manager\CCM\Incoming, No web.config
A: C:\Program Files\SMS_CCM\ServiceData\System, No web.config
A: C:\Program Files\SMS_CCM\ServiceData\System, No web.config
A: C:\Program Files\SMS_CCM\ServiceData\System, No web.config
A: C:\Program Files\SMS_CCM\CCM_STS, No Forms Auth Configured
A: C:\Program Files\SMS_CCM\CMUserService, No Forms Auth Configured
A: C:\Program Files\SMS_CCM\CMUserServiceWindowsAuth, No Forms Auth Configured
A: C:\Program Files\SMS_CCM\SMS_MP, No web.config
A: C:\Program Files\SMS_CCM\SMS_MP, No web.config
A: C:\Program Files\SMS_CCM\SMS_BGB, No web.config
A: C:\SCCMContentLib, No web.config
A: C:\SMSSIG$, No web.config
A: C:\Program Files\Update Services\WebServices\Root, No web.config
A: C:\Program Files\Update Services\WebServices\ReportingWebService, No Forms Auth Configured
A: C:\Program Files\Update Services\WebServices\ClientWebService, No Forms Auth Configured
A: C:\Program Files\Update Services\WebServices\SimpleAuthWebService, No Forms Auth Configured
A: C:\Program Files\Update Services\WebServices\ServerSyncWebService, No Forms Auth Configured
A: C:\Program Files\Update Services\WebServices\DssAuthWebService, No Forms Auth Configured
A: C:\Program Files\Update Services\Inventory, No web.config
A: C:\Program Files\Update Services\WebServices\ApiRemoting30, No Forms Auth Configured
A: C:\inetpub\wwwroot\test, SSL Enabled for Forms auth
T: 38.068 ms
I: plural ( folder, string )
We could also filter on our five items, if we only wish to show non-compliant ones - but you need to determine whether a missing web.config, or a web.config that doesn’t allow Forms-based authentication, is really non-compliant. By that standard, only my test site (the only one with Forms authentication enabled and SSL required on it) would be compliant. Here’s the query in the more-readable “expanded” form with filters added:
(
item 0 of it
, (if not item 1 of it then "No web.config"
else if not item 2 of it then "web.config not readable"
else if not item 3 of it then "No Forms Auth Configured"
else if item 4 of it then "SSL Enabled for Forms auth"
else "SSL Disabled for Forms auth"
)
) of (
it
, exists files "web.config" of it
, exists xml documents of files "web.config" of it
, exists xpaths "/configuration/system.web/authentication[@mode='Forms']" of xml documents of files "web.config" of it
, exists xpaths "/configuration/system.web/authentication[@mode='Forms']/forms[@requireSSL='true']" of xml documents of files "web.config" of it
) whose (
not item 2 of it /*web.config missing or not XML */
or not item 3 of it /* Forms authentication not configured */
or not item 4 of it /* SSL not required for Forms authentication */
) of
(folders (it)) of (expand environment string of (it as string) )
of node values of attributes "physicalPath" of xpaths "/configuration/*/sites/site/application/virtualDirectory[@path='/']"
of xml documents of files "applicationHost.config" of folders "config" of native folder (expand environment string of (it as string)
of value "InstallPath" of key "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\InetStp" of native registry)
A: C:\inetpub\wwwroot, No Forms Auth Configured
A: C:\Program Files\Microsoft Configuration Manager\Client, No web.config
A: C:\Program Files\Microsoft Configuration Manager\CCM\Incoming, No web.config
A: C:\Program Files\SMS_CCM\ServiceData\System, No web.config
A: C:\Program Files\SMS_CCM\ServiceData\System, No web.config
A: C:\Program Files\SMS_CCM\ServiceData\System, No web.config
A: C:\Program Files\SMS_CCM\CCM_STS, No Forms Auth Configured
A: C:\Program Files\SMS_CCM\CMUserService, No Forms Auth Configured
A: C:\Program Files\SMS_CCM\CMUserServiceWindowsAuth, No Forms Auth Configured
A: C:\Program Files\SMS_CCM\SMS_MP, No web.config
A: C:\Program Files\SMS_CCM\SMS_MP, No web.config
A: C:\Program Files\SMS_CCM\SMS_BGB, No web.config
A: C:\SCCMContentLib, No web.config
A: C:\SMSSIG$, No web.config
A: C:\Program Files\Update Services\WebServices\Root, No web.config
A: C:\Program Files\Update Services\WebServices\ReportingWebService, No Forms Auth Configured
A: C:\Program Files\Update Services\WebServices\ClientWebService, No Forms Auth Configured
A: C:\Program Files\Update Services\WebServices\SimpleAuthWebService, No Forms Auth Configured
A: C:\Program Files\Update Services\WebServices\ServerSyncWebService, No Forms Auth Configured
A: C:\Program Files\Update Services\WebServices\DssAuthWebService, No Forms Auth Configured
A: C:\Program Files\Update Services\Inventory, No web.config
A: C:\Program Files\Update Services\WebServices\ApiRemoting30, No Forms Auth Configured
edit: I didn’t mention it above, but each time I reference a folder I used the native folders
inspector, to make sure that 32-bit redirection didn’t block the result. Otherwise checking for folder "c:\windows\system32"
would be silently redirected to “c:\windows\syswow64”.