@@ -16,6 +16,8 @@ function Get-ShareSurferConflicts {
1616 $conflicts = New-Object System.Collections.ArrayList
1717 $sharePermissionsList = @ (ConvertTo-ShareSurferArray $SharePermissions )
1818 $aclEntriesList = @ (ConvertTo-ShareSurferArray $AclEntries )
19+ $aclTotal = $aclEntriesList.Count
20+ $conflictStatusIntervalSeconds = Get-ShareSurferConflictStatusIntervalSeconds - RequestedSeconds $StatusIntervalSeconds - AclRowCount $aclTotal
1921 $statusClock = [System.Diagnostics.Stopwatch ]::StartNew()
2022 $statusState = @ { LastSeconds = -999.0 }
2123 $showConflictProgress = [bool ]$ShowProgress -and -not [bool ]$Quiet
@@ -32,7 +34,7 @@ function Get-ShareSurferConflicts {
3234 }
3335
3436 $elapsed = [double ]$statusClock.Elapsed.TotalSeconds
35- if ($Force -or $StatusIntervalSeconds -le 0 -or ($elapsed - $statusState.LastSeconds ) -ge $StatusIntervalSeconds ) {
37+ if ($Force -or $conflictStatusIntervalSeconds -le 0 -or ($elapsed - $statusState.LastSeconds ) -ge $conflictStatusIntervalSeconds ) {
3638 $statusState.LastSeconds = $elapsed
3739 Write-ShareSurferStatus - Phase ' Export' - Message $Message
3840 }
@@ -70,43 +72,63 @@ function Get-ShareSurferConflicts {
7072 $ntfsAllowPatterns = @ {}
7173 $ntfsDenyItemIdentityKeys = @ {}
7274 $aclIndex = 0
73- $aclTotal = $aclEntriesList.Count
7475 foreach ($ace in $aclEntriesList ) {
7576 $aclIndex ++
76- if (-not $ntfsByShare.ContainsKey ($ace.ShareId )) {
77- $ntfsByShare [$ace.ShareId ] = @ {}
77+ $shareId = [string ]$ace.ShareId
78+ if (-not $ntfsByShare.ContainsKey ($shareId )) {
79+ $ntfsByShare [$shareId ] = @ {}
7880 }
7981
8082 $identityKey = ([string ]$ace.Identity ).ToUpperInvariant()
81- $ntfsByShare [$ace.ShareId ][$identityKey ] = $true
82-
83- $shareIdentityKey = ' {0}|{1}' -f [string ]$ace.ShareId , $identityKey
84- if (-not $ntfsIdentityExamples.ContainsKey ($shareIdentityKey )) {
85- $ntfsIdentityExamples [$shareIdentityKey ] = @ {
86- ShareId = [string ]$ace.ShareId
87- IdentityKey = $identityKey
88- Ace = $ace
89- EvidenceState = New-ShareSurferConflictEvidenceState
90- }
83+ $ntfsByShare [$shareId ][$identityKey ] = $true
84+
85+ $shareMap = @ {}
86+ if ($sharePermissionsByShare.ContainsKey ($shareId )) {
87+ $shareMap = $sharePermissionsByShare [$shareId ]
9188 }
92- Add-ShareSurferConflictEvidence - State $ntfsIdentityExamples [$shareIdentityKey ][' EvidenceState' ] - Ace $ace
89+ $shareMapHasIdentity = $shareMap.ContainsKey ($identityKey )
90+ $hasBroadAllowGate = ($shareHasBroadAllowGate.ContainsKey ($shareId ) -and [bool ]$shareHasBroadAllowGate [$shareId ])
9391
94- $accessType = Get-ShareSurferAccessType $ace.AccessControlType
95- if ($accessType -eq ' Allow' ) {
96- $allowPatternKey = ' {0}|{1}|{2}' -f [string ]$ace.ShareId , $identityKey , ([string ]$ace.Rights ).ToUpperInvariant()
97- if (-not $ntfsAllowPatterns.ContainsKey ($allowPatternKey )) {
98- $ntfsAllowPatterns [$allowPatternKey ] = @ {
99- ShareId = [string ]$ace.ShareId
92+ if ($shareMap.Count -gt 0 -and -not $shareMapHasIdentity -and -not $hasBroadAllowGate ) {
93+ $shareIdentityKey = ' {0}|{1}' -f $shareId , $identityKey
94+ if (-not $ntfsIdentityExamples.ContainsKey ($shareIdentityKey )) {
95+ $ntfsIdentityExamples [$shareIdentityKey ] = @ {
96+ ShareId = $shareId
10097 IdentityKey = $identityKey
10198 Ace = $ace
102- NtfsRank = Get-ShareSurferRightsRank - Rights $ace.Rights
10399 EvidenceState = New-ShareSurferConflictEvidenceState
104100 }
105101 }
106- Add-ShareSurferConflictEvidence - State $ntfsAllowPatterns [$allowPatternKey ][' EvidenceState' ] - Ace $ace
102+ Add-ShareSurferConflictEvidence - State $ntfsIdentityExamples [$shareIdentityKey ][' EvidenceState' ] - Ace $ace
103+ }
104+
105+ $accessType = Get-ShareSurferAccessType $ace.AccessControlType
106+ if ($accessType -eq ' Allow' ) {
107+ if ($shareMapHasIdentity ) {
108+ $shareIdentityCacheKey = ' {0}|{1}' -f $shareId , $identityKey
109+ $shareAllowRank = 0
110+ if ($shareAllowRankByShareIdentity.ContainsKey ($shareIdentityCacheKey )) {
111+ $shareAllowRank = [int ]$shareAllowRankByShareIdentity [$shareIdentityCacheKey ]
112+ }
113+
114+ $ntfsRank = Get-ShareSurferRightsRank - Rights $ace.Rights
115+ if ($shareAllowRank -gt 0 -and $ntfsRank -gt $shareAllowRank ) {
116+ $allowPatternKey = ' {0}|{1}|{2}' -f $shareId , $identityKey , ([string ]$ace.Rights ).ToUpperInvariant()
117+ if (-not $ntfsAllowPatterns.ContainsKey ($allowPatternKey )) {
118+ $ntfsAllowPatterns [$allowPatternKey ] = @ {
119+ ShareId = $shareId
120+ IdentityKey = $identityKey
121+ Ace = $ace
122+ NtfsRank = $ntfsRank
123+ EvidenceState = New-ShareSurferConflictEvidenceState
124+ }
125+ }
126+ Add-ShareSurferConflictEvidence - State $ntfsAllowPatterns [$allowPatternKey ][' EvidenceState' ] - Ace $ace
127+ }
128+ }
107129 }
108130 elseif ($accessType -eq ' Deny' ) {
109- $denyStateKey = ' {0}|{1}|{2}' -f [ string ] $ace .ShareId , [string ]$ace.ItemId , $identityKey
131+ $denyStateKey = ' {0}|{1}|{2}' -f $shareId , [string ]$ace.ItemId , $identityKey
110132 $ntfsDenyItemIdentityKeys [$denyStateKey ] = $true
111133 }
112134
@@ -282,6 +304,7 @@ function New-ShareSurferConflictEvidenceState {
282304 ExamplePath = ' '
283305 AffectedPathPrefix = ' '
284306 FirstSeenPath = ' '
307+ PrefixSampleCount = 0
285308 MaxDepth = 0
286309 }
287310}
@@ -300,28 +323,53 @@ function Add-ShareSurferConflictEvidence {
300323
301324 $State [' RowCount' ] = [int ]$State [' RowCount' ] + 1
302325
303- $itemId = Get-ShareSurferConflictRowValue - Row $Ace - Name ' ItemId'
326+ $itemId = ' '
327+ if ($null -ne $Ace.PSObject.Properties [' ItemId' ]) {
328+ $itemId = [string ]$Ace.PSObject.Properties [' ItemId' ].Value
329+ }
304330 if (-not [string ]::IsNullOrWhiteSpace($itemId )) {
305331 $State [' ItemIds' ][$itemId ] = $true
306332 }
307333
308- $path = Get-ShareSurferConflictEvidencePath - Row $Ace
334+ $path = ' '
335+ foreach ($name in @ (' FullPath' , ' ExamplePath' , ' UNCPath' , ' LocalPath' , ' RelativePath' )) {
336+ if ($null -ne $Ace.PSObject.Properties [$name ]) {
337+ $value = [string ]$Ace.PSObject.Properties [$name ].Value
338+ if (-not [string ]::IsNullOrWhiteSpace($value )) {
339+ $path = $value
340+ break
341+ }
342+ }
343+ }
344+
309345 if (-not [string ]::IsNullOrWhiteSpace($path )) {
310346 if ([string ]::IsNullOrWhiteSpace([string ]$State [' FirstSeenPath' ])) {
311347 $State [' FirstSeenPath' ] = $path
312348 }
313349 if ([string ]::IsNullOrWhiteSpace([string ]$State [' ExamplePath' ])) {
314350 $State [' ExamplePath' ] = $path
315351 }
316- if ([string ]::IsNullOrWhiteSpace([string ]$State [' AffectedPathPrefix' ])) {
317- $State [' AffectedPathPrefix' ] = $path
318- }
319- else {
320- $State [' AffectedPathPrefix' ] = Get-ShareSurferCommonPathPrefix - Left ([string ]$State [' AffectedPathPrefix' ]) - Right $path
352+
353+ $prefixSampleCount = [int ]$State [' PrefixSampleCount' ]
354+ if ($prefixSampleCount -lt 64 -or [string ]::IsNullOrWhiteSpace([string ]$State [' AffectedPathPrefix' ])) {
355+ if ([string ]::IsNullOrWhiteSpace([string ]$State [' AffectedPathPrefix' ])) {
356+ $State [' AffectedPathPrefix' ] = $path
357+ }
358+ else {
359+ $State [' AffectedPathPrefix' ] = Get-ShareSurferCommonPathPrefix - Left ([string ]$State [' AffectedPathPrefix' ]) - Right $path
360+ }
361+ $State [' PrefixSampleCount' ] = $prefixSampleCount + 1
321362 }
322363 }
323364
324- $depth = Get-ShareSurferConflictEvidenceDepth - Row $Ace
365+ $depth = 0
366+ if ($null -ne $Ace.PSObject.Properties [' Depth' ]) {
367+ $depthText = [string ]$Ace.PSObject.Properties [' Depth' ].Value
368+ [void ][int ]::TryParse($depthText , [ref ]$depth )
369+ }
370+ if ($depth -le 0 -and -not [string ]::IsNullOrWhiteSpace($path )) {
371+ $depth = @ ($path -split ' [\\/]' | Where-Object { -not [string ]::IsNullOrWhiteSpace($_ ) }).Count
372+ }
325373 if ($depth -gt [int ]$State [' MaxDepth' ]) {
326374 $State [' MaxDepth' ] = $depth
327375 }
@@ -415,6 +463,28 @@ function Get-ShareSurferConflictEvidenceDepth {
415463 @ ($path -split ' [\\/]' | Where-Object { -not [string ]::IsNullOrWhiteSpace($_ ) }).Count
416464}
417465
466+ function Get-ShareSurferConflictStatusIntervalSeconds {
467+ param (
468+ [int ] $RequestedSeconds = 15 ,
469+
470+ [int ] $AclRowCount = 0
471+ )
472+
473+ if ($RequestedSeconds -le 0 ) {
474+ return $RequestedSeconds
475+ }
476+
477+ if ($AclRowCount -ge 100000 -and $RequestedSeconds -lt 60 ) {
478+ return 60
479+ }
480+
481+ if ($AclRowCount -ge 25000 -and $RequestedSeconds -lt 30 ) {
482+ return 30
483+ }
484+
485+ $RequestedSeconds
486+ }
487+
418488function Get-ShareSurferCommonPathPrefix {
419489 param (
420490 [string ] $Left = ' ' ,
0 commit comments