Powershell проверяет, существует ли OU
Я пытаюсь проверить, существует ли OU перед его созданием. Моя проблема в том, что у меня есть 2 материнских OU "пользователь по сайту" и "группа по сайту", и мне нужно иметь точно такой же OU в этих 2, 1 для хранения пользователей, другой для хранения групп.
до сих пор я использовал эту функцию :
function CheckOUExist
{
param($OUToSeek)
$LDAPPath = "LDAP://dc=Domain,dc=local"
$seek = [System.DirectoryServices.DirectorySearcher]$LDAPPath
$seek.Filter = “(&(name=$OUToSeek)(objectCategory=organizationalunit))”
$Result = $seek.FindOne()
return $Result
}
есть моя проблема, я всегда получаю OU, существующий в" GROUP BY SITE", даже если $LDAPPath = "OU=USERS by SITE,DC=Domain, DC=local". Я что-то упускаю? Есть ли способ для [Система.DirectoryServices.DirectorySearcher] работать только в OU, который я дал в $LDAPPath?
Если вам нужна более точная деталь, я с радостью их предоставит.
спасибо заранее.
5 ответов
попробуйте метод Exists, вы получите true/false соответственно:
[adsi]::Exists("LDAP://OU=test,DC=domain,DC=com")
следующее, Как предложил Шей, отлично работает, если вы работаете с чистыми данными.
[string] $Path = 'OU=test,DC=domain,DC=com'
[adsi]::Exists("LDAP://$Path")
Спасибо за эту отличную отправную точку! Однако, если вы проверяете потенциально нечистые данные, вы получите сообщение об ошибке. Некоторые примеры возможных ошибок:
- если что-то не правильно отформатирован
- (ERR: указан недопустимый синтаксис dn)
- если домен не существовать
- (ERR: сервер не работает)
- если домен не будет общаться с вами
- (ERR: реферал был возвращен с сервера)
все эти ошибки должны быть пойманы с [System.Management.Automation.RuntimeException]
или вы можете просто оставить операторе catch пустым, чтобы поймать все.
Пример:
[string] $Path = 'OU=test,DC=domain,DC=com'
try {
$ou_exists = [adsi]::Exists("LDAP://$Path")
} catch {
# If invalid format, error is thrown.
Throw("Supplied Path is invalid.`n$_")
}
if (-not $ou_exists) {
Throw('Supplied Path does not exist.')
} else {
Write-Debug "Path Exists: $Path"
}
больше подробности: http://go.vertigion.com/PowerShell-CheckingOUExists
проблема заключается в построении объекта DirectorySearcher. Чтобы правильно установить корень поиска, DirectorySearcher должен быть построен с помощью объекта DirectoryEntry (ускоритель типа[ADSI]), в то время как вы используете строку. Когда используется строка, строка используется в качестве фильтра LDAP, а корень поиска равен null, в результате чего поисковик использует корень текущего домена. Вот почему похоже, что он не ищет OU, который вы хотите.
Я думаю, что вы получите результаты, которые вы ищете, если вы делаете что-то вроде следующего:
$searchroot = [adsi]"LDAP://OU=USERS BY SITE,DC=Domain,DC=local"
$seek = New-Object System.DirectoryServices.DirectorySearcher($searchroot)
$seek.Filter = "(&(name=$OUToSeek)(objectCategory=organizationalunit))"
... etc ...
обратите внимание, что сначала создается DirectoryEntry, который затем используется для создания DirectorySearcher.
как насчет:
#Requires -Version 3.0
# Ensure the 'AD:' PSDrive is loaded.
if (-not (Get-PSDrive -Name 'AD' -ErrorAction Ignore)) {
Import-Module ActiveDirectory -ErrorAction Stop
if (-not (Get-PSDrive -Name 'AD' -ErrorAction Silent)) {
Throw [System.Management.Automation.DriveNotFoundException] "$($Error[0]) You're likely using an older version of Windows ($([System.Environment]::OSVersion.Version)) where the 'AD:' PSDrive isn't supported."
}
}
Теперь AD:
PSDrive загружен, у нас есть несколько вариантов:
$ou = "OU=Test,DC=Contoso,DC=com"
$adpath = "AD:$ou"
# Check if this OU Exist
Test-Path $adpath
# Throw Error if OU doesn't exist
Join-Path 'AD:' $ou -Resolve
дополнительная информация по этой теме:играть с объявлением: привод для удовольствия и прибыли
Import-Module ActiveDirectory
Function CheckIfGroupExists{
Param($Group)
try{
Get-ADGroup $Group
}
catch{
New-ADGroup $Group -GroupScope Universal
}
}
также будет работать