Freigeben über


How to Manipulate (insert/replace/remove) LIST data type in IIS Configuration

After a long tour on newsgroups, I am starting my blog today.

For my first entry, I am going to discuss a frequent question about IIS programmatic administration - how to manipulate the LIST data type (i.e. ScriptMaps, HttpErrors, ServerBindings, etc). No, MIMEMap is not included in this because it is not a LIST (it is its own custom data type) - good topic for a future blog...

The astute reader should realize that ADSUTIL.VBS already allows you to set/delete these LIST properties. However, ADSUTIL.VBS has a fatal flaw for multi-valued properties like LIST - it only allows you to set/delete the entire LIST. It does not allow you to replace one LIST item with a new value. Even worse, the default implementation only allows nine commandline parameters. So, suppose you wanted to:

  • add a wildcard application mapping (with long filepath)
  • replace the 404 Custom Error URL while preserving all other Custom Error definitions
  • add/edit a Host header while preserving all others
  • recursively remove an application mapping from everywhere

THEY are all impossible do with an unmodified ADSUTIL.VBS. Therefore, I decided to write a little tool that illustrates how to:

  • Navigate and enumerate through the IIS configuration namespace (/RECURSE)
  • Locate LIST data types (like ScriptMaps, HttpErrors, ServerBindings, etc) (SYNTAX)
  • Enumerate and Manipulate LIST data type

In fact, the above tasks become very straight forward with this tool:

  • Add a wildcard application mapping for website ID 1
    <chglist.vbs> W3SVC/1/root/ScriptMaps "" "*,%ProgramFiles%\WildcardISAPI.dll,0" /INSERT /COMMIT
  • Change the 404 Custom Error for website ID 1
    <chglist.vbs> W3SVC/1/HttpErrors 404 404,*,URL,/CustomErrors/404.asp /COMMIT
  • Add a Host header for Website ID 2 while preserving all others
    <chglist.vbs> W3SVC/2/ServerBindings FIRST ":80:Host.domain.com" /INSERT /COMMIT
  • Recursively remove application mapping for ".ext" extension
    <chglist.vbs> W3SVC/ScriptMaps ".ext" "" /REMOVE /RECURSE /ALL /COMMIT

You can run the script with no commandline parameters for help, and operation should be self-explanatory.  The tool does not make any changes unless you add /COMMIT, so feel free to poke around the various options.  Feel free to post comments/suggestions as well as propose future topics.

[Updated 04/22/2006 - Added `` (double-backquote) syntax to put in double-quotes into a value. This allows manipulation of ScriptMaps, Application Extensions, etc pathnames with spaces.]

[Updated 05/11/2006 - Fixed bugs to make /recurse work correctly. Fixed bug when matching against "*" and /RegExp is not specified]

Enjoy.

//David

 '
' Allows append/insert/remove of specific elements from an IIS "List" type node
' i.e. ScriptMap, HttpError, ServerBindings
'
' Origin : https://blogs.msdn.com/David.Wang/archive/2004/12/02/273681.aspx
' Version: December 1 2004
'
Option Explicit
On Error Resume Next

const ERROR_SUCCESS             = 0
const ERROR_PATH_NOT_FOUND      = 3
const ERROR_INVALID_PARAMETER   = 87
const LIST_OP_FIRST             = "FIRST"
const LIST_OP_LAST              = "LAST"
const LIST_OPTION_REPLACE       = 0
const LIST_OPTION_INSERT        = 1
const LIST_OPTION_REMOVE        = 2
const LIST_OPTION_ALL           = 4
const LIST_OPTION_RECURSE       = 8

Dim CRLF
CRLF = CHR(13) & CHR(10)
Dim strHelp
strHelp = "Edit/Replace IIS metabase LIST properties" & CRLF &_
          CRLF &_
          WScript.ScriptName & " PropertyPath ExistValue NewValue [Options]" & CRLF &_
          CRLF &_
          "Where:" & CRLF &_
          "    PropertyPath IIS metabase property path whose data type is LIST." & CRLF &_
          "                 i.e. W3SVC/ScriptMaps, W3SVC/HttpErrors" & CRLF &_
          "    ExistValue   Value to case-insensitive literal match against existing" & CRLF &_
          "                 LIST elements." & CRLF &_
          "        FIRST    - matches the first LIST element." & CRLF &_
          "        LAST     - matches the last LIST element." & CRLF &_
          "    NewValue     New value that replaces the matched the LIST element." & CRLF &_
          "Options:" & CRLF &_
          "    /INSERT      Insert  before LIST element matching ." & CRLF &_
          "    /REMOVE      Remove LIST element matching ." & CRLF &_
          "    /ALL         Operate on ALL matching . Default is first match." & CRLF &_
          "    /REGEXP      Use  as RegExp to match. Default is literal." & CRLF &_
          "    /RECURSE     Recursively perform the operation underneath ." & CRLF &_
          "    /VERBOSE     Give more status/output." & CRLF &_
          "    /COMMIT      Actually perform changes. Default only shows." & CRLF &_
          ""

dim Debug
Debug = true
dim Verbose
Verbose = false
dim reMatch
reMatch = false

Dim strServer
Dim strNamespace
Dim strSchemaNamespace
Dim strNodeSyntax
Dim objNode

Dim nOperationType
Dim strNormalizedPath
Dim strPropertyPath
Dim strPropertyName
Dim strPropertyExistValue
Dim strPropertyNewValue

Dim i,j

'
' Start of script
'
strServer = "localhost"
strNamespace = "IIS://" & strServer
strSchemaNamespace = strNamespace & "/" & "Schema"

'
' Parse the commandline
'
If WScript.Arguments.Count < 3 Then
    Err.Number = ERROR_INVALID_PARAMETER
    HandleError "Insufficient number of arguments." & CRLF &_
                CRLF &_
                strHelp &_
                ""
End If

nOperationType = LIST_OPTION_REPLACE

For i = 0 To WScript.Arguments.Count - 1
    Select Case UCase( WScript.Arguments( i ) )
        Case "/INSERT"
            nOperationType = nOperationType Or LIST_OPTION_INSERT
        Case "/REMOVE"
            nOperationType = nOperationType Or LIST_OPTION_REMOVE
        Case "/ALL"
            nOperationType = nOperationType Or LIST_OPTION_ALL
        Case "/RECURSE"
            nOperationType = nOperationType Or LIST_OPTION_RECURSE
        Case "/COMMIT"
            Debug = false
        Case "/VERBOSE"
            Verbose = true
        Case "/REGEXP"
            reMatch = true
        Case Else
            If ( i = 0 ) Then
                '
                ' Split out PropertyName and its ParentPath from PropertyPath
                '
                Err.Clear
                strNormalizedPath = NormalizePath( WScript.Arguments( 0 ) )
                HandleError "Failed to normalize PropertyPath."

                j = InstrRev( strNormalizedPath, "/", -1, 0 )

                If ( j = 0 Or j = 1 ) Then
                    Err.Number = ERROR_PATH_NOT_FOUND
                    HandleError "Invalid PropertyPath."
                End If

                Err.Clear
                strPropertyPath = NormalizePath( Mid( strNormalizedPath, 1, j - 1 ) )
                HandleError "Failed to retrieve/normalize PropertyPath."

                Err.Clear
                strPropertyName = NormalizePath( Mid( strNormalizedPath, j + 1 ) )
                HandleError "Failed to retrieve/normalize PropertyName."
            ElseIf ( i = 1 ) Then
                '
                ' The existing match value
                '
                strPropertyExistValue = Replace( UCase( WScript.Arguments( 1 ) ), "``", """" )
            ElseIf ( i = 2 ) Then
                '
                ' The new replace value
                '
                strPropertyNewValue = Replace( WScript.Arguments( 2 ), "``", """" )
            Else
                Err.Number = ERROR_INVALID_PARAMETER
                HandleError "Unknown parameter " & WScript.Arguments( i ) & CRLF &_
                            CRLF &_
                            strHelp &_
                            ""
            End If
    End Select
Next

LogVerbose "OpType       = " & nOperationType
LogVerbose "PropertyPath = " & strPropertyPath
LogVerbose "PropertyName = " & strPropertyName
LogVerbose "ExistValue   = " & strPropertyExistValue
LogVerbose "NewValue     = " & strPropertyNewValue

'
' Check the data type for the given property
' If it is not LIST, do not process any further
'
Err.Clear
Set objNode = GetObject( strSchemaNamespace & "/" & strPropertyName )
HandleError "Cannot read schema for property " & strPropertyName
strNodeSyntax = UCase( objNode.Syntax )

LogVerbose "Syntax       = " & strNodeSyntax
LogVerbose ""

Select Case strNodeSyntax
    Case "LIST"
        '
        ' Finally, we are ready to do some real work
        '
        Err.Clear
        Err.Number = HandleListOps( nOperationType, strPropertyPath, strPropertyName, strPropertyExistValue, strPropertyNewValue, ( nOperationType And LIST_OPTION_RECURSE ) <> 0 )
        HandleError ""
    Case Else
        Err.Clear
        Err.Number = ERROR_PATH_NOT_FOUND
        HandleError "Cannot handle " & strPropertyPath & "/" & strPropertyName & " with type " & strNodeSyntax
End Select

'
' End of script
'

'
' Sub routines and functions
'
Sub HandleError( errorDescription )
    If ( Err.Number <> 0 ) Then
        If ( IsEmpty( errorDescription ) ) Then
            LogEcho Err.Description
        Else
            LogEcho errorDescription
        End If

        WScript.Quit Err.Number
    End If
End Sub

Function NormalizePath( strInput )
    '
    ' Replace all \ with /
    '
    strInput = Replace( strInput, "\", "/", 1, -1 )

    '
    ' Replace all // with /
    '
    Do
        strInput = Replace( strInput, "//", "/", 1, -1 )
    Loop While ( Instr( strInput, "//" ) <> 0 )

    '
    ' Removing leading and trailing /
    '
    If ( Left( strInput, 1 ) = "/" ) Then
        strInput = Right( strInput, Len( strInput ) - 1 )
    End If

    If ( Right( strInput, 1 ) = "/" ) Then
        strInput = Left( strInput, Len( strInput ) - 1 )
    End If

    NormalizePath = strInput
End Function

Function HandleListOps( OpType, strPropertyPath, strPropertyName, strPropertyExistValue, strPropertyNewValue, bRecurse )
    On Error Resume Next
    Dim objNode, objNodeAttribute
    Dim objList
    Dim objElement
    Dim objNewArray
    Dim PerformedOperation
    Dim Operation
    Dim re
    Dim reMatched
    Dim i, j

    Err.Clear
    Set objNode = GetObject( strNamespace & "/" & strPropertyPath )
    objList = objNode.Get( strPropertyName )

    If ( Err.Number <> 0 Or IsEmpty( objList ) ) Then
        LogEcho "Failed to retrieve " & strPropertyPath & "/" & strPropertyName
        HandleListOps = Err.Number
        Exit Function
    End If


    Err.Clear
    Set objNodeAttribute = objNode.GetPropertyAttribObj(strPropertyName)
    HandleError "Failed to retrieve Attributes for " & strPropertyPath & "/" & strPropertyName

    If ( objNodeAttribute.IsInherit = true ) Then
        LogEcho strPropertyPath & "/" & strPropertyName & " (Inherited)"

        If ( bRecurse = true ) Then
            LogEcho( "Ignoring inherited property for Recursive Modification" )
            Exit Function
        End If
    Else
        LogEcho strPropertyPath & "/" & strPropertyName
    End If


    '
    ' j is the count of elements in objNewArray
    ' So that we can resize it to the right size in the end
    '
    j = 0

    '
    ' Size objNewArray to maximum possible size up-front, later shrink it
    '
    Redim objNewArray( UBound( objList ) + UBound( objList ) + 1 )

    '
    ' PerformedOperation indicates whether something has matched and already
    ' operated upon, in this session.  Start with 'not yet' = 0
    '
    PerformedOperation = 0

    '
    ' Setup the RegExp match based on the existing value to search for
    '
    Set re = new RegExp
    re.Pattern = strPropertyExistValue
    re.IgnoreCase = true
    re.Global = true

    '
    ' Do this test outside of IF conditional because on error resume next
    ' turns off failures due to incorrect Pattern
    '
    Err.Clear
    reMatched = re.Test( objElement )
    If ( Err.Number <> 0 Or reMatch = false ) Then
        reMatched = false
    End If

    LogVerbose "Original:"

    For i = LBound( objList ) To UBound( objList )
        objElement = objList( i )
        'LogVerbose i & "(" & j & ")" & ": " & objElement

        If ( ( ( ( strPropertyExistValue = LIST_OP_FIRST ) And ( i = LBound( objList ) ) ) Or _
               ( ( strPropertyExistValue = LIST_OP_LAST  ) And ( i = UBound( objList ) ) ) Or _
               ( ( reMatch = false ) And ( Instr( UCase( objElement ), strPropertyExistValue ) > 0 ) ) Or _
               ( reMatched = true ) _
             ) _
             And _
             ( ( ( OpType And LIST_OPTION_ALL ) <> 0 ) Or ( PerformedOperation = 0 ) ) _
           ) Then
            Operation = "Replace "

            If ( ( OpType And LIST_OPTION_REMOVE ) <> 0 ) Then
                'Don't copy this element for deletion
                Operation = "Remove "
            Else
                objNewArray( j ) = strPropertyNewValue
                j = j + 1

                If ( ( OpType And LIST_OPTION_INSERT ) <> 0 ) Then
                    Operation = "Insert "
                    objNewArray( j ) = objElement
                    j = j + 1
                End If
            End If

            PerformedOperation = 1
        Else
            Operation = ""
            objNewArray( j ) = objElement
            j = j + 1
        End If

        LogVerbose Operation & objElement
    Next

    '
    ' Resize the final array to the correct size prior to SetInfo
    '
    ReDim Preserve objNewArray( j - 1 )

    LogVerbose "New:"

    For i = LBound( objNewArray ) To UBound( objNewArray )
        LogDebug i & ": " & objNewArray( i )
    Next

    If ( Debug = false ) Then
        If ( PerformedOperation = 1 ) Then
            Err.Clear
            objNode.Put strPropertyName, objNewArray
            objNode.SetInfo
            HandleError "Failed to SetInfo " & strPropertyPath & "/" & strPropertyName
            LogEcho "SUCCESS: Updated " & strPropertyPath & "/" & strPropertyName
        Else
            LogEcho "SUCCESS: Nothing to update"
        End If
    Else
        If ( PerformedOperation = 1 ) Then
            LogEcho "DEBUG: Matched. Did not SetInfo"
        Else
            LogEcho "SUCCESS: No Match. Did not SetInfo"
        End If
    End If

    If ( bRecurse = true ) Then
        For Each objElement In objNode
            LogEcho ""
            HandleListOps = HandleListOps( OpType, NormalizePath( Mid( objElement.AdsPath, Len( strNamespace ) + 1 ) ), strPropertyName, strPropertyExistValue, strPropertyNewValue, bRecurse )
        Next
    End If

    HandleListOps = 0
End Function

Sub LogEcho( str )
    WScript.Echo str
End Sub

Sub LogDebug( str )
    If ( Debug = true ) Then
        LogEcho str
    End If
End Sub

Sub LogVerbose( str )
    If ( Verbose = true ) Then
        LogEcho str
    End If
End Sub

Comments

  • Anonymous
    December 17, 2004
    I guess I could then run this from within vb.net using System.Diagnostics.Process.Start to open a cmd prompt and pass in the arguments. I set custom errors based on the web site being created, and it was a pain editing the metabase.xml file. I'll let you know how it goes. Thanks for the very nice script!

  • Anonymous
    June 06, 2005
    this is not working for me
    adding a Wildcard Application map on
    II 6.0 on Windows 2003..

    It just adds a blank space under the
    regular application mappings..

    Using adsutil.vbs does add it correctly
    but it deletes (under the wildcard application maps) but delets all the other mappings
    in the application section..

  • Anonymous
    June 14, 2005
    Can you give the exact command that you used.

    It worked fine for me to insert an ISAPI wildcard application mapping at any point that I wanted.

    //David

  • Anonymous
    July 13, 2005
    A powerful but often under-utilized and misunderstood feature of IIS is its programmatic configuration...

  • Anonymous
    July 13, 2005
    A powerful but often under-utilized and misunderstood feature of IIS is its programmatic configuration...

  • Anonymous
    October 20, 2005
    Thanks David! I used this code to hunt down a bug of my own today :)

  • Anonymous
    November 15, 2005
    The comment has been removed

  • Anonymous
    November 15, 2005
    There is a variable at the top of the script, strServer, which can be easily adjusted to any other server name or parameterized from the commandline.

    //David

  • Anonymous
    November 16, 2005
    I am wanting to add a hostheader to a particular site (ie: subdomain.domain.com on port 80). How is this done through this script?

  • Anonymous
    November 17, 2005
    Tim - Assuming the site ID is 1...

    <tool name.vbs> W3SVC/1/ServerBindings : ":80:subdomain.domain.com" /INSERT

    Which basically means:
    1. Inside of the LIST element named W3SVC/1/ServerBindings
    2. Search for a LIST element with ":" in it
    3. /INSERT ahead of that element another element whose value is ":80:subdomain.domain.com"

    In other words, that's exactly the mechanics of "adding a hostheader" element to a particular site's ServerBinding.

    //David

  • Anonymous
    November 18, 2005
    How come when I change a custom error page (401,1) to a URL

    <tool name.vbs> W3SVC/3/HttpErrors 401,1 401,1,URL,/errors/401-1.html

    It works great but when I go into IIS and change the same error page to the default or another file and re-run the VBS script to change another error page it still reports that 401,1 is set to /errors/401-1.html and not to what I changed it to in IIS?

    Is there a cache problem maybe?

  • Anonymous
    November 18, 2005
    How come when I change a custom error page (401,1) to a URL

    <tool name.vbs> W3SVC/3/HttpErrors 401,1 401,1,URL,/errors/401-1.html

    It works great but when I go into IIS and change the same error page to the default or another file and re-run the VBS script to change another error page it still reports that 401,1 is set to /errors/401-1.html and not to what I changed it to in IIS?

    Is there a cache problem maybe?

  • Anonymous
    November 18, 2005
    Shaun - You need to give /COMMIT on the commandline to have it actually change configuration (by default it just shows you what it is going to do - so that you can verify the right search/replace happens before you do something).

    So, if you use the above syntax, no matter what you changed the error page to in IIS, the tool will display /errors/401-1.html because that's what it is going to change it to.

    If you want to list what is in the property, either use ADSUTIL.VBS to retrieve the property directly, or use the tool's /INSERT syntax to insert an entry, which then gives you an idea what the original list looks like with the new entry inserted - but that's not a LISTing of what actually exists.

    //David

  • Anonymous
    January 16, 2006
    I am trying to remove a particular entry from scriptmaps of a website. It is a wildcard entry. But it is removing all entries from the scriptmap.

    How can I make this happen. The command I am using is:

    cscript <sample code>.vbs w3svc/3/root/scriptmap "*, E:CFusionMXruntimelibwsconfig1jrun_iis6_wildcard.dll,3" "" /remove /commit

  • Anonymous
    January 31, 2006
    Sandeep - hmm, weird. The "" seems to be tricking VBScript somehow, but I'm not certain why.

    Since that parameter is an inclusive match, you can simply work around the behavior by not specifying "
    ," because the rest will simply match and the right entry gets removed.

    I'll debug and figure out what is going on with "*" and post the update here...

    //David

  • Anonymous
    February 23, 2006
    Well I like the script as it saved me a lot of effort. I worked out the mime map thing and it followed the same principal of getting the existing array and redim presever with an increment on the current count.

    Only thing is that even from the command prompt it tells me that

    c:ADSIArrayListTool W3SVC/Root/RacketShop/HttpErrors 404 404,2,FILEc:WINDOWSiisHelpcommon404lw.htm /COMMIT

    has been successfull but Metabase Explorer and IIS Manager show that no change has occured. I'll peservere though as I'm close...

    Lenny

  • Anonymous
    February 23, 2006
    Note for the posting above -

    although I typed it wrong here the syntax does actually include the /n or /1 for the website path and there is a comma between FILE and the path.

    I have edit while running enabled in the metabase and the script does add a value to the custom errors list. Although the old one still is there and the new one shows up in metabase explorer but not on the custom errors tab for the Racket shop vdir.

    Interesting, I'll try removing an entry before adding one etc and see how it goes...

  • Anonymous
    March 03, 2006
    Question:
    What is a 999 error and how can I troubleshoot it? It's not an error code that IIS will allow...

  • Anonymous
    March 04, 2006
    TrackBack From:http://dudu.cnblogs.com/archive/2006/03/05/343135.html

  • Anonymous
    March 04, 2006
    TrackBack From:http://dudu.cnblogs.com/archive/2006/03/05/343135.html

  • Anonymous
    March 21, 2006
    Your site is very informational for me. Nice work.

  • Anonymous
    March 31, 2006
    Nice work but
    - "/remove" There are two equal elements but it remove only one.
    - "/insert" It shouldn't add a new element if it is already present.

  • Anonymous
    March 31, 2006
    ale5000 -
    1. As documented in help:
       /ALL         Operate on ALL matching <ExistValue>. Default is first match.

    So,  /remove /all  will remove all matching elements. Default is first match

    2. LIST data type does not have uniqueness constraint in IIS, so I am not introducing it. For example, it is ok to configure multiple identical *-scriptmaps.

    //David

  • Anonymous
    April 21, 2006
    Hi,

    Iʻm trying to add an application extension, but the path to the dll Iʻm adding has spaces in it so it needs quotes around the path.  I canʻt seem to get the quotes in there using this script.  Can someone help me out with this please?

    Thanks,
    loralynne

  • Anonymous
    April 21, 2006
    The comment has been removed

  • Anonymous
    April 21, 2006
    The comment has been removed

  • Anonymous
    April 22, 2006
    Thanks, David!  Works great.

    Yeah, I use iisext.vbs to add a Web Service Extension.  Iʻm using your script to add to the ScriptMaps property.

  • Anonymous
    April 25, 2006
    It never ceases to amaze me how easily users will download and install arbitrary binaries from arbitrary...

  • Anonymous
    May 05, 2006
    Hi David,
       I have  a script that does something like this -

    Find all the xml nodes where HTTPERRORS is defined in Metabase.xml
            Now, traverse through all the nodes and then update the list to the new set of HTTPERRORS list.

    Script looks like this -  
         Set iisPath = GetObject("IIS://" & strServerName)
         aryPathList = iisPath.GetDataPaths("HttpErrors",0)

         For Each strPath in aryPathList
              Set iisPath = GetObject(strPath)
              aryCustomErrors = iisPath.GetEx("HttpErrors")
              -- UPDATE THE LIST
              iisPath.PutEx  ADS_PROPERTY_UPDATE,"HttpErrors",aryMasterArray
              iisPath.SetInfo
         Next


    This seem to work fine, but I just discovered that for some folders under v-roots has HTTPERRORS defined as a custom element, where this script bails out.

    HTTPERRORS as a custom element looks like this --

    <IIsConfigObject Location ="/LM/W3SVC/1/ROOT/SampleVRoot/Folder1"
    >
    <Custom
    Name="HttpErrors"
    ID="6008"
    Value="400,*,URL,/err.aspx"
    Type="MULTISZ"
    UserType="IIS_MD_UT_FILE"
    Attributes="INHERIT"
    />

    Do you have any suggestions on handling this case? I can be more specific and precise on the script if you would like to know the exact script...

    Thanks,

  • Anonymous
    May 05, 2006
    Hi David,
           May be I should rephrase the question in this way - Can I update Custom properties via ADSI? If not, are there any other easy ways to achieve this?

    Thanks,

  • Anonymous
    May 10, 2006
    Hi David,

    First off, thanks for your help on the IIS Newsgroups;

    http://www.microsoft.com/technet/community/newsgroups/dgbrowser/en-us/default.mspx?dg=microsoft.public.inetserver.iis&tid=ce318b30-31e4-464a-9dd6-626b9fe2cbd8&p=1

    I think I am now very close to what I want by using your script.

    I am still having some problems though when trying to do a recursive replacement of a particluar application mapping. This is my script;

    cscript <script_name> W3SVC/ScriptMaps ".app" ".app,X:pathtoapp.dll,5" /ALL /RECURSE /COMMIT

    If I remove the "/COMMIT" switch and put in a "/VERBOSE" one, I can see that the script is matching all the existing application mappings for ".app" throughout the metabase. The problem is when I put the "/COMMIT" switch back in the script exits the first time it doesn't get a match instead of continuing through the metabase. Is this behaviour by design, is it a bug, or have I just gotten the syntax wrong (probable)? Thanks again.

  • Anonymous
    May 10, 2006
    Confused Admin - Ah, you found two bugs which I have fixed and reposted.

    Bug 1 - VBScript uses "Exit Function" to return from a function, not "Return". It silently ignored my syntax error of using "Return", a part of my error-checking, which played havoc on the remainder of the code since it then allowed: "If (Undefined AND true )" to return true, which caused the code to attempt to match and modify a property that it should not... which fails and since I expect it to succeed, the code fails fast and quits.

    It would have been nice for VBScript to tell me "syntax error" up-front because then I would have figured out "Exit Function" earlier...

    Bug 2 - When recursively editing a value, you should not edit inherited values.

    This should now address your issues.

    //David

  • Anonymous
    May 10, 2006
    Sandeep - Ok, I finally figured out what is going awry with your use of "" on the commandline. The "" was being used in a RegExp Test and failing (since "*" needs a qualifier), but due to "on error resume next", it still evaluated to "true" and thus mistakenly matching against entries.

    This is now fixed.

    //David

  • Anonymous
    May 10, 2006
    The comment has been removed

  • Anonymous
    May 11, 2006
    Hi David,

    Thanks very much for your help again, I really appreciate it. I'm using your updated script and I think there still might be an issue with the script exiting early. This time it is not exiting because it failed to find a match, but rather because it finds an inherited property. Should the script exit when it finds an inherited property, or should it just skip it and move onto the next one?



  • Anonymous
    May 11, 2006
    Confused Admin - I think something else specific to your machine is happening - maybe you have a property that is not type'd correctly from some 3rd party application.

    On /recurse, the tool skips the inherited property and moves on to the next one.

    //David

  • Anonymous
    May 11, 2006
    Hi David,

    Actually I think you're correct David, the issue I'm having is different than I first thought. I don't think it is to do with the inherited values now, and it seems to be due to property depth in the metabsae. This is the syntax I'm using to try and recursively remove any .app application mapping that is not inherited throughout the entire metabase;

    cscript <script_name> W3SVC/ScriptMaps ".app" "" /REMOVE / ALL /RECURSE /COMMIT

    This seems to only work until the script reaches Root. For example the recursive search  for these paths work;

    W3SVC/ScriptMaps

    W3SCV/1/ScriptMaps

    But the script seems to exit when it gets to here;

    W3SVC/1/Root/ScriptMaps

    If I run the script with the full path to where any custom application mappings are actually going to reside the script works fine, such as;

    cscript <script_name> W3SVC/1/Root/ScriptMaps ".app" "" /REMOVE / ALL /RECURSE /COMMIT

    Maybe I am missing something, but I have now tested this on two IIS 5.1 machines and one IIS 6 server with consistent results. Is Root treated differently perhaps?



  • Anonymous
    May 11, 2006
    Confused Admin - can you turn on /VERBOSE and /DEBUG so that we narrow down where the failure is coming from your commandline.

    Root is not treated differently; on my IIS 5.1 and IIS 6 machines the recursion worked just fine, including at W3SVC/1/Root/ScriptMaps.

    There is something consistently peculiar on your machines.

    //David

  • Anonymous
    May 12, 2006
    The comment has been removed

  • Anonymous
    June 05, 2006
    The comment has been removed

  • Anonymous
    June 05, 2006
    Hi David,

    I'm using your script to add an Application Mapping.  However, on  Windows 2000 and Windows XP, I need the path to the dll to be in 8.3 format.  Can you help me please?

    Thanks,
    loralynne

  • Anonymous
    June 07, 2006
    The comment has been removed

  • Anonymous
    June 07, 2006
    Pokche - Since you want to change the specific custom error 403;4, try matching match against "403,4" instead of just "403" for replacement.

    HttpErrors is a LIST of custom errors for ALL error codes, 403.1 as well as 403.4. Since 403.1 comes before 403.4 numerically in the LIST, the tool changes the FIRST entry that matches by default, and you gave "403", which matches 403.1, 403.2, 403.3, 403.4, etc, that is why you are updating 403.1 custom error with your syntax.

    //David

  • Anonymous
    June 14, 2006
    The comment has been removed

  • Anonymous
    June 14, 2006
    loralynne - I am not certain why you require a 8.3 filepath. IIS on Windows 2000, Windows XP, and Windows Server 2003 all support Application Mappings with long filepath. In fact, IIS6 rejects 8.3 filepath for security reasons.

    I updated the examples in the blog entry to show how to add an application mapping with long filepath (see the wildcard application mapping example which uses %ProgramFile%, usually a long filepath).

    Please consider using long filepath because it is the secure choice.

    //David

  • Anonymous
    June 15, 2006
    The comment has been removed

  • Anonymous
    June 15, 2006
    loralynne - PHP ISAPI DLL works fine for me in "C:Program FilesP H P" on Windows 2000, Windows XP, and Windows Server 2003 - I just tried it myself.

    So, I am still confused of what you are trying to ask of me. What is stopping you from giving the pathname in 8.3 format to the script? Or are you asking for the script to translate a longpath to shortpath for you?

    //David

  • Anonymous
    June 15, 2006
    loralynne - I just went to read the "Suggestions" made at the links that you pointed me to. What a good chuckle! :-)

    Don't get me wrong -- I understand and appreciate the efforts made by other kind users trying to help each other out. It's just that many of the "suggestions" are of the "I got it to work by doing this" variety and not necessarily done the right way through an understanding of IIS -- so you have to take it with a grain of salt. Most of the suggestions, while they'll "work", are actually quite bad because IIS works much better than they assume. I wish I can delete most of those bad suggestions!

    I assure you that using:
    chglist.vbs W3SVC/1/root/ScriptMaps "" ".php,%ProgramFiles%P H PPHP5ISAPI.DLL,1" /INSERT /COMMIT

    Will work for PHP installed in "C:Program FilesP H P". You do not need to use 8.3 format and you do not need the DLL nor PHP.INI to be in Windows directory.

    //David

  • Anonymous
    June 19, 2006
    Hi David,

    A colleague of mine actually showed me the error that occurs after he manually entered the long path on Win XP.  He then changed it to 8.3, and it worked like a champ.  So unless we come up with a better solution, we might actually have to resort to this solution, and I figured out how to do this in the script.

    Thanks again for all your help.  I really appreciate your input.

    -loralynne

  • Anonymous
    June 19, 2006
    loralynne - If you do not enter the long path correctly (from the UI or from the commandline), it will fail with a pretty bizarre error. I think that the older IIS Manager UI (W2K and WXP) actually require you to input a long path format that doesn't work; it was subsequently fixed in WS03.

    The instructions and samples I gave on how to use long paths work on W2K, WXP, WS03, and Vista - I literally installed PHP, then typed in that commandline, and verified PHP's phpinfo(); work with "%ProgramFiles%P H PPHP5isapi.dll" on all the platforms.

    You can certainly use 8.3 format if you need, but I am obligated to tell you that 8.3 will not work in any version of IIS after Windows XP due to security. All I can say is that suggestions to use 8.3 format as a "requirement" are incorrect.

    //David

  • Anonymous
    June 20, 2006
    Hi David,

    The instructions and samples you gave work great and add the information to the metabase as expected.  However, our problem is that using the long path on XP doesn't work.  If we don't find a correct fix, we're planning on using 8.3 format only on 2K and XP.  The long path works fine on Server 2003.

    Thanks for all your advice and taking the time to actually verify this on all the platforms.  I'll relay this information to my colleague.

    -loralynne

  • Anonymous
    June 20, 2006
    loralynne - when you say "our problem is that using the long path on XP doesn't work", are you saying:
    1. Your version of PHP does not work with long pathnames
    2. Your PHP-based application does not work with long pathnames

    Because it is possible that the PHP-based application fails with long pathnames, and that would be an issue with that application.

    From my casual observation, PHP itself seems to work fine with long pathnames, and IIS can certainly invoke the PHP Application Mapping with long pathnames.

    One thing to remember with long pathnames and a CGI Application Mapping (i.e. php-cgi.exe) - you may need to enclose %s parameter in quotes to make sure spaces are properly escaped. This totally depends on the CGI.

    For example, when configuring CMD.EXE as an Application Mapping for .cmd in IIS (so that you can launch batch files via an HTTP request), you have to use:
     cmd.exe /c "%s" "%s"
    Or else it will fail if the resource has a long pathname.

    //David

  • Anonymous
    June 21, 2006
    Hi David,

    My apologies.  I found out from my colleague (who ran your script) that the reason why the long path wasn't working was because there were quotes around it.  In my first post (on 4/21), I asked about how I can add quotes around the path using your script since when I manually entered it via the GUI, it gave the error "wrong executable filename", until I put quotes around it.  So I assumed that PHP wouldn't work if I ran your script to add the app mapping without quotes.

    I guess if you want to add an app mapping that has spaces in the path to the dll/exe, you'll have to do it via a script since the GUI won't let you without putting quotes around the path.

    Anyways, thanks again for all your help, and sorry for wasting your time on this.

    -loralynne

  • Anonymous
    June 23, 2006
    A short while ago, I came out with a small script to properly configure PHP for IIS7. Sure enough, I...

  • Anonymous
    June 27, 2006
    The comment has been removed

  • Anonymous
    June 27, 2006
    millhouse50 - this blog entry has the VBScript code as well as the sample commandline to do what you want.

    Please either take the necessary code snippet or determine your necessary commandline, or read the blog comments, to help yourself.

    //David

  • Anonymous
    June 28, 2006
    loralynne - Ah, I see. Yeah, long pathnames, quotes, and IIS Configuration can be confusing. Here's the short summary:
    - IIS uses Application Mapping pathnames as long pathname and without need for quotes
    - The GUI in W2K/XP had a bug where it puts quotes around pathnames and then puts it into the Application Mapping. This usually happens when type a pathname with spaces into the GUI.
    - When you run a script, it is impossible to pass in quotes unless you use a different encoding; but you need to use quotes on the commandline to pass in spaces

    What this means is that when you set an IIS configuration value, you need to know what value IIS wants, and what each configuration tool will actually put into configuration. No safe-guards anywhere.

    //David

  • Anonymous
    June 29, 2006
    Thanks for the summary, David!

  • Anonymous
    June 30, 2006
    Thanks for this script, i use before the Admin IIS 6.0 script iiscnfg.vbs for export and import the ScriptMaps, but the attribute was not exported with them. Only Export of the ScriptMaps when i edit the property before in MMC, bad!

    Now i use your script and i have integrate it to my deployment & building solution. Works fine.

    -Pat

  • Anonymous
    June 30, 2006
    Pat - it sounds like you are only exporting/importing settings on a per-Website basis, while many properties like ScriptMaps are inheriting from global values by default and do not show up per-Website. Thus, when you export, inheriting values are not there (so that you continue to re-inherit from global values on the destination machine).

    When you edit the property in MMC, it stops the inheritance and sets them on a per-Website basis, so it shows up on export.

    The problem you must resolve is that a website has many global settings on the source machine which are not exported/imported into the destination machine.

    //David

  • Anonymous
    July 01, 2006
    Thanks for the code. I'm trying to do the samething with javascript.
    How can I modify LIST data type in IIS with javascript.

    I can convert LISTs with toArray function of javascript but I can't put the updated value back!!!

  • Anonymous
    July 01, 2006
    Mert - Since you converted LISTs to JScript Array for modification, it makes sense that you must convert the JScript Array BACK INTO a VB SafeArray to put it back.

    This is one reason why I wrote the sample in VBScript - because LIST modification is simpler in VBScript.

    With JScript, I must convert LISTs from VBArray to JScript Array since VBScript cannot manipulate VBArray directly, manipulate it as JScript Array, then convert it back to VBArray to update the LIST data type.

    //David

  • Anonymous
    July 03, 2006
    Than the question becomes;

    How can I create a VB Safe Array and modify it with JScript?

    Why I'm insisting on JScript is because, it is way much powerful than VBScript. You've got classes, try catch blocks, cool arrays,  interesting object notation like (obj.property == obj["property"]) and also JSON ;)

    I am using HTA, Javascript, XMLHTTPRequest and JSON, JQuery in a Setup application, the possibilities are weird!!!

  • Anonymous
    July 03, 2006
    Than the question becomes;

    How can I create a VB Safe Array and modify it with JScript?

    Why I'm insisting on JScript is because, it is way much powerful than VBScript. You've got classes, try catch blocks, cool arrays,  interesting object notation like (obj.property == obj["property"]) and also JSON ;)

    I am using HTA, Javascript, XMLHTTPRequest and JSON, JQuery in a Setup application, the possibilities are weird!!!

    Mert

  • Anonymous
    July 03, 2006
    I recently got a question about how to manipulate the LIST data type within JScript since my sample code...

  • Anonymous
    July 03, 2006
    The comment has been removed

  • Anonymous
    August 24, 2006
    Excellent Script!!!! I needed to remove some script mappings from our websites and this made it possible to do it programmatically.  Thanks!!!!

  • Anonymous
    June 04, 2007
    Removing a Wildcard application map removes all Cache ISAPI extensions, althought it used to work before enabling SSL (I don't know it is related with the problem). Example: C:Inetpubchglist.vbs W3SVC/1/root/ScriptMaps "" "*,D:WWWdllsmyappMap.dll,0" /REMOVE /COMMIT

  • Anonymous
    June 09, 2007
    I'm trying to install a wildcard application mapping on every site on a server. If I invoke it like so:    <script> W3SVCScriptMaps "" "*,wildcard.dll,1" /insert /recurse /commit ...it successfully installs the map at the global server level, as specified, but it doesn't recurse into the siges (e.g., W3SVC/1/root/ScriptMaps); instead it says:    Ignoring inherited property for Recursive Modification It works the way I expect when I pass W3SVC/1/root/ScriptMaps (or similar), finding any overridden ScriptMaps settings in the subtree and adding my extension. Rather than simply change the code, I'd like to understand why you designed it this way. The obvious downside is that I have to know a priori which sites exist in the metabase (1, 2, 54241, etc), which means I need to manually enumerate them and invoke this script on each path. That doesn't seem like the best way to do this. I realize this has been partially asked before, but I'd appreciate it if you could explain the concept, rather than simply the syntax. Thanks.

  • Anonymous
    June 11, 2007
    Question: We use your "ChgList.vbs" script (called in as an external script to run "command = "chglist.vbs") in one of our IIS 6 server scripts to perform "Script Map Deletion". What is the easiest way to turn this around in a secondary script used to not actually perform the action but just to verify if it has been performed in the main script or if the specific types of files exist (.cer, .cdx, and .idc). I am new at this and just trying to learn how to. Thanks. Okey_Dokey1

  • Anonymous
    June 14, 2007
    I just wanted to drop a quick thank you for the script. I needed a way to flick the ASP.NET Web Service Extensions on and off and this worked like a charm. Thank you David for the script, I appreciate it.

  • Anonymous
    June 15, 2007
    This is perfect.  Thanks so much...

  • Anonymous
    June 23, 2007
    Joe - the reason for "Ignoring inherited property for Recursive Modification" is because I do not want to make a recursive config change at a node that is already inheriting that property value from its parent. You can view "recurvise modification" as the same as "manual-override of property value inheritance". In other words, suppose you only had ScriptMaps set at W3SVC/ScriptMaps. This means all websites are already inheriting this value, so when you tell ChgList.vbs to recurse from W3SVC/ScriptMaps, it only makes sense to change W3SVC/ScriptMaps. If ChgList.vbs also modified W3SVC/1/ROOT/ScriptMaps, it would change W3SVC/1/ROOT/ScriptMaps to no longer inherit from W3SVC/ScriptMaps, a conceptual change. While this is no danger this initial time, any future edits to W3SVC/ScriptMaps will no longer automatically inherit to W3SVC/1/ROOT/ScriptMaps. Now, in your situation, you may choose to always remember to use /recursive so it does not matter, but not everyone has that luxury in their environment, nor will everyone remember to use /recursive. Thus, ChgList.vbs explicitly ignores inherited property on /recurse It would be completely different functionality to recursively edit all non-inherited values. You can get that functionality by stitching together ADSUTIL.VBS FIND to do that recursion and ChgList.vbs to do the edit of the LIST data type. //David

  • Anonymous
    June 23, 2007
    Okey_Dokey1 - To Verify that the action has been performed or if specific types of extensions exist, you can simply call ChgList.vbs without /commit <chglist.vbs> W3SVC/1/root/ScriptMaps ".idc" "FOUND"" The output of the command will include FOUND if .idc is in any list entry of W3SVC/1/root/ScriptMaps . Just parse the output. //David

  • Anonymous
    August 21, 2007
    I recently decided to experiment with hosting my own blog and after looking at the various packages available

  • Anonymous
    September 20, 2007
    Brilliant - Works a treat for me !!

  • Anonymous
    November 15, 2007
    I love you David ! indeed ! thanks a lot .

  • Anonymous
    January 21, 2008
    The comment has been removed

  • Anonymous
    February 18, 2008
    The comment has been removed

  • Anonymous
    February 21, 2008
    I am new to all of this, can you cut and paste the section of your code that adds the host headers? The reason being is for someone like myself it is sometimes hard to wade through all the error checking, etc All I need to see is the snippet of code that adds the host headers On a side note: Have you considered providing more examples using WMI?

  • Anonymous
    February 21, 2008
    Hi David, I run PHP4 and PHP5 both on my IIS. I use following different mapping for them : PHP4 : C:phpphp.exe and for PHP5 : C:php5php-cgi.exe Now how can I list sites that are using PHP4 and PHP5 mapping respectively using this script. Thanks

  • Anonymous
    February 22, 2008
    Ritz - your specific task is best left to the reader. Hint: if you need to list sites, then you need to read the value of Script Mappings of IIS nodes. This script is all about editing/modifying Script Mappings, so I doubt it works for your scenario. I would use ADSUTIL.VBS to FIND all the ScriptMaps properties, then read them with ADSUTIL.VBS, and finally, parse the ScriptMaps entry to determine if PHP4 or PHP5 is installed the way you have it. //David

  • Anonymous
    February 22, 2008
    Moe - your specific task is best left to the reader. Basically, I am not allowed to write your code for you, including code snippets. You are free to take my existing code and reuse/modify as you wish. If you cannot wade through the code to find the necessary code snippet, then I suggest you use the entire source code to add the host header. //David

  • Anonymous
    February 22, 2008
    Dani - this tool illustrates how to remove a specific script mapping, so please read and follow the example. //David

  • Anonymous
    April 01, 2008
    Hi, I try to manipulate W3SVC/1/Root/DefaultDoc but I get an error message saying "Cannot handle W3SVC/1/ROOT/DefaultDoc with type string". I ran the following command: C:InetpubAdminScripts>cscript.exe chglist.vbs W3SVC/1/ROOT/DefaultDoc "" "index .php" /INSERT /COMMIT What is wrong?

  • Anonymous
    April 14, 2008
    Is there a simple way of adding the ability to target remote servers?  Like the adsutil.vbs "-s" switch for example. Thanks, great script.

  • Anonymous
    April 18, 2008
    The comment has been removed

  • Anonymous
    April 18, 2008
    Frode - DefaultDoc stores multiple values in a single string with commas separating their values. Meanwhile, this script is for dealing with multiple values in a LIST. Thus, this script will not work for DefaultDoc, and it stops with that error appropriately. I know this all looks confusing because you probably just want to have one way to deal with all the different types of multi-value properties in IIS. Unfortunately, that was not my intent for the script. Otherwise I would have named the blog entry: "How to manipulate multi-value data types in IIS Configuration". Minor cases like DefaultDoc and MimeMaps can be handled, just not in this script. //David

  • Anonymous
    June 26, 2008
    Hi,  I am trying to use your script to remove an application mapping for an extension (home directory tab, configuration via the GUI).  Then I am trying to add a new mapping.  Really the ultimate goal, and the purpose of using the script is that we are changing where the dll files are stored from the e:content directory to the e:inetpub directory.   So, I ran: cscript chglist.vbs W3SVC/1156155428/root/ScriptMaps "" ".myext,e:contentmyappwls-iismyfile.dll,0" /REMOVE /COMMIT and was able to remove the .myext however when I try to insert one using the following: cscript chglist.vbs w3svc/1156155428/root/ScriptMaps "" ".myext,e:inetpubwwwrootmyappwls-iismyfile.dll,1" /INSERT /COMMIT I get a success message that says nothing to update.  In addition, there are no mappings added when looking in the GUI I also tried to run the insert command first, thinking that I could remove the duplicate extension later, but when I do this and then run the remove command it removes the newly created ext (which is the one I want to keep) What am I doing wrong?  I just want to remove on app mapping and add another (or edit the app mapping that is in there) I am on IIS6 thanks!

  • Anonymous
    June 28, 2008
    how to check iis web side is up or down? is there a script to  check all web sites and write a text file. is it possible to conrtol with vbs thanks

  • Anonymous
    June 28, 2008
    The comment has been removed

  • Anonymous
    June 28, 2008
    postrgrl - in the blog entry there are functioning examples of how to add, remove, and edit a LIST property. The tool has a very simple syntax where you specify "the text to match against" to produce an index into the desired LIST property, and once you have an index, whether to remove the item, replace the text, or insert at that index. Thus, your /REMOVE syntax does not do what you say. It is only removing the first scriptmapping at W3SVC/1156155428/root/ScriptMaps, no matter what it is. If you want to remove the .myext scriptmapping, then you need to provide ".myext" to match against, instead of "". Likewise, your /INSERT syntax does not do what you want. It finds index 0 as the first item that matches "" and attempts to insert after that item. And since your /REMOVE syntax removes the first scriptmapping, that's why your removal of duplicates attempt does not work. The easiest thing for you to do is to change an existing item, documented in the blog entry. cscript chglist.vbs w3svc/1156155428/root/ScriptMaps ".myext" ".myext,e:inetpubwwwrootmyappwls-iismyfile.dll,1" /COMMIT The syntax looks for an entry with .myext and changes it to .myext,e:inetpubwwwrootmyappwls-iismyfile.dll,1 Of course, if .myext does not already exist, this will do nothing. //David

  • Anonymous
    July 02, 2008
    The comment has been removed

  • Anonymous
    July 12, 2008
    The comment has been removed

  • Anonymous
    July 24, 2008
    Is it possible to edit and update just the IP of a web site in an shared web server env.

  • Anonymous
    July 25, 2008
    Prakash - if you can modify the ServerBindings property then you can change the IP of a website in IIS with this tool. //David

  • Anonymous
    August 28, 2008
    The comment has been removed

  • Anonymous
    August 28, 2008
    I have run into a problem. I try to insert a record like this: C:windowssystem32cscript.exe C:InetpubAdminScriptschglist.vbs W3SVC/1110424359/ServerBindings LAST "66.155.112.33:80:aaateste.com" /INSERT /COMMIT It works fine. But then when I try to delete it like this: C:windowssystem32cscript.exe C:InetpubAdminScriptschglist.vbs W3SVC/1110424359/ServerBindings "66.155.112.33:80:aaateste.com"  /DELETE /COMMIT it deletes the entry, but I get a blank entry in the server bindings, which generates an error and stops the website. I can't find an example of how to delete the bindings. What am I doing wrong? Thanks

  • Anonymous
    August 28, 2008
    SORRY!!!! Wrong command. It is REMOVE and not DELETE. Sorry for the misunderstanding! It works now!

  • Anonymous
    September 04, 2008
    David you mentioned that we need to change the strServer = "localhost" line to take in commandline parameters if we wanted to make changes on remote servers. With the way I did it, I had to change another section of code  to ignore the additional commandline parameter as well as adjust the parameter count and parameter numbers now that I introduced the extra paramater. So here are the changes I made. ' changed from strServer = "localhost" so that the first paramater is the remote server name strServer = WScript.Arguments(0) strNamespace = "IIS://" & strServer strSchemaNamespace = strNamespace & "/" & "Schema" ' ' Parse the commandline ' ' Increased the WScript.Arguments.Count to check for from 3 to 4. If WScript.Arguments.Count < 4 Then    Err.Number = ERROR_INVALID_PARAMETER    HandleError "Insufficient number of arguments." & CRLF &_                CRLF &_                strHelp &_                "" End If nOperationType = LIST_OPTION_REPLACE 'Started the for loop to begin from the second parameter now that the first one is the name of the remote server (for i=1).   'Also increased the WScript.Argument numbers by 1. For i = 1 To WScript.Arguments.Count - 1    Select Case UCase( WScript.Arguments( i ) )        Case "/INSERT"            nOperationType = nOperationType Or LIST_OPTION_INSERT        Case "/REMOVE"            nOperationType = nOperationType Or LIST_OPTION_REMOVE        Case "/ALL"            nOperationType = nOperationType Or LIST_OPTION_ALL        Case "/RECURSE"            nOperationType = nOperationType Or LIST_OPTION_RECURSE        Case "/COMMIT"            Debug = false        Case "/VERBOSE"            Verbose = true        Case "/REGEXP"            reMatch = true        Case Else            If ( i = 1 ) Then                '                ' Split out PropertyName and its ParentPath from PropertyPath                '                Err.Clear                strNormalizedPath = NormalizePath( WScript.Arguments( 1 ) )                HandleError "Failed to normalize PropertyPath."                j = InstrRev( strNormalizedPath, "/", -1, 0 )                If ( j = 0 Or j = 1 ) Then                    Err.Number = ERROR_PATH_NOT_FOUND                    HandleError "Invalid PropertyPath."                End If                Err.Clear                strPropertyPath = NormalizePath( Mid( strNormalizedPath, 1, j - 1 ) )                HandleError "Failed to retrieve/normalize PropertyPath."                Err.Clear                strPropertyName = NormalizePath( Mid( strNormalizedPath, j + 1 ) )                HandleError "Failed to retrieve/normalize PropertyName."            ElseIf ( i = 2 ) Then                '                ' The existing match value                '                strPropertyExistValue = Replace( UCase( WScript.Arguments( 2 ) ), "&quot;, &quot;&quot;&quot;&quot; ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ElseIf ( i = 3 ) Then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;' The new replace value &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;strPropertyNewValue = Replace( WScript.Arguments( 3 ), &quot;", """" )            Else                Err.Number = ERROR_INVALID_PARAMETER                HandleError "Unknown parameter " & WScript.Arguments( i ) & CRLF &_                            CRLF &_                            strHelp &_                            ""            End If    End Select Next

  • Anonymous
    September 08, 2008
    Steve - your approach is one possible way. However, it introduces unnecessary positional-dependent parameters (i.e. your solution MUST pass in a server name for the first parameter, even though it is not necessary). My code uses a really quick and dirty commandline parsing routine, meant mostly for example/illustration. If I wanted to add server support on the commandline to this script, I would add a new switch case named "/SERVER", which sets strServer to the value of WScript.Arguments(i+1) (appropriately error checking against /SERVER without a follow-on parameter or /SERVER /COMMIT). And also move strNamespace and strSchemaNamespace assignments to after the commandline parsing for-loop. This would produce mostly code insertion, no modification of existing logic, and no positional-dependent parameters. //David

  • Anonymous
    November 03, 2008
    PingBack from http://www.jesusllor.es/?p=360

  • Anonymous
    November 12, 2008
    Thanks very much for this script - works a treat.

  • Anonymous
    December 04, 2008
    How do I use this if I don't know the site idendifier?  I only know the site description. I had already managed to use IISWEB to add new sites to IIS but unfortunately, it appears that it can only add one host header.  I need to be able to also bid the site domain without the host header "www" prefix. Is there any way to query the site identifier # (via coldfusion) and then pass that value to your script?

  • Anonymous
    December 04, 2008
    Thanks for make the script David, I use it to insert wildcard Application maps into IIS websites.  But I am not sure how to remove or change the one that is already there.   Would love it if you could show me how or let me know if it is possible.

  • Anonymous
    December 07, 2008
    Brendan - you can use ADSUTIL.VBS FIND ServerComment to get all site descriptions and then filter through it to find the corresponding SiteID. If you create/use a dedicated script calling ADSI, it is pretty easy because CreateWebsite will return the SiteID as well as the Site Object, which allows you to do the other manipulation. If you use script tools, then you have to be creative and stitch them together. //David

  • Anonymous
    December 07, 2008
    The comment has been removed

  • Anonymous
    January 21, 2009
    thanks david, it help me to avoid the shortage of adsutil.vbs

  • Anonymous
    February 24, 2009
    After much grinning, I found a script that would add just MIME types you want to add, NON-destructively. The original code was commented and formatted for a different purpose. I modified it specifically just to add Office 2007 MIME types and re-commented appropriately. You should be able to add MIME types easily by just simply replacing my Office 2007 MIME types with the ones you need. See http://dogma.swiftspirit.co.za/archives/183

  • Anonymous
    May 29, 2009
    The comment has been removed

  • Anonymous
    June 13, 2009
    PingBack from http://firepitidea.info/story.php?id=887

  • Anonymous
    June 15, 2009
    一.使用ASP.NETMVCBin编译 参考文章:http://haacked.com/archive/2008/11/03/bin-deploy-aspnetmvc.aspx 二.II...

  • Anonymous
    July 23, 2009
    David,  /INSERT option allows to add a value second to the last one in the LIST, but  how can I use this script to add new value to the end of the LIST?  I am trying to add new HTTPCustomHeader.   Than you.

  • Anonymous
    February 23, 2010
    I have one issue while getting httperrors list.  I am getting the list of httpErrors but only for the type 'FILE'.  Why I am not getting for the type'Default'?.  Somehow my 500 error code is set to 'Default' and I am not getting through ["HttpErrors"] property.  Any clue on that?

  • Anonymous
    May 05, 2010
    Hi, I've been running this on a test rig fine with no problems. I call this in a script: cscript /nologo chglist.vbs W3SVC/1595303702/HttpErrors 404 404,*,URL,/index.shtml /commit However, if the HttpError has been changed manually through the GUI beforehand, it won't make the change, although it does say it has been successful. Any ideas? Thanks Gary

  • Anonymous
    June 23, 2011
    The comment has been removed

  • Anonymous
    November 18, 2011
    王先生您好,我使用您的这个脚本 添加一项iaspi应用扩展,chglist.vbs W3SVC/ScriptMaps "" ".php,D:PHPphp5isapi.dll,5" /INSERT /COMMIT  只有主网站添加了这个扩展,而下面的网站都没有继承,请问有什么办法可以解决吗?

  • Anonymous
    June 17, 2015
    This is a great piece of code and I'd love to use it. Is there a license attached to it? I don't wish to presume it can be used freely without your permission