Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save dethbiscuit/a9427fa44963784edd06c96dc087bce7 to your computer and use it in GitHub Desktop.
Save dethbiscuit/a9427fa44963784edd06c96dc087bce7 to your computer and use it in GitHub Desktop.
Add a website to IIS on every node in a cluster
<#
.SOURCE
https://4sysops.com/archives/create-iis-websites-with-powershell/
http://www.jhouseconsulting.com/2015/01/04/script-to-import-and-bind-a-certificate-to-the-default-web-site-1548
.SYNOPSIS
.
.DESCRIPTION
Creates website in IIS and assign a application pool and create both HTTP and HTTPS bindings.
.PARAMETER WebSiteName
This is the site name you are going to create.
.PARAMETER RootFSFolder
Specifies a root folder where all the website's files are stored.
.PARAMETER HttpHostheaders
Specifies host headers (http) that will be added to each website.
Use quotes for this parameter to avoid errors and separate them with a comma.
.PARAMETER HttpsHostheaders
Specifies host headers (https) that will be added to each website.
Use quotes for this parameter to avoid errors and separate them with a comma.
.PARAMETER AppPoolName
Specifies the name for application pool to be assigned to the website.
.PARAMETER WebsiteIP
Specifies the Website IP to use.
.PARAMETER CertSubject
Specifies the certificate to assign to HTTPS website.
.PARAMETER Help
Displays the help screen.
.EXAMPLE
.\create_website.ps1 "mywebsite.com" "D:\IIS\mywebsite\wwwroot" "applicationPoolName" "mywebsite.com,sub.mywebsite.com" $null "192.192.192.192" "mywebsite.com"
.NOTES
Author: Dethbiscuit
Date: 2018.07.30
#>
# CmdletBinding() is a PowerShell keyword that tells the interpreter that this script should behave as a compiled C# application.
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True)]
[string]$RootFSFolder,
[Parameter(Mandatory=$True)]
[string]$AppPoolName,
[Parameter(Mandatory=$True)]
[string]$WebSiteName,
[Parameter(Mandatory=$False)]
[string]$HttpHostheaders,
[Parameter(Mandatory=$False)]
[string]$HttpsHostheaders,
[Parameter(Mandatory=$False)]
[string]$WebsiteIP,
[Parameter(Mandatory=$False)]
[string]$CertSubject
)
# I know that PowerShell now imports modules on the fly, but I still prefer do this explicitly to ensure that the module is really available.
import-module WebAdministration
Function AddNewApplication{
Param(
[string] $RootFSFolder,
[string] $AppPoolName,
[string] $WebSiteName,
[string] $HttpHostheaders,
[string] $HttpsHostheaders,
[string] $WebsiteIP,
[string] $CertSubject
)
# Test Root Folder
if(Test-Path -Path $RootFSFolder ){
Write-Host "Website's root directory $RootFSFolder exists"
}
else {
Write-Host "Website's root directory $RootFSFolder doens't exist" -ForegroundColor Red
exit
}
# Test application pool
if(Test-Path ("IIS:\AppPools\" + $AppPoolName)) {
Write-Host "The App Pool $AppPoolName was found and has been assigned"
}
else{
Write-Host "The App Pool doesn't exist !" -ForegroundColor Red
exit
}
# Test website
If(Test-Path "IIS:\Sites\$WebSiteName"){
Write-Host "The IIS site $WebSiteName already exists" -ForegroundColor Red
exit
}
else{
# Create website
New-Website -Name $WebSiteName -PhysicalPath $RootFSFolder -ApplicationPool $AppPoolName
Write-Host "The website has been created" -ForegroundColor Yellow
}
# Create bindings
SetupBindings $HttpHostheaders $HttpsHostheaders $WebSiteName $WebsiteIP $CertSubject
# End
Write-Host "Operation completed" -ForegroundColor Yellow
}
# As you can see, it accepts the $HttpHostheaders string as a parameter, and there can be several headers separated by commas.
Function SetupBindings {
Param(
[string] $HttpHostheaders,
[string] $HttpsHostheaders,
[string] $WebSiteName,
[string] $WebsiteIP,
[string] $CertSubject
)
$option = [System.StringSplitOptions]::RemoveEmptyEntries
# Mandatory to work with certificates
IMPORT-MODULE PKI
# HTTP headers
if($HttpHostheaders -ne $null){
$httpCharCount = ($HttpHostheaders.ToCharArray() | Where-Object {$_ -eq ','} | Measure-Object).Count + 1
$httphs=$HttpHostheaders.Split(',',$httpCharCount,$option)
foreach ($h in $httphs){
$header=$h.Trim()
New-WebBinding -Name $WebSiteName -HostHeader $header -IP $WebsiteIP -Port 80 -Protocol http
}
}
# HTTPS headers
if($HttpsHostheaders -ne $null){
$httpsCharCount = ($HttpHostheaders.ToCharArray() | Where-Object {$_ -eq ','} | Measure-Object).Count + 1
$httpshs=$HttpsHostheaders.Split(',',$httpsCharCount,$option)
foreach ($h in $httpshs){
$header= $h.Trim()
if($CertSubject -ne $null){
Write-Output "Locating the cert in the Store"
try{
$cert = Get-ChildItem cert:\LocalMachine\My | Where-Object {$_.subject -like "*$CertSubject*"}
$thumbprint = $cert.Thumbprint.ToString()
Write-Output $cert
}
catch{
Write-Output "Unable to locate cert in certificate store"
exit
}
try{
$AddSSLCertToWebBinding = (New-WebBinding -Name $WebSiteName -HostHeader $header -IP $WebsiteIP -Port 443 -Protocol https).AddSslCertificate($thumbprint, "MY")
Write-Output $AddSSLCertToWebBinding
}
catch{
Write-Output "Unable to add certificate"
exit
}
}
}
}
}
# Call function
AddNewApplication $RootFSFolder $AppPoolName $WebSiteName $HttpHostheaders $HttpsHostheaders $WebsiteIP $CertSubject
<#
.SOURCE
.
.SYNOPSIS
.
.DESCRIPTION
Creates website in IIS (on all nodes in the clcuster) and assign a application pool and create both HTTP and HTTPS bindings.
.PARAMETER WebSiteName
This is the site name you are going to create.
.PARAMETER RootFSFolder
Specifies a root folder where all the website's files are stored.
.PARAMETER HttpHostheaders
Specifies host headers (http) that will be added to each website.
Use quotes for this parameter to avoid errors and separate them with a comma.
.PARAMETER HttpsHostheaders
Specifies host headers (https) that will be added to each website.
Use quotes for this parameter to avoid errors and separate them with a comma.
.PARAMETER AppPoolName
Specifies the name for application pool to be assigned to the website.
.PARAMETER WebsiteIP
Specifies the Website IP to use.
.PARAMETER CertSubject
Specifies the certificate to assign to HTTPS website.
.PARAMETER Help
Displays the help screen.
.EXAMPLE
.\IISAddNewWebsite.ps1 "mywebsite.com" "D:\IIS\mywebsite\wwwroot" "applicationPoolName" "mywebsite.com,sub.mywebsite.com" $null "192.192.192.192" "mywebsite.com"
.NOTES
Author: Dethbiscuit
Date: 2018.07.30
#>
# CmdletBinding() is a PowerShell keyword that tells the interpreter that this script should behave as a compiled C# application.
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True)]
[string]$RootFSFolder,
[Parameter(Mandatory=$True)]
[string]$AppPoolName,
[Parameter(Mandatory=$True)]
[string]$WebSiteName,
[Parameter(Mandatory=$False)]
[string]$HttpHostheaders,
[Parameter(Mandatory=$False)]
[string]$HttpsHostheaders,
[Parameter(Mandatory=$False)]
[string]$WebsiteIP,
[Parameter(Mandatory=$False)]
[string]$CertSubject
)
Function AddNewApplicationOnNode{
Param(
[string] $RootFSFolder,
[string] $AppPoolName,
[string] $WebSiteName,
[string] $HttpHostheaders,
[string] $HttpsHostheaders,
[string] $WebsiteIP,
[string] $CertSubject
)
$ps1Path = "D:\Scripts\IIS\create_website.ps1"
# Test if file exists
if (Test-Path -Path $ps1Path) {
# Call function on the node
D:\Scripts\IIS\create_website.ps1 $RootFSFolder $AppPoolName $WebSiteName $HttpHostheaders $HttpsHostheaders $WebsiteIP $CertSubject
}
else{
Write-Host "File not found on node $server.Name" -ForegroundColor Red
Write-Host "Path : $ps1Path"
}
}
$servers = Get-ClusterNode
foreach ($server in $servers)
{
Write-Host "Running script on node $server.Name" -ForegroundColor Yellow
Invoke-Command -ComputerName $server.Name -ScriptBlock ${function:AddNewApplicationOnNode} -ArgumentList $RootFSFolder,$AppPoolName,$WebSiteName,$HttpHostheaders,$HttpsHostheaders,$WebsiteIP,$CertSubject
Write-Host ">"
Write-Host ">"
Write-Host ">"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment