Managing SSL Bindings with PowerShell

I recently wrote a blog post for the Hey, Scripting Guy! blog related to Updating SSL Bindings. This is a process that is time consuming and tedious when working with server farms. By automating this process with PowerShell, the manual importing of the certificates and updating the bindings can be done programmatically. Until you upgrade your IIS Servers to IIS 8 and can use the Centralized Certificate Store, this is the next best thing. Jump on over and take a look.

Terri is a Microsoft MVP (ASP .NET/IIS), an MCSA: Windows Server 2012, and IT Infrastructure Specialist at OrcsWeb, a Sherweb Company that offers managed hosting solutions

IIS Manager and Script generation

There are always questions on the forums related to scripting settings related to IIS configuration files. In IIS7 and above, there is a nifty feature called the Configuration Editor.  For reference, this blog post is written and pertains to IIS 8.5. This is important because some settings mentioned in this post are not available on any versions prior to IIS 8.5.

This feature allows you to ‘look’ at your configuration files and even update them via the GUI interface. This can be very handy since you are not manually updating one of the configuration files for either the entire IIS Server or one of your websites or applications. Since the format of the file requires specific items, using a tested script or GUI interface can aid in ensuring that you do not accidentally forget a “ or  < in the file which renders it unusable by IIS.

You access this feature by opening Internet Information Services (IIS) Manager. There is a Configuration Editor feature at the server level, the web site level, and for any folder, virtual directory or application within a website.

image.png

The location of the feature determines what configuration file will be modified by any changes made. Changes made at the server level will impact the primary configuration documents for the IIS installation. For example, if you would like to view the default settings for the application pools, you would access the Server name and double click on the Configuration Editor icon to open the feature. As you can see from the screenshot below, I have selected the section related to applicationPools. At the bottom of the screenshot, the active configuration file is listed as applicationhost.config.

image_thumb.png

The screenshot below shows the default settings for application pools as shown in both the configuration editor and the applicationhost.config file.

image.png

Making a change in the Configuration Editor updates the applicationhost.config file once you select Apply.

Let’s say for instance, you decide you would like to modify the default settings for your application pools but would like to script it so you can implement it at a later time or across multiple systems. Rather than the defaults for idleTimeout and idleTimeoutAction, you want to implement a longer timeout value and rather than terminating the process, you want to suspend it. The idleTimeoutAction item is only relative to IIS 8.5. For prior versions, you can change the idleTimeout following this same process as well. You are going to set the idleTimeout to 60 minutes rather than the default of 20. You are also going to change the idleTimeoutAction to Suspend rather than Terminate. This comes in handy when you have a website that takes a while to load but only has certain periods of time where it is active. By suspending the process, you do not have to wait for the initial spin-up which occurs after a worker process has been terminated. Any changes that are made in the editor are shown in BOLD in the GUI.

You will now notice that there are multiple actions available (Apply, Cancel, Generate Script). This is where the cool stuff happens. You are going to click Generate Script since you really want the PowerShell commands needed to make this change rather than applying the changes now. This will open a Script Dialog box that provides the auto-generated script in multiple languages including C#, AppCmd, and PowerShell.

image_thumb.png

You can now copy the script and integrate it into initial build scripts for creating a new IIS server or even as a stand alone script to simply update the settings that you have chosen.

The generated PowerShell script contains this code:

Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.applicationHost/applicationPools/applicationPoolDefaults/processModel" -name "idleTimeout" -value "01:00:00"

Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.applicationHost/applicationPools/applicationPoolDefaults/processModel" -name "idleTimeoutAction" -value "Suspend"

You will then open a PowerShell command window ran as Administrator. Paste the code into the window and run it. Voila, your updates were inserted into the applicationhost.config file and the default settings for new application pools are now configured the way that you want.

There are many settings that can be scripted following these same steps for websites. The Configuration Editor feature at the website level accesses the web.config file for the specified site or application. For example, if you want to change the way that customErrors are handled for your website, you can access the customErrors section of the web.config via the Configuration Editor and change the mode from the default RemoteOnly to On or Off. Once again, you can either apply the setting manually or Generate Script for your script repository or for future use.

I hope you find this blog post helpful, especially if you are just learning PowerShell and working with IIS.

Terri is a Microsoft MVP (ASP .NET/IIS), an MCSA: Windows Server 2012, and a Cloud Administrator at OrcsWeb, a hosted server company providing managed hosting solutions

Why Upgrade to PowerShell 4.0

If you have browsed my blog site, you see that I occasionally like to do a little PS scripting. It is fun to challenge yourself to learn other things. Over on the Hey, Scripting Guy! Blog, they are doing a ‘Why should I upgrade to PowerShell 4.0? blog series. Today, my guest post is the featured post in the series. Hop on over and check it out.

Terri is a Microsoft MVP (ASP .NET/IIS), an MCSA: Windows Server 2012, and a Cloud Administrator at OrcsWeb, a hosted server company providing managed hosting solutions

PowerShell Studio by Sapien

I am an administrator that is, to be quite honest, infatuated with PowerShell. I have done some minor coding in my past; mostly using Perl and XML for repetitive administrative functions. With the introduction of PowerShell v2, I started playing around with creating simple scripts to do some of my daily tasks. I then attended The PowerShell Saturday event in Charlotte, NC last year and was able to see some of the things that PowerShell v3 can do. Well, let’s just say the infatuation became an obsession. I still am not a ‘coder’ but have written and posted a few blogs which included scripts that I found very helpful.

I was previously using PowerGUI but when I upgraded to PowerShell v3 I started having problems and did not feel like trying to figure it out since the PowerShell ISE that is included with version 3 is quite good. I was quickly able to get the hang of using the ISE to step through my scripts for debugging and logic and was quite proud of myself. I remembered seeing that Sapien was one of the sponsors of PowerShell Saturday so I decided to take a look at what they offered. I found PowerShell Studio 2012 and downloaded a trial version. I then contacted the company since Sapien is one of many companies that have partnered with Microsoft to offer products to MVPs.

Being an administrator, it took me a little while to get used to the development interface. It reminds me of  the layout that Visual Studio uses. I had been fighting with debugging a PowerShell script that requires version 2. I had tried both PowerGUI and PowerShell ISE to help debug the application so that it would run on my laptop that has version 3.0 installed. Using the –version 2 switch did not resolve the issue. Once the form was created, the application would loop until it crashed. Enter PowerShell Studio 2012 and the powerful Debug File option. I was able to use this functionality to see that specific line of code that was causing the problem. I remarked out that single line of code, and Viola my application works again. This would not be a big deal, but the guy that wrote the application does not work with me anymore so I did not want to reach out to him to ‘fix’ it for me.

Here sits a happy MVP that is loving using PowerShell Studio 2012 and learning more and more each day. Take a look at what they have to offer. I am sure you will be as happy with the product as I am.

Terri is a Microsoft MVP (ASP .NET/IIS), an MCSA: Windows Server 2012, and a Support Specialist at OrcsWeb, a hosted server company providing managed hosting solutions

Using PowerShell and WMI to change Service settings

Recently we had a situation where a service would not start on initial boot up. The service could be started manually after the server had started so it was not a problem with the service or the account that it was running under. I had already tried setting the Startup Type to be Automatic (Delayed Start) but this did not allow the service to start after a reboot. I then checked the Recovery tab for the service and saw that all options were set to Take No Action. Since one of the recovery options is Restart the Service and another is Restart the Server, I decided to look to see if there was a way to programmatically set this to remove human error from the equation. Automation is always the best way to go to ensure that the same process is repeated each time.

I want to do this in PowerShell so the snippet can be added to our build scripts. This will work for any service but I am specifically trying to set the Recovery options for the SQL Agent. I found the Get-Service cmdlet within PowerShell but was not able to set access/set/update this value within the service. I then began looking at WMI options and came across sc.exe.  I found this great blog post that addressed the exact problem I was working on. Check it out for all of the information related to the arguments in my code snippet.

Here is the snippet that I used to update this setting.

$services = Get-WMIObject win32_service  | ? {$_.name -eq “SQLSERVERAGENT” -and $_.startmode -eq “Auto”}
foreach ($service in $services){sc.exe failure $service.name reset= 86400 actions= restart/5000}

I hope this helps you if you run across the need to perform this as well.

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Terri is a Microsoft MVP (ASP .NET/IIS), an MCSA: Windows Server 2012, and a Support Specialist at OrcsWeb, a hosted server company providing managed hosting solutions

Scripting Games 2013

So I decided to challenge myself and joined up for the Scripting Games 2013 edition. Last week I entered my first submission. Being that I am a novice at PowerShell, I was quite nervous about that first submission. All scripts are submitted anonymously, voted on by other participants/judges and a score (with comments or suggestions) is returned on your script. The scripts are graded on a scale of 1-5. I like the fact that comments on scoring are recommended for all values and required for 1s and 2s. This requires that the person scoring the script provide some feedback if a low score is given to support the grade and allows for suggestions for all other scores. It was nice to read the comments, for both good and bad scores, to see ways that I can improve my scripting skills.

In re-reading this before posting, I realized that it may sound like I totally bombed my first submission. I received a 3.28 score which solidifies my knowledge that I have lots to learn but also gives me hope since it wasn’t a 1.

Terri is a Support Specialist at OrcsWeb, a hosted server company providing managed hosting solutions.

SSL certificates for development sites on IIS7/7.5

On the topic of self-signed certificates, I wrote another blog post about SAN certificates that is over on my work blog. Jump over there and check it out. The post explains how to create a self-signed SAN certificate and then assign that certificate to multiple host header sites in IIS.

Terri is a Support Specialist at OrcsWeb, a hosted server company providing managed hosting solutions.

Self-Signed SSL certificates and IIS development site configuration using host header configurations for IIS7/7.5

One of our clients recently requested the ability to configure SSL for multiple development sites on a server with a single IP address. They had one certificate that was issued by an online CA for their production site and wanted self-signed certificates assigned to multiple development sites for testing purposes. In this walkthrough, I will provide information for creating a wildcard certificate that can be used for testing with any site in the same domain. Here is a blog, written by Scott Forsyth, which provides details about the localtest.me domain which I will use in this walkthrough. For the certificate creation, PowerShell 3.0 is required. PowerShell 3.0 is part of the Windows Management Framework 3.0 package which can be downloaded here. If you are not able to install this on your server, you can create the certificate on a different machine and export it to a pfx file for importing onto your server.

Here is a blog post that I wrote previously that can be used to create multiple localtest.me websites using PowerShell if you would like to experiment with this configuration. Once you have created your websites, you are ready to proceed through this post.

The cmdlet that we will use to create the self-signed wildcard is New-SelfSignedCertificate.

New-SelfSignedCertificate -DnsName www.fabrikam.com, www.contoso.com -CertStoreLocation cert:LocalMachineMy

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

The exact command that I ran for this walkthrough is ‘New-SelfSignedCertificate -DnsName *.localtest.me -CertStoreLocation cert:LocalMachineMy’. This created a self-signed certificate in my local machine store.

image

Since this certificate is created in the Personal store of the Local Machine, you can export and import it into the Trusted Root Certificate store so that it will be trusted by IIS. If you are planning to test these sites from a different machine than hosts the website, you can also import the certificate into the Trusted Root Certificate store on your workstation and you will not receive any certificate warning errors when testing.

You are now ready to open IIS Manager and assign your newly created certificate to your websites. In order to enable the GUI host header field within the https bindings, the friendly name of your certificate has to be *.domain.com. Since we created the certificate as a wildcard certificate, we do not have to make any modifications to the friendly name.

Open IIS Manager, select the website that you want to add the SSL certificate to, and open Bindings from the Action pane.

image

Click Add and change the Type to https. You will notice that the Host name: field is greyed out and cannot be edited.

image

Once you select your certificate (*.localtest.me), this field will be editable, as seen below.

image

Enter your host header name in the Host name: box and click OK. You can also add this information using appcmd with the following syntax (replace name with your website name):

appcmd set site /site.name:”name” /+bindings.[protocol=’https’,bindinginformation=’*.443:name]

If you used the localtest.me domain for this walkthrough, you are now ready to test your site without having to create DNS or local host file entries.

You are now on your way to happy development testing without pesky SSL warnings interrupting the flow.

Terri is a Support Specialist at OrcsWeb, a hosted server company providing managed hosting solutions.

Creating AD users in bulk with PowerShell

The other day I was lurking on the PowerShell forum and found a question about importing an Excel spreadsheet to use for AD user account creation. It looked like a quick fix so I decided to give it a go. I am new to PowerShell so real world ideas like this one provide a great way for me to learn while also helping out in the community. Needless to say, I found out that it wasn’t the quick fix that I thought it would be.

I decided to use a CSV file as the source rather than Excel since I was working on a server that did not have Excel installed and pretty quickly got the script to work using the ActiveDirectory module provided by Microsoft. When I went to verify the results, however, all of the programmatically created users were disabled. What good is a ‘working’ script if the output doesn’t provide the required functionality. All of the accounts were created, but, I was unable to even manually enable the account due to an error that the password did not meet my domains complexity requirements. I verified that the password used in the script, was actually a valid password. I could reset the user’s password to the one in the csv file and enable the AD account without any errors. This pointed to an issue with the way I was setting the password in the script. I googled the issue and low and behold there was a blog written about this exact issue.

After integrating the code snippet from the above blog post, I was able to successfully create enabled and functional AD users. Here is the script and a sample CSV file that can be used as a starting point. Since there are so many fields that can be set for an AD user, I created a very small sample but this can be expanded to include any attributes that are required by your organization.

   1: # CreateADUsers.ps1

   2: Set-ExecutionPolicy Unrestricted

   3: Import-Module ActiveDirectory

   4: $csvpath = "c:scriptsNewusers.csv"

   5: $date = Get-Date

   6: $logfile = "c:scriptscreate_AD_users.log"

   7: $i=0

   8:

   9: # Specify parent container for all new users.

  10: $OU =  "OU=UsersOU,DC=domain,DC=com"

  11:

  12: Import-Csv $csvpath |  ForEach-Object {

  13: $sam = $_.Username

  14:     Try   { $exists = Get-ADUser -LDAPFilter "(sAMAccountName=$sam)" }

  15:     Catch { }

  16:     If(!$exists)

  17:     {

  18:     $Password = $_.Password

  19: New-ADUser $sam -GivenName $_.GivenName -Initials $_.Initials -Surname $_.SN -DisplayName $_.DisplayName -EmailAddress $_.EmailAddress  -passthru |

  20: ForEach-Object {

  21: $_ | Set-ADAccountPassword -Reset -NewPassword (ConvertTo-SecureString -AsPlainText $Password -Force)

  22: $_ | Enable-ADAccount }

  23:

  24: # Set an ExtensionAttribute

  25:       $dn  = (Get-ADUser $sam).DistinguishedName

  26:       $ext = [ADSI]"LDAP://$dn"

  27:       $ext.SetInfo()

  28:       Move-ADObject -Identity $dn -TargetPath $OU

  29:

  30:       $newdn = (Get-ADUser $sam).DistinguishedName

  31:       Rename-ADObject -Identity $newdn -NewName $_.DisplayName

  32:

  33:       $output  = $i.ToString() + ") Name: " + $_.UserName + "  sAMAccountName: "

  34:       $output += $sam + "  Pass: " + $_.Password

  35:       $output | Out-File $logfile -append

  36:      }

  37:      Else

  38:      {

  39:      "SKIPPED - ALREADY EXISTS OR ERROR: " + $_.CN | Out-File $logfile -append

  40: }

  41: "----------------------------------------" + "`n" | Out-File $logfile -append

  42: }

This is the sample CSV (newusers.csv) data that I used in testing the script.

GivenName,Initials,SN,DisplayName,EmailAddress,UserName,Password
“Susan”,”SU”,”User”,”Susan User”,”susan@tdvm.me”,”susan”,”~RP:hoV.ZmE4tS6Z”
“James”,”JU”,”User”,”James User”,”james@tdvm.me”,”james”,”~RP:hoV.ZmE4tS6Z”
“Ronnie”,”RU”,”User”,”Ronnie User”,”ronnie@tdvm.me”,”ronnie”,”~RP:hoV.ZmE4tS6Z”

I hope you find this script useful and it saves you time when needing to create bulk AD users in your production or test environments.

Terri is a Support Specialist at OrcsWeb, a hosted server company providing managed hosting solutions.