I have a piece of code to search for all .txt and .csv files in the a bunch of submit folders inside a main folder.
#Folder to check for files
$path="\\Myfolder-DEV\RI*"
#variable which contains the number of files to be processed
$NumOfFiles = 0
Get-ChildItem $path -Recurse | % {
if (($_.Attributes -eq "Directory") -and ($_.FullName -match "submit")) {
$myPath = $_.FullName -replace "\\", "/"
Write-Host $myPath;
$fileEntries = Get-ChildItem -Path $_.FullName -include *.txt, *.csv -recurse;
foreach($fileName in $fileEntries){
$myDfile = $fileName.FullName -replace "\\", "/"
Write-Host $myDfile;
$myOfile = $myDfile -replace '\.[^.\\/]+$'
Write-Host $myOfile;
$NumOfFiles = $NumOfFiles + 1
}
}
}
echo "`n$NumOfFiles files were processed`n"
When I run this code in DEV, it works fine but when I do it in QA by modifying the path like this, it is not going through the folders at all.
$path="\\Myfolder-QA\RI*"
It even fails to write a value to the variable here
Write-Host $myPath;
I've tried modifying the scope - Clearing the variables at the end of the previous script. Restarting ISE but nothing seems to work.
Edit:
When I change the main directory to $path="\\Myfolder-QA\", it seems to work but it is searching through folders that I don't want it to. I need to search through only those folders which start with a RI and it doesnt seem to work. Any idea why it could happen?
Any help is appreciated
Thanks,
Sree
Related
I have a specific usecase where I need to identify if files from a list exist, and if so, copy them to a separate location with the relevant file structure kept. I need to keep my list of targets in the same script.
I believe my issue is something to do with the way the data inside isn't being parsed correctly due to ":" for drive letters, but I'm unsure of how to get round this issue.
As you can see from the code below, I attempted to fix the issue by ignoring the drive letter, and appending it during the Copy-Item, but it doesn't seem to work either. (e.g: C:\folder\file becomes \folder\file in the list.)
I created test directory to just help show the issue, of examples of files/folders that I want to grab (purely for testing, the real files are multiple locations/file types).
- test_dir_cmd
- folder
- folder1
* file2.db
* file3.json
* file2.txt
* file3.js
- folder2
* file.bak
* file.db
* file.txt
* temp.dat
This method works for folders and their contents, but not for specific files or wildcard.
"\USERS\$USER\AppData\Local\test_dir_cmd\folder\folder1",
"\USERS\$USER\AppData\Local\test_dir_cmd\folder\*.txt",
"\USERS\$USER\AppData\Local\test_dir_cmd\*\file.db",
"\USERS\$USER\AppData\Local\test_dir_cmd\temp.dat”
This is an example of how the list of files I'll need to get is presented and I'll need to work with.
Errors given:
Copy-Item : Illegal characters in path.
At F:\P2P.ps1:37 char:1
+ Copy-Item "C:$path" -Destination "$triage_location\$path" -Force -Rec ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Copy-Item], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.CopyItem
Command
Full script used for context:
$triage_location = "C:\temp\output\Triage\c"
ForEach-Object { #Looping through C:\Users to find folders that begin with numbers only and add to an array called $users
$users = #(Get-ChildItem -Path 'C:\Users'| Where-Object { $_.Name -match '^c+' } | Select -ExpandProperty Name)
}
Write-Host "users = $users"
write-host ""
$path_array = foreach ($user in $users) { # Loop through contents of users array and add each user to known locations
#(
"\USERS\$USER\AppData\Local\test_dir_cmd\folder\folder1",
"\USERS\$USER\AppData\Local\test_dir_cmd\folder\*.txt",
"\USERS\$USER\AppData\Local\test_dir_cmd\*\file.db",
"\USERS\$USER\AppData\Local\test_dir_cmd\temp.dat”
)
}
Write-Host "path_array = $path_array"
write-host ""
foreach ($path in $path_array) {
$a = Test-Path -Path "C:$path" # Creating variable called 'a' and setting it to Test-path value which is either True/False
if ($a -eq "True") # Test if browser location paths exist or not. If a returns True/False...
{
Write-Host "C:$path exists"
if(!(Test-Path -Path "$triage_location"))
{
New-Item -ItemType Directory -Path $triage_location
}
Copy-Item "C:$path" -Destination "$triage_location\$path" -Force -Recurse
}
else
{Write-Host "C:$path doesn't exist"}
}
if(Test-Path -Path "C:\temp\output\Triage")
{
Write-Host ""
Write-Host "Creating relevant .ZIP"
Compress-Archive -Path 'C:\temp\output\Triage' -DestinationPath 'C:\temp\output\P2P.zip' -Force # put zip in documents
}
Any help and advice on how I can fix this would be greatly appreciated!
The issue is that you are not joining the paths well. You do this:
-Destination "$triage_location\$path"
At that point $triage_location is C:\temp\output\Triage\c and $path is something like \USERS\TMTech\AppData\Local\test_dir_cmd\folder\folder1. You just make the path with string expansion but since $path starts with a \ and you include that in your string, so your string comes out looking like this:
"C:\temp\output\Triage\c\\USERS\TMTech\AppData\Local\test_dir_cmd\folder\folder1"
Use Join-Path instead:
Copy-Item (Join-Path 'C:\' $path) -Destination (Join-Path $triage_location $path) -Force -Recurse
I am new to Powershell and I am having an issue within a loop that I need assistance with. I am attempting to rename some files that are created as part of the process within the loop.
I have tested the code OUTSIDE of the loop and it works fine. However, when I try to put it in the loop, nothing seems to happen.
The files I need to rename are in the following locations…
(1)“\MYSERVER\MYCOMPANY\MYFOLDER\ MyPrintouts\EstimateImport\ImportPrintout.txt”
(2)“\MYSERVER\MYCOMPANY\MYFOLDER\ MyPrintouts\PostEntries\ImportPostEntries.txt”
I need to tack the date and time on the end. This code works for me OUTSIDE of the loop. I put it in a file I named RenameFiles.ps1
#File location
$ImportPrintout = “\\MYSERVER\MYCOMPANY\MYFOLDER\MyPrintouts\EstimateImport\ImportPrintout.txt”
$ImportPostEntries = “\MYSERVER\MYCOMPANY\MYFOLDER\ MyPrintouts\PostEntries\ImportPostEntries.txt”
#Find and rename the import printouts
Get-ChildItem $ImportPrintout -Filter "ImportPrintout.txt" | ForEach-Object {
Rename-Item $_.FullName "$BackupFolder$($_.BaseName -replace " ", "_" -replace '\..*?$')$(Get-Date -Format "MMddyyyy-HHmmss").txt"}
Get-ChildItem $ImportPostEntries -Filter "ImportPostEntires.txt" | ForEach-Object {
Rename-Item $_.FullName "$BackupFolder$($_.BaseName -replace " ", "_" -replace '\..*?$')$(Get-Date -Format "MMddyyyy-HHmmss").txt"}
This is how I added it to the loop as I want the files renamed BEFORE the next file is processed…
#Define actions after an Event is Detected
$action = {$files = Get-ChildItem -Path $watcher.Path -Filter $watcher.Filter #-Recurse
foreach ($file in $files)
{
#Define variables for log file
$changeType = $Event.SourceEventArgs.ChangeType #Your event trigger "Created"
$fileDate = $file.LastWriteTime #Date/Time Estimate was created
#logline contains = Date/Time of import, Created, Date/Time Created, filename
$logline = "$(Get-Date), $changeType, $fileDate, $file"
#Actions to take ==============================================================
#Write details to the log
Add-Content "“\\MYSERVER\MYCOMPANY\MYFOLDER\EstimateImportLog.txt" -value $logline
#Copy the estimate to the "ToBeProcessed" folder
Copy-Item $file.FullName -Destination $copyTo
#Move the estimate to the "EstimateHistory" folder
Move-Item $file.FullName -Destination $moveTo -Force
#Run the powershell script that launches the .bat file that launches the macro
Invoke-Expression "& '\\MYSERVER\MYCOMPANY\MYFOLDER\PSscriptToRunBATfile.ps1'"
#Pause the script for 30 seconds to allow the estimate to finish posting
Start-Sleep -Seconds 30
Invoke-Expression "& '“\\MYSERVER\MYCOMPANY\MYFOLDER\RenameFiles.ps1'"
}
}
This seems to “break” my loop. However, I need this to be done BEFORE going to the next file. How can I accomplish renaming these files before moving on. Any assistance would be greatly appreciated. Thank you!
As far as the loop failing, you're probably encountering an error. Either set your $ErrorActionPreference to Continue or set it to Stop and wrap try/catch blocks around your copy-item and move-item to detect and handle errors.
That probably also addresses the failure of the copy-item/move-item to change the file name, it's running into an error trying to perform that action and failing.
I have a script that I've been working on, which reads a specified directory, locates .CSV files, and executes some logic for each of the .CSV files and ultimately renames them .csv.archived .
The code was working fine last night, however this morning, when I execute the code it only loops through once. For example, last night, I had 5 .csv files in the directory, it would return the file names for all 5 files in a single action. Now, each time I execute my script, it grabs the first file, performs the actions intended, and then exits forcing me to manually initiate the script for each file.
I've gutted the irrelevant code for testing purposes, and would be happy if someone could tell me that I am doing something wrong, and that I am not crazy.
Here's the code:
$iterations = 1
#set the location where the .CSV files will be pulled from
$Filecsv = get-childitem "\\SERVERPATH\Audit Test\" -recurse | where {$_.extension -eq ".csv"} | % {
$filename = $_.Name
}
#for each file found in the directory
ForEach ($Item in $Filecsv) {
#spit out the file name
"File Name: " + $filename
#count the times we've looped through
"Iterations : " + $iterations
# get the date and time from the system
$datetime = get-date -f MMddyy-hhmmtt
# rename the file
rename-item -path ("\\SERVERPATH\Audit Test\"+ $filename) -newname ($filename + $datetime + ".csv.archived")
$iterations ++
}
...and here is the Output:
For the example I showed you, I had four .CSV files in the directory. I had to manually execute my script, and each time it would perform as expected, but only for the first item it encounters in the directory. It doesn't actually loop through, what am I missing here?
Right here (folded at the pipe for readability):
$Filecsv = get-childitem "\\SERVERPATH\Audit Test\" -recurse |
where {$_.extension -eq ".csv"} |
% {$filename = $_.Name}
You're looping through your files and for each one setting $filename to the name of that file instead of letting the filenames accumulate in $Filecsv
$Filecsv = get-childitem "\\SERVERPATH\Audit Test\" -recurse |
where {$_.extension -eq ".csv"} |
% {$_.Name}
So I have folder with files in it, in a certain location
C:\Users\ainfowara\Desktop\testfiles
so I want to move those files to this location
C:\Users\ainfowara\Desktop\destinationTestfiles
the "testfiles" have files of this format txt.*.test.* so basically I wanna check before I move the files that they have those two main stuff (txt) and (test) in the third part.
can someone help me, how can perform this in powershell script
I know I can do this, to set the folders paths
path_src= C:\Users\ainfowara\Desktop\testfiles
path_dst= C:\Users\ainfowara\Desktop\destinationTestfiles
thanks in advance for the help
If there are no subfolders in testfiles(at least that you need files from), try this:
$src = "C:\Users\ainfowara\Desktop\testfiles"
$dst = "C:\Users\ainfowara\Desktop\destinationTestfiles"
Get-ChildItem $src -Filter "txt.*.test.*" | Move-Item -Destination $dst -Force
If you have files in subfolders of the source-path, try this:
$src = "C:\Users\ainfowara\Desktop\testfiles"
$dst = "C:\Users\ainfowara\Desktop\destinationTestfiles"
Get-ChildItem $src -Filter "txt.*.test.*" -Recurse | % {
#Creates an empty file at the destination to make sure that subfolders exists
New-Item -Path $_.FullName.Replace($src,$dst) -ItemType File -Force
Move-Item -Path $_.FullName -Destination $_.FullName.Replace($src,$dst) -Force
}
Be aware that if your filename contains square-bracket [ ] you need another script (known PS bug).
Going out of my mind over here.
I have a script where I'm parsing a folder full of tifs, and breaking the files up into sub-folders to limit the number of pages to around 60 per folder. If a document is very large it gets its own folder.
The problem is that the process is locking up the files, so they cannot be deleted. Not every file though, most of them work fine, and my end clean-up portion of the script gets rid of everything else.
I wrote a lot of work-around sections to my code to fix this issue, and now it is pretty bad looking
#Large Documents
Get-ChildItem -Path "$directory" -recurse -filter "*.tif" | foreach {
$file = [System.Drawing.Bitmap]::FromFile($_.Fullname);
$pagecount = $file.GetFrameCount($file.FrameDimensionsList[0]);
if ($pagecount -gt $MaxSize){
$total = $total + $pagecount;
$name = $_.Basename;
New-Item $name -ItemType directory;
Copy-Item $_.fullname -Destination $name;
#Copy-Item $name".DS" -Destination $processingDir;
Write-Host "Sleeping in large doc loop";
$file.Dispose;
Write-Host "Dispose file object";
Write-Host $_.Fullname
$storename = $_.Fullname
$largeFiles = $largeFiles + $storename
Write-Host "Storing to array: " $largeFiles[$index];
$index = $index + 1;
sleep(15);
}
}
while ($delInd -lt $largeFiles.Count){
Write-Host "Deleting: " $largeFiles[$delInd];
Remove-Item $largeFiles[$delInd] -Force;
$delInd = $delInd + 1;
}
I'm absolutely perplexed by this. Any help is greatly appreciated.
As far as I understand with $file.Dispose you do not force underlying object to close the file. Dispose is a method and, in PowerShell (like in C#), to invoke a method you have to use (). So try $file.Dispose().
piece of advice : you can avoid ; at the end of the lines