2

Guys I am trying to remove a specific IP from IIS site bindings through C# (Microsoft Web Administration).

Basically what I want to do is, is to check all site's binding in IIS and if any binding IP matches user-provided IP, it should remove it and if the particular site doesn't have any other bindings with different IP then it should stop the site.

However, I can't seem to remove the IP in a loop as I am getting "Collection was modified; enumeration operation may not execute." error.

This is my code :

static void Main(string[] args)
{
    ServerManager mgr = new ServerManager();

    foreach (Site s in mgr.Sites)
    {
        Console.WriteLine("Site {0}", s.Name);

        foreach (Application app in s.Applications)
        {
            Console.WriteLine("\tApplication: {0}", app.Path);

            foreach (VirtualDirectory virtDir in app.VirtualDirectories)
            {
                Console.WriteLine("\t\tVirtual Dir: {0}", virtDir.Path);
            }
        }

        BindingCollection bindingCollection = s.Bindings;
        foreach (Binding b in  bindingCollection)
        {
            Console.WriteLine("\n Bindings: {0}",b.EndPoint);
            if (b.EndPoint != null)
            {
                //Hard Coded IP for testing purpose
                if (b.EndPoint.ToString() == "1.1.1.1:86")
                {
                    Console.WriteLine("Removing this ip : {0}",b.EndPoint.ToString());
                    bindingCollection.Remove(b);
                }
            }
        }
      mgr.CommitChanges();
    }
    Console.ReadLine();
}

What should I do to remove the binding ? I need to remove it in a loop because a site may have more than 1 binding which uses the same IP.

NewbieProgrammer
  • 874
  • 2
  • 18
  • 50

1 Answers1

1

The enumerator is versioned for most collections that are part of the BCL, meaning that you cannot modify a collection while you are looping over it. You can copy the collection like so:

var bindingCollection = new List<Binding>(s.Bindings);

So now your loop looks like this:

var bindings = s.Bindings;
var bindingCollection = new List<Binding>(bindings);
foreach (Binding b in bindingCollection)
{
    Console.WriteLine("\n Bindings: {0}", b.EndPoint);
    if (b.EndPoint != null)
    {
        //Hard Coded IP for testing purpose
        if (b.EndPoint.ToString() == "1.1.1.1:86")
        {
            Console.WriteLine("Removing this ip : {0}", b.EndPoint.ToString());
            bindings.Remove(b);
        }
    }
}

However, this does not actually remove the binding like you expect it to. You need to call b.Delete() to actually delete the binding. When you use Remove, all you are doing is removing it from the collection that was built from existing bindings. So add b.Delete() before you remove it from the collection.

vcsjones
  • 138,677
  • 31
  • 291
  • 286
  • Thank you for your answer. I tried what you suggested above and the iteration issue is gone however the binding is still there and doesn't seem to be deleted. I tried `b.Delete()` too but still I can see the bindings in IIS. Why is that? – NewbieProgrammer Dec 31 '14 at 14:30
  • @NewbieProgrammer I believe you need to call `mgr.CommitChanges();` after you are done removing all your bindings. – vcsjones Dec 31 '14 at 14:32