Verifying the private key property for a certificate in the store

I was recently asked as to how to figure out if the private key associated with a certificate is exportable or not. Typically the following code should work:

>$cert = (dir cert:\localmachine\my)[0]
>$cert.PrivateKey.CspKeyContainerInfo.Exportable
 

However, at times you would notice that $cert.PrivateKey is really null. However if you run "certutil -v -verify My 0", you can observe the private key and its properties. What's the difference?

The problem is that with the introduction of KSP, if the private key is stored in a KSP .NET classes are unable to find the private key (and hence the privateKey object is null). This is because .NET does not yet support KSP based AsymmetricAlgorithm objects (I'm not aware of it atleast for V3.5).

Fortunately there is a way to get around this using Certificate Enrollment Interface ISignerCertificate

>$cert = (dir cert:\localmachine\my)[0]
> $sc = new-object -com "X509Enrollment.CSignerCertificate.1"
> $sc.Initialize(1, 0, 4, $cert.GetRawCertDataString())
>$sc.PrivateKey.ExportPolicy

This is pretty powerful as IX509PrivateKey interface is much more richer and this solution should work regardless of whether the key is KSP based or CSP based.