Summer Calendar

Here is our summer schedule

Powershell MSMQ

I had to write a function to send MSMQ messages using powershell.  Here is the code that builds on an earlier post sending Unicode text messages with MSMQ

[Reflection.Assembly]::LoadWithPartialName("System.Messaging")
function SendMSMQ
{

param($queueName,$messageLabel,$messageBody)
 
$messageBody = $messageBody.replace("\<\?.+\>\r\n", "").Trim()

if($messageBody.length -gt 0)
{
 $queue = new-object System.Messaging.MessageQueue($queueName)
 $msg = new-object System.Messaging.Message
 $msg.Label = $messageLabel
 $enc = new-object System.Text.UnicodeEncoding($false, $false)
 $writer = new-object System.IO.StreamWriter($msg.BodyStream, $enc)
 $writer.Write($messageBody)
 $writer.Flush()
 $msg.BodyType = 8
 $queue.Send($msg, [System.Messaging.MessageQueueTransactionType]::Single)
 write-host $messageBody

 }
}

Win2003 Certs

I was working on installing a ServiceBus 1.1 client app on a Windows 2003 server.  I installed the server certs and crl on the client machine.  However I was still receiving the message:

System.UnauthorizedAccessException: The token provider was unable to provide a security token while accessing 
'https://myserver:9355/ServiceBusDefaultNamespace/$STS/Windows/'. Token provider returned message: 
'The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.'.
 ---> System.IdentityModel.Tokens.SecurityTokenException: The token provider was unable to provide a security 
 token while accessing 'https://myserver:9355/ServiceBusDefaultNamespace/$STS/Windows/'. 
 Token provider returned message: 'The underlying connection was closed: Could not establish trust relationship
 for the SSL/TLS secure channel.'. ---> System.Net.WebException: The underlying connection was closed: Could not
  establish trust relationship for the SSL/TLS secure channel. ---> 
  System.Security.Authentication.AuthenticationException: The remote certificate is
   invalid according to the validation procedure.

When I viewed https://myserver:9355/ServiceBusDefaultNamespace in the browser the cert had an exception of "This certificate has an nonvalid digital signature."
I looked at the cert in certmanager and noticed the signing algorithm was 1.2.840.113549.1.1.11  Apparently the SHA256 algorithm was not installed on the server.  I had to apply a hotfix from http://support.microsoft.com/kb/938397

Powershell COM objects

I was trying to create a COM object in powershell like this

$obj= New-Object -ComObject MyProject.MyClass
$obj|Get-Member

When I ran it I received this error:
New-Object : Retrieving the COM class factory for component with CLSID {E51BB9FD-F8EF-4636-8DE3-1ADE61B670AD} failed due to the following error: 80040154 Class not registered (Exception 
from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))

I just used regsvr32 on the dll so I knew it was registered and I verified it with regedit

Figured out I was running the 64bit version of powershell.  It worked using the 32bit version.

I also noticed that if the COM object is not registered the error is 
New-Object : Retrieving the COM class factory for component with CLSID {00000000-0000-0000-0000-000000000000} failed due to the following error: 80040154 Class not registered (Exception 
from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).

LocalSTS Web.config

I've been working on some Windows Identity Framework project and have been using the cool localSTS tool for claims authentication.  The one thing I did notice is that the web.config for the project is overridden when the localSTS is configured.  After my project was running correctly, I went in and added some claims to the existing configuration. When I started the project again the Windows Cardspace app popped up and there was a message

"Incoming policy failed validation."

Took me forever to figure out that the localSTS config replaced the existing issuermetadata element with

              <issuerMetadata address="https://localhost/adfs/services/trust/mex" />

The address should be something like https://localsts:port/wsTrustSTS/mex

How to get Service Bus for Windows client config

I installed the Service Bus for Windows Server application but did not save the client connection string.  I found out later how to do it so here it is.

1.  Open the Service Bus Powershell link under the Service Bus group (or add the ServiceBus PowerShell ps1 file)
2.  Execute the Get-SBClientConfiguration command.  

SAML2 FederationMetadata validation

I was working on a project using a SAML2 FederationMetadata document.  The Xml signature of the document had to be verified.  I had some issues out of the box so I thought I'd document them

"SignatureDescription could not be created for the signature algorithm supplied."

First issue was with the signature using the "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" encryption.  For some reason it's not included in System.Security.Cryptography.Xml.SignedXml so the following class has to be added

    public class RSAPKCS1SHA256SignatureDescription : SignatureDescription
    {
        public RSAPKCS1SHA256SignatureDescription()
        {
            base.KeyAlgorithm = "System.Security.Cryptography.RSACryptoServiceProvider";
            base.DigestAlgorithm = "System.Security.Cryptography.SHA256Managed";
            base.FormatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureFormatter";
            base.DeformatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureDeformatter";
        }

        public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
        {
            AsymmetricSignatureDeformatter asymmetricSignatureDeformatter = (AsymmetricSignatureDeformatter)
                CryptoConfig.CreateFromName(base.DeformatterAlgorithm);
            asymmetricSignatureDeformatter.SetKey(key);
            asymmetricSignatureDeformatter.SetHashAlgorithm("SHA256");
            return asymmetricSignatureDeformatter;
        }
    }
}

Before you create the SignedXml object the Encrytion algorithm has to added to the config
            CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");

            SignedXml signedXml = new SignedXml(metadataXmlDocument);

Some sample code can be found at http://www.copypastecode.com/168417/

Net issue I had was the signedXml.CheckSignature(certificate, false) returning false for valid signed files.  The issue was that the certificate was not in the trusted root certificate store.  Why that matters I'm not sure but the issue went away after I added it.


VB multiline string as XML Literals

Probably known by most programmers, but I want to document it so I can find it myself later.

An easy way to create a multiline VB string is to create a xml literal and use the value

Dim myTest = <string>Here is a multi
line string that I want to use in
some other code.  It
helps the readability and
cut and paste functionality.
Even if this is a poor example
</string>

Dim strInside as string = myTest.value

SearchServer2008Express Search Webservice

I was working on calling the Search Server 2008 Express search webservice from Powershell.  I kept getting

 <ResponsePacket xmlns="urn:Microsoft.Search.Response"><Response domain=""><Status>ERROR_NO_RESPONSE</Status><DebugErrorMessage>The search request was unable to connect to the Search Service.</DebugErrorMessage></Response></ResponsePacket>

I checked the user authorization, the webservice search status, even the WSDL.  

Turns out the URL for the SearchServer2008 search webservice was incorrect.  I was calling 
$URI= "http://ss2008/_vti_bin/spsearch.asmx?WSDL"
and it should have been
$URI= "http://ss2008/_vti_bin/search.asmx?WSDL"


Here is my sample powershell script:
# WSS Documentation http://msdn.microsoft.com/en-us/library/bb862916.aspx

$error.clear()

#Bad SearchServer2008Express Search URL 
$URI= "http://ss2008/_vti_bin/spsearch.asmx?WSDL"
#Good SearchServer2008Express Search URL 
$URI= "http://ss2008/_vti_bin/search.asmx?WSDL"

$search = New-WebServiceProxy -uri $URI -namespace WSS -class Search -UseDefaultCredential 

$queryXml = "<QueryPacket xmlns='urn:Microsoft.Search.Query' Revision='1000'>
  <Query >
    <SupportedFormats>
      <Format revision='1'>urn:Microsoft.Search.Response.Document.Document</Format>
    </SupportedFormats>
    <Context>
      <QueryText language='en-US' type='MSSQLFT'>SELECT Title, Path, Description, Write, Rank, Size FROM Scope() WHERE CONTAINS('Microsoft')</QueryText>
      <!--<QueryText language='en-US' type='TEXT'>Microsoft</QueryText> -->
    </Context>
  </Query>
</QueryPacket>"
 
$statusResponse = $search.Status()
write-host '$statusResponse:'  $statusResponse
 
$GetPortalSearchInfo = $search.GetPortalSearchInfo()
write-host '$GetPortalSearchInfo:'  $GetPortalSearchInfo
 
$queryResult = $search.Query($queryXml)
write-host '$queryResult:'  $queryResult
 
 

Runnin Framework 4.0 with Powershell

I had problems running scripts with Framework 4.0 assemblies I created.  The error I was getting was 
 
Add-Type : Could not load file or assembly 'file:///C:\myDLL.dll' or one of its depend
encies. This assembly is built by a runtime newer than the currently loaded run
time and cannot be loaded.
 
I had to add the supported framework to the powershell.exe.config file.
<supportedRuntime version="v4.0.30319"/>

I still had a problem running the assembly so I had to recompile and set "Generate serialization Assembly" to off.