首页 > 解决方案 > 我在使 Powershell Linq“加入”工作时遇到问题 [显式参数输入?]

问题描述

我一直致力于在 Oracle 和 Active Directory 之间配置脚本,更具体地说,是使用 Powershell 脚本。我找到了在 Powershell 中使用 Linq 的绝佳资源( Michael Sorens 的High Performance Powershell),但我在使用 JOIN 方法时遇到了问题,我认为这可能与我尝试输入参数的方式有关。我不得不承认我还没有完全掌握页面上的示例(Cross-Join)。我将设置问题,然后展示我正在尝试的内容(到目前为止失败了)。

我有一个数据库查询,它返回应该在 Active Directory 中的用户,并且我有一个“Get-ADUser”命令,可以获取每个在 Active Directory 中的人。我以前通过将两者中的属性数量减少到 ID (samaccountname) 来让“Except”运算符工作。所以,那时我可以推导出需要添加的每个人,以及需要删除的每个人。但我现在被简化为一个 ID 列表(即不再拥有我需要的完整字段......添加 AD 记录或发送“你即将被删除”电子邮件)。

因此,看到 Join 运算符,我想我会将删除列表重新加入“获取所有用户”AD 结果集。但是...我不断收到错误

Cannot find an overload for "Join" and the argument count: "5"

以下是简化移动部件的尝试,因此它是两个 AD 查询结果而不是原始问题(尽管显示相同的错误)。

$ad_host="my.adserver.edu"

$left = Get-ADUser -Server $ad_host -Identity 'knownuser' -Properties sAMAccountName | select sAMAccountName
$right = Get-ADUser -Server $ad_host -Filter * -SearchBase "OU=KnownUsersOU,OU=Students,OU=Users-Students,DC=my,DC=domain,DC=edu" -Properties sAMAccountName, givenName, sn | select sAMAccountName, givenName, sn

$outerKeyDelegate = [Func[Microsoft.ActiveDirectory.Management.ADAccount,string]] { $args[0].sAMAccountName }
$innerKeyDelegate = [Func[Microsoft.ActiveDirectory.Management.ADAccount,string]] { $args[0].sAMAccountName }
#$resultDelegate = [Func[Microsoft.ActiveDirectory.Management.ADAccount,Microsoft.ActiveDirectory.Management.ADAccount,string,string]] {'{0}, {1}, {2}, {3}, {4}' -f $args[0].sAMAccountName, $args[1].givenName, $args[1].sn, $args[1].mail, $args[1].employeeID }
$resultDelegate = [Func[Microsoft.ActiveDirectory.Management.ADAccount,string,string]] {'{0}, {1}' -f $args[0].sAMAccountName, $args[1].sAMAccountName }

[Linq.Enumerable]::Join($toRemove, $allUsers, $outerKeyDelegate, $innerKeyDelegate, $resultDelegate) | foreach { Add-Content -Path to_delete.csv -Value $_ }

因此,在这种情况下,我试图将我的联接属性显式键入为 Microsoft.ActiveDirectory.Management.ADAccount 对象...我实际上最初使用的是“字符串”,因为实际的联接属性是 samaccountname,当我运行一个“getType()”,它返回“String”......好吧,实际上它是“Name:String,BaseType:System.Object”。

在这一点上,我所知道的比我不知道的要重要:) 我可以通过将其全部移动到数据库中来制作“列表”来轻松做到这一点,但这似乎会更加优雅我可以掌握 Powershell-Linq!

标签: linqpowershellactive-directory

解决方案


我相信你的问题是类型。考虑这个命令:

$left = Get-ADUser -Server $ad_host -Identity 'knownuser' -Properties sAMAccountName | select sAMAccountName

此对象的类型将是ADUser.

对于这个命令:

$right = Get-ADUser -Server $ad_host -Filter * -SearchBase "OU=KnownUsersOU,OU=Students,OU=Users-Students,DC=my,DC=domain,DC=edu" -Properties sAMAccountName, givenName, sn | select sAMAccountName, givenName, sn

对象的类型将是Object[]。它需要是ADUser[]

你应该能够像这样投射它:

$right = [Microsoft.ActiveDirectory.Management.ADUser[]](Get-ADUser -Server $ad_host -Filter * -SearchBase "OU=KnownUsersOU,OU=Students,OU=Users-Students,DC=my,DC=domain,DC=edu" -Properties sAMAccountName, givenName, sn)

然后,由于您正在处理ADUser对象,因此您的关键代表也必须匹配:

$outerKeyDelegate = [Func[Microsoft.ActiveDirectory.Management.ADUser,string]] { $args[0].sAMAccountName } $innerKeyDelegate = [Func[Microsoft.ActiveDirectory.Management.ADUser,string]] { $args[0].sAMAccountName }

并且您的结果委托还必须与您正在处理的对象类型匹配(您在注释掉的代码中更接近):

$resultDelegate = [Func[Microsoft.ActiveDirectory.Management.ADUser,Microsoft.ActiveDirectory.Management.ADUser,string]] {'{0}, {1}' -f $args[0].sAMAccountName, $args[1].sAMAccountName }


推荐阅读