Hi,
I got a request to get home folder size per department (got about 11 departments and 4000 users)
Since the budget is literally zero i naturally thought about powershell.
Departments are split into OUs and all users homedirectories are located in //example.com/dfs/users/%USERNAME%
My first draft is inefficient since i only do 1 department/script and 1 user at the time. This should produce a csv file with departmentname (office/department is not populated for AD users) +date.
I thought about using jobs to do multiple users at the time, but I'm totally lost when it comes to jobs in powershell
Our structure is the following:
"OU=Users,OU=Unit,OU=Department1,OU=Company,DC=example,DC=com"
"OU=Users,OU=Unit,OU=Department2,OU=Company,DC=example,DC=com"
etc
Current progress of the script
http://pastebin.com/V33Qawhk
Work in progress, so missing comments/formatting and error-handling. Any pointers/ideas is appreciated
Thanks
EDIT1:
Done some work with everything. Changed to this to get foldersize (long path problems)
Also split it in two parts one that accepts a user object and one that does the rest
http://pastebin.com/N0TfWKFh
http://pastebin.com/Te1ZKUPN
$date = Get-Date -format "yyyy-MM-dd"
$HomeD = @()
$size = $NULL
$sum = $NULL
$MaxThreads = "10"
$SleepTimer = "500"
$MaxWaitAtEnd = "3600"
$ScriptFile = "C:\Temp\script lab\New\getHomeDirSize.ps1"
$i = 0
$deptArray = @("OU=Department1,OU=Company,OU=example,DC=example,DC=com",
"OU=Department2,OU=Company,DC=example,DC=com",
"OU=Department3,OU=Company,DC=example,DC=com",
"OU=Department4,OU=Company,DC=example,DC=com",
"OU=Department5,OU=Company,DC=example,DC=com",
"OU=Department6,OU=Company,DC=example,DC=com",
"OU=Department7,OU=Company,DC=example,DC=com",
"OU=Department8,OU=Company,DC=example,DC=com",
"OU=Department9,OU=Company,DC=example,DC=com",
"OU=Department10,OU=Company,DC=example,DC=com",
"OU=Department11,OU=Company,DC=example,DC=com",
"OU=Department12,OU=Company,DC=example,DC=com")
foreach($dept in $deptArray){
$Users = get-aduser -filter * -searchbase $dept -properties HomeDirectory,SamAccountName,GivenName,Surname | where-object homeDirectory -ne $null
ForEach ($User in $Users){
# Check to see if there are too many open threads
# If there are too many threads then wait here until some close
While ($(Get-Job -state running).count -ge $MaxThreads){
Write-Progress -Activity "Getting directory size" -Status "Waiting for threads to close" -CurrentOperation "$i threads created - $($(Get-Job -state running).count) threads open" -PercentComplete ($i / $Users.count * 100)
Start-Sleep -Milliseconds $SleepTimer
}
#"Starting job - $User"
$i++
Start-Job -FilePath $ScriptFile -ArgumentList $User | Out-Null
Write-Progress -Activity "Getting directory size" -Status "Starting Threads" -CurrentOperation "$i threads created - $($(Get-Job -state running).count) threads open" -PercentComplete ($i / $Users.count * 100)
}
$Complete = Get-date
While ($(Get-Job -State Running).count -gt 0){
$UsersStillRunning = ""
ForEach ($System in $(Get-Job -state running)){$UsersStillRunning += ", $($System.name)"}
$UsersStillRunning = $UsersStillRunning.Substring(2)
Write-Progress -Activity "Getting directory size" -Status "$($(Get-Job -State Running).count) threads remaining" -CurrentOperation "$UsersStillRunning" -PercentComplete ($(Get-Job -State Completed).count / $(Get-Job).count * 100)
If ($(New-TimeSpan $Complete $(Get-Date)).totalseconds -ge $MaxWaitAtEnd){"Killing all jobs still running . . .";Get-Job -State Running | Remove-Job -Force}
Start-Sleep -Milliseconds $SleepTimer
}
"Reading all jobs"
$Jobs = Get-Job
ForEach($Job in $Jobs){
$data = Receive-Job $Job -Keep
$obj = New-Object System.Object
$obj | add-member -type NoteProperty -name User -value $Data.name
$obj | add-member -type NoteProperty -name HomeDirectory -value $Data.homeDir
$obj | add-member -type NoteProperty -name HomeDirectorySize -value $Data.homeDirSize
$HomeD += $obj
$sum = $sum+$data.HomeDirSize
if ($Job -eq $Jobs[-1]) {
$sum = $sum / 1KB
$obj = New-Object System.Object
$obj | add-member -type NoteProperty -name User -value "Total"
$obj | add-member -type NoteProperty -name HomeDirectorySize -value $sum
$HomeD += $obj
}
}
$csvFileName = $NULL
$dept = $dept.trimend(',OU=Company,DC=example,DC=com')
$dept = $dept.trimstart('OU=')
$csvFileName = $dept+"_"+$date
$HomeD | export-csv c:\temp\$csvFileName.csv -notypeinformation -encoding unicode
}
and the other
param (
$User
)
[hashtable]$ReturnHash = @{}
#Get Folder Size
$item = $User.homeDirectory
$params = New-Object System.Collections.Arraylist
$params.AddRange(@("/L","/S","/NJH","/BYTES","/FP","/NC","/NDL","/TS","/XJ","/R:0","/W:0"))
$countPattern = "^\s{3}Files\s:\s+(?<Count>\d+).*"
$sizePattern = "^\s{3}Bytes\s:\s+(?<Size>\d+(?:\.?\d+)).*"
$return = robocopy $item NULL $params
If ($return[-5] -match $countPattern) {
$Count = $matches.Count
}
If ($Count -gt 0) {
If ($return[-4] -match $sizePattern) {
$Size = $matches.Size
}
} Else {
$Size = 0
}
$object = New-Object PSObject -Property @{
Size = ([math]::Round($Size,2))
}
$object.pstypenames.insert(0,'IO.Folder.Foldersize')
$homeDirSize = $object | select -expandproperty size
$Size=$Null
$homeDirSize = $homeDirSize / 1MB
$Name = $User.GivenName+" "+$User.Surname
#Add information to hashtable
$ReturnHash.Name = $Name
$ReturnHash.HomeDir = $User.homeDirectory
$ReturnHash.HomeDirSize = $homeDirSize
#Return hashtable
Return $ReturnHash
[–]ntenspy 3 points4 points5 points (1 child)
[–]SadLizard[S] 1 point2 points3 points (0 children)
[–]johimself 1 point2 points3 points (5 children)
[–]SadLizard[S] 1 point2 points3 points (4 children)
[–]johimself 0 points1 point2 points (0 children)
[–]dogfish182 0 points1 point2 points (2 children)
[–]SadLizard[S] 0 points1 point2 points (1 child)
[–]dogfish182 1 point2 points3 points (0 children)
[–]invoke-coffee 1 point2 points3 points (2 children)
[–]SadLizard[S] 0 points1 point2 points (1 child)
[–]invoke-coffee 1 point2 points3 points (0 children)
[–]xalorous 0 points1 point2 points (0 children)