我想从.xlsx批量更新DC用户,但脚本应跳过xlsx数据中的空值。
我已经用几种方法尝试过,但是没有用。
第一次尝试是
hash.GetEnumerator() | foreach {
if ($_.Value -eq "") {
$hash.Remove($_.Key)
}
}
Secound尝试如下代码所示:
foreach ($h in $hash.Keys) {
if ($(hash.Item($h)) -eq "") {
$hash.Remove($h)
try {
Import-Module ActiveDirectory -ErrorAction Stop -WarningAction Stop
} catch {
Write-Host "ActiveDirectory module not found!!" -ForegroundColor Red -BackgroundColor Black
Write-Host "Script Aborted." -ForegroundColor Red -BackgroundColor Black
# Abort the script.
break
}
try {
$credential = Get-Credential
[Threading.Thread]::CurrentThread.CurrentCulture = 'en-US'
#Declare file path and sheet name
$file = "...\UpdateUsers_test.xlsx"
#Create an Excel.Application instance and open that file
$Excelobject = New-Object -ComObject Excel.Application
$Workbook = $Excelobject.Workbooks.Open($file)
$sheetName = "Sheet1"
$sheet = $Workbook.Worksheets.Item($sheetName)
#$objExcel.Visible=$true
#Count max row
$rowMax = ($sheet.UsedRange.Rows).Count
#Count max column
$colMax = ($sheet.UsedRange.Columns).Count
$hash = @{}
$server = "IP-Address"
#Specify starting positions
$row, $col = 1, 1
$updatedCount = 0
#loop for rows
for ($i=1; $i -le $rowMax-1; $i++) {
#loop for columns
for ($c=0; $c -le $colMax-1; $c++) {
#Get all columns values to a hash
$hash += @{$sheet.Cells.Item($row, $col+$c).Text = $sheet.Cells.Item($row+$i, $col+$c).Text}
foreach ($h in $hash.Keys) {
if ($(hash.Item($h)) -eq "") {
$hash.Remove($h)
}
#Create an object and assign hash keys as object property
$Object = New-Object -TypeName PSObject -Property $hash
#Get User via SamAccountname
$user = Get-ADUser -Filter "SamAccountName -eq '$($Object.UserName)'" -
SearchBase 'DC=Domain, DC=local' -Server $server -Credential $credential
#Set Users attribute with matched object attribute
$user | Set-ADUser -DisplayName $Object.Displayname `
-OfficePhone $Object.PhoneNumber `
-EmailAddress $Object.email `
-Postalcode $Object.Postalcode `
-City $Object.City `
-Streetaddress $Object.Streetaddress `
-Country $Object.Country `
-Office $Object.Office `
-Title $Object.Title `
-Company $Object.Company `
-Department $Object.Department `
-Manager $Object.Manager `
-Mobile $Object.Mobile `
-Fax $Object.Fax
#If you want to edit Object common name, you can remove enable two lines
below.
#$userguid = $user.ObjectGUID.Guid
#$user | Rename-ADObject -NewName $Object.DisplayName -Server $server -
Credential $credential
$hash = @{}
Write-Host $User.Name "- User attributes have been updated." -
ForegroundColor Yellow
Start-Sleep -s 1
$updatedCount += 1
}
Write-Host $updatedCount "Users have been updated" -ForegroundColor Green
#close excel file
$Excelobject.Quit()
}
catch {
Write-Error $_.Exception.ToString()
Read-Host -Prompt "The above error occured. Press Enter to exit."
}
答案 0 :(得分:0)
我认为更好的方法是通过PSObject。有时一条记录可以具有多个属性,使用''搜索空值可能会很困难。
相反,您可以使用PSObject属性并搜索空值:
$_.PSObject.Properties | ForEach-Object {$_.Value}) -eq $null
答案 1 :(得分:0)
我想我建议您使用splatting而不是创建对象,这将涉及使用哈希表为Set-ADUser
指定参数。若要进行此工作,哈希表的键必须与cmdlet的参数相同。您的关系密切,但是有一些差异,因此首先我们需要创建一个哈希表,以将您的电子表格映射到正确的参数。将其放在循环行之前。
$ParamMap = @{
Displayname = 'DisplayName'
PhoneNumber = 'OfficePhone'
email = 'EmailAddress'
Postalcode = 'Postalcode'
City = 'City'
Streetaddress = 'Streetaddress'
Country = 'Country'
Office = 'Office'
Title = 'Title'
Company = 'Company'
Department = 'Department'
Manager = 'Manager'
Mobile = 'Mobile'
Fax = 'Fax'
}
现在,我们稍微修改一下如何创建哈希表以使用它来查找键名(这将替换您的$hast +=
行):
$hash.add($ParamMap[$sheet.Cells.Item($row, $col+$c).Text], $sheet.Cells.Item($row+$i, $col+$c).Text)
现在我们有了哈希表,我们可以检查null或空字符串,并将其删除。
$hash.keys | Where{ [string]::IsNullOrWhitespace($hash[$_]) } | ForEach-Object { $Hash.Remove($_) }
该行枚举$hash
的键,并检查每个键的值以查看其是否包含空值或仅包含空格(空格,制表符,换行)。如果它为null或空格,则会从哈希表中删除该键。
现在,我们有了一个哈希表,该哈希表仅具有表示cmdlet参数的有效键,并且每个键都有一个值,我们将其喷溅到Get-ADUser
cmdlet中,我们就完成了设置。
$user | Set-ADUser @hash
答案 2 :(得分:0)
@TheMadTechnician
谢谢!
您的回答对我很有帮助。但是我仍然存在将哈希表传递给Set-ADUser cmdlet的问题。
不幸的是,我自己无法解决这些错误消息
#loop for rows
for ($i=1; $i -le $rowMax-1; $i++)
{
#loop for columns
for($c=0; $c -le $colMax-1; $c++)
{
#Get all columns values to a hash
$hash += @{$sheet.Cells.Item($row, $col+$c).Text = $sheet.Cells.Item($row+$i, $col+$c).Text}
$hash.keys.Clone() | Where{ [string]::IsNullOrWhitespace($hash[$_]) } | ForEach-Object { $Hash.Remove($_) }
$hash | Out-String | Write-Host
}
#Create an object and assign hash keys as object property
$Object = New-Object -TypeName PSObject -Property $hash
#Get User via SamAccountname
$user = Get-ADUser -Filter "SamAccountName -eq '$($Object.SamAccountName)'" -SearchBase 'DC=domain, DC=local' -Server $server -Credential $credential
}
#Set Users attribute with matched object attribute
$user | Set-ADUser -Replace EmailAddress = $Object.Email; `
-Postalcode $Object.Postalcode `
-City $Object.City `
-Streetaddress $Object.Streetaddress `
-Country $Object.Country `
-Office $Object.Office `
-Title $Object.Title `
-Company $Object.Company `
-Department $Object.Department `
-Manager $Object.Manager `
-Mobile $Object.Mobile `
-Fax $Object.Fax
System.Management.Automation.ParameterBindingException:无法绑定参数“替换”。无法转换 类型为“ System.String”的“ EmailAddress”值将类型为“ System.Collections.Hashtable”。 -> System.Management.Automation.PSInvalidCastException:无法转换类型为“ System.String”的“ EmailAddress”值 键入“ System.Collections.Hashtable”。 在System.Management.Automation.LanguagePrimitives.ThrowInvalidCastException(对象valueToConvert,类型resultType) 在System.Management.Automation.LanguagePrimitives.ConvertNoConversion(Object valueToConvert,类型resultType, 布尔递归,PSObject originalValueToConvert,IFormatProvider formatProvider,TypeTable backupTable) 在System.Management.Automation.LanguagePrimitives.ConversionData
1.Invoke(Object valueToConvert, Type resultType, Boolean recurse, PSObject originalValueToConvert, IFormatProvider formatProvider, TypeTable backupTable) at System.Management.Automation.LanguagePrimitives.ConvertTo(Object valueToConvert, Type resultType, Boolean recursion, IFormatProvider formatProvider, TypeTable backupTypeTable) at System.Management.Automation.ParameterBinderBase.CoerceTypeAsNeeded(CommandParameterInternal argument, String parameterName, Type toType, ParameterCollectionTypeInformation collectionTypeInfo, Object currentValue) --- End of inner exception stack trace --- at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception) at System.Management.Automation.Interpreter.ActionCallInstruction
2.Run(InterpretedFrame框架)处 在System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame框架) 在System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame框架)