在 Array Powershell 中获取新的附加值
Get newly added value in Array Powershell
for (;;) {
#Get All Files from the Folder
$FolderItems = @(Get-PnPFolderItem -FolderSiteRelativeUrl $FolderURL -ItemType File)
Write-Host "Total Number of Files in the Folder:" $FolderItems.Count
if ($FolderItems.Count -gt $oldCount) {
foreach ($item in $FolderItems) {
if ($oldFolderItems -contains $item) {
}
else {
Write-Host $item.Name
}
}
}
$oldCount = $FolderItems.Count
$oldFolderItems = $FolderItems
timeout 180
}
它打印所有名称而不是一个新项目
tl;dr
用以下对 Compare-Object
的调用替换您的 foreach
循环:
# Compare the new and the old collection items by their .Name property
# and output the name of those that are unique to the new collection.
Compare-Object -Property Name $FolderItems $oldFolderItems |
Where-Object SideIndicator -eq '<=' |
ForEach-Object Name
为了安全起见,您还应该将 $oldFolderItems
初始化为 $null
并将 $oldCount
初始化为 0
,并且 - 除非您想要 all names to be output in the first iteration - 将封闭的 if
语句更改为:
if ($oldFolderItems -and $FolderItems.Count -gt $oldCount) { # ...
注意:对您的尝试的立即但效率低下的修复如下,原因在下一节中解释:
if ($oldFolderItems.Name -contains $item.Name) { # Compare by .Name values
注:$oldFolderItems.Name
实际上return是数组的.Name
属性值 集合 $oldFolderItems
中的元素 ,这是一个名为 member-access enumeration.
的便利功能
至于你试过的:
不清楚 .NET 类型 Get-PnPFolderItem
return 的实例,但可以公平地假设该类型是 .NET reference type (as opposed to a value type)。
除非引用类型明确设计为根据标识属性比较其实例,[1] 引用相等性 在等式 test-based 操作中测试 ,例如 -contains
(但也在其他 equality-comparison 操作中,例如 -in
和 -eq
),即 只有两个对 非常相同的实例 的引用被认为是相等的 。
因此,在您的案例中使用 -contains
是行不通的,因为集合的元素 - 即使它们 概念上 代表相同的对象 - 不同的实例 比较为不相等。
一个简化的示例,使用 System.IO.DirectoryInfo
个实例,由 Get-Item
:
输出
# !! Returns $false, because the two [System.IO.DirectoryInfo]
# !! instances are distinct objects.
@(Get-Item /) -contains (Get-Item /)
因此,.NET 引用类型的实例必须通过 属性 的 值进行比较(如果可用,例如 .Name
在这种情况下)而不是 作为一个整体 .
要发现给定实例是否是 .NET 引用类型之一,请访问该类型的 .IsValueType
属性: a return $false
的值表示引用类型;例如:
(Get-Item /).GetType().IsValueType # -> $false -> reference type
# Equivalent, with a type literal
[System.IO.DirectoryInfo].IsValueType # -> $false
[1] 一个值得注意的例子是 [string]
类型,作为例外,它通常表现得像 值类型 ,因此尽管涉及技术上不同的实例,但以下仍然是 $true
:$s1 = 'foo'; $s2 = 'f' + 'oo'; $s1 -eq $s2
for (;;) {
#Get All Files from the Folder
$FolderItems = @(Get-PnPFolderItem -FolderSiteRelativeUrl $FolderURL -ItemType File)
Write-Host "Total Number of Files in the Folder:" $FolderItems.Count
if ($FolderItems.Count -gt $oldCount) {
foreach ($item in $FolderItems) {
if ($oldFolderItems -contains $item) {
}
else {
Write-Host $item.Name
}
}
}
$oldCount = $FolderItems.Count
$oldFolderItems = $FolderItems
timeout 180
}
它打印所有名称而不是一个新项目
tl;dr
用以下对 Compare-Object
的调用替换您的 foreach
循环:
# Compare the new and the old collection items by their .Name property
# and output the name of those that are unique to the new collection.
Compare-Object -Property Name $FolderItems $oldFolderItems |
Where-Object SideIndicator -eq '<=' |
ForEach-Object Name
为了安全起见,您还应该将 $oldFolderItems
初始化为 $null
并将 $oldCount
初始化为 0
,并且 - 除非您想要 all names to be output in the first iteration - 将封闭的 if
语句更改为:
if ($oldFolderItems -and $FolderItems.Count -gt $oldCount) { # ...
注意:对您的尝试的立即但效率低下的修复如下,原因在下一节中解释:
if ($oldFolderItems.Name -contains $item.Name) { # Compare by .Name values
注:$oldFolderItems.Name
实际上return是数组的.Name
属性值 集合 $oldFolderItems
中的元素 ,这是一个名为 member-access enumeration.
至于你试过的:
不清楚 .NET 类型 Get-PnPFolderItem
return 的实例,但可以公平地假设该类型是 .NET reference type (as opposed to a value type)。
除非引用类型明确设计为根据标识属性比较其实例,[1] 引用相等性 在等式 test-based 操作中测试 ,例如 -contains
(但也在其他 equality-comparison 操作中,例如 -in
和 -eq
),即 只有两个对 非常相同的实例 的引用被认为是相等的 。
因此,在您的案例中使用 -contains
是行不通的,因为集合的元素 - 即使它们 概念上 代表相同的对象 - 不同的实例 比较为不相等。
一个简化的示例,使用 System.IO.DirectoryInfo
个实例,由 Get-Item
:
# !! Returns $false, because the two [System.IO.DirectoryInfo]
# !! instances are distinct objects.
@(Get-Item /) -contains (Get-Item /)
因此,.NET 引用类型的实例必须通过 属性 的 值进行比较(如果可用,例如 .Name
在这种情况下)而不是 作为一个整体 .
要发现给定实例是否是 .NET 引用类型之一,请访问该类型的 .IsValueType
属性: a return $false
的值表示引用类型;例如:
(Get-Item /).GetType().IsValueType # -> $false -> reference type
# Equivalent, with a type literal
[System.IO.DirectoryInfo].IsValueType # -> $false
[1] 一个值得注意的例子是 [string]
类型,作为例外,它通常表现得像 值类型 ,因此尽管涉及技术上不同的实例,但以下仍然是 $true
:$s1 = 'foo'; $s2 = 'f' + 'oo'; $s1 -eq $s2