How to take output of dir search and modify specified file - powershell

I'm trying to use this script to assist technicians with renaming files that are found on an end users computer within their %appdata% folder. The script works up until this point, but I can't figure out how to take the output of the DIR search to use it as the current directory so I can modify the destination folder.
Basically, I need to make changes to this folder:
C:\users\bob\appdata\local\apps\2.0\'7'\'7'\time...exe_bfe88f94fc69adaa_0005.0011_none_b883acbb6e8d0075
The two 7's or wildcards are always different folder directory names, so that's why I can't use a static path to make changes to these folders. Anyways, here is the script so far, it works just fine in locating the folder I need, but I cannot seem to use the output to specify it as the target so I can make changes to it. Thank you for your help.
cd %appdata%
cd ..
cd local\apps\2.0
dir "time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec" /ad /s
I've tried using the pipeline argument (|) and the '&' and then using a rename command or a removedir, but it cannot find the file specified.
Thank you for your help!

Here's a batch-file which is a little more direct than just recursing the entire tree. It only steps over the two 'unknown' directory names, (%%~nxG\%%~nxH), and checks there for the named directory, (which you should edit as needed on line 3):
#Echo Off & SetLocal EnableExtensions
Set "DirName=time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec"
Set "BaseDir=%LocalAppData%\apps\2.0"
Set "AppPath="
For /D %%G In ("%BaseDir%\*")Do For /D %%H In ("%%G\*")Do For %%I In (
"%%H\%DirName%")Do If "%%~aI" GEq "d" Set "AppPath=%%~I"
If Not Defined AppPath Echo %DirName% Not Found & Pause & Exit /B 1
Echo %%AppPath%% = %AppPath% & Pause
Nothing else should be modified except for the last line which I added just to provide some output, (you/your technicians would use "%AppPath%" to reference the target directory from that point forward).
If you were looking for something in powershell, then perhaps this will push you in the right direction:
$DirName = "time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec"
$AppPath = (RvPa "$Env:LocalAppData\apps\2.0\*\*\$DirName").Path
$AppPath
Once again the last line is just to provide output and show you the variable you'll need to reference your target directory, and the first line will need editing as needed.

This code uses a FOR loop to find directory names that match. There is an ECHO inside the loop since I do not know if multiple directories could be found.
#ECHO OFF
CD "%APPDATA%\.."
FOR /F "delims=" %%A IN ('DIR /S /B /A:D "time...exe_bfe88f94fc69adaa_0005.0011_none_39f58db4ac6311ec"') DO (
ECHO Found directory "%%~A"
SET THEDIR=%%~A
)
DIR "%THEDIR%"
REN "%THEDIR%\file1.txt" "file2.txt"

Related

Simple xcopy script using variables and a target text list to copy a folder to different computers

I wrote a script that wil copy a particular folder to a list of hosts, stored in a text file.
It works great from a short source path but fails to find the folder when located in a long path, which is how i need it to function.
Thsi what i tried, which should copy the folder to the list in the text.
Code below
set source=%~dp0%data
set source2=%~dp0%\target.txt
FOR /F "TOKENS=*" %%A IN (%source2%) DO XCOPY /d /y /f /i "%source%" "\%%~A\c$\users\test\test"
pause
Error: The system cannot find the file C:\Users\lenovo\OneDrive\Company\Red.
The above path is not the full path.
I understand there may well be more modern ways to achive this such as ropcopy or powershell and am open to ideas if this is not teh best method.
Thanks in advance for any help

Assist with batch file that searches and xcopy hidden file to specific dir

It's annoying to manually always search in the CMD and xcopy the hidden file, can someone whos good in scipting help me out?
I use these 2 commands:
Firstly i open CMD in the FOLDER2 and entering this command to find the hidden file in the hidden random sub dir:
dir /s /b | find "robotknow"
(robotknow is not the fullname of the file, only part of it.)
And then when it find the hidden file within the random made subdir i copy the whole path including the whole filename with the ending.
Xcopy /h *The whole path including the filename and ending* C:\hello
My folders:
$sourceDir = 'C:\Users\USER\AppData\Local\Packages\FOLDER1\FOLDER2'
$targetDir = 'C:\hello'
So i wish to create a batch that could search that string "robotknow" and copy the fullname of the file to my tagetdir.
Is it possible?
Im trying to learn commands but batching is harder, if i was unclear on anything please ask me thank you!
Edit:
I found few commands that could be useful but I dont know how to use them so that it works.
$searchStrings = For it to search after the string above i mentioned: "robotknow"
And
Copy-Item $_.FullName $targetpath
An example would be:
The filename has this in it's name "robotknow" and i want to copy it.
Copy the file im searching after to copy thats within the sub folder of the FOLDER2 which is an hidden random folder that i cannot se:
%LocalAppData%\Packages\FOLDER1\FOLDER2\THE-hidden-RANDOM-made-sub-DIR.
Copy it to it's final directory c:\hello
The final directory, simply just: c:\hello.
By hidden i mean that i cannot see in file explorer, windows GUI and neither if i put this simple command in CMD dir to show the hidden random folder where the file is located in, they are not showing.
The file only appears in CMD if i enter this command dir /s /b | find "robotknow" when im in the FOLDER2.
Only after that i can se the hidden random made dir/folder and the full hidden path to it (the file).
I suggest following batch file code for this task:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFolder=%LocalAppData%\Packages\FOLDER1\FOLDER2"
set "TargetFolder=C:\hello"
for /F "delims=" %%I in ('dir "%SourceFolder%\*robotknow*" /A-D /B /S 2^>nul') do %SystemRoot%\System32\xcopy.exe "%%~dpI*" "%TargetFolder%\" /C /E /H /K /Q /R /Y >nul
endlocal
The command FOR with option /F starts a separate command process with cmd.exe /C (more precisely %ComSpec% /C) in background to run the command line:
dir "C:\Users\{username}\AppData\Local\Packages\FOLDER1\FOLDER2\*robotknow*" /A-D /B /S 2>nul
DIR outputs to handle STDOUT of background command process
just the names of all files matching the wildcard pattern *robotknow* because of option /A-D (attribute not directory)
even on file having hidden attribute set because of using option /A and not excluding attribute hidden
in bare format because of option /B
with full qualified path because of option /S
found in specified directory or any subdirectory also because of option /S.
It is possible that DIR does not find any file system entry matching these criteria in which case it outputs an error message to handle STDERR. This error message is suppressed by redirecting it to device NUL.
Read the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background.
FOR with option /F captures all lines output to handle STDOUT of started command process and processes them line by line after started cmd.exe terminated itself.
FOR ignores empty lines which do not occur here. FOR ignores by default also all lines starting with a semicolon because of eol=; is the default for end of line character option. But a full qualified file name consisting of full file path, file name and file extension cannot start with ; and so default end of line option can be kept in this case. FOR splits up the lines by default into substrings with using normal space and horizontal tab character as string delimiters and assigns just first space/tab separated substring to specified loop variable. This line splitting behavior is not wanted here because of file path could contain a space character. For that reason option delims= is used to define an empty list of delimiters which disables the line splitting behavior.
So FOR assigns to specified and case-sensitive interpreted loop variable I the full qualified file name found and output by DIR and runs the command XCOPY.
XCOPY is executed with source being the full qualified path of found file referenced with %%~dpI always ending with a backslash concatenated with wildcard * and destination directory being specified target folder C:\hello.
The appended backslash at end of destination directory path makes it 100% clear for XCOPY that the destination is a directory and not a file which prevents the prompt if destination means a directory or a file. \ at end makes also usage of option /I unnecessary and XCOPY creates the entire destination directory structure if necessary.
The other XCOPY options are for really copying all files including files with hidden attribute set in directory containing the file matching the wildcard pattern *robotknow* with all subdirectories including empty subdirectories to destination directory with keeping attributes including read-only attribute.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
dir /?
echo /?
endlocal /?
set /?
setlocal /?
xcopy /?
See also the list of predefined Windows Environment Variables.

How to Copy files that are in a directory to another directory recursively in Windows?

I have to create an script to copy files from a folder structure to other.
My source folder structure is similar to this:
-RootFolder
--ParentFolder1
--SubParentFolder1
--ToCopy
/*Here are the files to copy*/
--SubParentFolder2
--ParentFolder2
--OtherSubParentFolder
--ToCopy
/*Here are the files to copy*/
--ParentFolder3
--OtherSubParentFolder2
I want to copy the files that are in the "ToCopy" folders, into another folder, with this structure:
Destination folder structure:
--TargetDirectory
--SubParentFolder1
//Here the files that were in the ToCopy folder inside the SubParentsFolder1
--OtherSubParentFolder
//Here the files that were in the ToCopy folder inside the OtherSubParentFolder
Notice that I use the name of the "ToCopy" parent folder in the destination subfolders.
I know how I would do this with code (like C#), but I am at a lost on how to achieve it with a Batch file. Is it even possible? Or I would need to use something like powershell?
How can I copy my files following the structure I described?
I think, this should work...
$Folder= gci -path "d:\pstest" -recurse -Filter "ToCopy" | where { $_.psiscontainer }
Foreach ($Foldername in $Folder) {
$Destinationfolder=$Foldername.Parent
copy-item $Foldername.fullname -Destination "d:\Outputfolder\$Destinationfolder" -recurse
}
Hi to follow is a script I hacked away (via help from stack overflow), that reads the files from a txt document, then requests destination folder input and also src folder name it then just goes and recursively copies all the files to the new folder without keeping the old subfolder structure.
I will update this in future with the link to the person that I got the base template from for the admin area, but to keep in mind once you click that Batch can run as though it was a php script then everything makes sense. Took me whole day to research every command and alternative on SS64.com
Major thing to note is the pushd "%~dp0" this I use to make sure batch always uses my current directory as root.
As said I will do a proper write up on this and further stream lining since I am using it actively for moving files during a woocommerce shop update. P.S. the text file name should be entered without the .txt extention and every file name should start on a new line. Also if the destination directory does not exist it will create it. Use excel maybe to list the names then for renaming could output to new column and compile the batch rename command copy to new batch run first batch to fetch files and second batch to rename to preferred title, I do it in steps to keep my sanity.
Sorry was just a example of how I use it, but yes go ahead and enjoy hope this works for you.
#echo off
CLS
setlocal EnableDelayedExpansion
REM Changes root path to relative of current bat folder
pushd "%~dp0"
REM finds files in provided .txt file and copies them to destination directory
REM CHECK FOR ADMIN RIGHTS
COPY /b/y NUL %WINDIR%\06CF2EB6-94E6-4a60-91D8-AB945AE8CF38 >NUL 2>&1
IF ERRORLEVEL 1 GOTO:NONADMIN
DEL %WINDIR%\06CF2EB6-94E6-4a60-91D8-AB945AE8CF38 >NUL 2>&1
:ADMIN
REM GOT ADMIN RIGHTS
COLOR 1F
ECHO Hi, %USERNAME%!
ECHO Please wait...
set /p DEST_DIR="Copy files to:"%=%
set /p SEARCH_DIR="Copy files from:"%=%
#echo.
#echo Please check folder name for accuracy.
#echo Copy files to: %DEST_DIR%
#echo Copy files from: %SEARCH_DIR%
set /p CORRECT_FOLDERS="Are these correct? (please check spelling) y/n:"
if '%CORRECT_FOLDERS%'=='y' GOTO:YES_ANSWER
if '%CORRECT_FOLDERS%'=='n' GOTO:NO_ANSWER
COLOR 2F
ECHO.
PAUSE
GOTO:EOF
:NONADMIN
REM NO ADMIN RIGHTS
COLOR 4F
ECHO.
ECHO PLEASE RUN AS ADMINISTRATOR
ECHO.
pause
GOTO:EOF
:YES_ANSWER
#echo.
#echo you answered yes
#echo.
if exist %DEST_DIR% GOTO:READ_DATA
if not exist %DEST_DIR% md %DEST_DIR%&GOTO:READ_DATA
PAUSE
:NO_ANSWER
#echo.
#echo you answered no
set /p TRY_AGAIN="Try again? y/n:"
if '%TRY_AGAIN%'=='y' GOTO:YES_ANSWER
if '%TRY_AGAIN%'=='n' GOTO:EXIT_PROGRAM
PAUSE
:EXIT_PROGRAM
#echo.
#echo "So Sorry"
PAUSE
GOTO:EOF
:READ_DATA
#echo.
set /p GET_FILENAMES="What is the name of the text file your filenames are stored in?"%=%
if exist %GET_FILENAMES%.txt #echo We will now read and copy the files for you, have some coffee might take awhile & GOTO:WRITE_DATA
if not exist %GET_FILENAMES%.txt #echo Filename does not match, please type only the name without .txt extention & GOTO:READ_DATA
PAUSE
:WRITE_DATA
#echo.
#echo reading file name...
for /f "usebackq delims=" %%a in ("%GET_FILENAMES%.txt") do (
for /r "%SEARCH_DIR%" %%b in ("%%a*") do (
#echo Copy Started...
copy "%%b" "%DEST_DIR%\%%~nxb"
)
)
#echo Copy finished, please review actions. Lekker Man.
PAUSE``

MSDOS command(s) to copy files matching pattern in directory structure to local directory

I have a job that periodically runs and archives files into a folder structure that looks like this:
ArchiveFolder
TimestampFolder
JobnameFolder
job<timestamp>.xml
For a given job, I'd like to collect all xml files in the archive folder into a flat directory (no subdirectories, just all the files) without having to drill down into each one, examine for the proper job, then copy the file.
It seems there should be a fairly straigtforward way of doing this. Any suggestions?
EDIT: I guess I wasn't clear here. The TimeStampFolder will have a name of something like 2011-07-24, the JobnameFolder will have a name like FooFeed or BarFeed, and the job file will have a name like job2011-07-24.xml. There are hundreds to thousands of TimeStampFolders, and each one may have one or more job folders in it. Given a specific job name, I want to collect all the files in all the directories that match that job type, and dump them into the local folder, with no subdirectories.
EDIT1:
SET JOB=JobName
SET OF=OutputFolder
START /wait NET USE Z: "\\ServerName\Sharename\ArchiveFolder" password password_here /USER:domainname\username /P:NO
PUSHD Z:\
FOR /F "USEBACKQ tokens=*" %%A IN (`DIR /b /a:d /s ^| FIND /I "%JOB%"`) DO (
FOR /R %%F IN (%%A) DO (
COPY /Y "%%~fF" "%OF%"
)
)
POPD
It basically locates each subdirectory of ArchiveFolder that includes the JobName in it, then digs into each one that it finds to copy the files out of them.
EDIT2:
Added NET USE to access your network share to perform tasks on the files. If your local machine already has the UNC assigned to a driveletter, you can remove the NET USE command line and change Z: to the assigned driveletter.
#ECHO OFF
FOR /R %%v IN (job*.xml) DO COPY "%%v" c:\out\

Having XCopy copy a file and not overwrite the previous one if it exists (without prompting)

I'm sending commands to a remote computer in order to have it copy a file.
I want the file to be copied, but not to overwrite the previous file with the same name (if it exists).
I also need the command to run without any prompts (xcopy likes to prompt whether the target name I've specified is file or directory, and it will also prompt about overwriting a file).
I have good results with xcopy /d.
It will copy NEWER files, and since we can assume that existing files have same time-stamp, you will copy only files that don't exist.
just in case anyone else finds this:
robocopy x:\sourcefolder Y:\destfolder /s /e /r:0 /z
much better than xcopy, even gives you a table at the end informing of any failed or skipped files. Doesn't prompt to not overwrite.
Well, there's a certain remedy! It has helped me with saving much of my effort and time on Win10 while writing a setup for our product demo.
Just try to use piping:
#ECHO N|COPY /-Y SourceFiles Destination
As an example I used this piece of code so that I would have a clean gentle quiet and safe copy!
#FOR /D %%F in ("FooPath") DO #(
#ECHO N|COPY /-Y ^"%%~npdxF\*.*^" ^"GooPath^" 3>NUL 2>NUL >NUL
)
where obviously FooPath is the source and GooPath is the destination.
Enjoy!
(main source: https://ss64.com/nt/copy.html)
Following command copy files and folder but not override file if already exist.
xcopy "*.*" "C:\test\" /s /y /d
No way to make it NOT overwrite as far as I know. but /Y will make it overwrite. and /I will get rid of the file/dict prompt. See xcopy /? for all options
You can also use the replace command. It has two modes: to add files that don't exist there or replace files that do exist. You want the previous mode:
replace <path1> <path2> /A
I had to copy AND rename files, so I got the prompt about creating a file or a directory.
This is the, rather "hackish" way I did it:
ECHO F | XCOPY /D "C:\install\dummy\dummy.pdf" "C:\Archive\fffc810e-f01a-47e8-a000-5903fc56f0ec.pdf"
XCOPY will use the "F" to indicate it should create the target as a file:
C:\install>ECHO F | XCOPY /D "C:\install\dummy\dummy.html" "C:\Archive\aa77cd6e-1d19-4eb4-b2a8-3f8fe60daf00.html"
Does C:\Archive\aa77cd6e-1d19-4eb4-b2a8-3f8fe60daf00.html specify a file name or directory name on the target
(F = file, D = directory)? F
C:\install\dummy\dummy.html
1 File(s) copied
I've also verified this command leaves existing files alone. (You should too :-)