IIS Powershell provider cmdlets require the config section path for the -filter parameter and the attribute names while getting/setting attribute value.
But it is not easy to memorize the full configuration path or attribute names for each config section.
So, I have created a utility method and a useful variable, such as $iis, and I put the full source code below so that you can customize if you want.
How to use this tool.
- Start powershell.exe
- Copy the below code and paste onto the powershell window to register the one utility function, Get-WebSchema, and to create a powershell variable, $iis with using the utility function
- Try to run the Example Scenario 6~9 and you will see how you can use this tool with the IIS Powershell cmdlets. (NOTE: you will know you can use the auto-tab funcationality while using the $iis variable, which is what I told about getting config section names and attribute names dynamically as the following example:
# Ex.) without using $iis variable; users should know the full config path and attribute name
>> PS C:\Windows\system32> Get-WebConfigurationProperty -filter /system.webServer/security/authentication/basicAuthentication -name enabled
# Ex.) using $iis variable; users can use the auto-tab to get the config section name string using $iis
>> Get-WebConfigurationProperty -filter $iis.basicAuthentication -name $iis.basicAuthentication._enabled
#### Copy and paste from here!!!
#
# -------------------------- EXAMPLE 1 --------------------------
# C:\> Get-WebSchema -list
# This command retrieves the list of schema files that are available.
#
# -------------------------- EXAMPLE 2 --------------------------
# C:\> Get-WebSchema -list -fileName "$env:windir\system32\inetsrv\config\schema\IIS_schema.xml"
# This command retrieves the list of sections that are available for IIS_Schema.xml file.
#
# -------------------------- EXAMPLE 3 --------------------------
# C:\> Get-WebSchema -list -fileName "$env:windir\system32\inetsrv\config\schema\IIS_schema.xml" -sectionName system.webServer/asp
# This command retrieves an xml node object for the asp section in Iis_Schema.xml file.
#
# -------------------------- EXAMPLE 4 --------------------------
# C:\> Get-WebSchema -fileName "$env:windir\system32\inetsrv\config\schema\IIS_schema.xml" -sectionName system.webServer/asp
# This command list all config information (Ie. attribute/method/element/collection) of the asp section
#
# -------------------------- EXAMPLE 5 --------------------------
# C:\> Get-WebSchema -fileName "$env:windir\system32\inetsrv\config\schema\IIS_schema.xml"
# This command list all config information (Ie. attribute/method/element/collection) of the IIS_Schema file
#
# -------------------------- EXAMPLE 6 --------------------------
# C:\> $iis
# This command will dump all available config sections
#
# -------------------------- EXAMPLE 7 --------------------------
# C:\> $iis.site
# This command will return string value of the full config path such as system.applicationHost/sites/site
#
# -------------------------- EXAMPLE 8 --------------------------
# C:\> $iis.appSettings._file
# This command will return string value of the attribute name, such as "file", of the appSettings config section.
# (NOTE: for quick find attribute name, I put "_" string at the beginning of attribute name.
# For the example, $iis.appSettings._<TAB> will show $iis.appSettings._file.
function global:Get-WebSchema()
{
param(
[string]$fileName=$null,
[string]$sectionName=$null,
[object]$nodeObject=$null,
[switch]$list,
[switch]$verbose
)
if ($list -and $sectionName -and -not $fileName)
{
throw $(Get-PSResourceString -BaseName 'ParameterBinderStrings' -ResourceId 'AmbiguousParameterSet')
}
if ($list -and $recurse)
{
throw $(Get-PSResourceString -BaseName 'ParameterBinderStrings' -ResourceId 'AmbiguousParameterSet')
}
if ($sectionName -and -not $fileName)
{
throw $(Get-PSResourceString -BaseName 'ParameterBinderStrings' -ResourceId 'AmbiguousParameterSet')
}
if ($list)
{
if ($sectionName)
{
[xml]$xml = Get-Content $filename
$rootNode = $xml.get_documentElement()
$rootNode.sectionSchema | ForEach-Object {
$nodeObject = $_
if ($nodeObject.name.tolower() -eq $sectionName.tolower())
{
$nodeObject
}
}
}
else
{
if ($fileName)
{
[xml]$xml = Get-Content $filename
$rootNode = $xml.get_documentElement()
$rootNode.sectionSchema | ForEach-Object {
$sectionName = $_.name
$sectionName
}
}
else
{
Get-ChildItem "$env:windir\system32\inetsrv\config\schema" -filter *.xml | ForEach-Object {
$filePath = $_.fullname
$filePath
}
}
}
}
else
{
if (-not $fileName -and -not $nodeObject) {
throw $($(Get-PSResourceString -BaseName 'ParameterBinderStrings' -ResourceId 'ParameterArgumentValidationErrorNullNotAllowed') -f $null,'fileName')
}
if (-not $nodeObject)
{
[xml]$xml = Get-Content $filename
$rootNode = $xml.get_documentElement()
$rootNode.sectionSchema | ForEach-Object {
$nodeObject = $_
if ((-not $sectionName) -or ($nodeObject.name.tolower() -eq $sectionName.tolower()))
{
Get-WebSchema -nodeObject $_ -filename $fileName -sectionName $nodeObject.name -verbose:$verbose
}
}
}
else
{
("element", "collection", "attribute", "method") | ForEach-Object {
$type = $_.tostring()
if ($nodeObject.$type -ne $null)
{
$nodeObject.$type | ForEach-Object {
$leafObject = $_
$output = new-object psobject
if ($type -eq "collection")
{
$name = $leafObject.addElement
if ($verbose)
{
$name = "[name]"
}
}
else
{
$name = $leafObject.name
}
$ItemXPath = $null
if ($verbose)
{
$ItemXPath = ($sectionName+"//"+$name)
}
else
{
$ItemXPath = ($sectionName+"/"+$name)
}
add-member -in $output noteproperty ItemXPath $ItemXPath
add-member -in $output noteproperty Name $name
add-member -in $output noteproperty XmlObject $leafObject
add-member -in $output noteproperty Type $leafObject.toString()
add-member -in $output noteproperty ParentXPath $sectionName
$output
if ($type -eq "element" -or $type -eq "collection")
{
Get-WebSchema -nodeObject $_ -filename $fileName -sectionName $ItemXPath -verbose:$verbose
}
}
}
}
}
}
}
$global:iis = new-object psobject
(dir "$env:windir\system32\inetsrv\config\schema\*.xml") | sort -Descending | select FullName,Name | foreach {
$file = $_.Name
$filepath = $_.FullName
$saved_section = $null
$sectionName = $null
$sectionValue = $null
Get-WebSchema -fileName $filePath | where {$_.Type -eq "attribute"} | foreach {
$sectionPath = $_.ParentXPath
$attribute = $_.Name
##
## when a new section is found
##
if ($saved_section -ne $sectionPath) {
if ($sectionName -ne $null)
{
##
## Now that the $sectionvalue is made for a specific config section,
## let's add the unique $sectionName noteproperty with $sectionName value onto $iis object
##
add-member -in $iis noteproperty $sectionName $sectionValue
}
##
## Let's create a new $sectionValue with assigning a new sectionPath value
##
$sectionValue = $sectionPath
##
## Let's get an unique $sectionName which was not used before
##
$tokens = $sectionPath.split("/")
$sectionName = $tokens[$tokens.length-1]
if ($tokens.length -gt 1 -and $tokens[$tokens.length-1] -eq "add")
{
$sectionName = $tokens[$tokens.length-2] + "_" + $tokens[$tokens.length-1]
}
##
## if existing one has the same section configPath, copy it to the $sectionValue and then remove existing one in order to append
##
if ($iis.$sectionName -ne $null -and $iis.$sectionName -eq $sectionPath)
{
$sectionValue = $iis.$sectionName
$iis = $iis | select * -exclude $sectionName
}
if ($iis.$sectionName -ne $null)
{
$i = 2;
do
{
$temp = $sectionName + $i
$i = $i + 1
}
while ($iis.$temp -ne $null)
$sectionName = $temp
}
# reset $saved_section variable with the new section path
$saved_section = $sectionPath
}
##
## Let's add all of the attributes as a child noteproperty onto the $sectionValue string object
##
$sectionValue = $sectionValue | add-member -membertype noteproperty -name ("_"+$attribute) -value $attribute -passthru
}
if ($sectionName -ne $null)
{
##
## Let's process the last $sectionValue after loop statement
##
add-member -in $iis noteproperty $sectionName $sectionValue
}
}