4 comments

ADFS: Certificate Private Key Permissions

Published on Friday, July 26, 2013 in ,

Just as a reminder for myself. The following error might appear in the ADFS Admin log after a user being faced with the ADFS error page. The error is pretty cryptic and gives no real clues away.

Error event ID 364: Encountered error during federation passive request.

Additional Data

Exception details:
Microsoft.IdentityServer.Web.RequestFailedException: MSIS7012: An error occurred while processing the request. Contact your administrator for details. ---> Microsoft.IdentityServer.Protocols.WSTrust.StsConnectionException: MSIS7004: An exception occurred while connecting to the federation service. The service endpoint URL 'net.tcp://localhost:1501/adfs/services/trusttcp/windows' may be incorrect or the service is not running. ---> System.ServiceModel.EndpointNotFoundException: There was no endpoint listening at net.tcp://localhost:1501/adfs/services/trusttcp/windows that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.

image

But after restarting the ADFS service an additional errors are shown:

Error event ID 102: There was an error in enabling endpoints of Federation Service. Fix configuration errors using PowerShell cmdlets and restart the Federation Service.

Additional Data
Exception details:
System.ArgumentNullException: Value cannot be null.
Parameter name: certificate
   at System.IdentityModel.Tokens.X509SecurityToken..ctor(X509Certificate2 certificate, String id, Boolean clone, Boolean disposable)
   at System.IdentityModel.Tokens.X509SecurityToken..ctor(X509Certificate2 certificate)
   at Microsoft.IdentityServer.Service.Configuration.MSISSecurityTokenServiceConfiguration.Create(Boolean forSaml)
   at Microsoft.IdentityServer.Service.Policy.PolicyServer.Service.ProxyPolicyServiceHost.ConfigureWIF()
   at Microsoft.IdentityServer.Service.SecurityTokenService.MSISConfigurableServiceHost.Configure()
   at Microsoft.IdentityServer.Service.SecurityTokenService.STSService.StartProxyPolicyStoreService(ServiceHostManager serviceHostManager)
   at Microsoft.IdentityServer.Service.SecurityTokenService.STSService.OnStartInternal(Boolean requestAdditionalTime)

And Event id 133: During processing of the Federation Service configuration, the element 'signingToken' was found to have invalid data. The private key for the certificate that was configured could not be accessed. The following are the values of the certificate:
Element: signingToken

This one is more descriptive. Here and there you see people saying that adding the ADFS service account to the local admins resolves this issue. Yeah I can imagine that, but that account is not supposed to have that kind of privileges! It’s sufficient to grant read (not even full control) to the private keys of the token signing and decrypting certificate. You can manage these by opening the mmc, adding the certificates snappin for the computer and browse the personal store.

image

1 comments

Quick Tip: Use PowerShell To Browse Through An Event Log

Published on in

When trying to troubleshoot AD FS claim rules, often I find myself going back and forth in the Security event log. But the interface doesn’t really allow to easily see whether the message is relevant or not. Here’s small PowerShell command, which probably can be optimized in many ways, that will print the last 60 (staring from the most recent) events that match the AD FS 2.0 Auditing source. Just press enter to go to the next event. Events are separate by a green dotted line.

get-eventlog Security -newest 60 | where-object {$_.Source -eq "AD FS 2.0 Auditing"}| % {write-host -foregroundcolor green "----------------------------------------------------";read-host " "; $_.message| fl}

image

Or even a bit more elaborate: a small script which allows you to go down, but also back up if you missed something:

$events = get-eventlog Security -newest 60 | where-object {$_.Source -eq "AD FS 2.0 Auditing"}|
$i = 0
while($i -lt $events.count -and $i -gt -1){
    write-host -foregroundcolor green "------------------$i-----------------------"
    $events[$i].message
    write-host ""
    write-host ""
    $direction = read-host "Continue? u(p) or d(own) [$default]"
    if($direction -eq $null -or $direction -eq ""){$direction = $default}
    if($direction -like "u"){
        $default = "u"
        $i--
    }
    else{
        $default = "d"
        $i++
    }
    $direction = $null
}

You can just copy paste this in a prompt, not even necessary to create a ps1 file for this. Although I can only encourage to modify this sample so you can easier find your needle in a haystack!

2 comments

SCCM: Task Sequence / Software Updates Paused

Published on in

Lately we had a ticket where a user was unable to execute task sequences from the Run Advertised Program console on his client. FYI, we’re running SCCM 2007 R2. The error the user was facing was this one:

This program cannot run because a reboot is in progress or software distribution is paused.

In the smsts.log file on the client (c:\Windows\System32\CCM\Logs\SMSTSLog\smsts.log) we saw the message “Waiting for Software Updates to pause”. So it seems that besides our Task Sequence we wanted to execute the client was also performing software updates in the background.

clip_image001[8]

In the UpdatesDeployment.log we found something alike “Request received – IsPasued” and “Request received – Pause”

clip_image001[10]

Somehow we couldn’t do much with this information. We hit a wall as we had no clue what updates were installing or why did they hang . So we continued our search. After some digging we found the following information in the registry:

clip_image001

So SCCM keeps track of the Task Sequence currently executing below HKLM\Software\Microsoft\SMS\Task Sequence. It will only allow one at a time. When comparing the registry entries with a working client we saw a small difference. The problem client didn’t had a “SoftwareUpdates” registry entry. As far as I can tell this is SCCM’s system of letting a Task Sequence know it can execute or not. In order to execute it needs two “cookies”. One for Software Distribution and one for Software Updates. If it has both, it means it has the necessary “cookies” to get started.

The actual value of the cookies can also be found in the following location: HLM\Software\Microsoft\SMS\Mobile Client\Software Distribution\State

clip_image001[4]

There we could see that indeed execute was paused as this entry had a value of 1. This was consistent with the error we were seeing in the Run Advertised Programs GUI. A lot of articles and blogs tell you to set it to 0 or delete it. We tried that, but it didn’t had any effects. And then I found the following forum post: http://www.myitforum.com/forums/Software-Updates-waiting-for-installation-to-complete-m221843.aspx With the information posted by gurltech I was able to perform the following steps:

Open wbemtest and connect to root\ccm\softwareupdates\deploymentagent

clip_image002

Execute the following query: select * from ccm_deploymenttaskex1

clip_image002[4]

If all goes well you find an instance

clip_image002[6]

And now check the AssignmentID property

clip_image002[8]

This ID can be used to track down the Deployment so called being “in progress”. When opening the “Status for a deployment and computer” report. And providing the id we just found and the computer name, we couldn’t find any updates to be installed or failed.

clip_image002[10]

So I figured using the script to clear the deployment task from WMI couldn’t hurt much. Either on a next software update cycle scan it would reappear, or it would be gone forever. And indeed, after setting the ID’s (AssignmentId and JobId) to 0 and recycling the SCCM client service we were able to execute Task Sequences again on that client. This situation might be very rare to run into, but I think it might inform you of some insights as to how SCCM works.

4 comments

AX 2012: Validate Settings Fails for Report Server Configuration

Published on Tuesday, July 9, 2013 in

Setting up AX 2012 Reporting involves installing SQL Reporting Services and registering that Reporting Services installation in AX. One of the issues we were having is that we were seeing some problems deploying reports. In order to troubleshoot we tried the Test-AxReportServerConfiguration cmdlet.

image

This cmdlet was telling us: the report server URL accessible: False Hmm. That’s odd. We’re pretty sure that all involved URLs (Report Server Manager & Report Server Service) were properly resolving and responding. When double checking the AX Report Server configuration within the AX Client we tried the validate settings button:

clip_image003

However, we stumbled upon the following error:

clip_image005

In words:  Exception has been thrown by the target of an invocation. The SQL Server Reporting Services server name RPRTAX1B.contoso.com does not exist or the Web service URL is not valid.

As it kept complaining about the URL I started to suspect what could be the root cause. From earlier experiences (Dynamics Ax 2012: Error Installing Enterprise Portal)  I know that not all AX components can properly handle host headers. Because this is how our SQL Reporting Services host header configuration looks like for the Report Server URL:

clip_image001

Jup, we got multiple entries. The reason is somehow historical and not relevant here. It seems that AX, when validating the settings, checks whether the Report Server URL matches with the first host header in the SQL Reporting Services configuration. So I went ahead, removed all entries but the good one, ok-ed and applied. After that I re-added them. This ensured the URL AX knows of was on top of the list. And jup, everything started working!

A colleague from the AX team showed me which code was performing this check. Here’s the offending code:

public boolean queryWMIForSharePointIntegratedMode(str serverName, str _serverUrl)

{

    boolean result = false;

    try

    {

        result = Microsoft.Dynamics.AX.Framework.Reporting.Shared.Proxy::QueryWMIForSharePointIntegratedMode(serverName, _serverUrl);

    }

    catch (Exception::CLRError)

    {

        // We must trap CLRError explicitly, to be able to retrieve the CLR exception later (using CLRInterop::getLastException() )

        SRSProxy::handleClrException(Exception::Error);

        result = false;

    }

    return result;

}

And that’s how I come to part two. When creating Report Server configurations within AX, one might be wondering how to register a load balanced Reporting Services setup…

Here’s the configuration extract of the server name & URLs for such a configuration. Now how do we handle the fact that there’s 2 Servers and one (virtual) load balanced URL?

clip_image007

In a load balanced setup with 2 reporting servers you’ll typically have 3 configurations FOR EACH AOS instance:

  1. RSServerA(Default Configuration: unchecked)
    1. Server name: ServerA
    2. Report Manager URL: axreports.contoso.com/reports
    3. Web service URL: axreports.contoso.com/reportserver
  2. RSServer B (Default Configuration: unchecked)
    1. Server name: ServerA
    2. Report Manager URL: axreports.contoso.com/reports
    3. Web service URL: axreports.contoso.com/reportserver
  3. RSVirtualServer (the Load Balancer) (Default Configuration: checked)
    1. Server name: ServerA
    2. Report Manager URL: axreports.contoso.com/reports
    3. Web service URL: axreports.contoso.com/reportserver

Now the clue is in the server name: this is the name which is being used to contact the actual Windows server for certain information. Like in the code above, the server will be contacted over WMI to read the requested setting. If you were to enter “axreports.contoso.com” as a servername, you’ll be seeing all kinds of errors. For starters typically your load balancer only balances port 80 or 443, but WMI uses other ports. So these connections will fail. As far as I learned from my AX colleague, the AOS instance can use the load balancer configuration entry, and you can use the node configuration for your report deployments. In that way, the server name probably doesn’t matter that much on the load balancer configuration item.

I hope I don’t sound to cryptically, if you like any further explanation, feel free to comment.