This script generates a report of shares on domain controllers which are not in the allowed list, allowing you to find shares which rogue admins have created.
Change domain.com to your forest name.
Adjust the shares allowed if required.
Adjust the maxThread variable as required.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | # Shares Report Script # Configure max threads and invalid share / error logging file path # The query filters on the remote side so less data transfer across the WAN is required # Once the jobs are done, a report will auto-open in Notepad to display the invalid shares found #============================================================================== #= OPTIONS ==================================================================== $maxThread = 30 $invalidSharesLog = "C:\Users\Public\InvalidShares_$(Get-Date -f yyyy-MM-dd_HH_mm_ss).txt" #============================================================================== CLS Stop-Job *; Remove-Job * $allDCs = New-Object System.Collections.ArrayList; $allJobs = New-Object System.Collections.ArrayList $doneJobs = New-Object System.Collections.ArrayList; $DCsToProcess = New-Object System.Collections.ArrayList $start = Get-Date If (Test-Path $invalidSharesLog){del $invalidSharesLog} (Get-ADForest -Server 'domain.com').Domains | % { $DCs = Get-ADDomainController -Server $_ -Filter * ForEach ($DC in $DCs) { Write-Host "Found $($DC.Name).$_ to process..." -ForegroundColor Cyan $null = $allDCs.Add("$($DC.Name).$_") } } Write-Host "Found $($allDCs.Count) Domain Controllers to process..." -ForegroundColor Yellow $DCcount = $allDCs.Count $DCsToProcess = $allDCs Do { Write-Host "Current Jobs: $($allJobs.count)" If ($allJobs.Count -le $maxThread){ $addMore = ($maxThread - $allJobs.Count) ForEach ($DC in ($DCsToProcess | Select-Object -First $addMore)){ $newJob = Start-Job -ScriptBlock { param ([string]$DC) $shares = Get-WmiObject -ComputerName $DC -ClassName Win32_Share -Filter ` "` Not Name like 'ADMIN$' and ` Not Name like 'C$' and ` Not Name like 'D$' and ` Not Name like 'IPC$' and ` Not Name like 'NETLOGON' and ` Not Name like 'SYSVOL' ` " ` -ErrorVariable shareERR -ErrorAction SilentlyContinue; If ($shares -eq $null -and -not $shareERR){ Write-Output "STATUS: $($DC): No Invalid Shares Found" }ElseIf ($shareERR){ Write-Output "ERROR: $($DC): $($shareERR | Out-String)" }Else{ Write-Output "ERROR: $($DC): Invalid Shares Found`n$($shares | Out-String)" } } -ArgumentList $DC Write-Host "Started Job for $DC..." -ForegroundColor Cyan $null = $allJobs.Add($newJob.Id) $null = $DCsToProcess.Remove($DC) } } ForEach ($job in $allJobs){ If ($doneJobs -notcontains $job){ $status = Get-Job -id $job If ($status.State -eq 'Completed' -and $status.HasMoreData -eq 'True'){ $end = Get-Date $dateDiff = New-TimeSpan $start $end $minutes = $dateDiff.Minutes $seconds = $dateDiff.Seconds Write-Host "Time Elapsed: $($minutes)m $($seconds)s" -ForegroundColor Cyan Do{ $result = Receive-Job -id $job If ($result -like "ERROR:*"){ Write-Host $result -ForegroundColor Red $result | Out-File -Append -FilePath $invalidSharesLog }Else{ Write-Host $result -ForegroundColor Green } }Until($result -eq $null) $null = stop-job -Id $job;$null = Remove-Job -Id $job; $null = $doneJobs.Add($job) } sleep -s 1 } } ForEach ($done in $doneJobs){ $allJobs.Remove($done) } Write-Host "Completed Jobs: $($doneJobs.count)" -ForegroundColor Cyan } Until ($doneJobs.count -eq $DCcount) Write-Host "Processing is complete" -ForegroundColor Yellow Stop-Job *; Remove-Job * start notepad.exe $invalidSharesLog |