我已经构建了一个脚本来读取所有Active Directory组成员身份并将其保存到文件中。
问题是,Get-ADPrincipalGroupMembership
cmdlet会像这样输出所有组:
CN=Group_Name,OU=Example Mail,OU=Example Management, DC=domain,DC=de
因此,我需要在这里做一些正则表达式和/或替换魔术,以仅用从“ CN =”到第一个“,”的第一个字符串替换整行。
结果将是这样的:
Group_Name
因此,有一个广告组无法替换。我已经知道为什么,但是我不知道该如何解决。在我们的广告中,有一个带有特殊字符的组,如下所示:
CN=AD_Group_Name+up,OU=Example Mail,OU=Example Management, DC=domain,DC=de
因此,由于有一个小的“ +”号,整行甚至都没有被触及。
有人知道为什么会这样吗?
Import-Module ActiveDirectory
# Get Username
Write-Host "Please enter the Username you want to export the AD-Groups from."
$UserName = Read-Host "Username"
# Set Working-Dir and Output-File Block:
$WorkingDir = "C:\Users\USER\Desktop"
Write-Host "Working directory is set to " + $WorkingDir
$OutputFile = $WorkingDir + "\" + $UserName + ".txt"
# Save Results to File
Get-ADPrincipalGroupMembership $UserName |
select -Property distinguishedName |
Out-File $OutputFile -Encoding UTF8
# RegEx-Block to find every AD-Group in Raw Output File and delete all
# unnaccessary information:
[regex]$RegEx_mark_whole_Line = "^.*"
# The ^ matches the start of a line (in Ruby) and .* will match zero or more
# characters other than a newline
[regex]$RegEx_mark_ADGroup_Name = "(?<=CN=).*?(?=,)"
# This regex matches everything behind the first "CN=" in line and stops at
# the first "," in the line. Then it should jump to the next line.
# Replace-Block (line by line): Replace whole line with just the AD group
# name (distinguishedName) of this line.
foreach ($line in Get-Content $OutputFile) {
if ($line -like "CN=*") {
$separator = "CN=",","
$option = [System.StringSplitOptions]::RemoveEmptyEntries
$ADGroup = $line.Split($separator, $option)
(Get-Content $OutputFile) -replace $line, $ADGroup[0] |
Set-Content $OutputFile -Encoding UTF8
}
}
答案 0 :(得分:1)
您的组名包含一个字符(+
),该字符在正则表达式中具有特殊含义(是前一个表达式的一倍或更多倍)。要禁用特殊字符,请在替换操作中转义搜索字符串:
... -replace [regex]::Escape($line), $ADGroup[0]
但是,我首先看不到您需要什么替代品。基本上,您将输出文件中的一行替换为之前提取过的该行 中的子字符串。只需将该子字符串写入输出文件即可。
$separator = 'CN=', ','
$option = [StringSplitOptions]::RemoveEmptyEntries
(Get-Content $OutputFile) | ForEach-Object {
$_.Split($separator, $option)[0]
} | Set-Content $OutputFile
更好的方法是使用Get-ADObject
cmdlet扩展组成员的名称:
Get-ADPrincipalGroupMembership $UserName |
Get-ADObject |
Select-Object -Expand Name
答案 1 :(得分:0)
就使用正则表达式而言,Ansgar的答案要好得多,但我认为在这种情况下,您可以使用IndexOf函数进行变通。在您的if语句中,您可以执行以下操作:
if ($line -like "CN=*") {
$ADGroup = $line.Substring(3, $line.IndexOf(',')-3)
}
此方法在这里起作用的原因是您知道输出将以CN = YourGroupName开头,这意味着您知道所需的字符串从第4个字符开始。其次,您知道组名将不包含任何逗号,这意味着IndexOf(',')将始终找到该字符串的末尾,因此您不必担心nth occurrence of a string in a string。
答案 2 :(得分:0)
首先,根据您在这里的操作,这可能是一个好主意,也可能不是一个好主意。 CN是/ not /不可变的,因此,如果将CN作为密钥存储在某个地方,则很可能会遇到问题。该组的objectGUID
属性是一个很好的主键。
就获得此价值而言,我认为您可以简化很多工作。 cmdlet输出的name
属性将始终具有您想要的值:
Get-ADPrincipalGroupMembership <username> | select name