I'm facing the following problem: In Windows AD every user logging in at a machine for the first time, shall get copied some program links on his desktop. Therefore desktop-pc and notebook are member of the AD and the desktops use serverbased-profiles while notebook use local profiles, it is necessary to differ the runonce-script.
My plan/script was the following one:
reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\explorer\Shell Folders" /v "Desktop" /f "R:\Profile\Desktop"
if %ERRORLEVEL% EQU 0 goto Domain
if %ERRORLEVEL% EQU 1 goto Notebook
:Domain
ECHO off
xcopy "c:\UserApps\Desktop-Verknuepfungen\*.lnk" "R:\Profile\Desktop\*.lnk" /Y > nul
exit
:Notebook
ECHO off
xcopy "c:\UserApps\Desktop-Verknuepfungen\*.lnk" "%USERPROFILE%\Desktop\*.lnk" /Y > nul
exit
The shell-folder desktop string should be examined if it's the ad-path or the local path to decide: desktop or notebook.
Unfortunately in every case, although it is a notebook, the errorlevel 0 returns and the script uses the wrong jumplabel. Normally it should return for a local path errorlevel 1.
Maybe someone can help out?
Thank you so much in advice,
Chris
here you have a solution that should solve your problem.
reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\explorer\Shell Folders" /v "Desktop" | find /i "R:\Profile\Desktop" && goto Domain
:Notebook
ECHO off
xcopy "c:\UserApps\Desktop-Verknuepfungen\*.lnk" "%USERPROFILE%\Desktop\*.lnk" /Y > nul
exit
:Domain
ECHO off
xcopy "c:\UserApps\Desktop-Verknuepfungen\*.lnk" "R:\Profile\Desktop\*.lnk" /Y > nul
exit
If the registry key is existent its content will be sent to find. Then find /i will search within the output without case sensitivity. if the string R:\Profile\Desktop is found the success can be used with && to trigger the goto Domain. Just had to switch :Notebook and :Domain so that in error (searchstring not found) he will choose :Notebook.
Andi
With the following builtin alternative you might solve this problem as well, but it doesn't need batch files. Microsoft tries to remove the need for that kind of skripts
Use GPP (Group Policy Preferences) with WMI filtering and let that do the copy job. You can define paths where files are and where they should be copied to. If you just need a fixed source / target definition or can use environmental variables that should be a good alternative.
Microsofts details about that:
Files extension:
Group Policy includes the Files preference extension.
For computers or users, this extension allows you to:
Copy a file (or multiple files in one folder) to a new location and then configure the attributes of those files. New subfolders are created as necessary.
Delete a file (or multiple files in one folder) and replace it with a copy of a file from a source folder.
Modify the attributes of a file (or multiple files in one folder).
Delete a file (or multiple files in one folder).
Modify the attributes of, replace, or delete all files with a
particular extension in one folder.
Modify the attributes of, replace, or delete all files in a particular folder.
Note:
To configure folders rather than individual files, use the Folder
extension.
You can create and configure File preference items for any
domain-based Group Policy object (GPO). You configure the settings by editing a GPO using the Group Policy Management Console. When editing a GPO, you can find this preference extension at the following location:
Computer Configuration or User Configuration
** └ Preferences
**** └ Windows Settings
****** └ Files
Source: https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/dn789188(v=ws.11)#files-extension
You have a lot more options there including some good filtering options.
Related
I am trying to create an active setup to copy files to all users profile after application launch.
Using this command, I am unable to copy file(s) to user profile
The problem is that although no one uses profiles, the "Default" Profile have a random prefix name (24xwe234.default \ 45qw324w.default).
xcopy "C:\Temp\123.cfg" C:\users\%username%\AppData\Roaming\Mozilla\Firefox\Profiles\*.default" /d /y
How can I copy the file to the ****.default/ Folder via batch script?
If you have Administrative privileges (in order to read/write other users %HOMEPATH%), then everything below could be applied to other users, else it's limited to your own user only.
Although xcopy is a pretty advanced command, I don't think it can handle wildcards at destination in this scenario (also didn't you miss an "*" after ".default"?).
One alternative would be to use a .bat script that iterates (using [SS64]: FOR /F (or [MS.Docs]: for)) over the .default* like dirs (corresponding to Firefox profiles - not an expert on this area, could there be more than 1?) and copies the file (using good old [MS.Docs]: copy) in each of them (if any).
code.bat:
#echo off
setlocal enableextensions
set _SOURCE_FILE="C:\Temp\123.cfg"
set _TARGET_USER=%USERNAME%
set _FIREFOX_PROFILES_PATH="C:\Users\%_TARGET_USER%\AppData\Roaming\Mozilla\Firefox\Profiles"
for /f %%f in ('dir /b "%_FIREFOX_PROFILES_PATH:"=%\*.default*"') do (
echo Copying %_SOURCE_FILE% to "%_FIREFOX_PROFILES_PATH:"=%\%%f"
copy /y %_SOURCE_FILE% "%_FIREFOX_PROFILES_PATH:"=%\%%f"
)
As it is now, the script copies the file in the default Firefox dir(s) for current user only.
Again, with Administrative privileges, it can be extended to iterate all existing users, and do the same thing for each of them (well, it could be extended anyway, but it will still do only what's doing now, when run by a regular user).
But anyway, the question (or, at least the step that posed problems) is about the current user's .default profile.
I currently use this code to copy shortcuts from a folder on a server to C:\Users\Desktop:
if not exist "%1" md "%1"
copy /y "%~dp0PlaceShortcutsHere\*.*" "%1"
This copies any shortcuts I place in the folder to the desktop.
I now need a way to remove these, baring in mind that the shortcuts in the source folder can and will change over time.
Is there a way to compare the shortcuts in the desktop and on the server and only delete the ones that are present in both folders, and only from the desktop of the computer?
These shortcuts are not all of the shortcuts on the desktop of the machines, there are others as well, hence wanting to only delete the ones present in both locations. I will also need this to be adaptive as the shortcuts present on the server will be added to or removed as needed.
This is to be deployed out through SCCM 2007/12 but I want to test it locally first.
And yes, using a GP would be easier but the GP we use has stopped working so I need a backup way of deploying shortcuts.
Took some time but I've found an answer myself. Posting this if it is useful to anyone in the future.
dir "%~dp0PlaceShortcutsHere\*" /a /b /-p /o:gen>>"%~dp0ShortcutList_%date:~-4,4%%date:~-7,2%%date:~-10,2%.txt"
Pushd \\<Server>\<Share>
for /F "delims=" %%G in (ShortcutList_%date:~-4,4%%date:~-7,2%%date:~-10,2%.txt) DO Del "C:\Users\Public\Desktop\%%G"
del "%~dp0ShortcutList_%date:~-4,4%%date:~-7,2%%date:~-10,2%.txt"
Breaking it down:
dir "%~dp0PlaceShortcutsHere\*" /a /b /-p /o:gen>>"%~dp0ShortcutList_%date:~-4,4%%date:~-7,2%%date:~-10,2%.txt"
The above created a text file with the names of the shortcuts in it for referencing by the next line.
Pushd \\<Server>\<Share>
for /F "delims=" %%G in (ShortcutList_%date:~-4,4%%date:~-7,2%%date:~-10,2%.txt) DO Del "C:\Users\Public\Desktop\%%G"
The above maps the server/share that the files are in temporarily, then uses the "For /F" loop to get the file names and then delete them.
del "%~dp0ShortcutList_%date:~-4,4%%date:~-7,2%%date:~-10,2%.txt"
Finally, this line deleted the text file that was created.
This is useful for when the contents of the folder is always changing, it will create an up to date list of the files and then delete the list afterwards, preventing confusion.
%date:~-4,4%%date:~-7,2%%date:~-10,2%
Lastly, this little line will input the current date into the filename of the text documet, so should the final delete line not work you can see the date on it. At a guess I would also think that putting it in paths will make the script only choose the files from the current day, not any others, but I have not tested this.
Please correct me if I'm wrong on anything.
Good day. I am trying to write my first batch file. I finally got it do to the most basic of tasks, and have read much here that helped including tutorials. I have not yet found an article to help me put what I'm looking for together. My search-fu is weak.
I want my batch file to copy all files every 30 minutes. However, if it comes to a file that has been updated, I want it to copy but not replace the existing in the destination. I'm assuming it would just add the (1) or 'copy' to the file name. I'm not sure if I used the proper switches or need to change them based on what I'm looking for. I think they're good, but I digress.
Here is the batch that I created without the logic:
REM Backup files 30 minutes
#echo off
:start
XCOPY "C:\source directory" "C:\target directory" /d /c /s /r /y /i
TIMEOUT /t 1800 /nobreak
goto start
Normal behaviour is to overwrite the file, or to fail (depending on the action). The (1) or (copy) postfixes are special features of Windows Explorer (the shell). If you want similar behaviour in your script, you'll have to implement it yourself.
The easiest thing (also to prevent a lot of (1), (2) .. (N) files, is to create separate folders. You can create a folder with a timestamp and copy all modified files to it.
To detect which files are modified, you might use the Archive flag of the files. When a file is modified, its Archive flag is set. XCopy has the possibility to copy only those files which have the flag set. Actually the main purpose of this flag is to determine modified files (or at least, files you want to archive).
So my suggestion:
Create a folder with a timestamp in the name. You may want to use the answer to this question for that.
Use XCopy with the /M parameter. /M copies only files with the Archive attribute, and clears the attribute afterwards.
Try to delete the directory using rd or rmdir, but without the /S parameter. It will fail if it contains files, but this way you will prevent a lot of empty directories.
Before implementing this, make sure that the process which modifies the files, also sets the Archive attribute again. It should do that automatically, but it can't hurt to test this.
-edit- Per request an example:
REM Backup files 30 minutes
#echo off
:start
REM generate a timestamp value that can be used as a file name.
setlocal TIMESTAMP=%DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2%-%TIME:~0,2%-%TIME:~3,2%-%TIME:~6,2%
REM Not needed, I think: Creating the directory yourself.
REM md "C:\target directory\%TIMESTAMP%"
REM /S for recursive. /I should create target directory? /M for backup mode.
XCOPY "C:\source directory" "C:\target directory\%TIMESTAMP%" /M /S /I
REM Not needed, I think: Removing the directory (if it's empty).
REM rd "C:\target directory\%TIMESTAMP%"
TIMEOUT /t 1800 /nobreak
goto start
I think /I already solves the other issues. It assumes that target is a directory if it doesn't exist. That makes me assume that it will in fact create that directory if it doesn't exist, and probably only if there is anything to copy. If that is right, you also won't have to remove the directory if it's empty.
Considering cleanup: Remember that this method (using /M) only copies files that have changed. If you cleanup old directories, you should make sure to copy the entire folder first. The timestamped folders will contain only the modified files (incremental backup), so if you clean up old ones, your backup/copy won't be complete anymore!
how can I organize my directories automatically?, I have a "downloads" folder, which currently contains lots of different info, for example, work related info, tv-shows, movies, etc, software, etc.
How can I automatically, maybe using some .bat execution, not sure, check for example the name of the files, or the type, and put them in the right subfolders?.
Thanks!.
You can use the move command to move files. You can also use wildcards in it.
So you could write a batch script that looks something like this:
cd C:\Users\You\Downloads
rem Excel sheets are work.
move *.xls Work
rem Reports are work.
move Report*.pdf Work\Reports
rem Pron and other viewing material ;)
move *.mp4 Private
You could run this script automatically by making it a scheduled job. Note that this script changes to the right directory first and then moves items to a relative subdirectory. This means that the directories Work, Work\Reports and Private must exist in the Downloads directory.
Of course you can expand the script to make it check and create directories as well, or you can specify different paths if you want to move the files out of the Downloads directory.
Basically, try to do it on the command line and then try to generalize those steps into your script.
This batch file will create a set of folders like .mkv .jpg .mp3 using the filetypes inside the folder, and move the files into the appropriate folders.
Launch it from your desktop and change the "c:\media" to the right folder name.
#echo off
cd /d "c:\media" && for %%a in (*) do md "%%~xa" 2>nul & move "%%a" "%%~xa" >nul
I am trying to modify a batch script that installs a simple script file into the users photoshop directory.
The basic process of the installer is to copy the bulk of the products files into the %APPDATA% folder, then this batch script runs post-install that copies a little hook script into photoshop\presets\scripts. However we've run into issues with %APPDATA% not being defined on some customers machines, would it be bad practice to check if it exist then set it if not, and if not how would you best set it accounting for different versions of Windows?
I've also taken a pretty bumpy ride down the 'reg query' road to try and find a consistent key that photoshop sets in order to find the "Path" which is the install directory but I'm wondering what the best-practices for that are as well.
Here's my current working version that has some vista permission relics
#echo off
rem | locate photoshop by querying the registry
echo Locating your photoshop installation..
set regpath="HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Photoshop.exe"
set regval="Path"
set photoshop_path=
rem | accumlate the path from the query
for /f "tokens=2,* delims= " %%A in ('reg query %regpath% /v %regval%') do (
set photoshop_path=%%B
)
rem | get rid of the last hanging space
set photoshop_path=%photoshop_path:~0,-1%
echo found photoshop at %photoshop_path%
set script_path=%photoshop_path%Presets\Scripts\script.jsx
echo Removing existing copies of script.jsx..
if exist "%script_path%" del "%script_path%"
echo ...Done!
echo Installing script.jsx to Photoshop Scripts directory... %script_path%
if exist "%photoshop_path%Photoshop.exe copy "%APPDATA%\My Company\etc\script.jsx" "%script_path%"
echo Done!
rem | some fix for vista permissions
ver | find "XP" > nul
if %ERRORLEVEL% neq 0 goto exit
echo Setting permissions for Vista...
echo ...Taking ownership of files...
takeown /f "%APPDATA%\My Company" /r /d y
echo ...Granting write access to files...
icacls "%APPDATA%\My Company" /grant Users:F /t
echo Done!
:exit
echo Creating Product Library entry in folderlist.cfg
echo Product Library=%APPDATA%\My Company\library>>"%APPDATA%\My Company\etc\folderlist.cfg"
echo Done!
However, problems arise when the key doesn't exist, the current solution that is deployed just brute force tries every known location photoshop might be installed (based on the %PROGRAMFILES%/%PROGRAMFILES(x86)% variables. Any help towards a more robust and consistent script is much appreciated as well as any advice on what installer products might work best for deploying this type of script in a cross-platform manner(Mac/Windows mostly).
Well, I basically solved this problem by writing a completely new installer using Inno setup. It rocks. It uses pascal which feels a little archaic to me but it was much easier to pickup and use than batch scripting. Somebody please write a python installer api!
As far as best practices go for locating a user's installation of photoshop(or any program for that matter), it seems like the brute force method of simply trying every possible key/directory it might be located in is the best bet.
For instance, when I installed photoshop recently, it actually gave me 2 installations in 2 separate folders, a 32 bit and 64 bit version. Ideally, when I run my installer to add things to photoshop's directory, it should go into both versions. It wouldn't do that if I simply queried some 'master registry key' and stuffed it in there. It seems that, over the years, even a big name like Adobe hasn't used the registry in a consistent manner. So, the best chance my installer has of working is making a big list of every possible registry key adobe has made for the installation path of photoshop and trying all of them, and then also trying raw directories myself (based on environment variables at least). If only people followed standards!