Я пишу сценарий Powershell для заполнения всех пользователей компании в Active Directory из файла CSV.
В скрипте используется команда Powershell New-ADUser
и он должен знать для каждого пользователя, где путь для их добавления, например:
"OU=IT Dept,OU=Users,DC=local,DC=contoso"
Проблема в том, что в этой Active Directory еще нет пользователей, поэтому организационные единицы не созданы, и всякий раз, когда я запускаю сценарий, если путь не существует, пользователь не создается.
Я искал команду для создания организационных единиц, например New-ADOrganizationalUnit
или dsadd
, однако они не поддерживают рекурсивные создания, например
"OU=Helpdesk,OU=IT Dept,OU=Users,DC=local,DC=contoso"
если
"OU=IT Dept,OU=Users,DC=local,DC=contoso"
еще не существует.
Есть ли способ сделать это, используя New-ADOrganizationalUnit?
Спасибо
Как упоминалось в комментариях Майк, вам нужно пройти через каждый уровень в дереве и проверить наличие предков OU, а затем создать те, которые не существуют, с самого верхнего уровня и ниже.
Так долго как New-ADOrganisationalUnit
не имеет параметра -Recurse, это самый элегантный способ, который я мог придумать:
function New-OrganizationalUnitFromDN
{
[CmdletBinding(SupportsShouldProcess=$true)]
param(
[string]$DN
)
# A regex to split the DN, taking escaped commas into account
$DNRegex = '(?<![\\]),'
# Array to hold each component
[String[]]$MissingOUs = @()
# We'll need to traverse the path, level by level, let's figure out the number of possible levels
$Depth = ($DN -split $DNRegex).Count
# Step through each possible parent OU
for($i = 1;$i -le $Depth;$i++)
{
$NextOU = ($DN -split $DNRegex,$i)[-1]
if($NextOU.IndexOf("OU=") -ne 0 -or [ADSI]::Exists("LDAP://$NextOU"))
{
break
}
else
{
# OU does not exist, remember this for later
$MissingOUs += $NextOU
}
}
# Reverse the order of missing OUs, we want to create the top-most needed level first
[array]::Reverse($MissingOUs)
# Prepare common parameters to be passed to New-ADOrganizationalUnit
$PSBoundParameters.Remove('DN')
# Now create the missing part of the tree, including the desired OU
foreach($OU in $MissingOUs)
{
$newOUName = (($OU -split $DNRegex,2)[0] -split "=")[1]
$newOUPath = ($OU -split $DNRegex,2)[1]
New-ADOrganizationalUnit -Name $newOUName -Path $newOUPath @PSBoundParameters
}
}
Использование с использованием WHATIF
# The desired resulting OU DN
$DN = "OU=Helpdesk,OU=IT Dept,OU=Users,DC=local,DC=contoso"
New-OrganizationalUnitFromDN $DN -WhatIf
Без WHATIF
# The desired resulting OU DN
$DN = "OU=Helpdesk,OU=IT Dept,OU=Users,DC=local,DC=contoso"
New-OrganizationalUnitFromDN $DN
Он сломается, если на пути есть несуществующие контейнеры, не входящие в состав OU.
Выход $NextOU.IndexOf("OU=")
чувствителен к регистру и вернет -1 для всех строчных букв ou=
пытаться: $NextOU.IndexOf("OU=",[StringComparison]"CurrentCultureIgnoreCase")