I've been modifying a local fork of the Tridion Powershell Module to work with a preview version of 2013. This is mostly a matter of fixing up the binding and endpoint to the relevant 2013 values. At the same time I have been adding support for the netTcp binding (which leads to more error information later in this question).
Prior to this modification work, I had been working with a simpler function to get a core service client in the Powershell:
$coreServiceClientPath = `
'C:\Program Files (x86)\Tridion\bin\client\CoreService\Tridion.ContentManager.CoreService.Client.dll'
function get-Core {
Add-Type -assemblyName System.ServiceModel
$binding = new-object System.ServiceModel.NetTcpBinding
$binding.MaxBufferPoolSize = [int]::MaxValue
$binding.MaxReceivedMessageSize = [int]::MaxValue
$binding.ReaderQuotas.MaxArrayLength = [int]::MaxValue
$binding.ReaderQuotas.MaxBytesPerRead = [int]::MaxValue
$binding.ReaderQuotas.MaxNameTableCharCount = [int]::MaxValue
$binding.ReaderQuotas.MaxStringContentLength = [int]::MaxValue
$endpoint = new-object System.ServiceModel.EndpointAddress `
net.tcp://localhost:2660/CoreService/2012/netTcp
Add-Type -Path $coreServiceClientPath
new-object Tridion.ContentManager.CoreService.Client.SessionAwareCoreServiceClient `
$binding,$endpoint
}
This works just fine, being very simple, however, when I came to port the module to 2013, I realised that the .Impersonate()
call gives some trouble.
The function Get-TridionCoreServiceClient uses Impersonate() as follows:
$proxy = New-Object $serviceInfo.ClassName -ArgumentList $binding, $endpoint;
Write-Verbose ("Connecting to the Core Service as {0}" -f $serviceInfo.UserName);
$proxy.Impersonate($serviceInfo.UserName) #| Out-Null;
Where UserName is ([Environment]::UserDomainName + "\" + [Environment]::UserName)
This invocation works fine in 2011, and my get-core
function which does not impersonate works fine, but in 2013, this approach results in an error condition. Here's the output (with some minor edits)
PS C:\Users\Administrator> Get-TridionCoreServiceClient -protocol http
Connecting to the Core Service at localhost...
Get-TridionCoreServiceClient : The HTTP request is unauthorized with
client authentication scheme 'Anonymous'. The
authentication header received from the server was 'Negotiate,NTLM'.
Microsoft.PowerShell.Commands.WriteErrorException,Get-TridionCoreServiceClient
PS C:\Users\Administrator> Get-TridionCoreServiceClient -protocol nettcp
Connecting to the Core Service at localhost...
Get-TridionCoreServiceClient : The socket connection was aborted.
This could be caused by an error processing your
message or a receive timeout being exceeded by the remote host,
or an underlying network resource issue. Local socket
timeout was '00:00:59.9958624'.
As you can see, the error output is different depending on the protocol you choose. For the netTcp variant, we also see the following in the Tridion Windows event log:
Stream Security is required at http://www.w3.org/2005/08/addressing/anonymous,
but no security context was negotiated. This is likely caused by the remote
endpoint missing a StreamSecurityBindingElement from its binding.
If I comment out the call to $proxy.Impersonate()
, everything works fine. What differences are there between 2013 and 2011 that might cause the impersonation to fail like this? How should I correctly use the 2013 API?