I have a list of .txt files inside a folder with the following naming: firstname[dot]lastname[underscore]nationality[underscore]date.txt
Examples:
charles.pearson_FR_08-11-2021.txt
lena.smith_GB_11-12-2019.txt
paul.miller_XX_08-03-2017.txt
I would like to replace the filenames of the files that have a 'XX' as nationality by the nationality coming from a lookup table.
What I have tried so far:
$sqlcn = New-Object System.Data.SqlClient.SqlConnection
$sqlcn.ConnectionString = "MyData; MyCatalog;"
$sqlcn.Open()
$sqlcmd = $sqlcn.CreateCommand()
$query = "select username, nationality from mytable"
$sqlcmd.CommandText = $query
$adp = New-Object System.Data.SqlClient.SqlDataAdapter $sqlcmd
$data = New-Object System.Data.DataSet
$adp.Fill($data) | Out-Null
# create a lookup Hashtable
$lookup = #{}
# build up the $lookup hash
foreach ($item in $data.Tables) {
$lookup[$item.username] = $item.nationality
}
[string]$rootPathForFiles = Join-Path -Path $env:USERPROFILE -ChildPath 'Desktop\testFolder'
[string[]]$listOfFilesToRename = Get-ChildItem -Path $rootPathForFiles -Filter '*_XX_*.txt' | Select-Object -ExpandProperty FullName
$listOfFilesToRename | ForEach-Object {
#get the filename without the directory
[string]$newName = Split-Path -Path $_ -Leaf
#NEEDED: Lookup on the hashtable and rename the file
}
It correctly lists all .txt files that have _XX_ in the name but I miss the lookup on the hashtable and the renaming.
For information, $data looks like this:
username nationality
-------- -----------
lena.jeankins
paul.mirabel GB
mickael.mudik GB
paul.miller FR
...
What you can do here is to not just select the files FullName, but instead keep the complete FileInfo object and use the .BaseName and .Extensions properties like this:
$rootPathForFiles = Join-Path -Path $env:USERPROFILE -ChildPath 'Desktop\testFolder'
(Get-ChildItem -Path $rootPathForFiles -Filter '*.*_XX_*.txt' -File) | ForEach-Object {
$userName,$nationality,$date = $_.BaseName -split '_'
if ($lookup.ContainsKey($userName)) {
$newName = '{0}_{1}_{2}{3}' -f $userName, $lookup[$username], $date, $_.Extension
$_ | Rename-Item -NewName $newName
}
else {
Write-Warning "Could not retrieve nationality for user $userName"
}
}
Related
I have a PowerShell script that stores the full paths of the files in a specific directory along with some other information. I have exported the CSV file. Now, the paths are actually being combined together to comprise of the full path. Let me give an example below:
$root= C:\Users\home\
$web = facebook website\domain
$app = facebook android\latest
These paths are then joined together with either Join-Path or $fbweb = $root + $web to make up the full path: C:\Users\home\facebook website\domain
Now the above mentioned path will have other files, subfolders etc in it but that's the gist of how the paths are structured. I have exported them in the CSV file but I'm having trouble with the following. I need the CSV file to have paths in such a way that the part leading up to the $web is trimmed out.
For instance if the CSV file is like this:
Path
C:\Users\home\facebook website\domain\version\version-feb-2020.txt
C:\Users\home\facebook website\domain\interface\somefile.html
C:\Users\home\facebook android\latest\messenger\messenger app files\code.js
C:\Users\home\facebook android\latest\application\somecode.js
I want it to turn out like this:
Path
facebook website\domain
\version\version-feb-2020.txt
\interface\somefile.html
facebook android\latest
\messenger\messenger app files\code.js
application\somecode.js
I have tried using the following to trim it out:
$number = [regex]::matches($fbweb,"\\").count
Select-Object Hash,
#{
Name = "FilePath";
Expression = { [string]::Join("\", ($_.Path -split "\\" | Select-Object -skip ($number)))}
}
Update:
I have tried this:
$replace = Join-Path -Path $root -ChildPath $web
echo $replace
$RefHash = Import-csv "C:\Users\Admin\Desktop\fb.csv"
$RefHash | ForEach-Object {
echo $_.Path
($_.Path).Replace($replace, "\")
} | Export-csv "C:\Users\Admin\Desktop\replaced.csv"
But this just results in the exported csv showing the following:
#TYPE System.String
"Length"
"numbers"
"numbers"
"numbers"
As discussed, you have 2 methods to manage this:
Treat the csv file as a text file and do a replace on a get-content:
(Get-Content -Path "C:\temp\TestMD5.csv").Replace($replace, "\") | Set-Content "C:\temp\TestMD5updated.csv"
Import the CSV, separate the each of the parameters, modify what you require and then build a pscustomobject which you then export as csv:
#Preparing variables
$scriptdir = [System.IO.Path]::GetDirectoryName($MyInvocation.MyCommand.Path)
$sourcecsv = Import-csv -path "C:\temp\TestMD5.csv"
$obj = #()
$root = "C:\Temp"
$web = "Test01\Test02\"
$replace = Join-Path -Path $root -ChildPath $web
$target = "\"
#Executing replace
foreach ($line in $sourcecsv) {
$object = New-Object -TypeName psobject
$algo = $line | Select-Object -ExpandProperty 'Algorithm'
$Hash = $line | Select-Object -ExpandProperty 'Hash'
$Path = ($line | Select-Object -ExpandProperty 'Path').Replace($replace, $target)
$object | Add-Member -MemberType NoteProperty -Name Algorithm -Value $algo
$object | Add-Member -MemberType NoteProperty -Name Hash -Value $Hash
$object | Add-Member -MemberType NoteProperty -Name Path -Value $Path
$obj += $object
$object
}
$obj | Export-Csv -NoTypeInformation -Path "$scriptdir\UpdatedVars.csv"
The first one is faster, the 2nd one provides you the flexibility that would allow you to build functions that are generalized and modify additional parameters as required.
OK assuming you don't actually need to import and deal with the file as a CSV file. You simply need to replace the strings in a text file. If so then you can use get-content instead of import-csv
You want to use REPLACE.
$SourceFile = Get-Content -Path "D:\URL.txt"
$root= "C:\Users\home\"
$web = "facebook website\domain"
$app = "facebook android\latest"
$replace1 = $root+$web
$replace2 = $root+$app
$SourceFile -replace [Regex]::Escape($replace1), "\" -replace [Regex]::Escape($replace2), "\" | Set-Content -Path "D:\urlreplaced.txt"
This will do the replace and output the new file to D:\urlreplaced.txt
To convert the csv data into a new format as you would like, you could do the following:
$root= 'C:\Users\home'
$web = 'facebook website\domain'
$app = 'facebook android\latest'
$webPath = [regex]::Escape((Join-Path -Path $root -ChildPath 'facebook website\domain'))
$appPath = [regex]::Escape((Join-Path -Path $root -ChildPath 'facebook android\latest'))
$data = Import-Csv -Path "C:\Users\Admin\Desktop\fb.csv"
$appData = ($data | Where-Object { $_.Path -match "^$appPath" } | Select-Object #{Name = 'Path'; Expression = {$_.Path -replace "^$appPath" }}).Path
$webData = ($data | Where-Object { $_.Path -match "^$webPath" } | Select-Object #{Name = 'Path'; Expression = {$_.Path -replace "^$webPath" }}).Path
# manually create the one-column csv (easiest is to do this in a Here-String)
$newData = #"
Path
$web
$($webData -join [Environment]::NewLine)
$app
$($appData -join [Environment]::NewLine)
"#
# output on screen
$newData
# output to new CSV file
$newData | Set-Content -Path "C:\Users\Admin\Desktop\replaced.csv" -Force
Output on screen
Path
facebook website\domain
\version\version-feb-2020.txt
\interface\somefile.html
facebook android\latest
\messenger\messenger app files\code.js
\application\somecode.js
I need assistance in filtering what is going in to my output.
Here is my code:
$FolderPath = Get-ChildItem -Directory -Path "Z:\D482\F11\SECURE" -Recurse -Force
$Output = #()
ForEach ($Folder in $FolderPath) {
$Acl = Get-Acl -Path $Folder.FullName
ForEach ($Access in $Acl.Access) {
$Properties = [ordered]#{'Folder Name'=$Folder.FullName;'Group/User'=$Access.IdentityReference }
$Output += New-Object -TypeName PSObject -Property $Properties
}
}
$Output | ConvertTo-Csv | Out-File C:\Temp\Secured.txt
My output looks like this:
#TYPE System.Management.Automation.PSCustomObject
"Folder Name","Group/User"
"Z:\D482\F11\SECURE\QA\CDM\To_Load\Duals\Load_Completed","S-1-5-21-1275210071-879983540-1801674531-105509"
"Z:\D482\F11\SECURE\QA\Files\CDM\To_Load\Duals\Load_Completed","S-1-5-21-1275210071-879983540-1801674531-121910"
"Z\D482\F11\SECURE\QA\D482\To_Load\Duals\Load_Completed","DOMAIN\CXL3708"
In my output, I only want lines that contain our domain name ( as illustrated by the line with DOMAIN in it.
I have not been successful - either I get nothing, or I get error messages in the console.
here is one way to do the job ... [grin]
what it does ...
sets the constants
builds a parameter splat for the Get-ChildItem call
grabs the dirs from the source path
iterates thru the dir list
gets the acl list for the current dir & filters for those that start with the required domain name
note that i don't have a .IdentityReference property in my ACL, so i used .Owner instead.
iterates thru those acl items
builds a [PSCustomObject] for the current acl
sends that out to the $AccessInfo collection
displays the content of the above on screen
saves the collection to a csv file
the code ...
$SourcePath = $env:TEMP
$DomainName = $env:USERDOMAIN
$ReportFile = "SO_Erich_Powershell - How To Filter Output.csv"
$FullReportFile = Join-Path -Path $env:TEMP -ChildPath $ReportFile
$GCI_Params = #{
LiteralPath = $SourcePath
Directory = $True
Force = $True
Recurse = $True
ErrorAction = 'SilentlyContinue'
}
$DirList = Get-ChildItem #GCI_Params
$AccessInfo = foreach ($DL_Item in $DirList)
{
$AclList = Get-Acl -LiteralPath $DL_Item.FullName |
Where-Object {
$_.Owner -match "^$DomainName"
}
foreach ($AL_Item in $AclList)
{
[PSCustomObject]#{
DirName = $DL_Item.FullName
# my single system has no ".IdentityReference" property
# so i used ".Owner"
GroupOrUser = $AL_Item.Owner
}
}
}
# display the data
$AccessInfo
# send to a csv file
$AccessInfo |
Export-Csv -LiteralPath $FullReportFile -NoTypeInformation
truncated screen output ...
DirName GroupOrUser
------- -----------
C:\Temp\1 MySysName\AnotherUserName
C:\Temp\2 MySysName\AnotherUserName
C:\Temp\3 MySysName\AnotherUserName
[*snip ...*]
C:\Temp\vscode-update-system-x64 MySysName\MyUserName
C:\Temp\WPF MySysName\MyUserName
C:\Temp\mbam\qt-jl-icons MySysName\MyUserName
truncated csv file content ...
"DirName","GroupOrUser"
"C:\Temp\1","MySysName\AnotherUserName"
"C:\Temp\2","MySysName\AnotherUserName"
[*snip ...*]
"C:\Temp\WPF","MySysName\MyUserName"
"C:\Temp\mbam\qt-jl-icons","MySysName\MyUserName"
What I like to do is pass the $sContractNumbers variable to the loop I have below which essentially pieces two csv files together based on the SQL queries.
I'm using the block below to get a value from an excel spreadsheet. Something that will be updated by a different user. The cell will always be static but the data in the cell will change in size so I have to use the IN clause.
My variable value looks like so.
$sContractNumbers = 'abc123','abc456','abc789','abc112','abc345'
$xl = New-Object -COM "Excel.Application"
$xl.Visible = $true
$wb = $xl.Workbooks.Open("C:\Dev\Blah\ManualContracts.xlsx")
$ws = $wb.Sheets.Item(1)
#Looking up a value in one column and assigning the corresponding value from another column to a variable could be done like this:
for ($i = 0; $i -le 1; $i++) {
if ( $ws.Cells.Item(1, 2).Text -eq $ColumnHeader ) {
$i = $i++;
$sContractNumbers = $ws.Cells.Item(2, 2).Value
#$sContractNumber
break
}
}
$wb.Close()
$xl.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl)
$sContractNumbers
Prior to adding this piece I was just copying and pasting my list of contracts in both queries.
Currently the error I'm getting is the following. I don't believe the loop is picking up on the variable. I've tried using AddWithValue but I don't think I'm placing it correctly, which is why its not listed. Fairly new to powershell but know a little bit of T-SQL. I think its a simple question but I cannot fully understand what I need to correct it since I'm noob. Be gentle...
$DetailContent[1] = "{0}`r`n{1}" -f $HeadeDetail, $DetailContent[1]
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Cannot index into a null array.
Function Run-Query
{
param([string[]]$queries,[string[]]$sheetnames)
Begin
{
$SQLServer = 'server'
$Database = 'warehouse'
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $Database; Integrated Security = True"
$FileNameDate = Get-Date -f 'yyyyMMdd'
}#End Begin
Process
{
# Loop through each query
For($i = 0; $i -lt $queries.count; $i++)
{
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $queries[$i]
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$DataSet.Tables[0] | Export-CSV -NoTypeInformation -Path "C:\Dev\blah\HeaderDetail\$($sheetnames[$i])_$FileNameDate-000.csv" -Delimiter '|'
}
}#End Process
End
{
$SqlConnection.Close()
}
}#End function run-query.
$queries = #()
$queries += #'
SET NOCOUNT ON
SET ANSI_WARNINGS OFF
/*FE Header*/
SELECT [sContractNumber] as ContractNumber,
into #Temp
FROM C
INNER JOIN D ON C.Id=D.iId
WHERE c.sContractNumber in ('$sContractNumbers')
order by sContractNumber
declare #TotalNewContracts int = 0
declare #TotalCanContracts int = 0
declare #TotalExpContracts int = 0
set #TotalNewContracts = (select COUNT(fe.ContractNumber) from #temp fe where Record_Type = 'P')
set #TotalCanContracts = (select COUNT(fe.ContractNumber) from #temp fe where Record_Type = 'C')
select
count(contractnumber) as 'Total Number of All Contracts',
FROM #temp ;
drop table #Temp;
'#
$queries += #'
SET NOCOUNT ON
SET ANSI_WARNINGS OFF
/*FE Header*/
SELECT [sContractNumber] as ContractNumber,
into #Table
FROM [pcmi_warranty_custom_twsi].[dbo].[Contract_Header] C
INNER JOIN [pcmi_warranty_custom_twsi].[dbo].[Dealer_Header] D ON C.iDealerId=D.iId
WHERE c.sContractNumber in ('$sContractNumbers')
order by sContractNumber
SELECT ContractNumber,
FROM #temp FE;
drop table #Temp;
'#
$sheetnames = #()
$sheetnames += 'Header'
$sheetnames += 'Details'
#FileName
$FileNameDate = Get-Date -f 'yyyyMMdd'
Run-Query -queries $queries -sheetnames $sheetnames
#Removes Double Quotes from File
(Get-Content C:\Dev\blah\HeaderDetail\Header_$FileNameDate-000.csv) | % {$_ -replace '"', ''} | out-file -FilePath C:\Dev\blah\Header\Header_$FileNameDate-000.csv -Force -Encoding ascii
(Get-Content C:\Dev\blah\HeaderDetail\Details_$FileNameDate-000.csv) | % {$_ -replace '"', ''} | out-file -FilePath C:\Dev\blah\Detail\Details_$FileNameDate-000.csv -Force -Encoding ascii
#Add Double Pipes as Delimter
(Get-Content C:\Dev\blah\Header\Header_$FileNameDate-000.csv) | % {$_ -replace "\|", "||"} | out-file -FilePath C:\Dev\blah\Header\Header_$FileNameDate-000.csv -Force -Encoding ascii
(Get-Content C:\Dev\blah\Detail\Details_$FileNameDate-000.csv) | % {$_ -replace "\|", "||"} | out-file -FilePath C:\Dev\blah\Detail\Details_$FileNameDate-000.csv -Force -Encoding ascii
#Add Header Detail Row to Detail File
#Header Path
$HeaderPath = "C:\Dev\blah\Header\Header_$FileNameDate-000.csv"
#Detail Path
$DetailsPath = "C:\Dev\blah\Detail\Details_$FileNameDate-000.csv"
#Gets second row of header file and sets it as a varaible
$HeadeDetail = Get-Content $HeaderPath -TotalCount 2 | Select-Object -Last 1;
#print the header detail row
$HeadeDetail
#Get Detail File content
$DetailContent = Get-Content -Path $DetailsPath
#Add Header Detail row to Detail file
$DetailContent[1] = "{0}`r`n{1}" -f $HeadeDetail, $DetailContent[1]
#Save Detail File
$DetailContent | Set-Content "C:\Dev\blah\blah$FileNameDate-000.csv" -Force -Encoding ascii
#Set the file name
$SourceFile = "C:\Dev\blah\blah$FileNameDate-000.csv"
$DestinationFolder = 'C:\Dev\blah'
$HeaderFile = "C:\Dev\blah\Header\Header_$FileNameDate-000.csv"
$DetailFile = "C:\Dev\blah\Detail\Details_$FileNameDate-000.csv"
$HDestinationFolder = 'C:\Dev\blah\Header'
$DDestinationFolder = 'C:\Dev\blah\Detail'
if (Test-Path $SourceFile)
{
$latest = Get-ChildItem -Path $DestinationFolder| Sort-Object Name -Descending | Select-Object -First 1
#split the latest filename, increment the number, then re-assemble new filename:
$newFileName = $latest.BaseName.Split('-')[0] + "-" + ([int]$latest.BaseName.Split('-')[1] + 1).ToString().PadLeft(3,"0") + $latest.Extension
Move-Item -path $SourceFile -destination $DestinationFolder"\"$newFileName
}
if (Test-Path $HeaderFile)
{
$latest = Get-ChildItem -Path $HDestinationFolder| Sort-Object Name -Descending | Select-Object -First 1
#split the latest filename, increment the number, then re-assemble new filename:
$newFileName = $latest.BaseName.Split('-')[0] + "-" + ([int]$latest.BaseName.Split('-')[1] + 1).ToString().PadLeft(3,"0") + $latest.Extension
Move-Item -path $HeaderFile -destination $HDestinationFolder"\"$newFileName
}
if (Test-Path $DetailFile)
{
$latest = Get-ChildItem -Path $DDestinationFolder| Sort-Object Name -Descending | Select-Object -First 1
#split the latest filename, increment the number, then re-assemble new filename:
$newFileName = $latest.BaseName.Split('-')[0] + "-" + ([int]$latest.BaseName.Split('-')[1] + 1).ToString().PadLeft(3,"0") + $latest.Extension
Move-Item -path $DetailFile -destination $DDestinationFolder"\"$newFileName
}
#Creates backup folder with corresponding date and places the file
$FolderName = Get-Date -f 'MMdd'
$FolderToCreate = "C:\Dev\blah\$FolderName"
if (!(Test-Path $FolderToCreate -PathType Container)) {
New-Item -ItemType Directory -Force -Path $FolderToCreate
}
Copy-Item -Path "$DestinationFolder\TWFE*.csv" -Destination $FoldertoCreate -force;
$ODrive = 'O:\blah\blah\blah'
$FolderToCopy = "O:\blah\blah\blah\$FolderName"
$LatestFile = Get-ChildItem -Path "$DestinationFolder\$FolderName" -Name TWFE*.csv | Sort-Object -Descending | Select-Object -First 1
if (!(Test-Path $FolderToCopy -PathType Container)) {
Copy-Item -Path "$DestinationFolder\$FolderName" -Destination $FolderToCopy -Recurse -Force -ErrorAction Continue
}
if ((Test-Path $FolderToCopy -PathType Container)) {
Copy-Item -Path $LatestFile -Destination $FolderToCopy -Recurse -Force -ErrorAction Continue
}
I am trying to create a script to read each folder name in a directory, count of zip files in each folder and then count of files in each zip. The output need to be written in an output file.
I came up with below:
$ZipRoot = 'C:\Users\Main Folder'
$ZipFiles = Get-ChildItem -Path $ZipRoot -Recurse -Filter '*.zip'
$Shell = New-Object -ComObject Shell.Application
$Results = foreach( $ZipFile in $ZipFiles ){
$FileCount = $Shell.NameSpace($ZipFile.FullName).Items() |
Measure-Object |
Select-Object -ExpandProperty Count
[pscustomobject]#{
FullName = $ZipFile.FullName
FileCount = $FileCount
}
}
$Results |
Export-Csv -Path 'C:\Users\mlkstq\Desktop\FFNS\ZipReport.csv' -NoTypeInformation
Output
Fullname Filecount
C:\Users\Main Folder\Subfolder1\Zip1 3
C:\Users\Main Folder\Subfolder2\Zip2 5
The problem is that I am having trouble getting the Subfolder name in putput file. Also want to substring subfolder name to get valid name. Whatever i try it fails.
If I've got you right I'd do it this way:
$ZipRoot = 'C:\Users\Main Folder'
$Shell = New-Object -ComObject Shell.Application
$subFolderList = Get-ChildItem -Path $ZipRoot -Recurse -Directory
$Result = foreach ($subFolder in $subFolderList) {
$zipFileList = Get-ChildItem -Path $subFolder.FullName -File -Filter *.zip
foreach ($ZipFile in $zipFileList) {
[PSCustomObject]#{
subFolder = $subFolder.FullName
zipFilesCount = $zipFileList.Count
zipFile = $ZipFile.Name
fileCount = $Shell.NameSpace($zipFile.FullName).Items().Count
}
}
}
Format-Table -InputObject $Result -AutoSize -InputObject $Result
Export-Csv -InputObject $Result -Path 'C:\Users\mlkstq\Desktop\FFNS\ZipReport.csv' -NoTypeInformation
In my opinion it just does not look that good to have the count of the zip files per subfolder repeated for each line of the subfolder
Basically what I'm trying to do is gather users folder size from their network folder then export that to a .csv, directory structure looks something like this: network:\Department\user...User's-stuff
The script I have right now gets the department file name and the user's folder size, but not the user's name (folder name in the department). As for the TimeStamp, I'm not sure it's working correctly. It's meant to make a timestamp when it starts on the users in the next department so basically, all users in the same department will have the same timestamp.
This is what I have so far:
$root = "network"
$container= #()
$place = "C:\temp\"
$file = "DirectoryReport.csv"
Function Get-FolderSize
{
BEGIN{$fso = New-Object -comobject Scripting.FileSystemObject}
PROCESS
{
$prevDept = (Split-Path $path -leaf)
$path = $input.fullname
$folder = $fso.GetFolder($path)
$Volume = $prevDept + "-users"
$user = $folder.name #can't figure this part out...
$size = $folder."size(MB)"
if ( (Split-Path $path -leaf) -ne $prevDept)
{
$time = Get-Date -format M/d/yyy" "HH:mm #Probably wrong too..
}
return $current = [PSCustomObject]#{'Path' = $path; 'Users' = $user; 'Size(MB)' = ($size /1MB ); 'Volume' = $Volume; 'TimeStamp' = $time;}
}
}
$container += gci $root -Force -Directory -EA 0 | Get-FolderSize
$container
#Creating the .csv path
$placeCSV = $place + $file
#Checks if the file already exists
if ((test-path ($placeCSV)) -eq $true)
{
$file = "DirectoryReport" + [string](Get-Date -format MM.d.yyy.#h.mm.sstt) + ".csv"
rename-item -path $placeCSV -newname $file
$placeCSV = $place + $file
}
#Exports the CSV file to desired folder
$container | epcsv $placeCSV -NoTypeInformation -NoClobber
But in the CSV file the user and the timestamp are wrong. Thanks for any/all help
This really seems to be doing it the hard way. Why you wouldn't just use Get-ChildItem to do this almost makes this script seem a little masochistic to me, so I'm going to use that cmdlet instead of creating a comobject to do it.
I am a little confused as to why you wouldn't want to recurse for size, but ok, we'll go that route. This will get you your folders sizes, in MB.
#Get a listing of department folders
$Depts = GCI $root -force -Directory
#Loop through them
ForEach($Dept in $Depts){
$Users = #()
$Timestamp = Get-Date -Format "M/d/yyy HH:mm"
#Loop through each user for the current department
GCI $Dept -Directory |%{
$Users += [PSCustomObject]#{
User=$_.Name
Path=$_.FullName
"Size(MB)"=(GCI $_|Measure-Object -Sum Length|Select Sum)/1MB
Volume="$($Dept.Name)-Users"
TimeStamp=$Timestamp
}
}
}
#Rename output file if it exists
If(Test-Path "C:\Temp\DirectoryReport.csv"){
Rename-Item "C:\Temp\DirectoryReport.csv" "DirectoryReport.$(Get-Date -format MM.d.yyy.#h.mm.sstt).csv"
}
#Output file
$Users | Export-Csv "C:\Temp\DirectoryReport.csv" -NoTypeInformation
If you want to get the total size for all files within each user's folder, including files within subfolders, change the "Size(MB)"=(GCI $_|Measure-Object -Sum Length|Select Sum)/1MB to be recursive by replacing it with "Size(MB)"=(GCI $_ -recurse|Measure-Object -Sum Length|Select Sum)/1MB and that should have you good to go.