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

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.