Transforms/DistinguishedName.ps1
[CmdletBinding()] param ( [Parameter()] [Switch] $FullLoad ) if($FullLoad) { Add-Type @' using System; using System.Collections.Generic; using System.Linq; public class DistinguishedName { private readonly static char _delimiter = ','; private readonly static char _escape = '\\'; private string _distinguishedName; public List<DistinguishedNameToken> Segments { get; set; } public override string ToString() { //performance optimization - return original string instead of parsed and reconstructed return _distinguishedName; //return string.Join(_delimiter.ToString(), Segments.Select(x => x.ToString())); } public DistinguishedName(string distinguishedName) { _distinguishedName = distinguishedName; Segments = new List<DistinguishedNameToken>(); int start = 0; for (int i = 0; i < distinguishedName.Length; i++) { if (distinguishedName[i] == _delimiter && distinguishedName[i - 1] != _escape) { Segments.Add(new DistinguishedNameToken(distinguishedName.Substring(start, i - start))); start = i + 1; } } Segments.Add(new DistinguishedNameToken(distinguishedName.Substring(start))); } } public class DistinguishedNameToken { private readonly static char[] _escapedChars = new char[] { ',', '\\', '#', '+', '<', '>', ';', '"', '=', '/' }; private readonly static char _delimiter = '='; private readonly static char _escape = '\\'; protected string Unescape(string value) { var result = new List<char>(); for (int i = 0; i < value.Length; i++) { if (value[i] == _escape && value[i + 1] == '0') { if (value[i + 2] == 'D') { result.Add('\r'); i += 2; continue; } if (value[i + 2] == 'A') { result.Add('\n'); i += 2; continue; } } //first space is escaped if (i == 0 && value[i] == _escape) { continue; } //last space is escaped if (i == value.Length-2 && value[i] == _escape) { continue; } if (value[i] == _escape) { if (i + 1 < value.Length && _escapedChars.Contains(value[i + 1])) { result.Add(value[i + 1]); i++; } else { result.Add(value[i]); } } else { result.Add(value[i]); } } return new string(result.ToArray()); } protected string Escape(string value) { var result = new List<char>(); for (int i = 0; i < value.Length; i++) { //escaping only first and last space if (value[i] == ' ' && (i == 0 || i == value.Length - 1)) { result.Add(_escape); } if (value[i] == '\r') { result.Add(_escape); result.Add('0'); result.Add('D'); continue; } if (value[i] == '\n') { result.Add(_escape); result.Add('0'); result.Add('A'); continue; } if (_escapedChars.Contains(value[i])) { result.Add(_escape); } result.Add(value[i]); } return new string(result.ToArray()); } public string Qualifier { get; set; } public string Value { get; set; } public DistinguishedNameToken(string token) { var start = token.IndexOf(_delimiter); Qualifier = token.Substring(0, start).Trim(); Value = Unescape(token.Substring(start + 1)); } public override string ToString() { return string.Format("{0}{1}{2}", Qualifier, _delimiter, Escape(Value)); } } '@ } $codeBlock= New-LdapAttributeTransformDefinition -SupportedAttributes @('distinguishedName','member','memberOf') $codeBlock.OnLoad = { param( [string[]]$Values ) Process { foreach($Value in $Values) { new-object DistinguishedName($Value) } } } $codeBlock.OnSave = { param( [DistinguishedName[]]$Values ) Process { foreach($Value in $Values) { $Value.ToString() } } } $codeBlock |