【问题标题】:PowerShell: Split user defined distinguished name into individual partsPowerShell:将用户定义的专有名称拆分为单独的部分
【发布时间】:2018-01-22 22:50:27
【问题描述】:

我有一个接受来自用户的一些 DN 的 GUI。我知道如何获取文本,但我一生都无法弄清楚如何将此 DN 拆分为各个部分。零件的数量可能会有所不同。例如:

$string1 = "ou=this,ou=is,dc=a,dc=string"
$string2 = "ou=this,ou=is,ou=another,dc=dn,dc=string

我正在尝试做的是将 ou 与 dc 分开,如果它们不存在则创建 ou。我只是不知道如何将 ou 与 dc 分开并将它们变成单独的字符串,所以我将留下:

$newString1 = "ou=this,ou=is"
$newString2 = "dc=a,dc=string"
$newString3 = "this,ou=is,ou=another"
$newString4 = "dc=dn,dc=string

我知道我可以使用$string1.Split(",") 拆分字符串,但我现在不知道如何将各个值存储在新变量中。我对 PowerShell 相当陌生,所以任何建议都将不胜感激。

我知道我可以仅根据我拥有的信息创建 ou,但我需要将它们分开以用于将在代码中完成的其他工作。也很高兴看到他们分开,这样我就可以单独抓住欧了。

【问题讨论】:

  • 您应该将这些附加注释编辑到您的问题中,而不是添加 cmets。另外,您是否正在使用两个专有名称?或者是否有一个变量号,比如从文件中读取?如果您有 2 个 DN,则拥有 $newString1$newString4 变量是可以的,但如果您有 20...或 200 个,则没有那么多。
  • 我将获得两个 DN。一个用于组,一个用于用户。我基本上是让用户定义他们希望组和用户在 Active Directory 上的位置,然后让我的脚本创建这些目录。总而言之,我真的很想学习如何在 Powershell 中将这样的字符串分解成单独的块,因为它将是用户定义的。

标签: string powershell join split distinguishedname


【解决方案1】:

尝试将它们拆分成一个数组,如下所示:

c:\>$string = "ou=this,ou=is,ou=another,dc=dn,dc=string"
c:\>$array = $string.split(",")
c:\>$array
ou=this
ou=is
ou=another
dc=dn
dc=string
c:\>

通过数组可以确定元素个数:

c:\>$array.Length
5
c:\>

或者循环处理:

c:\> foreach ($i in $array) { $i }
ou=this
ou=is
ou=another
dc=dn
dc=string
c:\>

显然,该循环与仅输出 $array 变量没有什么不同,但应该提供有关如何使用循环的见解。

希望这会有所帮助。

【讨论】:

  • 我得到了 foreach 循环;但是,为什么我不能这样做: foreach ($i in $array) { if ($i -contains "ou") { Write-Host $i}} 我仍然不知道如何使用分开的部分。我计划反转阵列,我知道该怎么做,但不知道如何拉出并使用各个块:(。
【解决方案2】:

希望这对所询问的内容有所帮助。这假设您希望将相对专有名称存储在两组中:在您点击 dc= 之前的那些和在您点击 dc= 之后(包括)之后的那些。

$string1 = "ou=this,ou=is,dc=a,dc=string"
$string2 = "ou=this,ou=is,ou=another,dc=dn,dc=string"

foreach ($dn in $string1, $string2)
{
    # Break the distinguished name up into a list of relative distinguished names
    $rdnList = $dn -split ',';
    $cnList = @();
    $nextIndex = 0;

    while ($nextIndex -lt $rdnList.Length)
    {
        $rdn = $rdnList[$nextIndex];
        $name, $value = $rdn -split '=';

        # Stop looping if we've hit a dc= RDN
        if ($name -eq 'dc')
        {
            break;
        }

        $cnList += $rdn;
        $nextIndex++;
    }
    # The remainder of the array is our RDN list
    $dcList = $rdnList[$nextIndex..($rdnList.Length - 1)];

    # Reassemble both lists into strings
    $cnText = $cnList -join ',';
    $dcText = $dcList -join ',';

    # The data has now been processed; print it out    
    Write-Host "`$dn: $dn";
    Write-Host "`$cnText: $cnText";
    Write-host "`$dcText: $dcText";
    Write-Host;
}

输出是...

$dn: ou=this,ou=is,dc=a,dc=string
$cnText: ou=this,ou=is
$dcText: dc=a,dc=string

$dn: ou=this,ou=is,ou=another,dc=dn,dc=string
$cnText: ou=this,ou=is,ou=another
$dcText: dc=dn,dc=string

【讨论】:

  • 谢谢,感谢您的快速回复!这比我想象的要难得多。
  • 最好avoid Write-Host
  • @mklement0 这只是诊断代码,用于显示拆分前后的字符串。我不知道作者打算用这个做什么,但他们会在那里放置代码来使用这些变量。
  • @BACON:明白了,但我仍然建议不要在 SO 答案中使用 Write-Host,至少不是没有解释,因为担心没有经验的用户会理解,但错误地推断 Write-Host 是等价的echo 在传统的贝壳中。使用 PowerShell 的隐式默认输出就可以了(这是一个很好的概念)。如果您真的想显示诊断输出,请使用Write-Verbose -Verbose ...
【解决方案3】:
# Define input strings.
$strings = 'ou=this,ou=is,dc=a,dc=string',
           'ou=this,ou=is,ou=another,dc=dn,dc=string'

foreach ($string in $strings) {

  # Split each string into the ou=... part and the dc=... part.
  $ouPart, $dcPart = $string -split ',(?=dc=)', 2

  # Now split each part into its constituent OU and DC names as arrays.
  $ous = $ouPart -split '(?:^|,)ou=' -ne '' -replace '\\'
  $dcs = $dcPart -split '(?:^|,)dc=' -ne '' -replace '\\'

  # Output result.
  [pscustomobject] @{ ouPart = $ouPart; dcPart = $dcPart; ous = $ous; dcs = $dcs}

}

以上产出:

ouPart                   dcPart          ous                 dcs         
------                   ------          ---                 ---         
ou=this,ou=is            dc=a,dc=string  {this, is}          {a, string} 
ou=this,ou=is,ou=another dc=dn,dc=string {this, is, another} {dn, string}

说明:

  • $string -split ',(?=dc=)', 2 将输入字符串拆分为 2 部分,通过子字符串 ,dc= 的第一次出现。只有两半之间的, 被删除,因为(?=...) - 一个(肯定的)前瞻断言 - 匹配封闭的表达式,但不捕获它;在这种情况下,它确保第二半仍然以dc= 开头。

  • $ouPart, $dcPart = ...-split 返回的 2 元素数组的元素分配给各个变量。

  • $ouPart -split '(?:^|,)ou='ou=...,ou=... 的一半拆分为嵌入的 OU 名称数组(拆分 dc=...,dc=... 的一半类似):

    • (?:^|,)ou= 匹配 ou= 出现在字符串开头 (^) 或 (|) , 之前。
      • ^|, 括在非捕获 子表达式((?:...)) 中可确保子表达式不包含在-split 结果中。
  • -ne '' 过滤掉由出现在输入字符串开始处的-split分隔符表达式产生的空数组元素。

  • -replace '\\' 从每个名称中删除\ 实例,因为它们可能包含\ 转义字符,例如值-嵌入 , 转义为@987654347 @

  • [pscustomobject] @{ ... } (PSv3+) 从哈希表文字 (@{ .... }) 构造自定义对象,并将提取的值作为属性。 请注意,简单地不将对象分配给变量它是隐式输出,PowerShell 的默认输出格式会自动提供漂亮的表格表示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多