Reputation: 13079
I am creating a Powershell script using the WebAdministration module to create a couple of sites and automatically add bindings
Import-Module WebAdministration
$config = @{
Sites = @(
@{
Name = "Site1";
Path = "Path1";
Bindings = @(
@{ Protocol = "http"; Port = 80;},
@{ Protocol = "https"; Port = 443;}
);
},
@{
Name = "Site2";
Path = "Path2";
Bindings = @(
@{ Protocol = "http"; Port = 3009;}
);
}
)
}
foreach($site in $config.Sites){
$physicalPath = Get-Item "$($site.Path)"
# Create the current site
New-WebSite -Name "$($site.Name)" -PhysicalPath $physicalPath.FullName
## Trying to remove default port 80 binding for the current site
Remove-WebBinding -Name $site.Name -Port 80 -Protocol "http"
## Add the desired bindings
foreach ($binding in $site.Bindings){
New-WebBinding -Name "$($site.Name)" -Protocol $binding.Protocol -Port $binding.Port
}
}
When I do this though, I'm left without a binding on port 80 Site1. It looks like Remove-WebBinding -Name $site.Name -Port 80 -Protocol "http"
is removing bindings for both sites.
PS > Get-ChildItem IIS:\Sites
Name ID State Physical Path Bindings
---- -- ----- ------------- --------
Site1 1 Started Path1 https *:443: sslFlags=0
Site2 2 Stopped Path2 http *:3009:
If I do this without attempting to modify any bindings
foreach($site in $config.Sites){
$physicalPath = Get-Item "$($site.Path)"
# Create the current site
New-WebSite -Name "$($site.Name)" -PhysicalPath $physicalPath.FullName
}
I end up with both sites bound to port 80
PS > Get-ChildItem IIS:\Sites
Name ID State Physical Path Bindings
---- -- ----- ------------- --------
Site1 1 Started Path1 http *:80:
Site2 2 Stopped Path2 http *:80:
What am I doing wrong? Is there a better way? Is this a bug?
Upvotes: 1
Views: 3123
Reputation: 1941
I just experienced this erroneous behavior of Remove-WebBinding. There is definitely a bug in the tool or at least implementation does not follow specification outlined in documentation as of version 1.0.0 in May 2024. Syntax variant #1 allows specifying target binding by site name, IP address and port, protocol and hostreader name. If you happen to omit IP address or port, default values of *
are inferred (consult the output with -WhatIf
).
PS C:\> Remove-WebBinding -WhatIf -Name Site2
What if: Performing the operation "Remove-WebBinding" on target "-Site Site2 -IPAddress * -Port *".
It correctly describes what it should (and is expected to) do if executed, but for whatever reason the site name is ignored during the actual execution.
Following the code you originally posted in the question, on 2nd iteration of outer loop the tool is called with -port 80
which counts and -name Site2
which is ignored, that's when it removes port 80 bindings from all sites.
If you happen to omit both IP address and port, it effectively wipes out all binding-website associations from IIS. Uncool.
Syntax variant #2 (the one with -InputObject passed) behaves correctly. That's the one featured in the only example on the page and also the one Brandon recommended in the answer above.
Upvotes: 0
Reputation: 51
I have seen similar behavior. Rather than attempting to explicitly find and remove a binding entry, I have found more success using the pipeline to reference an already identified object.
For example:
Get-Website -Name "$($site.Name)" | Get-WebBinding -Protocol "http" -Port 80 | Remove-WebBinding
Upvotes: 5
Reputation: 13079
Managed to get around Remove-WebBinding
by using the first binding when creating the site and then iterating through any remaining bindings.
foreach($site in $config.Sites){
$physicalPath = Get-Item "$($site.Path)"
$defaultBinding = ($site.Bindings | Select-Object -First 1)
# Use Splatting
$newWebSiteParams = @{
Name = $site.Name;
PhysicalPath = $physicalPath.FullName;
ApplicationPool = $site.ApplicationPool
Port = $defaultBinding.Port
SSL = $defaultBinding.Protocol -eq 'https'
}
# Create the current site with command splatting
New-WebSite @newWebSiteParams
## Add the remaining bindings
foreach ($binding in ($site.Bindings | Select-Object -Skip 1)){
New-WebBinding -Name "$($site.Name)" -Protocol $binding.Protocol -Port $binding.Port
}
}
Still not sure why Remove-WebBinding
appeared to be removing the binding from both sites.
Upvotes: 0