我在制作Powershell Linq“加入”工作时遇到了问题[明确的论证打字?]

时间:2018-05-03 15:08:52

标签: linq powershell active-directory

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

我有一个数据库查询,它返回应该在Active Directory中的用户,并且我有一个“Get-ADUser”命令可以获取每个在Active Directory中的人。我之前使用“Except”运算符来减少两者中的属性数量(samaccountname)。所以,在那时我可以派出每个需要添加的人,以及需要被删除的每个人。但我现在被缩减为ID列表(即不再需要我需要的完整补充内容......要么添加AD记录,要么发送“即将被删除”的电子邮件)。

所以,看到Join运算符,我以为我会将删除列表重新加入“get all users”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,那就更优雅了!

1 个答案:

答案 0 :(得分:1)

我相信你的问题与类型有关。请考虑以下命令:

$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 }