Wednesday, October 17, 2012

PowerShell: Current Script Folder (Call operator, dot source, and path)

There are a few ways to get the current directory of the executing PowerShell script, but the issue I ran into was that some of the ways changed based on how the script was called.  This was the PowerShell line I used previously and what works in the PowerShell ISE very well,

 

$scriptFolder = $myInvocation.InvocationName | Split-Path -parent

and this is the line I use now.

 

$scriptFolder = $myInvocation.MyCommand.Path | Split-Path -parent

 

The subtle difference in the usage of myInvocation is explained in detail in Kirk Munro’s deep dive on the topic, http://poshoholic.com/2008/03/18/powershell-deep-dive-using-myinvocation-and-invoke-expression-to-support-dot-sourcing-and-direct-invocation-in-shared-powershell-scripts/.  Basically, there are 3 ways you can call a PowerShell script using either the call operator (&), a dot source (.), or a path.  The first PowerShell line only works when using the full path.  This makes perfect sense after one realizes what the InvocationName property represents, but it was confusing at first.

Friday, August 17, 2012

PowerShell – SharePoint List Data to CAML Data

Here’s a handy PowerShell function that will convert an existing list instance’s data to a CAML data structure.  The output isn’t indented, but most editors like Visual Studio can do that for you.  This also doesn’t handle XML escape characters, but it would be simple enough to add if the data required it.

 

function ListDataToCamlData($webName, $listName, $fields){
    $newLine = [Environment]::NewLine
    $web = Get-SPWeb -Identity $webName
   
    $stringBuilder = New-Object -Type System.Text.StringBuilder
    $stringBuilder.Append("<Data><Rows>")
    #TODO - Handle XML escape values &amp; &quot; &lt; &gt; &apos;
    $web.Lists[$listName].Items | %{$stringBuilder.Append("<Row>"); foreach($field in $fields){$stringBuilder.AppendFormat("<Field Name=""{0}"">{1}</Field>", $field, $_.$field)}; $stringBuilder.AppendFormat("</Row>{0}", $newLine)}
    $stringBuilder.Append("</Rows></Data>")
   
    $web.Dispose()
   
    return $stringBuilder.ToString()
}

 

And here’s an example in calling it

 

ListDataToCamlData “http://www.somesite.local” "Announcements" @("ID", "Title")

Thursday, May 28, 2009

SSL Certificate and Sysprep

SSL connections will fail to an IIS server that has been sysprep'd. Windows sysprep will change the SIDs on all the existing accounts. This will effectively remove access to the private key for the IIS account i.e. Network Service. In order to restore it, you'll need to remove the certificate from IIS, delete the certificate from the certificate store, and import the certificate again.

Friday, May 22, 2009

Wireshark and Capturing Local Traffic

Wireshark cannot be used to capture local traffic because the packets never make it to the network interface. They are routed internally, inside of the TCP/IP stack. There are few workarounds listed in the link below.

 

Loopback capture setup

http://wiki.wireshark.org/CaptureSetup/Loopback

Thursday, May 21, 2009

Security Assertion Markup Language (SAML) – Simple Assertion Example (v1.1)

For the detailed version, read the SAML assertion section of the SAML specification: http://www.oasis-open.org/committees/download.php/3406/oasis-sstc-saml-core-1.1.pdf.

 

Below is a simple example of a SAML assertion (v1.1) that contains the following:

  • Assertion – The container item.
  • Conditions – Conditions that restrict or qualify the usage of the assertion.
  • Attribute Statement – The identity and claim information.
  • Signature – An XML digital signature that cryptographically identifies who issued the token as well as provides assertion integrity

The parts highlighted in yellow are particularly useful from a claims based identity model perspective.

  • MajorVersion and MinorVersion – Identifies the version of SAML being used.
  • NotBefore and NotOnOrAfter – Defines a lifetime for the token.
  • Subject's NameIdentifier – The identity being represented.
  • Subject's Confirmation Method – Used by applications for further confirmation of the subject. Bearer is used when possession of the token is sufficient for authentication purposes. Holder-of-key uses an advanced verification method that encrypts a secret key in the assertion. This key can be used as extra verification that the person sending the token can legitimately use it. For example, during a request to a Secure Token Service (STS), a user is authenticated, given a token, and also given (or negotiates) a proof of possession key. The user may then send a SOAP message to a web service, provide the token as authentication, and sign the message with the proof of possession key. The receiving service decrypts the holder-of-key (because it was encrypted only for the intended web service) and can validate the message signature was generated with the proof key.
  • Attribute Name, Namespace, and Value – This is the representation of a claim in the SAML structure. The claim type is a combination of the Namespace and Name and the claim resource is the value. All attributes represent themselves as a right of PossessProperty.

 

<saml:Assertion MajorVersion="1" MinorVersion="1" AssertionID="_4311722f-8e78-4ae2-8fbe-e24b1b3b9675" Issuer="Issuing STS" IssueInstant="2009-03-05T16:57:06.013Z" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">

<saml:Conditions NotBefore="2009-03-05T16:52:05.419Z" NotOnOrAfter="2009-03-06T16:57:05.419Z"></saml:Conditions>

<saml:AttributeStatement>

<saml:Subject>

<saml:NameIdentifier>AccountName</saml:NameIdentifier>

<saml:SubjectConfirmation>

<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:holder-of-key</saml:ConfirmationMethod>

<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">

<e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">

<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">

<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>

</e:EncryptionMethod>

<KeyInfo>

<o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">

<o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier">gThFQ32F9Eu+Jv+0qvZEuBnjthM=</o:KeyIdentifier>

</o:SecurityTokenReference>

</KeyInfo>

<e:CipherData>

<e:CipherValue>q+72FhXYpZTYy50ACugWCth3cJ1/NyHUg0...</e:CipherValue>

</e:CipherData>

</e:EncryptedKey>

</KeyInfo>

</saml:SubjectConfirmation>

</saml:Subject>

<saml:Attribute AttributeName="name" AttributeNamespace="http://schemas.xmlsoap.org/ws/2005/05/identity/claims">

<saml:AttributeValue>AccountName</saml:AttributeValue>

</saml:Attribute>

<saml:Attribute AttributeName="lastActivityDate" AttributeNamespace="http://host.name.com/ws/2009/05/claims/token">

<saml:AttributeValue>2009-03-05T16:57:06.013Z</saml:AttributeValue>

</saml:Attribute>

</saml:AttributeStatement>

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">

<SignedInfo>

<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod>

<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod>

<Reference URI="#_4311722f-8e78-4ae2-8fbe-e24b1b3b9675">

<Transforms>

<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform>

<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform>

</Transforms>

<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>

<DigestValue>fJDD/+Reo2gQOPQ+dKCfrSbPkhw=</DigestValue>

</Reference>

</SignedInfo>

<SignatureValue>L2n4ZYUleQSqgHVFHU5IOF023Ilind...</SignatureValue>

<KeyInfo>

<o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">

<o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier">gThFQ32F9Eu+Jv+0qvZEuBnjthM=</o:KeyIdentifier>

</o:SecurityTokenReference>

</KeyInfo>

</Signature>

</saml:Assertion>

Saturday, May 16, 2009

.NET COM Interop and Binary Contract Compatibility

When manually creating COM interfaces and classes in .NET, it's critical that the declared order of the .NET operations matches the order in the COM interface. For example, the following IUniformResourceLocator .NET interface matches the layout of the actual COM interface.

using System.Runtime.InteropServices;

 

[

ComImport(),

InterfaceType(ComInterfaceType.InterfaceIsIUnknown),

Guid("CABB0DA0-DA57-11CF-9974-0020AFD79762")

]

public interface IUniformResourceLocator

{

void SetURL(

[In, MarshalAs(UnmanagedType.LPWStr)] string pszURL,

[In, MarshalAs(UnmanagedType.U4)] IURL_SETURL_FLAGS dwInFlags);

 

void GetURL(

[Out, MarshalAs(UnmanagedType.LPWStr)] out string pszURL);

 

void InvokeCommand(

[In] URLINVOKECOMMANDINFO pURLCommandInfo);

}

 

If the methods are declared in alphabetical order (which is what I mistakenly did), then a fairly generic, "Value does not fall within the expected range" error is thrown when calling SetURL.