Create VSTS Service Principal

Working with one of our CSP customer’s and they needed to connect their Visual Studio Team Services account to their CSP Azure account. If you have a regular Pay-As-You-Go subscription, then you have access to the old portal ( but if you’re a CSP that doesn’t work. So after talking Brian Moore at Microsoft I created a series of steps that I thought I’d get down for the next time I need to do this.

Step 1

You will need to logon to your Visual Studio Team Services account. As you can see I have logged into mine and I have a couple of projects.

Step 2

You will need to select a project that you will deploy/integrate with Azure, I’ve selected my sample project.

Step 3

This step is where you configure the project to connect to VSTS by creating an endpoint.

Step 4

I’ve given my endpoint an incredibly creative name and associated it with a specific subscription.

Step 5

Here the endpoint is complete and you have the option to change it’s configuration, manage the endpoint’s role within Azure as well as manage the service principal itself, and finally to disconnect the service principal. The disconnect will in fact delete the service principal from azure, so in production this service principal should only ever be used with Visual Studio.

As a side note, the manage service principal link kicks you over to the old portal, so for CSP customer’s this may in fact fail. See images below.

Update Service Configuration

You have a couple of options here, change the connection name, and change the subscription.

Manage Endpoint Roles

This will take you to the Azure portal and let you adjust and generally fiddle with the roles associated with this Service Principal.

Manage Service Principal

By default this appears to connect you over to the old portal. But this gives you the ability to manipulate the properties of the Service Principal.

Here is where you can find the same information in the new portal. This is difficult to see, but Azure Active Directory > App Registrations and then choose the Service Principal named VisualStudioSPN.


Finally, to remove the Endpoint and Service Principal, simply choose disconnect, and this will go through and clean everything up.


Fix Windows Server 2012 R2 DFSR Event ID 4614

Recently had a ticket come in where a newly created Domain with two DC’s was not replicating properly. Upon logging into the DC’s I noted the following log entry in the DFS Replication Log

The DFS Replication service initialized SYSVOL at local path S:\SYSVOL\domain and is waiting to perform initial replication. The replicated folder will remain in the initial synchronization state until it has replicated with its partner . If the server was in the process of being promoted to a domain controller, the domain controller will not advertize and function as a domain controller until this issue is resolved. This can occur if the specified partner is also in the initial synchronization state, or if sharing violations are encountered on this server or the synchronization partner. If this event occurred during the migration of SYSVOL from File Replication service (FRS) to DFS Replication, changes will not replicate out until this issue is resolved. This can cause the SYSVOL folder on this server to become out of sync with other domain controllers.

Additional Information:
Replicated Folder Name: SYSVOL Share
Replicated Folder ID: C0037E37-EF20-4CDF-968A-932E669ED810
Replication Group Name: Domain System Volume
Replication Group ID: 35F23B97-543A-4310-A08E-5F28D6342C18
Member ID: 41E8F809-5114-48DC-8297-B7E866502101
Read-Only: 0

Working backwards through the log I found this entry

The DFS Replication service encountered an error communicating with partner AD-02 for replication group Domain System Volume.

Partner DNS address:

Optional data if available:
Partner WINS Address: AD-02
Partner IP Address:

The service will retry the connection periodically.

Additional Information:
Error: 1726 (The remote procedure call failed.)
Connection ID: 3E337B81-109F-4A97-880C-63E30F52E63F
Replication Group ID: 35F23B97-543A-4310-A08E-5F28D6342C18

I didn’t see that error on AD-02 but I did see several alerts like this one leading up to when the above alert fired on AD-01.

The DNS server is waiting for Active Directory Domain Services (AD DS) to signal that the initial synchronization of the directory has been completed. The DNS server service cannot start until the initial synchronization is complete because critical DNS data might not yet be replicated onto this domain controller. If events in the AD DS event log indicate that there is a problem with DNS name resolution, consider adding the IP address of another DNS server for this domain to the DNS server list in the Internet Protocol properties of this computer. This event will be logged every two minutes until AD DS has signaled that the initial synchronization has successfully completed.

As both DC’s are also DNS servers I configured the binding to be the statically set IP address. Which should once and for all rule out any sort of weird resolution issues. This had no affect either. There is not a lot else to go on from either server around the date where I think things went sideways. There is an odd 15 day gap in the DFSR Log, but maybe that’s normal? I don’t really see any indication of a problem in the Directory Services, System or Application logs around that time.

I then installed the Active Directory Replication Status Tool (, while it was interesting to run there were no issues reported. The next thing I ran was the health report from the DFS Management console, which told me more or less what I already knew, DFS was waiting on initial synchronization.

So the next thing to try was to figure out how to force that synchronization to happen. I found the following article ( on Microsoft’s Support site. I ran through the Authoritative Synchronization steps and after going through that the servers were happy. I was able to drop a test file in SYSVOL and see it replicate to the other server, delete that file on the server and see it drop off the other server.

While I don’t really know what the root cause for this issue was, hopefully the next time it crops up I’ll be able to figure it out a lot more quickly. As a side note to the steps I followed below I would tell you that I restarted the DFSR service after making changes in ADSI, each time.

Prior to running dfsrdiag, you may need to install that feature

Add-WindowsFeature -Name RSAT-DFS-Mgmt-Con

In order to force Active Director Replication throughout the domain you will run this command

repadmin /syncall /APed

You want to force the non-authoritative synchronization of SYSVOL on a domain controller. In the File Replication Service (FRS), this was controlled through the D2 and D4 data values for the Burflags registry values, but these values do not exist for the Distributed File System Replication (DFSR) service. You cannot use the DFS Management snap-in (Dfsmgmt.msc) or the Dfsradmin.exe command-line tool to achieve this. Unlike custom DFSR replicated folders, SYSVOL is intentionally protected from any editing through its management interfaces to prevent accidents.

How to perform a non-authoritative synchronization of DFSR-replicated SYSVOL (like “D2” for FRS)

  1. In the ADSIEDIT.MSC tool modify the following distinguished name (DN) value and attribute on each of the domain controllers that you want to make non-authoritative:
    1. CN=SYSVOL Subscription,CN=Domain System Volume,CN=DFSR-LocalSettings,CN=servername,OU=Domain Controllers,DC=domainname
    2. msDFSR-Enabled=FALSE
  2. Force Active Directory replication throughout the domain.
  3. Run the following command from an elevated command prompt on the same servers that you set as non-authoritative:
  4. You will see Event ID 4114 in the DFSR event log indicating SYSVOL is no longer being replicated.
  5. On the same DN from Step 1, set:
    1. msDFSR-Enabled=TRUE
  6. Force Active Directory replication throughout the domain.
  7. Run the following command from an elevated command prompt on the same servers that you set as non-authoritative:
  8. You will see Event ID 4614 and 4604 in the DFSR event log indicating SYSVOL has been initialized. That domain controller has now done a “D2” of SYSVOL.

How to perform an authoritative synchronization of DFSR-replicated SYSVOL (like “D4” for FRS)

  1. Stop the DFSR service on all domain controllers
  2. In the ADSIEDIT.MSC tool, modify the following DN and two attributes on the domain controller you want to make authoritative (preferrably the PDC Emulator, which is usually the most up to date for SYSVOL contents):
    1. CN=SYSVOL Subscription,CN=Domain System Volume,CN=DFSR-LocalSettings,CN=servername,OU=Domain Controllers,DC=domainname
    2. msDFSR-Enabled=FALSE
    3. msDFSR-options=1
  3. Modify the following DN and single attribute on all other domain controllers in that domain:
    1. CN=SYSVOL Subscription,CN=Domain System Volume,CN=DFSR-LocalSettings,CN=servername,OU=Domain Controllers,DC=domainname
    2. msDFSR-Enabled=FALSE
  4. Force Active Directory replication throughout the domain and validate its success on all DCs.
  5. Start the DFSR service set as authoritative:
  6. You will see Event ID 4114 in the DFSR event log indicating SYSVOL is no longer being replicated.
  7. On the same DN from Step 1, set:
    1. msDFSR-Enabled=TRUE
  8. Force Active Directory replication throughout the domain and validate its success on all DCs.
  9. Run the following command from an elevated command prompt on the same server that you set as authoritative:
  10. You will see Event ID 4602 in the DFSR event log indicating SYSVOL has been initialized. That domain controller has now done a “D4” of SYSVOL.
  11. Start the DFSR service on the other non-authoritative DCs. You will see Event ID 4114 in the DFSR event log indicating SYSVOL is no longer being replicated on each of them.
  12. Modify the following DN and single attribute on all other domain controllers in that domain:
    1. CN=SYSVOL Subscription,CN=Domain System Volume,CN=DFSR-LocalSettings,CN=servername,OU=Domain Controllers,DC=domainname
    2. msDFSR-Enabled=TRUE
  13. Run the following command from an elevated command prompt on all non-authoritative DCs (i.e. all but the formerly authoritative one):

Stuck in Maintenance Mode

It’s been ages, I do have plans to start writing again, and in fact this particular posting came about because I was going to write up something I just came across at work. I went to login to my site, and was presented with a 500 error. Since I’ve recently moved the entirety of both my sites to Azure Web Apps, I was mildly concerned as I had no real access to any of the switches, buttons or levers that make things go. I checked to see if I could login to my other site and received the same error message, which I guess is good. They are both running on the same App Service in Azure and while the actual pages would load and such I just was unable to login.

I thought about restarting the App Service itself, but chose to start small. I restarted the Web Application and was able to login, I then repeated that process on the other site and logged in to it as well.

That’s when I noticed that there were some updates available, specifically the plugin for Windows Azure Storage, and WordPress itself. So I updated WP first, it took longer than HTTP was willing to hang around so I got a nifty timeout. Reloaded the page and it came back, and I updated the rest of my plugins. Then I rolled over to update this site, same process, same plugins, same timeout. Only a refresh didn’t bring the site back after the plugins updated. I gave it a little more time and still I got the maintenance page. Keep in mind there is no server that I have access to, to really do anything that I would normally do. So i did a search and came across this article.

Apparently the update process drops a hidden file .maintenance in the root of the site, neat. All I needed to do was delete that file, but how do you do that when you don’t have a thing to login into?

Turns out Web Apps have a console, this can be found under the Development Tools on the Web App. This drops you into a shell on the root of your site, even though I know this is Windows it felt like Linux, so

> uname -a
MSYS_NT-6.2-WOW RD0003FF42E552 2.5.0(0.295/5/3) 2016-03-31 18:26 i686 Msys

That’s neat, all I needed to do then was run ls -a to make sure .maintenance was there, and then just rm .maintenance to get rid of it, refresh and the site is back up and available. I’m going to paste the contents of that page here, in case it goes away.

Has your WordPress site ever gotten stuck in maintenance mode? Many people seem to run into this problem. They update a WordPress theme or plugin or maybe even WordPress itself, and in the middle of the update, something goes wrong, and their site gets stuck in maintenance mode with nothing appearing but the message, “Briefly unavailable for scheduled maintenance. Check back in a minute.”
Not only are visitors locked out, but even the Admin is locked out of the backend.
If this happens to you, try one of the following solutions.
1. The solution that seems to work for most is to delete a file called “.maintenance” from the root of your site. This is a temporary file that gets created in the update process, and more than likely, this is your culprit. (Notice the *dot* at the beginning of the file name.)
Again, this file rests on your server in your main WordPress install section. You CANNOT access it through the Admin area of your site. You will need to access the server through your webhost’s system (like Cpanel) or via FTP.
If you do not have access to files on your server, then contact your host and let them know the problem (and the solution, of course).

2. Although removing the .maintenance file seems to work for most, it doesn’t work for all. If it doesn’t work for you, then try the following:
a Delete the .maintenance file as outlined in option #1 above.
b Delete the plugin or theme that you were attempting to update.
c. If your site does is not back at this point, then in your wp-content folder, you will find a folder called “upgrade.” Delete the files or folders you find there.
* Remember to clear the cache in your browser (or use a different browser) to make sure that you aren’t getting an old version of your site.
Once you have your site back, you may want to run your updates again to make sure they’ve taken.

Showing off some DSC Resources

Yesterday I wrote three articles ( Part 1, Part 2, Part 3 ) about Desired State Configuration. I thought I would post a slightly more complex Configuration. This configuration performs several actions on the target node.

  1. Install the Web-Server feature
  2. Install several additional features that depend on the Web-Server
  3. Install the WebDeploy application
  4. Configure Windows Firewall to allow WebDeploy traffic

This particular Configuration has some nice features to note. The first of which are the parameters. You must provide a ComputerName (or guid) and a path to the WebDeploy MSI. You can also optionally specify a source path for the features, this is useful if you have cloned a server.

You will also notice that nearly all the Resources use the DependsOn property. Since all the features are web server related, I set the DependsOn property to be the WebServerRole. If you look in the documentation I believe that Microsoft has this down as Requires, but I believe it’s changed since the docs came out.

The Package Resource installs WebDeploy. The ProductID I was able to pull from the MSI using ORCA ( SDK Download ). If you don’t have that installed, or don’t want to install it, you can install WebDeploy on a reference machine and ought to be able to query the ProductID from WMI.

The Script Resource was a little more difficult for me, and thankfully I found a wonderful article that did the deep diving. Basically a Script has three scripts that need to run. The TestScript must evaluate to True or False. If the TestScript == False then the SetScript runs. The GetScript must return a HashTable, and the only thing that it needs to return is the Result property, but you can also specify the contents of the GetScript, TestScript and SetScript scripts. Finally the SetScript is the script that will do the thing you need done. In this example create a firewall rule to allow port 8172.

So basically what happens is when you run Start-DSCConfiguration, the script will perform a test. If that test returns true then we can assume that the thing we need done is done. If that test returns false then we need to do the thing, whatever that thing is.

When you run Get-DSCConfiguration, the script will get the state of what we did, which is why all we need is a result.

DSC Part 3

It’s been a busy day, I haven’t posted anything since July and today three posts!

Well in Part 1 we talked about what Desired State Configuration was, in Part 2 I showed you how to manually setup the pull server. Now I’ll show you how to get your target node to pull configurations from the pull server. This is basically tying the loose ends together. I don’t anticipate adding any additional posts around this particular series as it really just fills a need for me. Detailed steps on how to get from point A to point B.

So in order for the client to talk to the server we need a GUID. This GUID will represent this client, if you have several clients it may be worthwhile noting these down, along with the name and or IP of the client. Honestly, the best way to make these things is in PowerShell, it’s a one-liner.


Guid                                                                                                      ----

Now that our pull server is up and running, we’ll need to modify our Configuration, and really all that needs to be changed is where we specify ComputerName. This time around our command looks like this

BasicWebServer -ComputerName "6e4bc22c-1ea3-4be6-b6a9-5694f0cfcaf8"

Note we passed in the GUID we just created, this is important as it will update the MOF we have locally stored with the GUID instead. If we look inside our .\BasicWebServer folder you will see a new MOF file with the GUID as the name. Now we need to create our checksum file.

New-DSCCheckSum -ConfigurationPath .\BasicWebServer -OutPath .\BasicWebServer

This result of this cmdlet is a .checksum file that is the same name as the MOF file that we just created. These two files are then copied to the pull server’s configuration directory. Once these have been copied over we can run the Configuration that configures the Local Configuration Manager.

This is run like you would run any other configuration EXCEPT, you must specify the GUID we just created, as well as the URL to the pull-server. In Part 2, our URL was not a virtual directory so we can just pass in the name of the server. If you created a virtual directory, you will need to pass in the full URL.

This particular configuration TURNS OFF SSL. I put that in caps because I think it’s important to note that DSC defaults to working over SSL only.

SetupDSCClient -NodeId "6e4bc22c-1ea3-4be6-b6a9-5694f0cfcaf8" -PullServer "webserver01"

Now, every 30 minutes your client will communicate with your pull-server and make sure that all the basic web server features are available. You should remove all those features and test it out.

I had some trial and tribulation when I was first setting this up, my first obstacle was my server was 2012, so I had to install WMF 4.0. Then I needed to change my configuration to run unsecure since I didn’t want to mess with certs. Finally since there were other web sites running on the server I needed to change to a different port.

DSC Part 2

In my previous article I talked about Desired State Configuration in a more or less generic way. I provided a sample Configuration that installed the basic services needed for a web server. This Configuration could be applied locally and once applied you could manage it manually as needed.

But the cool setup what is called a pull server ( a push server can also be setup but is more complex ). A pull server is basically a web server that has been configured with the proper DSC services and setup to listen.

The main difference between something local and a pull server is the Configurations are required to use GUID’s instead of computer names. Additionally the MOF files get hashed and the hash is stored in a file named after the MOF. These two files are then uploaded to the pull server and your client ( target node ) is configured to point at the pull server.

You can define intervals such that every 30 minutes the client will check in with the pull sever to validate it’s configuration. If something is missing, it will re-apply the configuration automatically.

So, if you already ran the Configuration from part 1, then you’re already halfway there. I’ll setup through the manual process for configuring the web portion of the pull server ( keep in mind Microsoft has released some Configurations that will assist with this ). We’ll need to make sure that the DSC service is available.

The next thing we need to do is setup the web portion of the pull-server. This entails copying files, creating an Application Pool, and setting up a website.

This leaves a few manual steps left to do, adding a few lines to the web.config file and setting the newly created Application Pool’s identity to LocalSystem.

<add key="dbprovider" value="System.Data.OleDb" />
<add key="dbconnectionstr" value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Program Files\WindowsPowerShell\DscService\Devices.mdb;" />
<add key="ConfigurationPath" value="C:\Program Files\WindowsPowerShell\DscService\Configuration" />
<add key="ModulePath" value="C:\Program Files\WindowsPowerShell\DscService\Modules" />

These lines are added inside the appSettings section of the web.config file. These are default values and can be left as is, they define where the modules are if you need any, and where the Configurations will be stored.

The last thing you need to do is open up IIS Manager, open Application Pools and find your Application Pool in the list. Click on it, and select Advanced Settings, click on Identity and then the build button, and from the list choose LocalSystem.

Once you’re done you should be able to point your browser at your server and see an xml output

<?xml version="1.0" encoding="utf-8" ?> 
<service xml:base="" xmlns="" xmlns:atom="">
<collection href="Action">
<collection href="Module">

DSC Part 1

Desired State Configuration is a new feature of PowerShell 4.0 that is included out of the box with Windows 8.1 and Windows Server 2012 R2. This feature can be loaded on down-level clients by installing the Windows Management Framework 4.0.

The way it works is pretty straightforward, PowerShell 4.0 has introduced a few new keywords, one of which is Configuration. If you’ve written any PowerShell functions it operates in a similar fashion as the Function keyword. Within a Configuration you can have one or more Nodes, each Node is defined as either a string “computer name”, or a variable $Computer, or as a GUID. Within each Node you can have 0 or more resources, there are a dozen built-in resources, and you can roll your own. In addition Microsoft has just released a handful of custom resources that I’ve not played with yet.

Here is an overview of the process

The flow is very straightforward, you create a configuration and save it as a ps1. Executing the ps1 creates a new function, named for your configuration in memory. Run this new function and a subfolder is created named for the configuration and inside the folder a .MOF file is created named for the target node.

You will need to run the function in order to create the directory and proper MOF files

BasicWebServer -ComputerName webserver01

To apply that configuration to the local machine you simply run the following

Start-DSCConfiguration -Path .\BasicWebServer

This will run as a job, if you would like to see it happen, you can add –wait and –verbose to the command above and it will display everything it’s doing.

Start-DSCConfiguration -Wait -Verbose -Path .\BasicWebServer

This configuration is stored on the computer and you can test to see if the configuration has drifted any by running the following


It will return True if it’s happy or False if something is missing. This configuration is stored with the computer and survives reboots, so you can always run


That will return a collection of configurations that are to be applied to the computer. If you would like to bring the target node back in line with its configuration you simply run the following


The end result of this command is that your server will now have all the features its supposed to have available again.

Setspn.exe wrapper

It’s been a while since I’ve posted anything, so I thought I would post about setspn, because you know, it’s so awesome right?

So one of the projects I’ve been working on lately is the upgrade to SCCM 2012. Outside of a few things it’s been going very well. We ran into an issue though when we rolled out the production server. Maybe I’ll write a post for that, needless to say part of the solution is SPN’s.

Now, I’m no stranger to this tool, but needless to say it leaves a LOT to be desired. Especially when we consider this came out for Windows Server 2003! So, since I had to do some work with SPN’s I decided I needed a PowerShell way of handling this.

There is really only handful of things we ever need setspn for, add an spn to an object, get an spn for an object, remove an spn from an object, find an spn or find duplicate spns.

So I came up with a handful of functions, based on the builtin help from the setspn utility and the TechNet article about setspn.

Reset-Spn -HostName

This will reset the SPN for the given hostname.

Asd-Spn -Service -Name -HostName -NoDupes

This will add an SPN to a given host and optionally check for duplicates within the domain first.

Remove-Spn -Service -Name -HostName

This removes an SPN from a given host.

Get-Spn -HostName

This will return the SPN’s for a given host.

Find-Spn -Service -Name

This will find all SPN’s of a given service, or of  given name, or both.

Find-DuplicateSpn -ForestWide

This will find all duplicate SPNs within the domain or optionally the entire forest.

Currently my functions are just wrappers for setspn.exe but I’m planning a V2 that will leverage .NET to handle this. I don’t get a lot of flexibility in error handling and output when I use a stand alone command.

  • I want to return objects
  • I want to be able to not have dependencies
  • I want the flexibility of .NET

Hyper-V Server 2012 Cluster with Powershell Deployment Toolkit

I recently came across a lovely show on Channel 9. It talks about setting up a simple Hyper-V Server 2012 cluster for use in a lab or test environment or whatever. I won’t go over the details, watch the show, it’s great! In addition to that I had come across an article on the Building Clouds Blog, about the PowerShell Deployment Toolkit. So over Memorial Day weekend I decided to stand up my cluster and spin up a test environment similar to what I use at work.

In my environment I have 6 servers, I have 3 set aside for Hyper-V, one is my firewall, one is a Domain Controller and the last is a management server. I’m using my DC as the file server as well. I didn’t need the iscsi target stuff, as I’m using Windows Server 2012 and used the new File and Storage Services to configure my iscsi drives.

I decided to let vmcreator.ps1 build the vm’s for me, originally I had spun up my own, but I was having difficulties getting the installer to work properly. Turns out that there is a requirement that the PDT tools be run from the C: drive of your computer. Also if you’re running them from the server OS, you will need to install the Hyper-V role in order vmcreator.ps1 to function properly. I don’t recall seeing either of those things mentioned in the TechNet article, but I may have overlooked that part.

So, linked from the vmcreator.ps1 article is a great utility, Convert-WindowsImage.ps1 that I used to create my base OS image. The utility is super handy and has a gui or cmdline version. I wimped out initially and used the gui version, pointed it an ISO of Windows Server 2012 and after a while I had a lovely vhdx ready for vmcreator.ps1.

After renaming the half dozen vm’s the script had created for me, in record time btw, I ran the installer.ps1. There’s not really a whole lot mentioned on the article about it’s use, it is rather self-explanatory and once you realize the limitation to the C: drive then it’s a no-brainer. That part took me a bit to figure out as I had an external drive with all the bits the downloader.ps1 had downloaded for me.

The end result is I now have the basic System Center infrastructure that I can play with locally to try out new features, or test the scripts and apps I create for work. It was really very slick, and I could totally see how I would use something like this in our QA environment at work.


SCOM 2007 R2 and Get-Event

For whatever reason I’ve not been able to find what I’ve been looking for regarding this cmdlet. Namely a decent example of it’s use with regards to the –Criteria parameter. For better or worse I have several event collectors setup and it would be nice to ask SCOM for a list of specific events. Normally you would think that would be simple, and perhaps for some it is, but for me I was having some issues, that is until yesterday.

I poked around in my history but I couldn’t find the page I was looking at that enlightened me, so I’ll just add my own here in case anyone else is having the same problem.

So I’m looking at a screen that has the following columns:

  • Level
  • Date and Time
  • Source
  • Name
  • Event Number

Now the examples I have seen show that you pass field=value into the –Critera parameter, but the problem for me is that Event Number or EventNumber aren’t things. In the Event Viewer it’s called ID but in SCOM ID is the ID of the specific entry you’re looking at, much like a primary key in a database.

It turns out that the Event Number field, in SCOM is simply Number. I literally felt like Homer Simpson, D’OH!

Get-Event -Criteria ‘Number=4729’

That actually yields useful information, well assuming you’re logging Event ID 4729. At any rate, I needed to write this down somewhere as it’s a regular thing for me, that up until now has been very difficult.