Practical App

5-Minute How-To: Quick and Easy Web Servers with Windows PowerShell

A step-by-step guide to help you deploy IIS and default Web sites using PowerShell in less than five minutes!

Think about how many times you install IIS. Not much? Really? Consider platforms such as Exchange and SharePoint that need IIS as prerequisite software, Web farm deployments, testing environments and development environments. You might spend more time installing IIS than you think.

Add to this the need for disaster recovery automation. Can you bring your Web farm back online in minutes? Installing and configuring IIS along with your Web sites is a simple task. It's a long and boring process if you have a lot of servers.

No one wants to spend weekends setting up servers. You want to manage your Web farm, Web sites and all that Web "stuff" Monday through Friday, nine to five. You want to take every opportunity to expedite and automate the tasks in your job.

This step-by-step guide will help you deploy IIS and default Web sites to a bunch of servers, all at once, in about four minutes. You can't do this with the GUI Server Manager tool and the GUI IIS Manager. In fact, the GUI is part of the problem. How can you do these magical things? With Windows PowerShell. (Note: This applies to IIS 7.5 and IIS 8.)

PowerShell Remoting
Before we get started, do you have Windows PowerShell Remoting enabled on your servers? If not, you should. That's how this plan is going to work. Before I get to the quick and easy part of deploying, let's walk through how to get Windows PowerShell Remoting enabled in case you haven't done so already.

There are two methods to do this. If you're going to try this in a test environment, then the first method might be quicker. There are two Windows PowerShell capabilities you need to enable: Windows PowerShell Remoting and script execution. The first method requires that you visit each server you want to manage. You can use Remote Desktop Protocol (RDP) or sneaker-net, and run two commands:

  1. Open a Windows PowerShell console with administrative privileges and use the Enable-PSRemoting cmdlet to enable Windows PowerShell Remoting on each server:
    PS> Enable-PSRemoting -Force
  2. You'll want to use some of the additional modules of cmdlets stored on these servers. To use those later, you'll need to be able to run scripts -- which, by default, Windows PowerShell does not permit. So let's change that:
    PS> Set-ExecutionPolicy RemoteSigned –Force
    

At this point, you're ready to deploy and manage your IIS servers. If you have hundreds of servers to manage, you'll want to issue a Group Policy to make these changes. Running around to all those servers is a ridiculous waste of time, so here are the steps to enable Windows PowerShell Remoting with a Group Policy Object (GPO):

  1. Enable "Allow automatic configuration of listeners," and set IPv4 and IPv6 to "*". You'll find the key at: Computer Configuration\Policies\Administrative templates\Windows Components\Windows Remote Management\WinRM Server.
  2. Enable script execution under "Turn on Script Execution" and set the policy setting to "Allow only signed scripts" or "Allow local scripts and remote signed scripts." You'll find the key at: Computer Configuration\Policies\Administrative templates\Windows Components\Windows PowerShell.
  3. Set the Windows Remote Management (WinRM) service to start automatically, at this key: Computer Configuration\Policies\Windows Settings\Security Settings\System Services.

If you have Windows Firewall running on those computers, you'll need an Inbound Rule because WinRM listens on port 5985. You'll find the key at: Computer Configuration\Policies\Windows Settings\Windows Firewall with Advanced Security.

Deploy Those Web Servers
Now the fun begins. This is fairly straightforward, as it only takes a few Windows PowerShell one-liners to make the magic happen.

1. Store a list of all the server names that are going to be part of the deployment to a variable. You can create a list in notepad if you wish, and then use Windows PowerShell to read that list:

PS> $servers= get-content c:\servers.txt

This is a little sloppy, especially when dealing with a large server list. It's better to make Windows PowerShell do all the work. Did you know that Active Directory cmdlets can get you a list of computer names? To use the Active Directory cmdlets, you'll need the Remote Server Administration Tools (RSAT) for Active Directory installed. With the RSAT installed, the first task is to import the module for the Active Directory cmdlets:

PS> Import-Module ActiveDirectory 

Once imported, you can use the Get-ADComputer cmdlet to grab the computer names of your choice. In this example, the computers to which we'll deploy IIS all begin with the name "Web." Filter the Get-ADComputer cmdlet to find only those computers that begin with the name "Web," and pipe to Select-Object to grab only the name of the computer:

PS> $servers= Get-ADComputer -filter 'name -like "web*"' 
| Select-Object -ExpandProperty name 

2. Now it's time to use the power of Windows PowerShell Remoting to make easy lifting of what would normally be a long and boring process. Let's deploy IIS. First, we'll build a session to all those servers we collected:

PS> $session=New-PSSession -ComputerName $servers

3. The next step is to import the Server Manager module on the remote computers. This module has the cmdlets that will install and remove server Roles and Features. We're using the Invoke-Command cmdlet with a parameter for the session we created previously. The interesting thing about this is that all servers will immediately receive any instructions sent inside the script block { }:

PS> Invoke-Command -Session $session {Import-module 
ServerManager}

Let's talk about installing IIS for a moment before I plunge into the commands. IIS has a default installation that only permits static Web pages. This is great for security reasons, but most of you will need some of the additional components for your own application needs.

When you're using the GUI for the install, the components are all listed and you can simply check the box. With Windows PowerShell, you have to tell the remote computers specifically what components you'd like. If you're sitting at any Windows Server 2008 R2 or Windows Server 8 computer, for example, you can use the Get-WindowsFeature to list all the components available for IIS (note that you must import the ServerManager module first):

PS> Get-WindowFeature *web*

Once you know the names of the components, you can use the Add-WindowsFeature to install them. Start with the Web-Server and then add each component, separated by a comma:

PS> Add-WindowsFeature Web-Server, ASP

You can install all the IIS components without typing a long string of them. Keep in mind that installing everything isn't a good idea for security reasons, but the Add-WindowsFeature cmdlet has a parameter that will help:

PS> Add-WindowsFeature Web-Server 
-IncludeAllSubFeature

Now back to the remote IIS deployment. You want the default install and the additional components for ASP and ASP.NET. Once again, you'll use the Invoke-Command cmdlet. Once you run this command, all servers will install IIS:

PS> Invoke-command -Session $session 
{Add-WindowsFeature web-server,web-asp,web-asp-net}

4. For testing purposes, deploy a set of Web pages to the new Web servers. Use a default.htm and a testpage.asp file. Mapping drives to the servers and copying the files to the default Web site will take a long time. Instead, use Windows PowerShell and the server list to do the copying.

In this example, the Web files are located in c:\files. Copy them with the Copy-Item cmdlet to a destination that's a UNC path. The UNC needs the server name; the server list ($Servers) was passed to the Foreach-Object cmdlet. Foreach will iterate through each server name in $Server. To fix the UNC path so that you don't have to type in the server names, use the Windows PowerShell special variable "$_". This variable holds the current server name from $Server:

PS> $servers | foreach{copy-item -Path c:\files\*.* 
-Destination "\\$_\c$\inetpub\wwwroot"}

You just deployed IIS and a default Web site to a bunch of servers in about four minutes.

About the Author

Jason is a 25-year IT veteran and author at Pluralsight. He’s an avid supporter of the PowerShell community as board member and CFO of PowerShell.Org and a Windows PowerShell MVP. He is the author of “Learn Windows IIS in a Month of Lunches” and contributing author to "PowerShell Deep Dives", along with a columnist for TechNet and TechTarget Magazine and other industry publications.

Featured

comments powered by Disqus

Subscribe on YouTube