- Is there a way to write a PSObject in a file/to disk?
- Practical folder question: how many files/folders in a folder is too many?
- Is there a way to use Move-Item without using foreach on a collection?
I'll explore the various issues I dealt with in the these threads individually. For this post, I primarily wanted to share the script I came up with the handle the excessively large file collection. Without further rambling:
cls
Start-Transcript -Path (Join-Path ($scriptpath = "C:\Documents and Settings\will\My Documents\scripts") -ChildPath "transcript.txt");
#region variables
$path = "C:\Documents and Settings\will\My Documents\data";
$filecount = (Get-ChildItem $path).Count
$maxfilecount = 1000;
#endregion variables
#region functions
# Define Write-DateTime function to alias
function Write-DateTime {
return (Get-Date).ToString("yyyyMMdd hh:mm:ss");
}
# Set alias for quick reference
Set-Alias -Name wdt -Value "Write-DateTime";
#endregion functions
#region Script Body
# Output status to host.
Write-Output "$(wdt): Gathering file names.";
# Get file count
$filecount = (Get-ChildItem $path | Where-Object {$_.PSIsContainer -ne $true}).Count;
# Output status to host.
Write-Output "$(wdt): Processing files.";
# Enumerate folders based on filecount and maxfilecount parameter
for($i = 1; $i -le ($filecount/$maxfilecount); $i++) {
# Clear the $files objects.
$files = $null;
# Set the foldername to zero-filled by joining the $path and counter ($i)
$foldername = Join-Path -Path ($path) -ChildPath ("{0:00000}" -f $i);
# Output status to host.
Write-Output "$(wdt): Creating folder $foldername.";
# Create new folder based on loop counter
New-Item -Path $foldername -ItemType Directory | Out-Null;
# Output status to host.
Write-Output "$(wdt): Gathering files for $foldername.";
# Break files into smaller collections to move to subfolders.
$files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -ne $true} | select -first $maxfilecount;
# Output status to host.
Write-Output "$(wdt): Moving files to $foldername.";
# Enumerate collection.
foreach($file in $files) {
# Output status to host.
Write-Output "$(wdt): Moving $($file.fullname).";
# Move files in collection to subfolder.
Move-Item -Path $file.fullname -Destination $foldername;
}
}
# End logging.
Stop-Transcript
#endregion Script Body
Side effect :
ReplyDelete#Output status to host OR pipeline
Write-Output "$(wdt): Processing files.";
#Output status to host
Write-Host "$(wdt): Processing files.";
;-)
Thanks and good catch. I have fought battles with Write-Host/Write-Output and didn't think to include the distinction. I started focusing more on this intentionally after reading Don Jones' article:
ReplyDeletehttp://www.windowsitpro.com/blog/powershell-with-a-purpose-blog-36/scripting-languages/what-to-do--not-to-do-in-powershell-part-1-137475