Extensiones de String útiles para usar PowerShell

23/09/2010 - Actualizado con la sugerencia de Rido.

Para utilizar PowerShell desde .NET, necesitaremos entre otras cosas crear un Runspace con el que tener acceso al Pipeline y poder así ejecutar comandos PowerShell. Bien, para crear ese Runspace utilizando credenciales, tendremos que usar un objeto PSCredential y la contraseña nos la van a pedir en un objeto SecureString (tiene sentido, no?).

A continuación tenéis unas extensiones de String para convertir el String a SecureString. También hay otra para escapar las cadenas de texto según las normas de PowerShell.

 public static class StringExtensions
{
    public static SecureString ToSecureString(this String s)
    {
        if (string.IsNullOrEmpty(s)) return null;
        SecureString secure = new SecureString();
        Array.ForEach(s.ToCharArray(), secure.AppendChar);
        return secure;
    }

    public static String ToPSEscapedString(this String s)
    {
        return String.Join("", s.ToCharArray().Select<Char, String>(c => c.ToPSEscapeSequence()).ToArray<String>());
    }

    public static String ToPSEscapeSequence(this char c)
    {
        string result = c.ToString();
        switch(c)
        {
            case '\n':
                result = "`n";
                break;
            case '\r':
                result = "`r";
                break;
            case '\t':
                result = "`t";
                break;
            case '"':
                result = "`\"";
                break;
            case '\'':
                result = "`'";
                break;
            case '`':
                result = "``";
                break;
        }
        return result;
    }
}

Y un par de test…

 [TestClass]
public class StringExtensionsTest
{
    [TestMethod]
    public void ToSecureStringTest()
    {
        string ejemplo = "MiTextoSinAsegurar";
        SecureString stringSeguro = ejemplo.ToSecureString();
        Assert.AreEqual(stringSeguro.Length, ejemplo.Length);
        Assert.IsTrue(stringSeguro.IsReadOnly()); 
    }

    [TestMethod]
    public void ToPSEscapedStringTest()
    {
        string s = "\"DoubleQuote\nNewline\rCarriageReturn\tTab'SingleQuote`BackQuote";
        Assert.AreEqual("`\"DoubleQuote`nNewline`rCarriageReturn`tTab`'SingleQuote``BackQuote", s.ToPSEscapedString());

        s = new String('"', 1000);
        Assert.AreEqual(2000, s.ToPSEscapedString().Length);
    }

}