Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ARS中具有值比较的Powershell问题-误报_Powershell_Active Directory_Comparison_Updates - Fatal编程技术网

ARS中具有值比较的Powershell问题-误报

ARS中具有值比较的Powershell问题-误报,powershell,active-directory,comparison,updates,Powershell,Active Directory,Comparison,Updates,我正在更新有关用户的大量信息。脚本从文件中获取数据,与ARS中的当前数据进行比较,并在必要时进行更改 不幸的是,对于“st”和“postOfficeBox”这两个参数,尽管文件和AD中的数据相同,但它始终在更新数据 第一个是空的,第二个不是 我直接查过了- PS> $user.$parameters.postofficebox -eq $userQuery.$parameters.postofficebox True 我该怎么办?这并不是一个错误,但总是更新相同的数据会让人恼火且效率低

我正在更新有关用户的大量信息。脚本从文件中获取数据,与ARS中的当前数据进行比较,并在必要时进行更改

不幸的是,对于“st”和“postOfficeBox”这两个参数,尽管文件和AD中的数据相同,但它始终在更新数据

第一个是空的,第二个不是

我直接查过了-

PS> $user.$parameters.postofficebox -eq $userQuery.$parameters.postofficebox 
True
我该怎么办?这并不是一个错误,但总是更新相同的数据会让人恼火且效率低下

#Internal Accounts
$Parameters = @("SamAccountName", "co", "company", "department", "departmentNumber","physicalDeliveryOfficeName","streetAddress","l","st","postalCode","employeeType","manager", "division", "title", "edsvaEmployedByCountry", "extensionAttribute4", "EmployeeID", "postOfficeBox")

#import of users
$users = Import-csv -Path C:\ps\krbatch.csv -Delimiter "," -Encoding UTF8 
Connect-QADService -Proxy

#Headers compliance
$fileHeaders = $users[0].psobject.Properties | foreach { $_.Name }
$c = Compare-Object -ReferenceObject $fileHeaders -DifferenceObject $Parameters -PassThru
if ($c -ne $null) {Write-Host "headers do not fit"
break}

#Check if account is enabled
foreach ($user in $users) {
    $checkEnable = Get-ADUser $user.SamAccountName | select enabled
    if (-not $checkEnable.enabled) {
        Write-Host $user.SamAccountName -ForegroundColor Red
    }
}

#Main loop
$result = @()
foreach ($user in $users) {
    $userQuery = Get-QADUser $user.sAMaccountName -IncludedProperties $Parameters | select $Parameters
    Write-Host "...updating $($user.samaccountname)..." -ForegroundColor white
    foreach ($param in $Parameters) {
        if ($user.$param -eq $userQuery.$param) {
            Write-Host "$($user.samaccountname) has correct $param" -ForegroundColor Yellow
        }        
        else {
            try {
                Write-Host "Updating $param for $($user.samaccountname)" -ForegroundColor Green
                Set-QADUser -Identity $user.SamAccountName -ObjectAttributes @{$param=$user.$param} -ErrorVariable ProcessError -ErrorAction SilentlyContinue | Out-Null
                If ($ProcessError) { 
                    Write-Host "cannot update $param for $($user.samaccountname) $($error[0])" -ForegroundColor Red
                    $problem = @{}
                    $problem.samaccountname = $($user.samaccountname)
                    $problem.param = $param
                    $problem.value = $($user.$param)
                    $problem.error = $($error[0])
                    $result +=[pscustomobject]$problem
                    }
                }
            catch { Write-Host "fail, check if the user account is enabled?" -ForegroundColor Red}
        }
    }
}
$result | Select samaccountname, param, value, error | Export-Csv -Path c:\ps\krfail.csv -NoTypeInformation -Encoding UTF8 -Append

如果您对我的代码有任何建议,我将不胜感激。

与Mathias R.Jessen的建议类似,您测试比较的方式看起来不正确。随着调试的临近,可以添加建议的
Write Host
命令,也可以添加断点,以便在运行时进行测试

尽管存在问题的比较方面,但我将尝试解决一个定义松散的咨询请求

为什么使用QAD而不是本机AD模块。QAD非常棒,在一些领域仍然超越了本地工具。但是,(没有深入的调查)看起来你可以在这里使用本地工具

我要指出的是,AD cmdlet中有一个实例功能,允许进行增量更新,即使不进行比较。。。ie您可以运行
Set-ADUser
cmdlet,它只会在属性不同时写入属性

查看

对我来说,重写这篇文章既不合适又耗时。我建议你检查一下2.0版的那些概念。。。然而,我可以提供一些受当前方法限制的建议

按照代码的结构,它将为每个需要更新的属性运行
Set QADUser
,而不是根据每个用户一次设置所有属性。相反,您可以收集所有更改并在每个用户的一次
Set QADUser
中应用。这将更快,并且可能有更紧凑的日志记录等

当您检查帐户是否已启用时,除了
写入主机
之外,您没有执行任何操作。如果您想跳过该用户,可以将该逻辑移到主循环中,并添加Continue语句。这也可以避免您循环两次

避免使用
+=
,您可以使用
[ArrayList]
。+=的性能和可伸缩性问题有很好的文档记录,因此您可以在谷歌上搜索更多信息<代码>[ArrayList]可能看起来像:

$result = [Collections.ArrayList]@()
# ...
[Void]$result.Add( [PSCustomObject]$problem )

如果设置了
-ErrorAction SilentlyContinue
,我也不确定catch块应该如何触发。您可能可以删除
If($ProcessError).
并将$Result的填充移动到
Catch{}
块。

postoofficebox
看起来像一个打字错误(两个连续的
o
's)@MathiasR.Jessen您是对的,但我只是在这里手动编写的,在终端中还可以。我已经在这里纠正了我的错误,感谢您的手动测试没有多大价值-两个表达式的计算结果可能都是
$null
,这就是它们相等的原因。您可以在
if($user.$param…
语句上方添加
Write Host“Testing:$($user.$param)-eq$($userQuery.$param)”
行,以查看正在比较的各个值。您是对的。我后来也弄明白了。谢谢非常感谢你。我会分析你所有的建议并付诸实施。代码进化了很多次,所以出现了过时的片段,比如
Catch{}
,我对Powershell还是相当陌生的。祝你有美好的一天!