如何将 -Identity 从 Get-ADUser 传递给变量? (用于将用户组复制到新用户)

How to pass -Identity from Get-ADUser to a variable? (For copying user groups to new user)

基本上这个脚本的想法是在 AD 中创建一个新用户,但也通过用户输入的搜索从 AD 中的另一个用户复制组。

例如,将销售组从当前团队成员复制到新创建的成员。我得到的错误是我的 $ID 变量始终为空并且 -Identity 无法使用它。如果我硬编码我想从此代码复制的用户。

我可以只要求用户输入并让他们输入身份/用户名/samaccountname 以从中复制组,但他们不会突然想到这一点,因为 AD 中的命名约定包括员工数字。他们必须导航 AD 才能找到它,这避免了脚本的重点。

我希望此脚本能够仅根据名称查找用户以便于使用。这就是它使用 -filter 的原因。如果您对如何在搜索过程中处理具有相同姓名的潜在重复用户有任何建议,我也很乐意听取建议。

找到要从中复制的用户后,它将组从搜索到的用户复制到新创建的用户。

感谢您的帮助!

Do {

$Given = Read-Host -Prompt "Input new user first name"
$Surname = Read-Host -Prompt "Input new user last name"
$PW = Read-Host -Prompt "Input new user password"
$Phone = Read-Host -Prompt "Input new user phone number"
$NewSam = Read-Host -Prompt "Input preferred new user ID"
$User = "$Given $Surname"

$Confirmation = Read-Host "You input '$User' , '$NewSam' , '$PW' , and '$Phone' is this correct (y/n)?" 
}
while ($confirmation -ne "y")


New-ADUser -Name $User -GivenName $Given -Surname $Surname -SamAccountName $NewSam -AccountPassword (ConvertTo-SecureString -AsPlaintext "$PW" -Force) -Enabled $True `
-OfficePhone $Phone -ChangePasswordAtLogon $true

Do {

$clone = Read-Host -Prompt "Who are we copying groups from?"
$Confirmation2 = Read-Host "You input '$clone' is this correct (y/n)?" 
}
while ($confirmation2 -ne "y")

$ID = Get-ADUser -Filter 'Name -eq "$clone"'| Select-Object -ExpandProperty SamAccountName
$GetUserGroups = Get-ADUser -Identity "$ID" -Properties memberof | Select-Object -ExpandProperty memberof
$GetUserGroups | Add-ADGroupMember -Members $NewSam -Verbose

您的脚本在这里开始横向运行:

$ID = Get-ADUser -Filter 'Name -eq "$clone"'| Select-Object -ExpandProperty SamAccountName
$GetUserGroups = Get-ADUser -Identity "$ID" -Properties memberof | Select-Object -ExpandProperty memberof

离你这么近,需要的是:

$ID = Get-ADUser -Filter "Name -eq '$clone'"|
    Select-Object -ExpandProperty SamAccountName

过滤器需要在名称周围加上单引号。这方面的文档很糟糕,对于 Filter 参数,在示例中使用 ScriptBlocks(花括号内的代码),而实际类型是 [string]。在修复了使用 ScriptBlocks 掩盖的问题后,我学会了坚持使用字符串。

如果您简化为:

,您甚至不会 运行 解决这个问题
$ID = Get-ADUser -Identity $clone | 
    Select-Object -ExpandProperty SamAccountName

只要我们简化,你只需要一行:

$GetUserGroups = Get-ADUser -Identity $clone -Properties memberof |
    Select-Object -ExpandProperty memberof

还有一件事需要考虑。虽然通过管道传输到 Select-Object 是 PowerShell 方式,也是我倾向于从命令行使用的样式,但在我个人更喜欢的脚本中:

$GetUserGroups = (Get-ADUser -Identity $clone -Properties memberof).memberof

但这是一个品味问题(同时也更快(这只在长 运行ning 脚本中很重要))。

虽然通过 Read-Host 要求用户输入总是很棘手(用户可以输入 he/she 想要的任何虚假文本),但我至少会为该用户提供退出循环的机会也在那里添加 q 选项。

那么在使用 New-ADUser.

创建之前,您真的应该首先检查用户是否已经存在

最后,$GetUserGroups | Add-ADGroupMember -Members $NewSam -Verbose不会像你预期的那样工作,因为Add-ADGroup的-Identity参数一次只接受一个组id,所以你需要循环在那里分组。

尝试

do {
    $Given   = Read-Host -Prompt "Input new user first name"
    $Surname = Read-Host -Prompt "Input new user last name"
    $PW      = Read-Host -Prompt "Input new user password"
    $Phone   = Read-Host -Prompt "Input new user phone number"
    $NewSam  = Read-Host -Prompt "Input preferred new user ID (SamAccountName)"
    $User    = "$Given $Surname"

    $Confirmation = Read-Host "You input '$User' , '$NewSam' , '$PW' , and '$Phone' is this correct (y/n/q)?" 
    switch -Wildcard ($confirmation) {
        'q*' {
            # user wants to quit
            exit
        }
        'y*' {
            # here first check if that user already exists or not
            $existingUser = Get-ADUser -Filter "SamAccountName -eq '$NewSam'"
            if ($existingUser) {
                Write-Warning "A user with SamAccountName '$NewSam' already exists"
                $Confirmation = 'n'  # rerun the loop
            }
        }
    }
} while ($confirmation -notlike "y*")

# now proceed creating the new AD user
# because New-ADUser can take a lot of parameters, the cvleanest way is to use splatting
$userProps = @{
    Name                  = $User
    GivenName             = $Given
    Surname               = $Surname
    SamAccountName        = $NewSam
    AccountPassword       = ConvertTo-SecureString -AsPlaintext $PW -Force
    Enabled               = $True
    OfficePhone           = $Phone
    ChangePasswordAtLogon = $true
    # add switch parameter PassThru, so the cmdlet returns the new user object
    PassThru              = $true
}
$newUser = New-ADUser @userProps

do {
    $clone = Read-Host -Prompt "Who are we copying groups from? (SamAccountName)"
    $Confirmation = Read-Host "You input '$clone' is this correct (y/n/q)?" 
    switch -Wildcard ($Confirmation) {
        'q*' {
            # user wants to quit
            Write-Host "New user '$($newUser.Name)' has been created but not added to any groups.."
            exit
        }
        'y*' {
            # here first check if that user already exists or not
            $cloneUser = Get-ADUser -Filter "SamAccountName -eq '$clone'" -Properties MemberOf
            if (!$cloneUser) {
                Write-Warning "A user with SamAccountName '$clone' does not exist"
                $Confirmation = 'n'  # rerun the loop
            }
            else {
                # get the MemberOf properties from the second user
                # and add the new user to these groups
                $cloneUser.MemberOf | ForEach-Object {
                    $_ | Add-ADGroupMember -Members $newUser -Verbose
                }
            }
        }
    }
}
while ($confirmation -notlike "y*")

P.S。我在确认输入上使用通配符比较 ('y*'),否则如果用户键入 'yes',循环将不会将其视为 YES