Wensveen's Blog

October 19, 2018

Quickie: Generate EXM.CryptographicKey with PowerShell

Filed under: Uncategorized — Tags: , , — wensveen @ 9:37 am

The Sitecore documentation states that the EXM.InternalApiKey , EXM.CryptographicKey and the EXM.AuthenticationKey

must be represented in hexadecimal format by 64 characters and you can only use the symbols 0-9 and A-F.

However, it doesn’t say how to obtain said keys, nor the security considerations and implications of said keys. It’s obviously a Bad Thingtm to copy the example, or just use 64 zeroes (or any other character that fits the pattern).

I came up with two quick ways to generate the keys, which are essentially a hexadecimal representation of a 32-byte sequence.

Method 1 (use the .Net Random class)
$r = New-Object Random; $key = ""; for ($i = 0; $i -lt 32; $i++) { $key += $r.Next(256).ToString("X2"); }; $key | Set-Clipboard

Cons: You have to trust the .Net RNG to be secure enough.

Method 2 (use random.org):
(Invoke-WebRequest 'https://www.random.org/cgi-bin/randbyte?nbytes=32&format=h').Content.ToUpper() -Replace "[`n ]","" | Set-Clipboard

Cons: You need an active internet connection (and you need to trust random.org)

Both commands place the generated key on the clipboard, ready to paste into your configuration files.

HTH,
Matthijs

November 12, 2012

Synchronous .NET event handling with PowerShell

Filed under: Uncategorized — Tags: , , , — wensveen @ 11:12 pm

There are multiple ways in Windows PowerShell to handle events generated by objects in the .NET framework. The most common, or at least, the most documented way to register an event handler to a .NET object is with Register-ObjectEvent. Usage is fairly straightforward: Register-ObjectEvent -InputObject $obj -EventName "BeforeProcess" -Action { Write-Host "BeforeProcess called" }.

The thing is, that the action you registered with Register-ObjectEvent is called asynchronously. This means that the code that generates the BeforeProcess event doesn’t have to wait for the action to end. Consider, for example, a .NET class:

namespace Echo
{
	public class Echo
	{
		public event EventHandler<EchoEventArgs> BeforeEcho;

		public void EchoMessages(string messages)
		{
			foreach (string message in messages.Split(','))
			{
				EchoEventArgs args = new EchoEventArgs { Message = message };
				if (BeforeEcho != null)
				{
					BeforeEcho(this, args);
				}

				Console.WriteLine(message);
			}
		}
	}

	public class EchoEventArgs : EventArgs
	{
		public string Message { get; set; }
	}
}

Now, create an Echo object in PowerShell:

[void] [System.Reflection.Assembly]::LoadFrom('echo.dll')
$echoObject = New-Object Echo.Echo

Running it without event handlers:

$echoObject.EchoMessages('Mary,had,a,little,lamb')

should yield:
Mary
had
a
little
lamb

Now, when you attach an event handler with Register-ObjectEvent:

Register-ObjectEvent -InputObject $echoObject -EventName "BeforeEcho" -Action { Write-Host ("ObjectEvent: " + $EventArgs.Message) }
$echoObject.EchoMessages('Foo,bar')

Result:
Foo
bar
ObjectEvent: Foo
ObjectEvent: bar

As you can see, the foreach loop in EchoMessages doesn’t wait for the Action to finish, before going on to the next message.

Very often, this is exactly what you want. A lot of examples use System.Timers.Timer, where you just want to execute something every so-and-so hours. But once in a while, you may need the event handler to finish before the next line of code is executed.

Let’s say we want the event handler to be able to skip certain messages, or cancel the rest of the messages altogether. Or maybe modify the message before it is written.

namespace Echo
{
	public class Echo
	{
		public event EventHandler<EchoEventArgs> BeforeEcho;

		public void EchoMessages(string messages)
		{
			foreach (string message in messages.Split(','))
			{
				EchoEventArgs args = new EchoEventArgs { Message = message };
				if (BeforeEcho != null)
				{
					BeforeEcho(this, args);
				}

				if (args.Cancel)
				{
					break;
				}
				else if (!args.Skip)
				{
					Console.WriteLine(args.Message);
				}
			}
		}
	}

	public class EchoEventArgs : EventArgs
	{
		public string Message { get; set; }
		public bool Skip { get; set; }
		public bool Cancel { get; set; }
	}
}

Now, let’s say I want to cancel all messages straight away:

Register-ObjectEvent -InputObject $echoObject -EventName "BeforeEcho" -Action { $EventArgs.Cancel = $true }
$echoObject.EchoMessages('1,2,3,4,5')

Result:
1
2
3
4
5

Why? Because you’re already too late. When you decide to cancel, the number is already outputted. Next invocation is with a new EchoEventArgs object. So we need to register the event handler for synchronous execution. Unfortunately, it isn’t documented at all how to do this. Looking with Reflector, we can see the compiler generated two methods for us: add_BeforeEcho and remove_BeforeEcho:
Echo class in Reflector

So, when we register the event handler with add_BeforeEcho, it all works as expected:

$echoObject.add_BeforeEcho({
  param($Source, $EventArgs)
  if ($EventArgs.Message -eq '2') {
    $EventArgs.Skip = $true
  } elseif ($EventArgs.Message -eq '7') {
    $EventArgs.Cancel = $true
  } else {
    $EventArgs.Message = ($EventArgs.Message + ".00")
  }
})
$echoObject.EchoMessages('1,2,3,4,5,6,7,8,9,10')

Result:
1.00
3.00
4.00
5.00
6.00

Hurray!

Blog at WordPress.com.