views:

470

answers:

1

I've long had a bunch of VBS automations for IIS 6, including one that gets/sets complex server bindings on several farms of paired servers, each having dozens of apps, each app having 3-12 host headers. Each app has hostname, hostname-fullyqualified, and Disaster Recovery enabled hostname, so they can be a mess to maintain manually.

I did all my vbs stuff using ADSI, but I'm thinking WMI is probably more flexible than ADSI from a full server maintenance perspective. Please correct me if I'm wrong. So now I'm trying to move up to Powershell + WMI to prepare for Windows 2008 + IIS 7.5. I'm enjoying the learning process, but I've hit a roadblock on this problem.

I can get/set all properties via WMI on my IIS 6 WebServers, except ServerBindings. I feel like I'm close, but I'm missing some layer of containment, and I just can't get the objects I'm building to cast over to the right automation object.

The following code gets and reads the ServerBindings just fine. I simply can't figure out a way to write my changes back. Any advice is welcomed.

$objWMI = [WmiSearcher] "Select * From IISWebServerSetting"
$objWMI.Scope.Path = "\\" + $server + "\root\microsoftiisv2" 
$objWMI.Scope.Options.Authentication = 6 
$sites = $objWMI.Get() 
foreach ($site in $sites)
{
    $bindings = $site.psbase.properties | ? {$_.Name -contains "ServerBindings"} 
    foreach ($pair in $bindings.Value.GetEnumerator())
    {
        # The pair object is a single binding and contains the correct data
        $pair
        $pair.IP    
        $pair.Port
        $pair.Hostname
        # And this line will successfully erase the contents of the ServerBindings
        $bindings.Value = @{}
        # but I can't figure out what to do to update $bindings.Value
    }
    $site.Put()
}

I'm liking Powershell so far, so thanks for any help you're able to offer.

A: 

Alright. I got distracted with major disk failures. The fun never stops.

Anyway, the solution to this problem is simpler than I'd made it:

process
{
    $bindings = $_.ServerBindings
    foreach ($binding in $bindings)
    {
        $binding.IP = $ip
        $binding.Port = $port
        $binding.Hostname = $hostname
    }
    $_.ServerBindings = $bindings
    $_.Put()
}

ServerBindings is an array, but it likes to be an array of its own kind. I was trying to build the array from scratch, but my home-rolled array didn't smell right to Powershell. So, pull the array out of ServerBindings into a new variable, manipulate the variable, then assign the manipulated variable back to the ServerBindings property. That keeps all the right typing in place. It's smooth as silk, and seems easier than ADSI.

codepoke