Obtaining an STS token from ADFS using Windows Authentication

This one has had me stumped for a bit now. An organisation where I work has an Office365 tenancy which is federated with an on-premises Active Directory. I have been working on an application which needs to authenticate to SharePoint Online to perform actions on behalf of users. The first version I wrote worked well, however it had a drawback in that it needed the user to enter their password on a Windows form before it could be used – the user principal name can be easily obtained from the session information.

I wanted to upgrade the application so that it would use integrated authentication to obtain a SAML token from ADFS and try to use this to authenticate before using the username/password combination as a fallback. Things weren’t straight forward, however, as a lot of the documentation around how to connect to ADFS in this manner is out of date. Microsoft have rolled a lot of the identity framework stuff into .NET natively from 4.5 onwards, so the old .NET 3.5 ways of doing things are no longer possible as the classes, properties and methods you need to create and manipulate are deprecated and not available in newer versions of .NET.

Some people may suggest that re-targeting the application at .NET 3.5 might have gotten around this, however I don’t like to go back to older versions of technology unless it’s absolutely necessary. To that end, I used the following code to pass through the currently logged on user’s information to ADFS and get a token back from the STS endpoint:

        public GenericXmlSecurityToken GetToken()
        {
            WS2007HttpBinding binding = new WS2007HttpBinding(SecurityMode.Transport);
            binding.Security.Message.EstablishSecurityContext = false;
            binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
            WSTrustChannelFactory factory = new WSTrustChannelFactory((binding), new EndpointAddress(stsEndpoint));
            factory.TrustVersion = TrustVersion.WSTrustFeb2005;
            factory.Credentials.SupportInteractive = false;
            var rst = new RequestSecurityToken
            {
                RequestType = RequestTypes.Issue,
                AppliesTo = new EndpointReference(realm),
                KeyType = KeyTypes.Bearer
            };
            IWSTrustChannelContract channel = factory.CreateChannel();
            return channel.Issue(rst) as GenericXmlSecurityToken;
        }

The stsEndpoint string is the link to your ADFS STS endpoint, e.g.: https://my.adfs.org/adfs/services/trust/2005/windowstransport for integrated authentication. The realm string is the link to Microsoft’s own STS server that secures Office365: https://login.microsoftonline.com/extSTS.srf

The method above returns a GenericXmlSecurityToken object which has a TokenXml property. Passing the GenericXmlSecurityToken.TokenXml.OuterXml property into a parametised SOAP request to the Office365 STS endpoint will allow you to pass through the user’s logged on details without needed to capture a password first.

Hope this helps anyone out there trying to do the same kind of thing.

Share and Enjoy:
  • Digg
  • StumbleUpon
  • Technorati
  • del.icio.us
  • Twitter
  • blogmarks
  • HackerNews
  • Tumblr
  • Posterous
  • email

Backing up lots of SQL databases

Sometimes you might need to back up databases in a SQL instance, perhaps to keep a checkpoint or to restore them to another SQL server or instance. Its easy to do this manually if you only have a couple of databases in the instance, but what if you have lots of them? That would be time consuming and tedious in the extreme… That’s where this handy little SQL script will come in:

BEGIN
SET NOCOUNT ON;

DECLARE @name VARCHAR(50) -- Holds the database name
DECLARE @path VARCHAR(256) -- Holds the path for the backup
DECLARE @fileName VARCHAR(256) -- Filename for the backup
DECLARE @fileDate VARCHAR(20) -- Used to date stamp the filename
SET @path = 'D:\Backups\' -- Change this to your backup location
SELECT @fileDate = CONVERT(VARCHAR(20),GETDATE(),104)
DECLARE db_cursor CURSOR FOR
  SELECT name
  FROM MASTER.dbo.sysdatabases
  WHERE name NOT IN ('master','model','msdb','tempdb','ReportServer$INSTANCE','ReportServer$INSTANCETempDB') -- Modify to exclude databases
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
  SET @fileName = @path + @name + '_' + @fileDate + '.BAK'
  BACKUP DATABASE @name TO DISK = @fileName
  FETCH NEXT FROM db_cursor INTO @name
END
CLOSE db_cursor
DEALLOCATE db_cursor
END

You’ll need to change the list of excluded databases so it will skip ones that you don’t want to back up, and change the names of the ReportServer databases to reflect the correct name based on the name of your SQL instance.

Share and Enjoy:
  • Digg
  • StumbleUpon
  • Technorati
  • del.icio.us
  • Twitter
  • blogmarks
  • HackerNews
  • Tumblr
  • Posterous
  • email

Removing Accepted Domains

Had an interesting one just recently whereby an accepted domain in an Exchange organisation I administer could not be removed. Despite the fact that all users and distribution groups with the relevant address had long been deleted, along with their mailboxes and organisational units, each attempt to remove the domain from Exchange returned the following message:

Cannot remove the domain example.com because it is referenced by the proxy address template: 'smtp:@example.com'.

I went through all the other address policies in Exchange and found that none of them were configured to assign proxy addresses for this domain, despite what Exchange was saying.

The resolution required the use of ADSI Edit to modify the attributes of the address policies themselves…

  1. On a domain controller, start the ADSI Edit snap-in and connect to the Configuration partition
  2. Browse down through Services > Exchange > Organisation > Recipient Policies. Here you will see ADSI objects representing the Email Address Policies visible in Exchange
  3. Right-click on each in turn and choose Properties. Check the values of the gatewayProxy and DisabledgatewayProxy attributes, removing the domain in question from each, if it is present
  4. Allow for replication between your domain controllers, then try removing the accepted domain from Exchange again

The joys of Exchange, eh readers?

Share and Enjoy:
  • Digg
  • StumbleUpon
  • Technorati
  • del.icio.us
  • Twitter
  • blogmarks
  • HackerNews
  • Tumblr
  • Posterous
  • email

DPM and the 100 failed file limit

Regular readers and viewers will know that I use Microsoft’s Data Protection Manager (DPM) a lot, and I’m a fan of the product, despite some serious issues with recent updates (see other DPM posts for the details)…

One thing that I never could never get my head around, though, is the fact that if you’re doing a file system backup, DPM will abort the job and mark it as a failure if it encounters more than 100 files that it can’t back up.

This is design madness in a backup product. Sure, log the failed files and tell us about them, but for the sake of all that’s holy don’t just abandon the job! That is not data protection…

Thankfully, there is a way you get around this if you have a server where this is an issue. On the server you’re having issues backing up, open the registry editor and navigate to:

HKLM\Software\Microsoft\Microsoft Data Protection Manager\Agent

Create a new key called ContinueOnFailure and a DWORD value inside it called MaxFailedFiles and leave it with a value of zero (0) to turn this feature off. If you use DPM to back up your entire environment, it may be worth looking at using a Group Policy to create this registry key on all your domain-joined machines to avoid having to deal with this issue in a reactive manner.

Share and Enjoy:
  • Digg
  • StumbleUpon
  • Technorati
  • del.icio.us
  • Twitter
  • blogmarks
  • HackerNews
  • Tumblr
  • Posterous
  • email

Exchange Online Migration Error

Had a strange one at work this week when trying to migrate a user from our on-premises Exchange environment to Exchange Online. After starting a migration batch for a specific user, the following error message was reported almost immediately and the migration batch went into a state of permanent failure:

Error: MigrationPermanentException: Couldn‎'t load the request. Not enough information was provided to read the orphaned request message. --> Couldn‎'t load the request. Not enough information was provided to read the orphaned request message.

After removing the migration batch for the user, executing a Get-MoveRequest | Where { $_.DisplayName -eq "Display Name" } PowerShell statement revealed an orphaned move request with no target database:

Exchange-orphaned-move-request
 To resolve the issue, the orphaned move request has to be removed by piping the PowerShell statement identifying it through a Remove-MoveRequest -Verbose -Force command to remove it. Once complete, a repeat of the Get-MoveRequest statement should return no values. The migration batch can then be re-created using the standard migration wizard in the portal and should sync successfully.

Share and Enjoy:
  • Digg
  • StumbleUpon
  • Technorati
  • del.icio.us
  • Twitter
  • blogmarks
  • HackerNews
  • Tumblr
  • Posterous
  • email

Final Fantasy 15: Windows Edition

In advance of Square releasing FFXV on PC, I’ve been playing the demo that has been available on Steam. Please enjoy these few clips I captured from the first part of the game.

 

 

 

 

Expect more clips and a full review after the game is released…

Share and Enjoy:
  • Digg
  • StumbleUpon
  • Technorati
  • del.icio.us
  • Twitter
  • blogmarks
  • HackerNews
  • Tumblr
  • Posterous
  • email

Extra History: The Cuban Missile Crisis

The guys and gals over at Extra Credits on YouTube do an occasional series called Extra History where they outline events and people of interest from history. I encourage you to watch the series, they’re very interesting, well researched and very well put together. Just recently they did a series on the Cuban Missile Crisis. Along with the little-known Exercise Able Archer in 1983, this is possibly the closest that we have ever come to nuclear war… Just thinking how close all the secrecy has brought us to midnight makes me feel a little cold at times…

Part 1: The Failed Checkmate

April, 1962: Soviet Premier Nikita Khrushchev is walking near his villa on the Black Sea. He looks across the water. On the far shore is Turkey where, months before President Kennedy had stationed nuclear missiles. Their warheads threaten Moscow, and he wonders: why, then, can’t we do the same in Cuba?

And the world slips one minute closer to midnight…

Part 2: Eyeball to Eyeball

It’s October 22, 7PM. Camera equipment clutters the Oval Office.

3… 2… 1…

The President is live, announcing to 100 million Americans that there are nuclear weapons in Cuba.

The US Military goes to DEFCON3: missiles and bombers can launch within 15 minutes of a Presidential order.

The clock ticks another minute toward midnight.

Part 3: Black Saturday

It’s October 27, 03:35am. The bomber lets go: a flash lights the Arctic Circle. Shockwaves tear outward with the power of 20 Hiroshima bombs. Radioactive ash collects on the barren island below. A Soviet atmospheric test, scheduled before the crisis.

In Cuba, Soviet troops are transporting warheads to missile sites. They, and the American troops in Florida, are prepared for an invasion. At the quarantine line, Soviet subs play cat and mouse with American destroyers. At noon, America conducts its own test: a mushroom cloud rises 60,000 feet over the Pacific.

Thus dawns Black Saturday… The clock sits at 11:59…

At the time of writing, the Doomsday Clock sits at 11:58

Share and Enjoy:
  • Digg
  • StumbleUpon
  • Technorati
  • del.icio.us
  • Twitter
  • blogmarks
  • HackerNews
  • Tumblr
  • Posterous
  • email

FF7: Getting a Gold Chocobo without racing

There are actually two ways to get a Gold Chocobo without competing in the Chocobo races at the Gold Saucer. One of those involves defeating Ultima WEAPON to make Ruby WEAPON appear, then defeating Ruby to get the Desert Rose, for which the Kalm Traveller will reward you with a Gold Chocobo. However, as defeating Ruby WEAPON pretty much requires you to have Knights of the Round, for which you need a Gold Chocobo, this is pretty much a non-starter.

There is another way, however. To make use of it, you’ll need to be far enough into the game to have access to the Highwind and about 100,000 gil in spare cash. I’ll include an image of the World Map below, the key areas you’ll need to visit are the Icicle Area, the Mideel Area, the Chocobo Farm and Goblin Island.

worldmap
Follow these steps to get yourself your Gold Chocobo:

  1. Head to the Chocobo Farm and rent all six stables (6 x 10,000 gil needed)
  2. Buy 70 Krakka Greens from Choco Billy (or enough to make your total up to 70, if you already have some)
  3. Buy 1 Saraha Nut (skip this if you already have one or more of these)
  4. Fly to the Icicle Inn Area and fight an enemy called Vlakorados. Steal a Carob Nut from this enemy. You may want to run away from this battle once this is done as these creatures have 33,333 HP. You’ll need to do this twice to get two Carob Nuts.steal-a-carob-nut-from-the-vlakorados-be
  5. Fly to Goblin Island and steal a Zeio Nut from the Goblins in the forests on the island.wonderful-chocobos-dwell-alongside-jumpi
  6. Return to the Icicle Area and capture a Wonderful Chocobo. You’ll be able to identify whether the chocobo that has appeared is Wonderful or not by the enemies it appears with. Wonderful Chocobos always appear with one or two Jumpings (they look like rabbits) and nothing else. If your chocobo appears with a wolf or anything else, it’s not Wonderful so let it go and try again.0127-Wonderful-Chocobo-Jumping
  7. Send your Wonderful Chocobo back to the stables.
  8. Head to the Mideel Area to capture a Great Chocobo. You can identify whether the chocobo that appears is Great or not by the enemies it appears with. Great Chocobos always appear with one or two Spiral enemies (they look like armadillos) and nothing else. If your chocobo appears with anything else, its not Great so let it go and try again.0119-Great-Chocobo-Spiral
  9. Send your Great Chocobo back to the stables and head back there yourself.
  10. Save your game right next to the farm and quit / reset. You’ll need to do this a couple of times throughout this process.
  11. Reload your game and run into the stables as fast as possible
  12. Talk to Choco Billy about Moving Chocobos and move the Great Chocobo in first. This should be female, and this rule should be followed throughout the process: ladies first!
  13. Talk to Choco Billy again and move in the Great Chocobo. This one should be male.
  14. Head out to the world map, and save and quit / reset your game again.
  15. Reload your game and run back into the stables as fast as possible and speak to Choco Billy about feeding chocobos.
  16. Feed one Krakka Green to your female Great Chocobo.
  17. Speak to Choco Billy again and mate your two chocobos together with a Carob nut, making sure you choose the female Great Chocobo first: ladies first, remember!
  18. This should give you a female River (blue) Chocobo.blue
  19. Head back to the world map and fight six random encounters.
  20. Save your game next to the ranch and save and quit / reset your game.
  21. Reload and head back into the stables as fast as possible.
  22. Talk to Choco Billy about feeding chocobos and feed 50 Krakka Greens to your female Great Chocobo.
  23. Mate the Great and the Wonderful Chocobos together with a Carob Nut, making sure you choose the lady first.
  24. This should get you a Mountain (green) Chocobo which should be male.green
  25. Head back to the world map and fight eight random encounters.
  26. Repeat the save and quit / reset ritual.
  27. Reload the game and head back in to Choco Billy as fast as possible.
  28. Feed 5 Krakka Greens to your female Great Chocobo.
  29. Mate your River and Mountain Chocobos together using a Saraha Nut, making sure you chose the female (River) Chocobo first.
  30. This should give you a Black Chocobo which should be female.black
  31. Head back to the world map and fight three random encounters.
  32. Save and quit / reset your game.
  33. Reload and head back to Choco Billy as fast as possible.
  34. Feed six Krakka Greens to your female Great Chocobo.
  35. Mate the Black Chocobo with your Wonderful Chocobo and use a Zeio Nut, again making sure you choose the female chocobo first.
  36. This should give you a female Gold Chocobo.gold

After getting your Gold Chocobo you can head out to all the Materia Caves to get the special material, including Knights of the Round from Round Island. This might seem like a complicated process, however it can be completed in about 20 minutes, whereas the racing process can take a lot longer than this to complete. Your Gold Chocobo also won’t suffer any slowdown effects from racing, which means getting to Class S should be much easier this way. Enjoy!

Share and Enjoy:
  • Digg
  • StumbleUpon
  • Technorati
  • del.icio.us
  • Twitter
  • blogmarks
  • HackerNews
  • Tumblr
  • Posterous
  • email

Exchange OU picker

It came to my attention recently that in one of the Exchange 2013 environments I look after, when creating a new object (whether that’s a mailbox, distribution group or anything else) that requires you to choose an Organizational Unit (OU) for the new object to sit in, the following screen was appearing instead of the OU picker:

ou-picker

So there are more results that can be displayed… But also no items in the view.

This is because Exchange, by default, returns the first 500 items it finds that match any given criteria. For mailboxes this just means the first 500 in the organisation, and you can search for more. If you need to populate a tree, like in the example above, all list items have to be returned so that the tree view can be drawn properly. If your Active Directory domain has more than 500 OUs you’re going to run into this problem.

Fortunately the fix is simple: on all your Exchange servers that have the Mailbox role installed open the following file:

C:\Program Files\Microsoft\Exchange Server\V15\ClientAccess\ecp\web.config

And add the following text above the </appsettings> tag:

<add key="GetListDefaultResultSize" value="x" />

Just change x for a number that is slightly higher than the number of OUs you have in your domain, then restart the MSExchangeECPAppPool application pool in IIS.

You can find the number of OUs you have by running one of the following PowerShell statements:

(Get-OrganizationalUnit –ResultSize unlimited).Count

This can be run in the Exchange Management Shell. Or you can run:

(Get-ADOrganizationalUnit -Filter *).Count

In any PowerShell session where you have imported the ActiveDirectory module.

Unfortunately as the file you need to change is a core part of Exchange, each time you install a new CU you’ll have to re-apply this fix.

Share and Enjoy:
  • Digg
  • StumbleUpon
  • Technorati
  • del.icio.us
  • Twitter
  • blogmarks
  • HackerNews
  • Tumblr
  • Posterous
  • email

ADFS: Finding when users were synced

ADFS – Active Directory Federation Services – is a great technology that allows you to synchronise your on-premises Active Directory environment with an Office365 tenancy.

Unfortunately it can sometimes be a little impenetrable in terms of querying when changes to objects are replicated to O365. While you can search for objects using the Metaverse Search tab in the GUI, this may not always give you what you’re looking for. Indeed, searching is hampered by the fact that ADFS references objects based on either their ImmutableID or Cloud DN values. And ImmutableID value might look something like this:

4sEbBR5F7oeFz3R23dtLSe==

While a Cloud DN would look something like this:

CN={635257457869502f4145365a65474e6c4166637377513d3d}

Neither of these things are recorded against any on-premises object, and ADFS PowerShell doesn’t make it easy to to find an object by one value to obtain the other. This can be frustrating when you realise that all entries in the ADSync SQL database are referenced by Cloud DN value, making querying the database tricky. Thankfully the following script (found here, credits to the author) allows you to enter either value and obtain its counterpart:

[CmdletBinding()]
param
(
[Parameter(Mandatory = $true,
HelpMessage="ImmutableID string or Azure CS DN value")]
[string]$Value
)
$done = $NULL
If ($value.EndsWith("=="))
{
$enc = [system.text.encoding]::utf8
$result = $enc.getbytes($Value)
write-host "CN={" -nonewline
$result | foreach {write-host -object ([convert]::tostring($_,16)) -NoNewline};write-host "}"
}
ElseIf ($value.ToLower().StartsWith("cn="))
{
$hexstring = $value.replace("CN={","")
$hexstring = $hexstring.replace("}","")
$array = @{}
$array = $hexstring -split "(..)" | ? {$_}
$array | FOREACH {WRITE-HOST –object ( [CHAR][BYTE]([CONVERT]::toint16($_,16))) –nonewline };write-host
}
Else
{
Write-host -fore red "You provided a value that was neither an ImmutableID (ended with ==) or a DN (started with CN=), please try again."
}

If you were interested in which synchronisation runs a user was updated in, you would find the ImmutableID value by running the following command in ADFS PowerShell after connecting to your tenant:

Get-MsolUser -UserPrincipalName user@domain.com | Select ImmutableID

This can then be passed through a run of the script above to get the Cloud DN value, which can then in turn be entered into the following SQL command which you can run against your ADSync SQL database:

select * from mms_step_object_details so where so.step_history_id in (
       select step_history_id from mms_step_history sh where sh.run_history_id in (
       select run_history_id from mms_run_history where start_date > '2018-01-13 17:00:00' and
       start_date < '2018-01-13 23:59:59')
       and sh.stage_update > 50) and cs_dn = 'CN={635257457869502f4145365a65474e6c4166637377513d3d}'

Naturally you can tailor this to extend the date range you’re searching for; the sh.stage_update criteria can also be removed if you’re interested in every run the user appeared in; running the statement as it is above will only return those batches where the update stage of the run contained more than 50 objects.

I hope this helps if you’re having trouble querying the internals of your ADFS / ADSync databases, but as ever if you have any questions please feel free to let me know and I’ll do my best to try and help.

Share and Enjoy:
  • Digg
  • StumbleUpon
  • Technorati
  • del.icio.us
  • Twitter
  • blogmarks
  • HackerNews
  • Tumblr
  • Posterous
  • email