简体   繁体   English

Powershell 如何从另一个变量中减去一个变量,两者都包含 Exchange 邮箱 Object 身份

[英]Powershell how to subtract a variable from another variable, both contain the Exchange Mailbox Object Identity

I have two variables both which contain the Get-Mailbox object "Identity" of user accounts.我有两个变量,它们都包含用户帐户的Get-Mailbox object "Identity" I need to subtract the contents of one from the other IE:我需要从另一个 IE 中减去一个的内容:

$termednofwd = (domain.local/OUname/SubOU/Users/first1 last1, domain.local/OUname/SubOU/first2 last2)

$termedfmr = (domain.local/OUname/SubOU/Users/first1 last1)

I want something that would subtract the contents of $termedfmr from $termednofwd giving something like the below.我想要一些可以从$termednofwd中减去$termedfmr内容的东西,如下所示。 Compare-Object only lists the contents that are in both, I basically need to subtract what is in both from the first variable. Compare-Object只列出两者中的内容,我基本上需要从第一个变量中减去两者中的内容。 essentially: $termednofwdnofmr = $termednofwd - $termedfmr resulting in this:本质上: $termednofwdnofmr = $termednofwd - $termedfmr导致:

$termednofwdnofmr = (domain.local/OUname/SubOU/first2 last2)

In set theory terms, you're looking for the relative complement between two collections, which Compare-Object can provide, although it requires additional effort:在集合论术语中,您正在寻找Compare-Object可以提供的两个 collections 之间的相对互补,尽管它需要额外的努力:

By default, Compare-Object provides the symmetric difference between two sets, ie it lists the union of relative complements;默认情况下, Compare-Object提供两个集合之间的对称差,即列出相对补的并集; that is, given two sets A and B, it lists both those elements of B not present in A and those elements of A not present in B, and it uses the .SideIndicator property to indicate which is which:也就是说,给定两个集合 A 和 B,它列出B 中不存在于 A 中的那些元素那些不存在于 B 中的 A 元素,并且它使用.SideIndicator属性来指示哪个是哪个:

  • '<=' indicates objects unique to set A ( -ReferenceObject argument, or first positional argument), whereas '<='表示集合 A 唯一的对象( -ReferenceObject参数或第一个位置参数),而
  • '=>' indicates elements unique to set B ( -DifferenceObject argument, or second positional argument). '=>'表示集合 B 唯一的元素( -DifferenceObject参数或第二个位置参数)。

Therefore, you need to filter the output objects by their .SideIndicator values.因此,您需要通过其.SideIndicator值过滤 output 对象。
The -PassThru switch additionally ensures that the input objects are passed through (as opposed to wrapping them in a [pscustomobject] instance whose .InputObject contains them): -PassThru开关还确保输入对象被传递(而不是将它们包装在.InputObject包含它们的[pscustomobject]实例中):

$termednofwd = 'domain.local/OUname/SubOU/Users/first1 last1',
               'domain.local/OUname/SubOU/first2 last2'

$termedfmr = 'domain.local/OUname/SubOU/Users/first1 last1'

# Return the elements in $termednofwd that aren't also present in $termedfmr
Compare-Object $termednofwd $termedfmr -PassThru |
  Where-Object SideIndicator -eq '<='

The above yields 'domain.local/OUname/SubOU/first2 last2' , ie those element(s) in $termednofwd that aren't also present in $termedfmr .以上产生'domain.local/OUname/SubOU/first2 last2' ,即$termednofwd中不存在于$termedfmr中的那些元素。

Note: The above uses strings as input objects for brevity;注意:为简洁起见,以上使用字符串作为输入对象; in your case, since you're working with the objects returned by the Get-Mailbox cmdlet and want to compare based on their .Identity property values, you need to use:在您的情况下,由于您正在使用Get-Mailbox cmdlet 返回的对象并希望根据它们的.Identity属性值进行比较,因此您需要使用:

# If you only need the identity values as results.
Compare-Object $termednofwd.Identity $termedfmr.Identity -PassThru |
  Where-Object SideIndicator -eq '<='

# Alternatively, if you need the whole mailbox objects.
Compare-Object -Property Identity $termednofwd $termedfmr -PassThru |
  Where-Object SideIndicator -eq '<='

See also: GitHub issue #4316 , which proposes enhancing Compare-Object with set operations .另请参阅: GitHub issue #4316 ,它建议使用set operations增强Compare-Object

So this is essentially a practical example of Set theory ie I'd like all the items from Set 1 that isn't in Set 2. PowerShell doesn't have direct commandlets to do that but through the power of.Net you can lervage the Microsoft Linq libraries to do this work for you.所以这本质上是集合论的一个实际例子,即我想要集合 1 中不在集合 2 中的所有项目。PowerShell 没有直接的命令行开关来做到这一点,但通过.Net 的力量,你可以利用Microsoft Linq 库为您完成这项工作。

The only trick is that you need to cast your PowerShell variables to arrays of Objects to make the function call work right:唯一的技巧是您需要将 PowerShell 变量转换为对象的 arrays 以使 function 调用正常工作:

$results = [System.Linq.Enumerable]::Except([object[]]$mainArray, [object[]]$subArray)

Lastly, the items you are comparing in the two arrays have to be comparable.最后,您在两个 arrays 中比较的项目必须具有可比性。 For simple things like strings this is always works.对于像字符串这样简单的东西,这总是有效的。 If the things you are comparing are more complex objects, they may not be comparable directly.如果您要比较的事物是更复杂的对象,则它们可能无法直接进行比较。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM