我有一个脚本,自动批量广告帐户的创建。
该脚本工作正常,但当我尝试为每个用户定义帐户到期日期和时间(-AccountExpirationDate)时,它失败了。
脚本如下:
# Store the data from NewUsersFinal.csv in the $ADUsers variable
$ADUsers = Import-Csv C:\temp\NewUsersSent.csv
# Define UPN
$UPN = "my.domain.net"
# Loop through each row containing user details in the CSV file
foreach ($User in $ADUsers) {
#Read user data from each field in each row and assign the data to a variable as below
$username = $User.username
$password = $User.password
$firstname = $User.firstname
$lastname = $User.lastname
$OU = $User.ou #This field refers to the OU the user account is to be created in
$email = $User.email
$telephone = $User.telephone
$jobtitle = $User.jobtitle
$accountexpires = $User.accountexpires
# Check to see if the user already exists in AD
if (Get-ADUser -F { SamAccountName -eq $username }) {
# If user does exist, give a warning
Write-Warning "A user account with username $username already exists in Active Directory."
}
else {
# User does not exist then proceed to create the new user account
# Account will be created in the OU provided by the $OU variable read from the CSV file
New-ADUser `
-SamAccountName $username `
-UserPrincipalName "$username@$UPN" `
-Name "$firstname $lastname" `
-GivenName $firstname `
-Surname $lastname `
-Enabled $True `
-DisplayName "$lastname, $firstname" `
-Path $OU `
-OfficePhone $telephone `
-MobilePhone $telephone `
-HomePhone $telephone `
-EmailAddress $email `
-Description $jobtitle `
-AccountExpirationDate $accountexpires `
-AccountPassword (ConvertTo-secureString $password -AsPlainText -Force) -ChangePasswordAtLogon $False -PasswordNeverExpires $True
# If user is created, show message.
Write-Host "The user account $username is created." -ForegroundColor Cyan
}
}
CSV文件如下:
当我运行代码时,我得到以下错误(帐户实际上没有创建):
New-ADUser : Cannot bind parameter 'AccountExpirationDate'. Cannot convert value ""11/17/2023 2:22:48 PM"" to type "System.DateTime". Error: "String was not recognized
as a valid DateTime."
At C:\Users\Me\Desktop\BulkNewUsers.ps1:45 char:36
+ -AccountExpirationDate $accountexpires `
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-ADUser], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.ActiveDirectory.Management.Commands.NewADUser
The user account TTesting1 is created.
New-ADUser : Cannot bind parameter 'AccountExpirationDate'. Cannot convert value "0" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
At C:\Users\Me\Desktop\BulkNewUsers.ps1:45 char:36
+ -AccountExpirationDate $accountexpires `
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-ADUser], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.ActiveDirectory.Management.Commands.NewADUser
The user account TTesting2 is created.
Press Enter to exit:
PS好像不接受我的日期时间格式。
我试着从以下网站阅读:
https://ss64.com/ps/new-aduser.html
https://ss64.com/ps/syntax-dateformats.html
我相信我需要指定格式模式的PS接受我的日期时间在CSV。
我也读到过声明“0”设置帐户不过期-可以澄清一下吗?
我还想知道是否也可以定义要添加到CSV中的AD组,以便使用添加新用户;作为每个AD组名称的分隔符?-我认为我可能需要将Get-ADPrincipalGroupMembership合并到脚本中。
更新1
感谢Theo运行您的脚本执行没有错误,但帐户到期日未设置:
是否因为我在以前失败的尝试中创建了这些帐户(在尝试再次创建帐户之前是否需要等待24小时-缓存详细信息),我确实删除了帐户并在DC中强制复制。
更新2
西奥的要求。
我尝试了下面的第一个建议代码:
错误代码:
PS C:\Windows\system32> C:\Users\Me\Desktop\BulkNewUsers.ps1
At C:\Users\Me\Desktop\BulkNewUsers.ps1:48 char:67
+ $accountexpires = (Get-Date) ; [datetime]::TryParse(11/17/2023 2:22:48 PM, [ ...
+ ~
Missing ')' in method call.
At C:\Users\Me\Desktop\BulkNewUsers.ps1:48 char:68
+ $accountexpires = (Get-Date) ; [datetime]::TryParse(11/17/2023 2:22:48 PM, [ ...
+ ~~~~~~~
Unexpected token '2:22:48' in expression or statement.
At C:\Users\Me\Desktop\BulkNewUsers.ps1:8 char:29
+ foreach ($User in $ADUsers) {
+ ~
Missing closing '}' in statement block.
At C:\Users\Me\Desktop\BulkNewUsers.ps1:48 char:100
+ ... $accountexpires) {
+ ~
Unexpected token ')' in expression or statement.
At C:\Users\Me\Desktop\BulkNewUsers.ps1:64 char:1
+ }
+ ~
Unexpected token '}' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEndParenthesisInMethodCall
我尝试了下面的第二个建议代码:
错误代码:
PS C:\Windows\system32> C:\Users\Me\Desktop\BulkNewUsers.ps1
At C:\Users\Me\Desktop\BulkNewUsers.ps1:48 char:72
+ $accountexpires = (Get-Date) ; [datetime]::TryParseExact(11/17/2023 2:22:48 ...
+ ~
Missing ')' in method call.
At C:\Users\Me\Desktop\BulkNewUsers.ps1:48 char:73
+ $accountexpires = (Get-Date) ; [datetime]::TryParseExact(11/17/2023 2:22:48 ...
+ ~~~~~~~
Unexpected token '2:22:48' in expression or statement.
At C:\Users\Me\Desktop\BulkNewUsers.ps1:8 char:29
+ foreach ($User in $ADUsers) {
+ ~
Missing closing '}' in statement block.
At C:\Users\Me\Desktop\BulkNewUsers.ps1:48 char:159
+ ... $accountexpires){
+ ~
Unexpected token ')' in expression or statement.
At C:\Users\Me\Desktop\BulkNewUsers.ps1:64 char:1
+ }
+ ~
Unexpected token '}' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEndParenthesisInMethodCall
看起来像是同一个错误代码?
请参阅下面的CSV记事本格式:
FirstName,LastName,Username,Email,Password,Telephone,JobTitle,AccountExpires,OU
Test1,Test2,TTesting1,Testing1@email.co.uk,V6DyG3H7a,4.47723E+11,This is a Test 1,11/17/2023 2:22:48 PM,"CN=Users,DC=my,DC=domain,DC=net"
Test3,Test4,TTesting2,Testing2@email.co.uk,438MXn8D5,4.47723E+11,This is a Test 2,0,"CN=Users,DC=my,DC=domain,DC=net"
更新3
我照你说的做了
$accountexpires = (Get-Date)
[datetime]::TryParseExact('11/17/2023 2:22:48 PM', 'MM/dd/yyyy h:mm:ss tt', [cultureinfo]'en-US', 'None',[ref]$accountexpires)
这在PowerShell中返回“true”。
奇怪的是,你提到了非打印字符,因为我们有一个问题,从MS SharePoint复制文本到记事本,然后到AD -这将包含特殊的隐藏字符,来克服这一点(懒惰)我,而不是复制到从微软SharePoint到微软Word,然后到广告,其中固定的特殊隐藏字符(为了查看特殊隐藏字符,我们对文本执行了“ASCII到十六进制”的转换,然后返回到“十六进制到ASCII”,这将显示特殊隐藏字符)
我做了你问我在记事本领域的双引号之间的变化,并重新键入到期日期,这解决了问题!到期日期显示在新创建的用户。
谢谢!!!
现在,我试图添加广告组和它半失败(我猜他们包含“-”和“_”在那里的名称的广告组的命名约定)
请参阅以下记事本格式的新CSV:
FirstName,LastName,Username,Email,Password,Telephone,JobTitle,AccountExpires,OU,ADGroups
"Test1","Test2","TTesting1","Testing1@email.co.uk","V6DyG3H7a","447723000000","This is a Test 1","11/17/2023 2:22:48 PM","CN=Users,DC=my,DC=domain,DC=net","ADGroupName1;AD_Group_Name_2;AD-Group-Name-3;"
"Test3","Test4","TTesting2","Testing2@email.co.uk","438MXn8D5","447723000001","This is a Test 2","0","CN=Users,DC=my,DC=domain,DC=net""ADGroupName1;AD_Group_Name_2;"
我在下面使用的代码:
# Store the data from NewUsersFinal.csv in the $ADUsers variable
$ADUsers = Import-Csv -Path 'C:\temp\NewUsersSent.csv'
# Define UPN
$UPN = "my.domain.net"
# Loop through each row containing user details in the CSV file
foreach ($User in $ADUsers) {
# Read some user data from each field in each row and assign the data to a variable as below
$username = $User.username
# Check to see if the user already exists in AD
if (Get-ADUser -Filter "SamAccountName -eq '$username'") {
# If user does exist, give a warning
Write-Warning "A user account with username $username already exists in Active Directory."
continue # skip this one and proceed with the next user
}
# User does not exist then proceed to create the new user account
# Account will be created in the OU provided by the $OU variable read from the CSV file
# create some convenience variables from the csv data as these are used more than once
$firstname = $User.firstname
$lastname = $User.lastname
$telephone = $User.telephone
# create a splatting Hashtable for the New-ADUser cmdlet
$userParams = @{
SamAccountName = $username
UserPrincipalName = "$username@$UPN"
Name = "$firstname $lastname"
GivenName = $firstname
Surname = $lastname
Enabled = $true
DisplayName = "$lastname, $firstname"
Path = $User.ou
OfficePhone = $telephone
MobilePhone = $telephone
HomePhone = $telephone
EmailAddress = $User.email
Description = $User.jobtitle
AccountPassword = (ConvertTo-secureString $User.password -AsPlainText -Force)
ChangePasswordAtLogon = $false
PasswordNeverExpires = $true
}
# see if we can get a valid DateTime from the csv field 'accountexpires'
$accountexpires = (Get-Date)
if ([datetime]::TryParseExact($User.accountexpires, 'MM/dd/yyyy h:mm:ss tt', [cultureinfo]'en-US', 'None',[ref]$accountexpires)) {
# this user does have an account expiration date, so add it to the Hash
$userParams['AccountExpirationDate'] = $accountexpires
}
# create the user (PassThru makes the cmdlet return the user object just created)
$newUser = New-ADUser @userParams -PassThru
Write-Host "The user account $username is created." -ForegroundColor Cyan
#####################################################################################
# If you have a field in the CSV where groups are listed the new user should become
# a member of (as you said, separated by ;), you can add the user to these groups here:
$User.adgroups -split ';' | Where-Object { $_ -match '\S' } | ForEach-Object {
Add-ADGroupMember -Identity $_ -Members $newUser
}
}
当我尝试使用AD组运行代码时,我从PS得到了错误消息:
PS C:\Windows\system32> C:\Users\Me\Desktop\BulkNewUsers.ps1
The user account TTesting1 is created.
New-ADUser : The object name has bad syntax
At C:\Users\Me\Desktop\BulkNewUsers.ps1:54 char:16
+ $newUser = New-ADUser @userParams -PassThru
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (CN=Test3 Test4,...AD_Group_Name_2;:String) [New-ADUser], ADException
+ FullyQualifiedErrorId : ActiveDirectoryServer:8335,Microsoft.ActiveDirectory.Management.Commands.NewADUser
The user account TTesting2 is created.
奇怪的是,第一个帐户被创建,但第二个没有。
我还必须在代码的$userParams
部分定义Groups = $User.ADGroups
吗?
更新4
Theo我发现UPDATE 3中的问题是CSV文件中第二个用户的OU字段和AD组字段的双引号之间没有定义“,”:"CN=Users,DC=my,DC=domain,DC=net""ADGroupName1;AD_Group_Name_2;"
变更为:"CN=Users,DC=my,DC=domain,DC=net","ADGroupName1;AD_Group_Name_2;"
这解决了问题!
1条答案
按热度按时间9ceoxa921#
这里的主要问题是,当创建一个永远不会过期的用户时,不应该设置
AccountExpirationDate
。否则,应该使用有效的DateTime对象来设置过期日期和时间。(如果没有指定时间,则假定时间为本地时间12:00:00 AM。)您的代码使用讨厌的反引号将New-ADUser的参数分隔在新的一行中,但更好的方法是在需要大量参数的cmdlet上使用Splatting。
这样,代码就很容易阅读/维护,另外,您可以根据条件添加或省略某些参数,例如本例中的
AccountExpirationDate
。也请阅读底部的注解代码,以展示如何将新用户添加到组中。
除了使用
[datetime]::TryParse()
,您还可以使用[datetime]::TryParseExact()
方法,具体取决于您如何格式化csv文件中的日期。如果您使用这种英语12小时制时钟格式,
[datetime]::TryParseExact($User.accountexpires, 'MM/dd/yyyy h:mm:ss tt', [cultureinfo]'en-US', 'None',[ref]$accountexpires)
可以工作。您可以在PowerShell中使用
返回
True
如果返回
False
,那么要么是日期模式不匹配,要么是日期字符串被不可见的控制字符搞得一团糟。在这种情况下,手动重新输入日期并再次测试。