20 March 2010

IIS6: How to add new ServerBinding with PowerShell 1.0

Few day ago I needed to write automation script which will add new domain to existing site in IIS6 with using PowerShell. I already developed several scripts to automate different operations with using WMI interface. So, obviously I decided to use WMI again.
It looks like pretty simple task - just to add new item to ServerBindings array in IIS website configuration object. But I spent near 3 hours to get to working script. You can found different samples in C#, but nothing completely working on PowerShell 1.0 + WMI.

Main issues:
  1. You can't add new item to $site.ServerBinding, because it is read only list. But you can replace it. You have to act in following order:
    • create generic list
    • copy all existing bindings to it
    • add new binding
    • convert to array and replace existing list of bindings
  2. You can't simply create new list item by calling code like "New-Object -type ServerBinding", because you don't know actual class name (it derived from System.Management.ManagementBaseObject). You even can't clone existing binding, because there is no method .Clone()
    You should use classes ManagementScope, ManagementPath and ManagementClass from System.Management namespace to create new binging.
Source code:
function AddServerBinding($siteName, $hostName, $port, $ip) {
    function _New-GenericList {
        param ([Type]$Type)
 
        $base = [System.Collections.Generic.List``1]
        $qt = $base.MakeGenericType(@($Type))
        New-Object $qt
    }
   
    function _New-ServerBinding {
        $scope = new-object -type System.Management.ManagementScope("\\.\root\MicrosoftIISV2")
        $scope.Connect()
        $managementPath = new-object -type System.Management.ManagementPath("ServerBinding")
        $classBinding = new-object -type System.Management.ManagementClass($scope, $managementPath, $null)
        return $classBinding.CreateInstance()
    }
 
    # get web site configuration
    $site = Get-WMIObject -query "select * from IIsWebServerSetting where ServerComment='$siteName'" -namespace "root\microsoftiisv2"
 
    # create list of bindings
    $bindings = _New-GenericList -Type System.Object # If it doesn't work, change the type to System.Management.ManagementBaseObject
   
    # copy old bindings
    foreach ($item in $site.ServerBindings) {
        $bindings.Add($item)
    }
 
    # add new binding
    $newBinding = _New-ServerBinding
    $newBinding.hostName = $hostName
    $newBinding.port = $port
    $bindings.Add($newBinding)
 
    # save site configuration
    $site.ServerBindings = $bindings.ToArray()
    $site.Put()
}
 
# example of usage
AddServerBinding "SampleWebSite" "www.example.com" 80 $null
 

Download source: AddServerBinding.ps1

No comments:

Post a Comment

Profile