# encoding: ascii # api: powershell # title: Remove broken NTFS perm # description: COMMENT: # version: 4.0 # type: script # author: Stephen Wheet # license: CC0 # x-poshcode-id: 4985 # x-archived: 2014-03-21T14:07:36 # x-published: 2014-03-13T20:53:00 # # This script was created to find unknown SIDs or old domain permissions # on folders. It ignores folders where inheirtance # is turned on. # Version 2: completely changed the query method and ACL removal # Version 3: Added ability to query AD for servers, and handles getting # getting shares automatically from Netapp and Windows servers # Version 4: Cleaned up folder checking and added checking for local # account checking so we could ignore. # #========================================================================== # NAME: getunknownsids.ps1 # # AUTHOR: Stephen Wheet # Version: 4.0 # Date: 6/11/10 # # COMMENT: # This script was created to find unknown SIDs or old domain permissions # on folders. It ignores folders where inheirtance is turned on. # # This works on NETAPPS and WINDOWS servers. You will need the DLL's # # Version 2: completely changed the query method and ACL removal # Version 3: Added ability to query AD for servers, and handles getting # getting shares automatically from: # NETAPP FILERS # Windows servers # Version 4: Cleaned up folder checking and added checking for local # account checking so we could ignore. # #========================================================================== Function checkshare { Param($PassedShareName) Process { $path = "\\$serverFQDN\$PassedShareName" $filename = $path.Replace("\","-") + ".csv" #Place Headers on out-put file $list = "Task,Path,Access Entity," $list | format-table | Out-File "c:\reports\unknownsids\$filename" #Populate Folders Array Write-Host "Writing results to : $filename" $date = Get-Date Write-Host $date Write-Host "Getting Folders in: $Path" #PSIscontainer means folders only [Array] $folders = Get-ChildItem -path $path -recurse | ? {$_.PSIsContainer} #Process data in array ForEach ($folder in [Array] $folders) { #Check to see if there are any folders If ($folder.pspath){ #Convert Powershell Provider Folder Path to standard folder path $PSPath = (Convert-Path $folder.pspath) Write-Host "Checking Dir: $PSPath" #Check to make sure valid If ($PSPath){ #Get the ACL's from each folder $error.clear() $acl = Get-Acl -Path $PSPath #Write log if no access if (!$?) { $errmsg = "Error,$PSPath,ACCESS DENIED" $errmsg | format-table | Out-File -append "$filename" } #end IF $ACL.Access | ?{!$_.IsInherited} | ?{ $_.IdentityReference -like $unknownsid -or $_.IdentityReference -like $olddomain } | % {$value = $_.IdentityReference.Value #Check for Local account $localsid = 0 If ($value -like $unknownsid){ $checkforlocal = $value.split("-") $total =$checkforlocal.count -1 if ($checkforlocal[$total] -match "100?" -or $checkforlocal[$total] -match "500"){ $localsid = 1 # You can uncomment the below if you want to report on local accounts. #$list = ("Local,$PSPath,$value") #$list | format-table | Out-File -append "$filename" } #end IF } #end IF If (!$localsid){ Write-host "Found - $PSPath - $value" $list = ("Found,$PSPath,$value") $list | format-table | Out-File -append "$filename" #Remove Bad SID if ($removeacl) { $ACL.RemoveAccessRuleSpecific($_) Write-host "Deleting - $PSPath - $value" $list = ("Deleting,$PSPath,$value") $list | format-table | Out-File -append "$filename" }#end IF if ($removeacl -and $value) { $date = Get-Date Write-Host $date Write-host "Setting - $PSPath" $list = ("Setting,$PSPath") $list | format-table | Out-File -append "$filename" Set-ACL $PSpath $ACL $value = "" } #end IF } #end if } #end foreachobj } #end if } #end if } #end ForEach }#end Process } #end function get-pssnapin -registered | add-pssnapin -passthru [void][Reflection.Assembly]::LoadFile('C:\reports\ManageOntap.dll') #Need this DLL from netapp 3.5SDK $ReqVersion = [version]"1.2.2.1254" $QadVersion = (Get-PSSnapin Quest.ActiveRoles.ADManagement).Version #Need Quest plugins installed if($QadVersion -lt $ReqVersion) { throw "Quest AD cmdlets version '$ReqVersion' is required. Please download the latest version" } #end If #Set variables $value = "" $unknownsid = "*S-1-5-21-*" #Broken SID Verify the Broken SID number on your system and replace $olddomain = "Domain.local*" #Old w2k/nt4 domain $ErrorActionPreference = "SilentlyContinue" $removeacl = 0 #change to 1 if you want to remove the SID, 0 for only logging $localsid = 0 #Get all the servers from the specified OU $Servers = get-QADComputer -SearchRoot 'domain.local/ou/Server' # change the container. Foreach ($server in $Servers ) { $serverFQDN = $server.dnsname write-host $serverFQDN #Test ping server to make sure it's up before querying it $ping = new-object System.Net.NetworkInformation.Ping $Reply = $ping.Send($serverFQDN) if ($Reply.status -eq "Success"){ Write-Host "Online" #Check for Netapp .. if found get the shares differently If ($serverFQDN -like "*netapp*"){ $server = new-object netapp.manage.naserver($serverFQDN,1,0) #pass authentication $server.Style = "RPC" # Issue command to get the shares $NaElement = New-Object NetApp.Manage.NaElement("system-cli") $arg = New-Object NetApp.Manage.NaElement("args") $arg.AddNewChild('arg','cifs') $arg.AddNewChild('arg','shares') $NaElement.AddChildElement($arg) $CifsString = $server.InvokeElem($NaElement).GetChildContent("cli-output") # Split the returned txt up .. the $null makes it skip a line $null,$null,$Lines = $CifsString.Split("`n") Foreach ($line in $Lines ) { # Had to trick it so skip the line with permissions, then exclude ETC$ adn c$ if (!$line.startswith(" ") -and $line -notlike "*Etc$*" -and $line -notlike "*C$*"){ $l= $line.Split(" ") checkshare -PassedShareName $l[0] #Pass share to function } #end if } #end foreach } #end if Else{ #Else if a Windows server query via WMI Get-WMIObject Win32_Share -Computer $serverFQDN | where {$_.Name -like "*$*" -and $_.Name -notlike "*ADMIN*" -and $_.Name -notlike "*IPC*" -and $_.Name -notlike "*lib*"} | %{ #Set path $sharename = $_.name checkshare -PassedShareName $sharename #Pass share to function } #end ForEachObj } #End Else } #End If } #end ForEach