我无法使用给定和创建的属性与 New-ADUser 一起工作

I am unable to get splatting to work with New-ADUser using given and created attributes

我正在处理从一个域中提取的一组 AD 用户数据,以便在另一个域中重新创建。我创建了一个散列 table,将 New-ADUser 参数与从 CSV 导入的用户数据(从我打算重新创建的域填充)链接起来。当我使用散列 table 调用 New-ADUser 时,没有创建用户并且没有错误。

这是散列 table:

$NewUserAttr = @{
    'Name'              = $ADUser.UsersName
    'SamAccountName'    = $ADUser.UsersSamAccountName
    'Company'           = $ADUser.UsersCompany
    'Department'        = $ADUser.UsersDepartment
    'DisplayName'       = $ADUser.UsersDisplayName
    'EmailAddress'      = $ADUser.UsersMail
    'EmployeeID'        = $ADUser.UsersEmployeeID
    'Enabled'           = $UsersEnabled
    'GivenName'         = $ADUser.UsersGivenName
    'Initials'          = $ADUser.UsersInitials
    'Manager'           = $ADUser.Manager
    'MobilePhone'       = $ADUser.UsersMobileNum
    'OfficePhone'       = $ADUser.UsersTelephoneNumber
    'PostalCode'        = $ADUser.UsersPostalCode
    'State'             = $ADUser.UsersST
    'StreetAddress'     = $ADUser.UsersStreetAddress
    'Surname'           = $ADUser.UsersSN
    'Title'             = $ADUser.UsersTitle
    'userPrincipalname' = $ADUser.UsersUPN
    'Path'              = $ParentOU
    'Server'            = $TargetDomain

    'OtherAttr' = @{
        'c'                  = $ADUser.Usersc
        'GIDNumber'          = $ADUser.UsersGIDNumber
        'l'                  = $ADUser.UsersL
        'LoginShell'         = $ADUser.UsersLoginShell
        'msSFU30Name'        = $ADUser.UsersMsSFU30Name
        'msSFU30NisDomain'   = $ADUser.UsersMsSFU30NisDomain
        'PhysicalDeliveryOfficeName' = $ADUser.UsersPhysicalDeliveryOfficeName
        'SSN'                = $ADUser.UsersSSN
        'Uid'                = $ADUser.UsersUid
        'uidNumber'          = $ADUser.UsersUidNum
        'unixHomeDirectory'  = $ADUser.UsersUHD
    }
}

PS > New-ADUser @NewUserAttr

我已将 NewUserAttr 缩减为 Name、SamAccountName、Path 和 Server,这确实创建了用户,但这远远少于我需要的参数。

继续我的评论:

To avoid empty fields from being assembled in the attributes Hashtable to use for splatting, you could create two lookup tables in which you  map the CSV header names with the actual AD user attribute names.
Something like this:

    # create two mapping lookup Hashtables for 'normal' attributes and one for the OtherAttributes
    # format is: PropertyNameFromCsv = PropertyNameForActiveDirectory
    $attribMap = @{
        UsersName           = 'Name'
        UsersSamAccountName = 'SamAccountName'
        UsersCompany        = 'Company'
        Usersc              = 'Country'
        Manager             = 'Manager'
        # etc.
    }

    $otherMap = @{
        UsersGIDNumber        = 'GIDNumber'
        UsersLoginShell       = 'LoginShell'
        UsersmsSFU30Name      = 'MsSFU30Name'
        UsersmsSFU30NisDomain = 'MsSFU30NisDomain'
        # etc.
    }

接下来,导入 CSV 文件并遍历每个条目:

$csv = Import-Csv -Path 'X:\your_importFile.csv'

foreach ($item in $csv) {
    # two empty Hashtables for splatting
    $NewUserAttr = @{}
    $OtherAttr   = @{}
    # pre fill the default attributes you need for all users
    $NewUserAttr['Enabled'] = $UsersEnabled
    $NewUserAttr['Server']  = $TargetDomain
    $NewUserAttr['Path']    = $ParentOU

    # loop over the properties for each item in the CSV and only store 
    # the ones that are not empty and for which you can find a mapping
    $item.PsObject.Properties | ForEach-Object {
        if (![string]::IsNullOrWhiteSpace($_.Value)) { 
            if ($attribMap.Contains($_.Name))    { $NewUserAttr[$attribMap[$_.Name]] = $_.Value }
            elseif ($otherMap.Contains($_.Name)) { $OtherAttr[$otherMap[$_.Name]] = $_.Value }
        }
    }
    # join the hashtables together if we have OtherAttributes
    if ($OtherAttr.Count) { $NewUserAttr['OtherAttributes'] = $OtherAttr }

    # now try and create the new user
    try {
        New-ADUser @NewUserAttr -ErrorAction Stop
    }
    catch {
        Write-Warning "Error creating user $($NewUserAttr.Name): $($_.Exception.Message)"
    }
}

我运行经常使用命名参数和空值。为避免 $null 指示参数应 省略 而不是提供的命名参数的空值,请在创建 splat-hashtable 时遵循以下规则:

  1. 定义哈希表时,定义任何不会(或不应该)的属性$null,像这样:

    $splatArgs = @{
      ParameterOne = 'Value'
      ParameterTwo = 'OtherValue'
    }
    
  2. 对于根据其值是否为$null(或计算为假)可能需要提供或不需要提供的参数,有条件地添加到哈希表中:

    if( $someVar ) {
      $splatArgs.ConditionalParameter = $someVar
    }
    

对每个条件参数重复2.。或者,您可以使用所有可能的参数名称和值初始化哈希表,然后在检查虚假性、与 $null 等进行比较后将它们删除。

  # You could do any condition here but in this example,
  # We will do a simple falsiness test on each key's value
  $removeParameterNames = $splatArgs.Keys | Where-Object {
    !( $splatArgs.$_ )
  }

  # Use another loop here since we don't want to modify the hashtable
  # while iterating over its keys
  foreach( $key in $removeParameterNames ) {
    $splatArgs.Remove($key)
  }

这是我最终开始工作的内容,这与 Bender 推荐的内容以及我上述评论中 link 的 Richard 推荐的内容非常相似。

$NewUserAttr = @{
    'Name'                  = $ADUser.UsersName
    'SamAccountName'        = $ADUser.UsersSamAccountName
    'AccountPassword'       = (ConvertTo-SecureString -AsPlainText "<Ab@1Cd!2>" -Force)
    'Company'               = $ADUser.UsersCompany
    'Department'            = $ADUser.UsersDepartment
    'DisplayName'           = $ADUser.UsersDisplayName
    'EmailAddress'          = $ADUser.UsersMail 
    'EmployeeID'            = $ADUser.UsersEmployeeID
    'Enabled'               = $UsersEnabled
    'GivenName'             = $ADUser.UsersGivenName
    'MobilePhone'           = $ADUser.UsersMobileNum 
    'OfficePhone'           = $ADUser.UsersTelephoneNumber 
    'SurName'               = $ADUser.UsersSN 
    'Title'                 = $ADUser.UsersTitle
    'userPrincipalname'     = $ADUser.UsersUPN
    'Path'                  = $ParentOU
    'Server'                = $TargetDomain

    'OtherAttr' = @{
        'GIDNumber'                     = $ADUser.UsersGIDNumber
        'LoginShell'                    = $ADUser.UsersLoginShell
        'msSFU30Name'                   = $ADUser.UsersMsSFU30Name
        'msSFU30NisDomain'              = $ADUser.UsersMsSFU30NisDomain
        'Uid'                           = $ADUser.UsersUid
        'uidNumber'                     = $ADUser.UsersUidNum
        'unixHomeDirectory'             = $ADUser.UsersUHD
    } 
}

# Check the uncommon attributes and add them to the hash table if not null
if($ADUser.Usersl){$NewUserAttr.add('City',$ADUser.Usersl)}
if($ADUser.Usersc){$NewUserAttr.add('Country',$ADUser.Usersc)}
if($ADUser.UsersInitials){$NewUserAttr.add('Initials',$ADUser.UsersInitials)}
if($ADUser.Manager){$NewUserAttr.add('Manager',$ADUser.Manager)}
if($ADUser.UsersPostalCode){$NewUserAttr.add('PostalCode',$ADUser.UsersPostalCode)}
if($ADUser.UsersST){$NewUserAttr.add('State',$ADUser.UsersST)}
if($ADUser.UsersStreetAddress){$NewUserAttr.add('StreetAddress',$ADUser.UsersStreetAddress)}
if($ADUser.physicaldeliveryofficename){$NewUserAttr.OtherAttr.add('physicaldeliveryofficename',$ADUser.physicaldeliveryofficename)}
if($ADUser.UsersSSN){$NewUserAttr.OtherAttr.add('SSN',$ADUser.UsersSSN)}

#Add new user to destination domain
try {
    $UserExists = Get-ADUser -Identity $ADUser.UsersName -Server $TargetDomain
    if ($UserExists) {
        "Exists,$($ADUser.UsersName),$ParentOU`n" | Out-File $UserCreationLog -Append -Force
    } else {
        New-ADUser @NewUserAttr -ErrorAction Continue
        #Change password
        "Added,$($ADUser.UsersSamAccountName),$($ADUser.UsersName),$ParentOU`n" | Out-File $UserCreationLog -Append -Force
    }
} catch {
    $ErrorMsg = $_.Exception.Message
    Write-Log -Message "Unable to create user, $($ADUser.UsersName): $ErrorMsg." -Severity Error -LogPath $LogFile
    Write-Log -Message "Failed users attributes: $NewUserAttr $($NewUserAttr.OtherAttr)" -Severity Error -LogPath $LogPath
}

现在我只需要测试每个建议的答案,看看哪个是最快的!谢谢大家!!