Reputation: 69
I ran across this code in another post that almost does what I need, but can't figure out how to modify it to look for specific file types, i.e. *.bak, .txt, etc. I'm using Powershell with [System.IO.DirectoryInfo] because, like others have stated, using Get-ChildItem is too slow across the network. I thought it would just be something like $fileEntries = [IO.Directory]::GetFiles("C:\", ".bak"), but it still returns every file in every directory. --PS/.NET newbie
try
{
$fileEntries = [IO.Directory]::GetFiles("C:\")
[System.IO.DirectoryInfo]$directInf = New-Object IO.DirectoryInfo("C:\")
$folders = $directInf.GetDirectories()
}
catch [Exception]
{
$_.Exception.Message
$folders = @()
}
foreach($fileName in $fileEntries)
{
#[Console]::WriteLine($fileName);
}
Remove-Variable -ErrorAction SilentlyContinue -Name fileEntries
foreach($folder in $folders)
{
recurse("C:\" + $folder + "\")
}
Upvotes: 7
Views: 33282
Reputation: 1034
Here's a simple PowerShell script to move many files from a directory into a structured directory by year, month and day. This is very fast, I had over 500K files.
$listofFiles = [System.IO.Directory]::EnumerateFiles("D:\LotsOfFiles","*.*","TopDirectoryOnly")
$listofFiles |% {
$file = New-Object System.IO.FileInfo($_)
$date = Get-Date ($file.CreationTime)
$filepath = ("{0}\{1:00}\{2:00}-{3}\{4:00}\" -f "D:\LotsOfFiles", $date.year,
$date.month, $date.toString("MMM"), $date.day)
Write-Output ("Move: {0} to {1}" -f $file.Fullname, $filepath)
if (! (Test-Path $filepath)) {
new-item -type Directory -path $filepath
}
move-item $file $filepath
}
This probably can be improved but it works.
Upvotes: 1
Reputation: 69
This worked after creating a config file to use the .NET 4.0 Framework:
try{
$path = "\\$Server\$($drive.replace(':','$'))"
foreach ($filepath in [System.IO.Directory]::EnumerateFiles($path,"*.bak","AllDirectories"))
{
$file = New-Object System.IO.FileInfo($filepath)
write-host $file
# insert file into database table
}
}
catch [UnauthorizedAccessException]
{
$exception = $_.Exception.Message #I don't need to write/insert exception
}
Upvotes: -1
Reputation: 3784
This will loop through each extension searching for all files in the root and sub-directories. Ensure you have the correct privileges on all the directories especially when you're running from C:\ as the root.
$Extensions = @(".bak",".csv",".txt")
Foreach ( $Extension in $Extensions )
{
[System.IO.Directory]::EnumerateFiles("C:\","*$Extension","AllDirectories")
}
This method will only work with Powershell running .Net 4.0 or higher. To check and update the version of .Net:
$PSVersionTable
Name Value
---- -----
CLRVersion 2.0.50727.4971
BuildVersion 6.1.7600.16385
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
The CLRVersion value is the .net version.
Update the config file as follows:
$Config = @"
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>
"@
$Config > $PSHOME\Powershell.exe.config
Restart the Powershell session and verify the CLRVersion value in the $PSVersionTable variable.
Upvotes: 2