Managing IIS with PowerShell: Creating New Sites

We’re back with our look at enabling IIS remote management using PowerShell! Previously in part one I showed you how to create an application pool. Today I’ll show you how you can speed up the site creation on IIS by using PowerShell to create a website and configure the bindings. By the end, you should be ready to either create a script to create your website or just create the website interactively through PowerShell.

Managing IIS with PowerShell: Create a Website

When I create a website, I have found that there are a lot of steps that I have to repeat for each site. I’ve already shown you how to create an application pool running as an active directory account, and now that the application pool is created, I will create a website that runs in the application pool. I also need to create a folder for the website files and I’ll assign file permissions to the user account that runs the application pool. I usually have a site that runs behind a proxy server or load balancer, so I have found that having the site be bound to a secondary hostname that is not routed through the proxy server is great for troubleshooting any issues with the routing rules.

So here are the list of items to configure:

  • Find the application pool identity
  • Create a folder for the website
  • Assign read permissions for the app pool ID to the site folder
  • Create the website in IIS
  • Set an alternate binding for the website

Let’s get started!

Setup PowerShell to Create IIS Websites

Using an elevated PowerShell session, load the IIS commands:

Import-Module webadministration

Managing IIS with PowerShell: Import-ModuleWebAdministration

Get the Application Pool Identity

Now that the webadministration module is loaded, a PSDrive is available that gives access to several IIS components, including the application pools. We can now browse the application pools just like they are files in a folder.

Set-Location IIS:\AppPools\

From this location, you can use Get-ChildItem to list the application pools available.


If you see the application pool that you’re going to use, save it as a variable. Note that we’ll use the Get-Item cmdlet so that we get the actual item itself and not Get-ChildItem.

​ $AppPool = Get-Item .\WWW_AppPool

The username that the application pool runs as is stored in the processmodel property collection. You can access it with “$_.processmodel.username” from a loop or directly in the variable itself. You can easily save the username as another variable.

​ $AppPoolID = $AppPool.processmodel.userName

Managing IIS with PowerShell: GetAppPool-ID

Create a Folder for the Website and Set Permissions

You’ve got some important pieces of the puzzle now that you’ve gotten both the app pool and the user account. We’ll need the app pool later when we’re creating the website. But now we’re going to use the application pool ID to set some permissions on a folder. It is very common that the app pool identity requires read permissions to the web folder. Sometimes additional permissions are required so that the app pool id can write changes to some or all of the files in the folder. Tweak the permissions here to suit your needs.

Create the folder with PowerShell

We’ll use the New-Item command to create a folder. I usually have a specific place that all websites are created, and it doesn’t have to be in the default folder location for sites. I’ll create one on a data drive, in a folder called “websites.”

$folder = New-Item  D:\websites\WWW_root  –ItemType directory

The folder is created, now we’re going to set the permissions.

Set read permissions on the folder

Permissions on a folder are all stored in an access control list, or ACL. The ACL is made up of individual rules, called access control entries, or ACEs. To add permissions to a folder, we’ll go through this process.

  • Get a copy of the existing access control list for the folder.
  • Create a new rule granting read permissions to our application pool identity account.
  • Add the new rule to the copied ACL.
  • Replace the old ACL on the folder with the new ACL that we just modified.

The getting and setting of the ACLs is done with PowerShell cmdlets, and the rule is treated like a .NET object of the type [security.fileaccess.accesscontrolentry]

$Acl = Get-ACL $folder

Managing IIS with PowerShell: CreateNewFolder

Create the ACE for the ACL

An access control entry is made of several parts:

  • An Identity which says who the rule applies to
  • A right that tells what we’re defining
  • A permission that tells whether we’re allowing or denying that right
  • An inheritance flag to tell it what it propagates to
$Rights = [System.Security.AccessControl.FileSystemRights]'Read' $Inheritance = [System.Security.AccessControl.InheritanceFlags]'ContainerInherit, ObjectInherit' $Propagation = [System.Security.AccessControl.PropagationFlags]'None' $Access = [System.Security.AccessControl.AccessControlType]'Allow'

$Rule = New-Object System.Security.AccessControl($AppPoolID, $Write, $Inheri, $Propag, $Access)

You now have the ACL stored in the $ACL variable, and the new rule stored in the $Rule variable. Add the rule to the ACL using a method of the ACL object.


The ACL copy now has the rule applied, but remember it’s only a copy of the ACL that’s on the folder. We’ll now copy the ACL back to the folder using the Set-ACL cmdlet.

$Acl | Set-ACL –Path $folder

The folder is created, and ready for you or the site developer to copy over the site files to it.

Create the Site in IIS with PowerShell

We’ll use the New-Website command to actually create the IIS site. Since we’ve already saved the app pool and the physical path folder to variables, we only need to set some basic settings on our site and we’ll be ready to go. So that we can easily administer this site afterwards, we’ll save the output to a variable.

$Website = New-Website -Name "WWW_Root" -HostHeader "www.mydomain.local" -Port 80 -PhysicalPath $folder  -ApplicationPool $AppPool

Managing IIS with PowerShell

Add an Alternate Binding for the Website with PowerShell

We’re almost done! All we have left to do is add an alternate binding to your website.

To complete this we use the New-WebBinding cmdlet.

$Website | New-WebBinding –Name “MyDomain_Bypass” –HostHeader “www.mydomain.proxybypass.local” –Port 80 –Protocol “http”

With this last step completed, we’re ready for the developer to drop their files into place, and you’ve gotten your site ready completely outside of the INETMGR tool.