用户被创建多次

问题描述 投票:0回答:2

我正在尝试编写一个脚本来为我的 DC 创建组、用户和 OU。它应该添加 250 个用户,并将前 60 个用户放入 RODC,然后将其他 250 个用户随机拆分到 OU 中,但在将前 60 个用户放入 RODC OU 后,它将尝试将相同的用户添加到其他用户出现此错误的 OU:

dsadd 失败:cn=amohn1,ou=DB_Engineers,ou=Programmers,ou=BRAAN,dc=BRAAN,dc=COM:指定的帐户已存在。

我不确定它为什么这样做。这是我的脚本:

$scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent ##Grabs the directory path of the script to be used as a relevant path.##
$domainname = (Get-ADDomain -Current LocalComputer).NetBIOSName ##Grabs the computers domainname##
$filecontent = Get-Content $scriptDir\Users.txt ##Reads the .txt file##

##Setting global variables.##
$iteration = 0
$AdminCount = 0
$ComputerName = "default"
$ComputerNumber = 1
$ComputerType = "default"
$ServicePack = ""

if($domainname -eq "BRAAN") ##Is the computer on the BRAAN domain?##
{
    ##Build OU and Group Structure inside the domain.##
    dsadd ou "ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd ou "ou=CustomDom,dc=BRAAN,dc=COM"
    dsadd ou "ou=BRAANComputers,ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd ou "ou=IT,ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd ou "ou=HR,ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd ou "ou=Sales,ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd ou "ou=Executive,ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd ou "ou=Programmers,ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd ou "ou=DB_Engineers,ou=Programmers,ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd ou "ou=Content_Experts,ou=Programmers,ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd ou "ou=Animators,ou=Programmers,ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd ou "ou=Operations,ou=CustomDom,dc=BRAAN,dc=COM"
    dsadd ou "ou=RODC,dc=BRAAN,dc=COM"
    dsadd group "cn=IT_Staff,ou=IT,ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd group "cn=HR_Staff,ou=HR,ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd group "cn=Sales_Staff,ou=Sales,ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd group "cn=Executive_Staff,ou=Executive,ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd group "cn=DB_Engineers_Staff,ou=BRAAN,dc=BRAAN,dc=COM"
    dsadd group "cn=Content_Experts_Staff,ou=BRAAN,dc=BRAAN,dc=COM" 
    dsadd group "cn=Animators_Staff,ou=BRAAN,dc=BRAAN,dc=COM"  
    dsadd group "cn=Operations_Staff,ou=Operations,ou=CustomDom,dc=BRAAN,dc=COM" 
    dsadd group "cn=RODC_Staff,ou=RODC,dc=BRAAN,dc=COM" 
    
    ##Sets the computer name##
    $ComputerName = "Braan-"
    while($iteration -ne 80) ##While loop used to create ComputerObjects.##
    {
        $random = Get-Random -Minimum 1 -Maximum 3 ##Random number used to randomly assign OperatingSystem to the computers.##
        if($random -eq 1)
        {
            $ComputerType = "Windows 10"
        }
        ##Creation of PCs.##
        $Computer = $ComputerName+$ComputerNumber
        New-ADComputer -Name $Computer -OperatingSystem $ComputerType -OperatingSystemServicePack $ServicePack -Path "ou=BRAANComputers,ou=BRAAN,dc=BRAAN,dc=COM"
        $iteration++
        $ComputerNumber++
    }
    ##Resetting the iteration variable.##
    $iteration = 0
    ##Resetting the random variable.##
    $random = 0
    while($iteration -ne 250) ##Begins loop for user creation.##
    {     
        while($iteration -lt 60) ##Places first 60 users into the RODC OU.##
        {
            ##Splits the values in the .txt file via spaces.##
            $values = $filecontent[$iteration] -split(' ')
            $usrname = $values[0]
            dsadd user "cn=$usrname,ou=RODC,dc=BRAAN,dc=COM" -fn $values[1] -ln $values[2] -disabled no -pwd "Password1" -memberof "cn=RODC_Staff,ou=RODC,dc=BRAAN,dc=com" ##Create user and add to group.##
            $iteration++
        }

        $values = $filecontent[$iteration] -split(' ')
        ##Random used to determine which OUs a user is put in.##
        $random = Get-Random -Minimum 1 -Maximum 9
        $usrname = $values[0]
        ##Sets iteration to 70 above zero so we have no repeat accounts.##
        $iteration = 70
   
        while($iteration -ne 180)##Begins loop for user creation.##
        {
            if($random -eq 1) ##IT OU.##
            {
                dsadd user "cn=$usrname,ou=IT,ou=BRAAN,dc=BRAAN,dc=COM" -fn $values[1] -ln $values[2] -disabled no -pwd "Password1" -memberof "cn=IT_Staff,ou=IT,ou=BRAAN,dc=BRAAN,dc=com" ##Create user and add to group.##
            }elseif($random -eq 2) ##HR OU.##
            {
                dsadd user "cn=$usrname,ou=HR,ou=BRAAN,dc=BRAAN,dc=COM" -fn $values[1] -ln $values[2] -disabled no -pwd "Password1" -memberof "cn=HR_Staff,ou=HR,ou=BRAAN,dc=BRAAN,dc=com" ##Create user and add to group.##
            }elseif($random -eq 3) ##Sales OU.##
            {
                dsadd user "cn=$usrname,ou=Sales,ou=BRAAN,dc=BRAAN,dc=COM" -fn $values[1] -ln $values[2] -disabled no -pwd "Password1" -memberof "cn=Sales_Staff,ou=Sales,ou=BRAAN,dc=BRAAN,dc=com" ##Create user and add to group.##
            }elseif($random -eq 4) ##Finance OU.##
            {
                dsadd user "cn=$usrname,ou=Finance,ou=BRAAN,dc=BRAAN,dc=COM" -fn $values[1] -ln $values[2] -disabled no -pwd "Password1" -memberof "cn=Finance_Staff,ou=Finance,ou=BRAAN,dc=BRAAN,dc=com" ##Create user and add to group.##
            }elseif($random -eq 5) ##Executives OU.##
            {
                dsadd user "cn=$usrname,ou=Executives,ou=BRAAN,dc=BRAAN,dc=COM" -fn $values[1] -ln $values[2] -disabled no -pwd "Password1" -memberof "cn=Executives_Staff,ou=Executives,ou=BRAAN,dc=BRAAN,dc=com" ##Create user and add to group.##
            }elseif($random -eq 6) ##DB_Engineers Group.##
            {
                dsadd user "cn=$usrname,ou=DB_Engineers,ou=Programmers,ou=BRAAN,dc=BRAAN,dc=COM" -fn $values[1] -ln $values[2] -disabled no -pwd "Password1" -memberof "cn=DB_Engineers_Staff,ou=DB_Engineers,ou=Programmers,ou=BRAAN,dc=BRAAN,dc=com" ##Create user and add to group.##
            }elseif($random -eq 7) ##Content_Experts Group.##
            {
                dsadd user "cn=$usrname,ou=Content_Experts,ou=Programmers,ou=BRAAN,dc=BRAAN,dc=COM" -fn $values[1] -ln $values[2] -disabled no -pwd "Password1" -memberof "cn=Content_Experts_Staff,ou=Content_Experts,ou=Programmers,ou=BRAAN,dc=BRAAN,dc=com" ##Create user and add to group.##
            }
            elseif($random -eq 8)##Animators Group.##
            {
                dsadd user "cn=$usrname,ou=Animators,ou=BRAAN,dc=BRAAN,dc=COM" -fn $values[1] -ln $values[2] -disabled no -pwd "Password1" -memberof "cn=Animators_Staff,ou=Animators,ou=Programmers,ou=BRAAN,dc=BRAAN,dc=com" ##Create user and add to group.##
            }
            ##Checks if admin accounts are needed, if so then adds one admin account given that they are also in the Management OU.##
            if($AdminCount -ne 2 -and $random -eq 2)
            {
                $AdminCount++
                dsmod group "cn=Domain Admins,cn=Users,dc=BRAAN,dc=COM" -addmbr "cn=$usrname,ou=Management,ou=BRAAN,dc=BRAAN,dc=com"    ##Adds account to Domain Admins.##
                dsmod group "cn=Enterprise Admins,cn=Users,dc=BRAAN,dc=COM" -addmbr "cn=$usrname,ou=Management,ou=BRAAN,dc=BRAAN,dc=com" ##Adds account to Enterprise Admins.##
            }
            $iteration++
        }
    }
}else ##Computer is not on any of the above domains and script will exit.##
{
    Write-Host "Domain not listed, exiting script."
}
powershell while-loop active-directory user-accounts
2个回答
2
投票

因为您不断将

$iteration
变量重置为
70

在外部

while($iteration -ne 250)
循环第一次运行期间:

while ($iteration -ne 250) {

    # runs 60 times ($iteration -in 0..59)
    while ($iteration -lt 60) {
        $iteration++
    }

    # $iteration is reset (to a higher value)
    $iteration = 70

    # runs 110 times ($iteration -in 70..179)
    while ($iteration -ne 180) {
        $iteration++
    }
}

好吧,到目前为止一切顺利 -

$iteration
不是 250,所以循环体再次运行:

while ($iteration -ne 250) {

    # $iteration is now 180, so we skip this loop
    while ($iteration -lt 60) {
        $iteration++
    }

    # $iteration is reset (this time to a lower value!)
    $iteration = 70 # <-- endless loop detected

    # runs another 110 times ($iteration -in 70..179)
    while ($iteration -ne 180) {
        $iteration++
    }
}

1
投票

你的数学在这里不成立。你说...

应该添加250个用户,并将前60个放入rodc中,然后将其他250个随机分配到ous中

...但是没有“其他250”。初始 60 需要“其他 190”,总计 为 250。

此外,给出这个骨架代码......

##Resetting the iteration variable.##
$iteration = 0
$userCount = 0

while ($iteration -ne 250) { ##Begins loop for user creation.##     
    while ($iteration -lt 60) { ##Places first 60 users into the RODC OU.##
        $iteration++
        $userCount++
    }

    ##Sets iteration to 70 above zero so we have no repeat accounts.##
    $iteration = 70

    while ($iteration -ne 180) { ##Begins loop for user creation.##
        $iteration++
        $userCount++
    }
}

...如果应该执行

while ($iteration -ne 250)
的一次迭代,那么首先,它根本不应该是循环,但在第一次迭代中,计数是这样的...

  • while ($iteration -lt 60)
    :60 次迭代 (0..59)
    • 总用户60个,RODC用户60个
  • $iteration = 70
    :0 次迭代(60..69 跳过
    • 总用户60个,RODC用户60个
  • while ($iteration -ne 180)
    :110 次迭代 (70..179)
    • 总用户170个,RODC用户60个

如您所见,我们只有 170 个用户。由于 @MathiasR.Jessen 的回答中指出的错误,外部

while
是一个无限循环。在随后的每次迭代中,不会进入
while ($iteration -lt 60)
循环,但会进入
while ($iteration -ne 180)
循环,因此用户数量每次都会增长 70..179 = 110 个用户:170、280、390 等;没有一个是 250。

简而言之,不要这样做。它不应该需要这种级别的复杂性(即带有跳过的迭代器的嵌套循环)从 0..60 到 60..250 进行计数,也不应该需要这种级别的分析来确认这是否是它实际在做的事情。相反,一个简单的修复方法是将内部

while
循环转换为
if
/
else
的分支,并且仅在循环末尾修改
$iteration
...

while ($iteration -ne 250) { ##Begins loop for user creation.##     
    if ($iteration -lt 60) {
        ##Places first 60 users into the RODC OU.##
        # dsadd user "cn=$usrname,ou=RODC,dc=BRAAN,dc=COM" ...
    } else {
        ##Begins user creation.##
        # dsadd user ...
    }
    $iteration++
}

这也可以很容易地转化为

for
循环。

更好的是,由于范围 0..60 和 60..250 的逻辑重叠最小,它们甚至不需要占用同一个循环。我还认为这使得意图更加明确,这是一件好事。如果您想要 60 个 RODC 用户,请编写一个循环来执行此操作...

for ($rodcUserCount = 0; $rodcUserCount -lt 60; $rodcUserCount++)
{
    ##Places first 60 users into the RODC OU.##
    # dsadd user "cn=$usrname,ou=RODC,dc=BRAAN,dc=COM" ...
}

如果您想要另外 190 个普通用户,请继续另一个循环...

for ($generalUserCount = 0; $generalUserCount -lt 190; $generalUserCount++)
{
    ##Begins user creation.##
    # dsadd user ...
}

您有两个简单直接的循环来创建 250 个用户。请注意,我命名迭代变量是为了清楚地表明正在计算的内容。

编写这样清晰易懂的代码将对你当前的自己、未来的自己以及可能需要使用此代码的任何其他人有很大帮助。


我发现的其他一些我认为是错误的东西......

  • 您正在设置用户创建循环的
    $random
    outside...
    $random = Get-Random -Minimum 1 -Maximum 9
    $usrname = $values[0]
    ##Sets iteration to 70 above zero so we have no repeat accounts.##
    $iteration = 70
    
    while ($iteration -ne 180) { ##Begins loop for user creation.##
    

这意味着该循环的 110 次迭代中的每一次都将具有相同的

$random
值,因此会在同一部门中创建这些用户。相反,我认为您想在循环体的开头设置
$random

  • $random -eq 8
    时,您将在
    cn=$usrname,ou=Animators,ou=BRAAN,dc=BRAAN,dc=COM
    创建用户,但将其添加到
    cn=Animators_Staff,ou=Animators,ou=Programmers,ou=BRAAN,dc=BRAAN,dc=com
    组(请注意额外的
    ou=Programmers
    )。这就是代码重复的危险。

对于第二点,您可以在脚本的顶部定义它,而不是测试

if
的长链
elseif
/
$random
语句...

$departmentBaseDN = 'ou=BRAAN,dc=BRAAN,dc=COM'
$departments = @(
    'IT',
    'HR',
    'Sales',
    'Finance',
    'Executives',
    'Programmers\DB_Engineers',
    'Programmers\Content_Experts',
    'Animators'
)

...然后调整您的

Get-Random
调用以返回该数组范围内的索引...

$random = Get-Random -Maximum $departments.Length # 0 ≤ $random < $departments.Length

...然后在循环中使用它来动态构建用户、部门 OU 和部门组的可分辨名称...

# This returns a one-element array for departments with no \
$departmentParts = $departments[$random] -split '\\'
# The last part is the department name
$departmentName = $departmentParts[-1]

$departmentUnitDN = $departmentBaseDN
# Prepend to the base DN the OU for each part in order
foreach ($departmentPart in $departmentParts)
{
    $departmentUnitDN = "ou=$departmentPart,$departmentUnitDN"
}
$departmentGroupDN = "cn=$departmentName`_Staff,$departmentUnitDN"
$userDN = "cn=$usrname,$departmentUnitDN"

dsadd user "$userDN" -fn $values[1] -ln $values[2] -disabled no -pwd "Password1" -memberof "$departmentGroupDN"  ##Create user and add to group.##

您也可以利用相同的

$departments
变量来替换脚本开头的一些重复的
dsadd ou
dsadd group
命令。

最后,请注意,PowerShell 有一个

ActiveDirectory
模块,除了您已经使用的
New-ADComputer
cmdlet
之外,还提供了许多您可以在此处使用的其他 cmdlet...

© www.soinside.com 2019 - 2024. All rights reserved.