param( [string]$RootDir = '', [string]$SizeReport = "Normal", [string]$Action = "ReportOnly") ## Create the default Trap and Error Action Preference $ErrorActionPreference = "SilentlyContinue" trap { Write-Host "Could not continue, an exception was thrown:" -ForeGroundColor "Red" Write-Host $_.Exception.Message -ForeGroundColor "Yellow" $LogBuffer.Add("$(Get-Date -Format `"yyyy-MM-dd HH:mm:ss`"); !!! ERROR EXCEPTION THROWN !!!") | Out-Null $LogBuffer.Add("$(Get-Date -Format `"yyyy-MM-dd HH:mm:ss`"); $($_.Exception.Message)") | Out-Null continue } # Retrieves the filename of this script. $ScriptName = Split-Path $MyInvocation.MyCommand.Definition -leaf Function Show-Help { Write-Host "" Write-Host "Script created by Mike Bijl (Login Consultants)" -ForeGroundColor "DarkGreen" Write-Host "Script version 2.0" -ForeGroundColor "DarkGreen" Write-Host "" Write-Host "DEPENDANCY:" Write-Host " - Quest AD CmdLets from `"http://www.quest.com/powershell/activeroles-server.aspx`" " -ForeGroundColor "Green" Write-Host " - This must be started from a domainmember" -ForeGroundColor "Green" Write-Host "" Write-Host "DESCRIPTION:" Write-Host "This script will get the subdirs of -RootDir and gets the username out of the" Write-Host "folder name. That username will be checked against the Active Directory." Write-Host "It will move the profile dir of deleted and `"longer then a month disabled`" users" Write-Host "to the _Deleted or _Disabled folder." Write-Host "" Write-Host "The script will log the actions or reports in a Comma Seperated Value file .\-.csv" -ForeGroundColor "DarkGray" Write-Host "" Write-Host "EXAMPLE:" Write-Host ".\Clean-ProfileSharev2.ps1 -RootDir \\domain.local\profileshare$ -SizeReport Full -Action ReportOnly" -BackGroundColor "DarkGray" -ForeGroundColor "DarkBlue" Write-Host " Creates only a report about your share and don't change anything." -ForeGroundColor "DarkYellow" Write-Host ".\Clean-ProfileSharev2.ps1 -RootDir \\domain.local\profileshare$ -Action Move" -BackGroundColor "DarkGray" -ForeGroundColor "DarkBlue" Write-Host " Moves all the obsolete directories in the profile share. (You don't delete anything!!!)" -ForeGroundColor "DarkYellow" Write-Host "" Write-Host "SYNTAX:" Write-Host ".\Clean-ProfileSharev2.ps1 -RootDir [-SizeReport ] [-Action ]" -ForeGroundColor "Yellow" Write-Host "-RootDir " -ForeGroundColor "Yellow" Write-Host "This is a required argument and points to the share where the profiles are located. For example: \\domain.local\profileshare$ " Write-Host "" Write-Host "-SizeReport " -ForeGroundColor "Yellow" Write-Host "This is an optional argument that defines the way the foldersize is reported. Default = Normal" Write-Host " Full: The size of all the subfolders of Rootdir will be reported. (Slow)" Write-Host " Normal: Only the size of the moved or `"should be moved`" (deleted/disabled profile) folders are reported. (Somewhat Slow)" Write-Host " None: None of the foldersizes are reported. (Fastest)" Write-Host "" Write-Host "-Action " -ForeGroundColor "Yellow" Write-Host "This is an optional argument that defines the action to be taken when a user is deleted or disabled. Default = ReportOnly" Write-Host " ReportOnly: None of the folders are moved. The log file tells which folders could be moved." Write-Host " MoveDeletedOnly: Moves only the profile folder which foldername doesn't corresponds to a AD user account." Write-Host " Move: Moves the profile folder which foldername doesn't corresponds to a AD user account and moves the `n folder which foldername corresponds to a AD user account that is disabled for more than a month." Write-Host "" Write-Host "" Exit } ## Arrays of all arguments (and the possible values) $arrSizeReport = "Full", "Normal", "None" $arrAction = "ReportOnly", "MoveDeletedOnly", "Move" If (!$RootDir) { Show-Help } If (!($arrSizeReport -contains $SizeReport)){ Show-Help } If (!($arrAction –contains $Action)){ Show-Help } ## This function is the actual script Function Script { ## Creates a logfile if it does not exist and creates the firstline with the header. $LogFile = $($ScriptName).replace("ps1","csv") $DateRevMin = get-date -uformat "%Y-%m-%d" If ( -not (Test-Path -Path ./$DateRevMin-$LogFile)){ New-Item -path . -Name ./$DateRevMin-$LogFile -Type "file" -Value "Time;Status;Username;Size;Unit;Directory;Action`n" | Out-Null} ## Removes the limit of returned items of 1000 within the Quest AD CmdLets Set-QADPSSnapinSettings -DefaultSizeLimit 0 ## Creates the ArrayList to put the log in. This way there are less write actions in the logfile $LogBuffer = New-Object System.Collections.ArrayList ## Gets the Directory size. Includes also hidden en systemfolders with the specified folder. Function Get-DirSize($path) { $totalSize = Get-ChildItem -path $path -recurse -force -errorAction "SilentlyContinue"| Measure-Object -property length -sum "{0:n2}" -f ($totalSize.sum / 1MB) + ";MegaBytes" } ## Gets the netbios domain name $domain = $($(Get-QADRootDSE).Domain).Name write-progress -id 1 -activity "Getting SubDirs from $RootDir" -status "..." -percentComplete (0); $DirList = Get-ChildItem $RootDir $i=0 ## A counter to count the progress of the subdirs of $RootDir Foreach ($Dir in $Dirlist) { ##Checks if the foldername starts with a "_". These folders will be skipped. If (($($Dir.Name).indexof("_")) -ne 0) { $a = $i/$($DirList.count)*100 write-progress -id 1 -activity "Getting SubDirs from $RootDir" -status "$("{0:N0}" -f $a)% Processing $($Dir.Fullname)" -percentComplete ($a); $UsrName = $Dir -replace(".$domain","") ## Removes the postfix .$domain from the profile directories ## Queries the AD for this account. $ADQueryResult = (Get-QADObject "$domain\$UsrName").AccountIsDisabled switch ($ADQueryResult) { True { ## The user is disabled. If ( -not($SizeReport -eq "None")){ $DirSize = Get-DirSize("$($Dir.Fullname)") } ELSE { $DirSize = "N/A;MegaBytes"} ## Move the directory to $RootDir\_Disabled\ ONLY IF THE ACCOUNT IS LONGER THAN A MONTH DISABLED If ((Get-QADUser "$domain\$UsrName" -Disabled).ModificationDate -lt ($(Get-Date).AddMonths(-1))) { If ($Action -eq "Move") { $Comment = "The profiledir is moved because this account is disabled longer than a month" } ELSE { $Comment = "The profiledir would be moved. This user account is disabled longer than a month. But the action parameter should be Move" } $LogBuffer.Add("$(Get-Date -Format `"yyyy-MM-dd HH:mm:ss`");The user is disabled;$UsrName;$DirSize;$($Dir.Fullname);$Comment")|Out-Null If ($Action -eq "Move"){ $Destination = "$($($Dir.Parent).FullName)\_Disabled\$($Dir.Name)" If ( -Not (Test-Path -Path "$($($Dir.Parent).FullName)\_Disabled")) { New-Item -Type directory -Path "$($($Dir.Parent).FullName)\_Disabled" | Out-Null} Move-item -Path "$($Dir.Fullname)" -Destination "$Destination" -Force } } ELSE { $LogBuffer.Add("$(Get-Date -Format `"yyyy-MM-dd HH:mm:ss`");The user is disabled;$UsrName;$DirSize;$($Dir.Fullname);The profiledir is NOT moved because this account is just disabled this month")|Out-Null } } False { ## The user is enabled. If ($SizeReport -eq "Full"){ $DirSize = Get-DirSize("$($Dir.Fullname)") } ELSE { $DirSize = "N/A;MegaBytes"} $LogBuffer.Add("$(Get-Date -Format `"yyyy-MM-dd HH:mm:ss`");The user exists;$UsrName;$DirSize;$($Dir.Fullname);-")|Out-Null } "" { ## The user does not exist. If ( -not($SizeReport -eq "None")){ $DirSize = Get-DirSize("$($Dir.Fullname)") } ELSE { $DirSize = "N/A;MegaBytes"} If ( -not($Action -eq "ReportOnly")) { $Comment = "The profiledir is moved" } ELSE { $Comment = "The profiledir should be moved when -Action is not ReportOnly" } $LogBuffer.Add("$(Get-Date -Format `"yyyy-MM-dd HH:mm:ss`");The user does not exist;$UsrName;$DirSize;$($Dir.Fullname);$Comment")|Out-Null ## Move the directory to $RootDir\_Deleted\ If ( -not($Action -eq "ReportOnly")){ $Destination = "$($($Dir.Parent).FullName)\_Deleted\$($Dir.Name)" If ( -Not (Test-Path -Path "$($($Dir.Parent).FullName)\_Deleted")) { New-Item -Type directory -Path "$($($Dir.Parent).FullName)\_Deleted" | Out-Null} Move-item -Path "$($Dir.Fullname)" -Destination "$Destination" -Force } } } } $i += 1 Add-Content -Path ./$DateRevMin-$LogFile -Value $LogBuffer If ($LogBuffer){ $LogBuffer.Clear() } ## If the LogBuffer is not empty then clear the LogBuffer } } Script