├── IIS-Builder.ps1 ├── LICENSE ├── README.md ├── download-iisbuilder.ps1 └── iis-config.json /IIS-Builder.ps1: -------------------------------------------------------------------------------- 1 | param ([string]$path) 2 | 3 | $script = $myinvocation.mycommand.definition 4 | $dir = Split-Path $MyInvocation.MyCommand.Path 5 | Write-Host "Script location $script" 6 | Write-Host "Script started in $dir" 7 | 8 | if((![string]::IsNullOrWhiteSpace($path))) { 9 | if((Test-Path $path)){ 10 | if([System.IO.Path]::IsPathRooted($path)){ 11 | $dir = $path 12 | } 13 | else { 14 | $dir = Resolve-Path -Path $path 15 | } 16 | Write-Host "Path has been supplied passing in: $dir as working directory" 17 | } 18 | else { 19 | Write-Host "Unable to locate $path please provide a valid path" 20 | exit 21 | } 22 | } 23 | 24 | if ((Test-Path "$dir\iis-config.json") -eq $false){ 25 | Write-Host "Could not find iis-config.json in $dir" 26 | exit 27 | } 28 | 29 | #Ensure our script is elevated to Admin permissions 30 | If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) 31 | { 32 | Write-Host "Script has been opened without Admin permissions, attempting to restart as admin" 33 | $arguments = "-noexit & '" + $script + "'","-path $dir" 34 | Start-Process powershell -Verb runAs -ArgumentList $arguments 35 | Break 36 | } 37 | # Known limitations: 38 | # - does not handle entries with comments afterwards (" # comment") 39 | # https://stackoverflow.com/questions/2602460/powershell-to-manipulate-host-file 40 | # 41 | 42 | function add-host([string]$filename, [string]$ip, [string]$hostname) { 43 | remove-host $filename $hostname 44 | $ip + "`t`t" + $hostname | Out-File -encoding ASCII -append $filename 45 | } 46 | 47 | function remove-host([string]$filename, [string]$hostname) { 48 | $c = Get-Content $filename 49 | $newLines = @() 50 | 51 | foreach ($line in $c) { 52 | $bits = [regex]::Split($line, "\t+") 53 | if ($bits.count -eq 2) { 54 | if ($bits[1] -ne $hostname) { 55 | $newLines += $line 56 | } 57 | } else { 58 | $newLines += $line 59 | } 60 | } 61 | 62 | # Write file 63 | Clear-Content $filename 64 | foreach ($line in $newLines) { 65 | $line | Out-File -encoding ASCII -append $filename 66 | } 67 | } 68 | 69 | function assignUmbracoFolderPermissions($dir, $iisAppPoolName){ 70 | #Assign Umbraco IIS permissions to parent folder 71 | Write-Host $dir 72 | $Acl = Get-Acl $dir 73 | $Ar = New-Object system.security.accesscontrol.filesystemaccessrule("IUSR","Modify", "ContainerInherit, ObjectInherit", "None", "Allow") 74 | $Acl.SetAccessRule($Ar) 75 | Set-Acl -Path $dir -AclObject $Acl 76 | 77 | $Ar = New-Object system.security.accesscontrol.filesystemaccessrule("IIS_IUSRS","Modify", "ContainerInherit, ObjectInherit", "None", "Allow") 78 | $Acl.SetAccessRule($Ar) 79 | Set-Acl -Path $dir -AclObject $Acl 80 | 81 | $iisAppPoolName = "IIS apppool\$iisAppPoolName" 82 | $Ar = New-Object system.security.accesscontrol.filesystemaccessrule($iisAppPoolName,"Modify", "ContainerInherit, ObjectInherit", "None", "Allow") 83 | $Acl.SetAccessRule($Ar) 84 | Set-Acl -Path $dir -AclObject $Acl 85 | } 86 | 87 | #verification helpers 88 | function checkSiteExisiting($iisAppName){ 89 | $exists = $false 90 | if(Get-Website -Name "$iisAppName"){ 91 | $exists = $true 92 | } 93 | return $exists 94 | } 95 | 96 | function checkAppPoolExists($iisAppPool){ 97 | #check if the app pool exists 98 | return (Test-Path IIS:\AppPools\$iisAppPool -pathType container) 99 | } 100 | 101 | #Buggy still - not in use 102 | function getExisitingIISBindings($iisAppName){ 103 | return Get-IISSiteBinding -Name $iisAppName 104 | } 105 | 106 | function getSiteStatus($iis){ 107 | $exists = checkSiteExisiting($iis.siteName) 108 | if($exists){ 109 | $status = [pscustomobject]@{ 110 | siteExists = $exists 111 | appPoolExists = checkAppPoolExists($iis.appPoolName) 112 | #bindings = getExisitingIISBindings($iis.siteName) 113 | } 114 | } 115 | else { 116 | $status = [pscustomobject]@{ 117 | siteExists = $exists 118 | appPoolExists = checkAppPoolExists($iis.appPoolName) 119 | bindings = $false 120 | } 121 | } 122 | 123 | return $status 124 | } 125 | 126 | function createAppPool($appPoolName, $runtimeVersion){ 127 | #create the app pool 128 | $appPool = New-WebAppPool $appPoolName 129 | $appPool | Set-ItemProperty -Name "managedRuntimeVersion" -Value $runtimeVersion 130 | } 131 | 132 | function createSite($iis){ 133 | #Assign http bindings 134 | $i = 0 135 | foreach ($binding in $iis.siteBindings){ 136 | if($i -eq 0){ 137 | New-Website -Name $iis.siteName -PhysicalPath $iis.dir -ApplicationPool $iis.appPoolName -HostHeader $binding 138 | } 139 | else { 140 | New-WebBinding -Name $iis.siteName -IPAddress "*" -Port 80 -HostHeader $binding 141 | } 142 | $i++ 143 | } 144 | } 145 | 146 | function identifyLatestCertificate($certs){ 147 | Write-Host $certs.count " Certificates found for $binding identifying latest" 148 | $latest = "" 149 | foreach ($cert in $certs){ 150 | if($latest -eq ""){ 151 | #Load our first cert into latest 152 | $latest = $cert 153 | } 154 | else { 155 | if($latest.NotAfter -lt $cert.NotAfter){ 156 | #if latest expiry is before the next cert replace latest 157 | $latest = $cert 158 | } 159 | } 160 | } 161 | return $latest 162 | } 163 | 164 | function deleteCerts($certs){ 165 | foreach ($cert in $certs){ 166 | Remove-Item -LiteralPath $cert.PSPath 167 | Write-Host "Deleted redundant cert with Thumbprint" $cert.Thumbprint 168 | } 169 | } 170 | 171 | function createCert($binding){ 172 | $newCert = New-SelfSignedCertificate -DnsName "$binding" -CertStoreLocation "cert:\LocalMachine\My" 173 | Write-Host "Created new certificate with Thumbprint" $newCert.Thumbprint 174 | return $newCert 175 | } 176 | 177 | function rationaliseCerts($binding){ 178 | $certs = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -eq "CN=$binding"} 179 | Write-Host "Checking for existing certificate" 180 | if($certs){ 181 | #Identify and remove multiple certificates 182 | if($certs.count -gt 1){ 183 | $latestCert = identifyLatestCertificate($certs) 184 | $redundantCerts = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -eq "CN=$binding" -and $_.Thumbprint -ne $latestCert.Thumbprint} 185 | deleteCerts($redundantCerts) 186 | 187 | #WARNING! The code below will delete expired certs from your trusted certificate store enable at your own risk. 188 | #Check if cert is in trusted store and remove it 189 | 190 | # $redundantRootCerts = Get-ChildItem -Path Cert:\LocalMachine\Root | Where-Object {$_.Subject -eq "CN=$binding" -and $_.Thumbprint -ne $latestCert.Thumbprint} 191 | # Write-Host "Found " $redundantRootCerts.count "redundant Trusted Root certs for " $binding 192 | # deleteCerts($redundantRootCerts) 193 | } 194 | 195 | #Attempt to get the certificate 196 | $cert = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -eq "CN=$binding"} 197 | Write-Host "Found " $cert.count "certificates using the CNAME of " $binding 198 | Write-Host "Found Cert expires on" $cert.NotAfter 199 | #Check if the certificate is close to expiry 200 | if($cert.NotAfter -le (Get-Date).AddDays(30)){ 201 | Write-Host "Certificate will expire in less than 30 days, renewing..." 202 | deleteCerts($cert) 203 | $cert = createCert($binding) 204 | 205 | } 206 | 207 | } 208 | else { 209 | #No certificate was found 210 | Write-Host "No certificate was found creating one.." 211 | $cert = createCert($binding) 212 | } 213 | 214 | return $cert 215 | } 216 | 217 | #Bindings need to be organised before they are added 218 | function ensureSSL($iis){ 219 | # # Assign certificates to https bindings 220 | foreach ($binding in $iis.siteBindings){ 221 | #create a https binding 222 | #Check if certificate exists, create a new self cert if it doesn't 223 | Write-Host "Ensuring Certificate for $binding" 224 | $cert = rationaliseCerts($binding) 225 | Write-Host "Rationalised Thumbprint " $cert.Thumbprint 226 | $cert = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -eq "CN=$binding"} 227 | Write-Host "Picked Cert after search " $cert.Thumbprint 228 | New-WebBinding -Name $iis.siteName -Protocol "https" -Port 443 -IPAddress * -HostHeader $binding -SslFlags 1 229 | 230 | #Check if certificate already exisits in trusted certificates 231 | if(!(Get-ChildItem -Path Cert:\LocalMachine\Root | Where-Object {$_.Thumbprint -eq $cert.Thumbprint})){ 232 | 233 | Write-Host "Certificate is not in trusted store. Adding..." 234 | $DestStore = new-object System.Security.Cryptography.X509Certificates.X509Store( 235 | [System.Security.Cryptography.X509Certificates.StoreName]::Root,"localmachine" 236 | ) 237 | 238 | $DestStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite) 239 | $DestStore.Add($cert) 240 | $DestStore.Close() 241 | } 242 | #Using netsh to assign the ssl certs to the binding. powershell cmdlets seem to add certificates to all https bindings in the web site, not ideal 243 | (Get-WebBinding -Name $iis.siteName -Port 443 -Protocol "https" -HostHeader $binding).AddSslCertificate($cert.Thumbprint, "my") 244 | } 245 | } 246 | 247 | # ============== Start Script 248 | Import-Module WebAdministration 249 | $hostsPath = "C:\Windows\System32\drivers\etc\hosts" 250 | Write-Host "Starting in $dir" 251 | #Load JSON 252 | $iisconfig = Get-Content "$dir\iis-config.json" | Out-String | ConvertFrom-Json 253 | 254 | $iis = [pscustomobject]@{ 255 | siteName = $iisconfig."IIS-Site-Name" 256 | appPoolName = $iisconfig."App-Pool-Name" 257 | siteBindings = $iisconfig."bindings" 258 | dir = $dir 259 | dotNetVersion = $iisconfig."IIS-App-Pool-Dot-Net-Version" 260 | } 261 | Write-Host "Loaded in JSON" 262 | #Obtain current status of site 263 | $status = getSiteStatus($iis) 264 | 265 | # Create App pool if it doesn't exist 266 | if(!$status.appPoolExists){ 267 | createAppPool $iis.appPoolName $iis.dotNetVersion 268 | } 269 | Write-Host "Ensured App Pool" 270 | #Easier to remove the IIS site and re create it than editing the bindings 271 | if($status.siteExists){ 272 | Remove-WebSite -Name $iis.siteName 273 | Write-Host "Site already exists - Removing..." 274 | } 275 | 276 | #Create our IIS site which will add both http and https bindings 277 | Write-Host "Creating IIS Site" 278 | createSite $iis 279 | Write-Host "Assigning folder permissions on Web Root" 280 | assignUmbracoFolderPermissions $iis.dir $iis.appPoolName 281 | Write-Host "Ensuring SSL" 282 | ensureSSL $iis 283 | 284 | Write-Host "Adding non localtest.me domains to hosts file" 285 | # #Add bindings to hosts file 286 | foreach ($binding in $iis.siteBindings){ 287 | #Look for .localtest.me domain 288 | #if the domain is .localtest.me don't create a entry in the hosts file 289 | if(-Not ($binding -Match"localtest.me")){ 290 | add-host $hostsPath "127.0.0.1" $binding 291 | } 292 | if(-Not ($binding -Match"https://") -or -Not ($binding -Match"http://")){ 293 | $binding = "https://$binding" 294 | } 295 | 296 | #Enable me if you would like the browser to automatically open when the script is ran 297 | #Start-Process $binding 298 | } 299 | 300 | Write-Host "Bindings added" 301 | foreach ($binding in $iis.siteBindings){ 302 | Write-Host "$binding" 303 | } 304 | 305 | Write-Host "Done, thanks for using IIS Builder" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Matthew 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IIS-Builder 2 | 3 | 4 | 5 | 6 | ## Overview 7 | 8 | Automate your local IIS Development Environment with this script, its designed to build a development IIS site for your project. 9 | 10 | This script does **NOT** support 32-Bit Windows. 11 | 12 | ## New features for 1.3.0 13 | 14 | As of 1.3.0 you can now provide a path to the script using the **-Path** argument. 15 | 16 | Since this is a minor update this means the new version is still backwards compatible with projects that have been using previous versions of IIS Builder. 17 | 18 | If you are finding issues with this update you can download the previous versions from the [tags](https://github.com/mattou07/iis-builder/tags) page. 19 | 20 | 21 | 22 | 23 | ## Quick Start 24 | 25 | The easiest way to download IIS builder is to just use the two Powershell commands below. 26 | 27 | As of v1.3.0 this command doesn't need to be ran within the web root as we can now supply a **-Path** argument. However feel free to download into the web root of your project if that is preferred. 28 | 29 | ```powershell 30 | (new-object System.Net.WebClient).DownloadFile('https://raw.githubusercontent.com/mattou07/iis-builder/master/IIS-Builder.ps1','IIS-Builder.ps1') 31 | ``` 32 | The next command which downloads the JSON file **MUST** be ran inside your web root and committed into source control. This will allow others to share the same domains and enforce your best practices for your local domains on a project. 33 | ```powershell 34 | (new-object System.Net.WebClient).DownloadFile('https://raw.githubusercontent.com/mattou07/iis-builder/master/iis-config.json','iis-config.json') 35 | ``` 36 | The two commands will use **System.Net.WebClient** to download the needed files. Similar to wget in linux. 37 | 38 | Here is a gif demonstrating the process: 39 | 40 | ![Gif demonstrating how to download the script and JSON](https://i.imgur.com/9FCteS0.gif) 41 | 42 | We now need to configure the domains we will be using for our IIS Site. Open the JSON file and edit the contents to set the **Site name**, **App Pool name** and **bindings**. You can leave the dot net version as the default value. 43 | 44 | ```json 45 | { 46 | "IIS-Site-Name": "test-site", 47 | "App-Pool-Name": "test-site", 48 | "IIS-App-Pool-Dot-Net-Version": "v4.0", 49 | "bindings": ["test-site.localtest.me"] 50 | } 51 | ``` 52 | 53 | - IIS-Site-Name should be the name of the IIS site **my-awesome-site** 54 | - App-Pool-Name is the name of the App Pool for the site, ideally this should be the same as the IIS Site Name 55 | - Bindings is a comma separated list, you can specify **multiple bindings** and the script will add both a **HTTP** and **HTTPS** for each binding to your IIS site 56 | - **HTTPS** is provided by a self signed certificate 57 | 58 | Then run the script by right clicking the **IIS-Builder.ps1** file and clicking **Run with Powershell** or typing **.\IIS-Builder.ps1** inside powershell if its open in your web root. 59 | 60 | No need to open an eleveted powershell session it will open its own elevated session. 61 | 62 | ### As of update v1.3.0 63 | 64 | You can now supply a -**path** argument into the script instead of explicitly storing the script within your web root. 65 | 66 | C:\dev\github\iis-builder\IIS-Builder.ps1 **-Path "D:\dev\my-website\web-root"** 67 | 68 | Below I setup a local IIS Site for my blog, the script and the web root are not in the same folder anymore. 69 | 70 | ![Supplying a -Path argument to IIS Builder](https://i.imgur.com/ZOzNtnK.gif) 71 | 72 | ### Running IIS Builder as an external tool in Visual Studio with v1.3.0 73 | 74 | We can take this further and streamline the process with **Visual Studio's External tools** feature. Below I run IIS Builder within Visual Studio without needing to look for the Powershell script on my machine or open the web root folder. Simply **click** on the web project **containing the iis-config.json file** and then run the external tool (**YOU MUST SELECT THE WEB PROJECT BEFORE RUNNING**) 75 | 76 | Below you can see the process to run an external tool. Simply click it from your menu and then start hacking away in seconds: 77 | 78 | ![Running IIS Builder as an external tool](https://i.imgur.com/nadG9Dp.gif) 79 | 80 | ### Setting up the external tool 81 | 82 | In Visual Studio go to **Tools > External Tools...** 83 | 84 | ![Location of External tools in Visual Studio](https://i.imgur.com/7evwBQ5.png) 85 | 86 | Then fill out the details: 87 | 88 | ![Image showing filled out details for IIS Builder as an External Tool](https://i.imgur.com/aDRRgMa.png) 89 | 90 | 91 | 92 | **Title** can be whatever you wish. I named mine IIS Builder 93 | 94 | **Command** should be: **%SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe** or wherever your 64 bit version of Powershell lives. This should work on all 64 bit machines. 95 | 96 | **Arguments** should be the location of the IIS Builder script: **C:\location\of\script\IIS-Builder.ps1 -Path $(ProjectDir)**. Ensure you add the **-Path $(ProjectDir)** argument on the end. This allows you to tell IIS Builder where your web project lives. Ensure you provide the correct path for where IIS Builder lives. 97 | 98 | Nothing needs to be supplied into Initial directory. 99 | 100 | Ensure **Use Output window** is **enabled** this will allow you to see the output of IIS Builder within Visual Studio. 101 | 102 | To prevent IIS Builder popping up an Elevated Powershell Window, open Visual Studio as Admin. However this is not necessary. 103 | 104 | ### Setup a Powershell Alias 105 | 106 | If you love using the terminal you could setup a Powershell Alias. Where all you need to do is navigate to your folder via Powershell and type **IISBuilder** or whatever alias/shortcut you prefer. This then runs IIS-Builder.ps1 in your current working directory: 107 | 108 | ![Running IISBuilder as a Powershell Alias](https://i.imgur.com/jN0SiDp.png) 109 | 110 | To set this up you need to identify where your Powershell user profile lives, by typing: `echo $profile` 111 | 112 | This will reveal where Powershell thinks the User profile lives. Usually its **~Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1**. Adding any code within this file will be executed on each Powershell session for your User. When you set an Alias its forgotten when you close the Powershell session. By setting our alias in our profile, Powershell will create the alias each time we start a Powershell Session 113 | 114 | Navigate to your profile location and open the **Microsoft.PowerShell_profile.ps1** file. If it doesn't exist **create** it. Then add the following code to setup the alias: 115 | 116 | ```powershell 117 | Function IISBuilderFunc {C:\your-path-to-iisbuilder\IIS-Builder.ps1 -Path $(Get-Location)} 118 | 119 | Set-Alias -Name IISBuilder -Value IISBuilderFunc 120 | ``` 121 | 122 | Make sure to provide the correct path to where the IIS-Builder.ps1 file lives. Feel free to change the Alias name to whatever you wish or even rename the function. These two lines tell Powershell to create an Alias called IISBuilder that triggers the function IISBuilderFunc above. The function just calls the IISBuilder script file and passes in the current location of the terminal as the **-Path** parameter allowing you to run the alias anywhere. 123 | 124 | Save the file and re-open a Powershell Terminal, then navigate to your web root and type IISBuilder. 125 | 126 | ## Additional tips 127 | 128 | ### Attaching script to Visual Studio Post build event 129 | 130 | This script can be setup as a post build event in Visual Studio, so every time you build the project the script will run. 131 | 132 | To set this up right click on the web project and click properties. 133 | 134 | ![Web Project Properties](https://i.imgur.com/wzzS8tE.png) 135 | 136 | Head to the Build events section and in the Post-build event command line add this: 137 | 138 | `%SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Unrestricted -file $(ProjectDir)\IIS-Builder.ps1` 139 | 140 | ![Build Events](https://i.imgur.com/PUGiiP7.png) 141 | 142 | #### What this command means 143 | 144 | `%SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe` 145 | 146 | We fetch the location of your Windows Powershell exe. Some users may not have it in the same place so using: **%SystemRoot%\sysnative** should allow it to work on most windows machines. 147 | 148 | `-ExecutionPolicy Unrestricted` 149 | 150 | Since this script is being downloaded from the internet powershell will automatically block it. Setting the Execution Policy to Unrestricted will allow you run the script without having to create your own Powershell file and copy the code and save. 151 | 152 | `-file $(ProjectDir)\IIS-Builder.ps1` 153 | 154 | We then specify that the powershell script is in the same directory as the web project being built using $(ProjectDir). 155 | 156 | ### Would you like the browser to open the website automatically after running the script? 157 | 158 | Uncomment line 201. This is commented out by default as it can get annoying. 159 | 160 | ## What the script does 161 | 162 | First the script needs admin privileges so it will attempt to start an elevated powershell process. It then pulls in the properties defined in the json for the site that needs to be built. Using those properties it checks to see if an IIS site already exists. If a site already exists with the name, it will be removed. App pools will not be removed if they already exist. 163 | 164 | Next the script will create an IIS site and App pool using the details defined in the json. We then need to setup the bindings. The script allows you to define multiple urls in an array in the json. First the script adds the HTTP bindings as that is straightforward to do. 165 | 166 | Now we need to setup the HTTPS bindings, first we create a New-SelfSignedCertificate for each binding and set the Dns name to be the one of the bindings we have defined in the json. Now that we have a certificate created we can create the binding for the IIS site. 167 | 168 | The next part will take our newly created certificates and assign it to our bindings. For the certificates to be trusted by the browser we add it to the Root directory of the local machine. 169 | 170 | We then need to setup the correct file permissions on the folder. This was primarily setup for Umbraco you may want to enforce stricter permissions or assign other entities to meet your requirements. 171 | 172 | We give the following entities Modify permissions on the web root: 173 | 174 | - IUSR 175 | - IIS_IUSRS 176 | - App Pool Identity (As defined in the iis-config.json) 177 | 178 | We then loop through the bindings and if they don't contain .localtest.me they are not added to the hosts file. Domains ending with .localtest.me automatically point to 127.0.0.1 therefore its not needed in the hosts file. 179 | 180 | Please raise an issue if something is not working as expected! 181 | 182 | Made with :heart: at [Moriyama](https://www.moriyama.co.uk/) 183 | 184 | [My devops focused blog](https://mu7.dev) 185 | -------------------------------------------------------------------------------- /download-iisbuilder.ps1: -------------------------------------------------------------------------------- 1 | (new-object System.Net.WebClient).DownloadFile('https://raw.githubusercontent.com/mattou07/iis-builder/master/IIS-Builder.ps1','IIS-Builder.ps1') 2 | (new-object System.Net.WebClient).DownloadFile('https://raw.githubusercontent.com/mattou07/iis-builder/master/iis-config.json','iis-config.json') 3 | -------------------------------------------------------------------------------- /iis-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "IIS-Site-Name": "test-site", 3 | "App-Pool-Name": "test-site", 4 | "IIS-App-Pool-Dot-Net-Version": "v4.0", 5 | "bindings": ["test-site.localtest.me"] 6 | } --------------------------------------------------------------------------------