Сопоставьте регулярное выражение и замените ошибку специальными характеристиками
Я создал скрипт для чтения всех членств в группах Active Directory и сохранения их в файл. Проблема в том, Get-ADPrincipalGroupMembership
Командлет выводит все группы следующим образом:
CN = Group_Name,OU= Пример почты,OU= Пример управления, DC= домен,DC=de
Так что мне нужно сделать немного магии регулярных выражений и / или замены, чтобы заменить всю строку только первой строкой, начинающейся с "CN=" до первой ",".
Результат будет таким:
Имя группы
Итак, есть одна группа AD, которая не будет заменена. Я уже понял, почему, но я не знаю, как обойти это. В нашей AD есть группа со специальным символом, что-то вроде этого:
CN = AD_Group_Name + up,OU= Пример почты,OU= Пример управления, DC= домен,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
}
}
3 ответа
Во-первых, в зависимости от того, что вы делаете здесь, это может быть или не быть хорошей идеей. CN является / не / неизменным, поэтому, если вы храните его где-то в качестве ключа, вы, вероятно, столкнетесь с проблемами в будущем. objectGUID
свойство группы является хорошим первичным ключом.
Что касается получения этого значения, я думаю, вы можете значительно упростить это. name
свойство, которое выводит командлет, всегда будет иметь желаемое значение:
Get-ADPrincipalGroupMembership <username> | select name
Название вашей группы содержит символ (+
), который имеет особое значение в регулярном выражении (один или несколько раз предыдущего выражения). Чтобы отключить специальные символы, экранируйте строку поиска в операции замены:
... -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
Командлет для расширения имен членов группы:
Get-ADPrincipalGroupMembership $UserName |
Get-ADObject |
Select-Object -Expand Name
Ответ Ансгара намного лучше с точки зрения использования регулярных выражений, но я считаю, что в этом случае вы могли бы сделать грязный обходной путь с функцией IndexOf. В своем условии if вы можете сделать следующее:
if ($line -like "CN=*") {
$ADGroup = $line.Substring(3, $line.IndexOf(',')-3)
}
Причина, по которой это работает, заключается в том, что вы знаете, что вывод будет начинаться с CN=YourGroupName, что означает, что вы знаете, что строка, которую вы хотите, начинается с 4-го символа. Во-вторых, вы знаете, что имя группы не будет содержать запятой, то есть IndexOf(',') всегда будет находить конец этой строки, поэтому вам не нужно беспокоиться о n-м появлении строки в строке.