icacls Deny Everyone Directory Delete Permission - batch-file

I am trying to deny all users from being able to delete a folder (as well as its contents, if possible).
What I currently have is not working.
icacls pics /deny Everyone:(OI)(CI)(DE)
Using the above line neither protects the folder nor its content as I can still delete the folder and all files within it.

I think i found a solution:
icacls pics /deny Everyone:(OI)(CI)(DE,DC)
which denies the specific rights to delete (DE) and to delete childs (DC).
To get this language independent use *S-1-1-0 instead of Everyone. (see Well-Known SIDs)
You might still be able to remove the folder if it happens to be empty. If that's a problem, consider setting the read-only flag, e.g., attrib +r pics, and then denying (WA) so it can't be changed (credit to Harry Johnston)

To prevent deletion of a file, you need deny the Delete permission on the file and deny Delete Child permission (a.k.a. "Delete subfolders and files") on the containing folder. Both must not be allowed in order to truly prevent deletion.
In other words, Windows allows deleting a file if either or both of the permissions are granted.
The above part of the answer should be enough if you are permitted to change permissions of the containing folder, otherwise, there are tricks that can prevent your folder from being deleted (all experimented by me).
You can create a (hidden) dummy file within the folder, and prevent deletion on that file (using access control again).
All delete actions, whether through Windows Explorer GUI or DEL or RMDIR command, cannot delete a read-only file or folder directly, what the aforementioned commands do is to try removing the read-only attribute on the file before doing the delete operation. So setting read-only attribute on a folder while denying Write Attributes (WA) permission will effectively prevent the folder from being deleted.
Here is a batch script example of combining two tricks together:
ECHO.>"myfolder\dummy"
REM Technically R is sufficient to prevent deletion,
REM but it wouldn't hurt to add H and S attributes.
attrib +R +H +S "myfolder\dummy"
REM Deny permissions on dummy file.
REM Hint: S-1-1-0 means Everyone; S-1-5-7 means Anonymous Logon group
icacls "myfolder\dummy" /deny *S-1-1-0:^(DE,WA^) *S-1-5-7:^(DE,WA^)
REM Make folder read-only and deny permissions on it.
attrib +R "myfolder"
icacls "myfolder" /deny *S-1-1-0:^(DE,DC,WA^) *S-1-5-7:^(DE,DC,WA^)

Related

Batch file to delete all *.auc files in %LOCALAPPDATA% for a specified user?

Is there a way to build a batch file to delete all *.auc files in %LOCALAPPDATA% for a specified user. Like maybe to have it ask for a username and then use that as the target for the delete function?
I tried to look around but couldn't figure out a way to do it with both the wildcard and a specified user. In all fairness I am pretty new at this. We have users who pretty regularly have to delete these files, while we are troubleshooting the underlying cause, it would be nice to simplify this process as much as possible.
Try something like below (not TESTED though but should work fine)
#echo off
set /p uname="Enter user ID: "
set path_firstpart = "C:\Users\"
set path_secondpart = "\AppData\Local"
set pathtodeletein = %path_firstpart%%uname%%path_secondpart%
del "%pathtodeletein%\*.auc" /S /Q
If you want to provide this batch for the current user you can use %LOCALAPPDATA% as the path to delete in or use %username% in order to avoid asking for the username.
If you want more fancy user interaction you could switch to windows scripting host and vbscript (phew ...) which allows you to open input boxes.

Batch File To Get It's Own Directory Or The Directory Defined In The "Start In" Property Of A Shortcut

I am writing a batch file on my Windows 8.1 machine. In one section of my batch file I need to start a command prompt in the "current working directory".
So far, this is what my batch file looks like:
#echo OFF
set WORKING=%cwd%
start cmd.exe /K pushd %WORKING%
exit
Let's say the batch file is located in the folder C:\Temp\Utilities. If I open an explorer window and double click the batch file to run it everything works great. A new command prompt is created in the directory C:\Temp\Utilities. However, if I right-click the batch file and select Run as administrator the working directory is no longer the location of the batch file, it's C:\Windows\System32.
Similarly, if I create a shortcut to the batch file in a different folder (for example. C:\Temp) and repeat the two steps above the results are the same. If I double click the shortcut and run it as a normal user the working directory is what I would expect. (Note, the working directory for the shortcut it's whatever is set for "Start in" of the shortcut properties, not the location of the batch file.) If I right click the shortcut and run it as administrator I again get a command prompt opened to the folder C:\Windows\System32.
I assume this is a "bug" or "feature" (if you want to call it that) in Windows 8.1 and it probably happens because execution environments for programs run as administrator are forced to run in the System32 folder? (I remember with Windows 7 this did not happen so it must be a new feature to Windows 8.)
I found one way to fix the issue and stop the command prompt from starting in C:\Windows\System32. I did this by modifying the following line in the batch file:
set WORKING=%~dp0
Doing it this way sets the working directory to the location of the batch file. With this change, no matter how I run the batch file or the shortcut (administrator or normal) the working directory ends up being the same, C:\Temp\Utilities.
The problem with this solution is I don't want the working directory to always be the location of the batch file. If the batch file is run directly then it's okay but if I run it from a shortcut I need the working directory to be whatever is set in the "Start in" property of that shortcut. For example, if the batch file is located in the folder D:\Temp\Utilities this is what I need to happen regardless of whether I run as administrator or not:
Shortcut Location Start In Property Command Prompt Working Directory
-------------------- ------------------- ------------------------------------------
C:\Temp <undefined> D:\Temp\Utilities
C:\Data\bin C:\Data\bin C:\Data\bin
C:\Data\bin D:\Temp\Utilities D:\Temp\Utilities
What this means is I can't always use %~dp0 to set the working directory in my batch file. What I need is some way for the batch file to know if it was run either directly or by a shortcut. If the batch file is run directly then the working directory is easy to get, it's just the value of %cwd%. If the batch file is run by using a shortcut, I don't know how to get the "Start in" property inside the batch file.
Does anyone know how I can do these two things inside my batch file:
1. Check whether it was run directly or by a shortcut.
2. If run by a shortcut, get the "Start in" property of the shortcut that started it.
Thank you,
Orangu
UPDATE
I found sort-of a "hackish" way to fix the issue. For the shortcut I edited the "Target" field and changed it to the following:
cmd.exe /k pushd "C:\Temp" && "D:\Temp\Utilities\batchfile.bat"
Now the working directory can be obtained by calling %CD% in the batch file and this works for both administrator and normal users. It does not, however, work for the case when I run the batch file directly. I still need to use %~dp0 in that case.
I don't like this solution, however, because it requires me to manually change all shortcuts I make and it also makes the icon look like a cmd prompt icon rather than a batch file.
Have you already considered to not use shortcuts at all?
You could e.g. create a batchfile_exec.bat containing your call
REM optionally do
REM cd /D working_directory
REM if you want to force a special working directory
D:\Temp\Utilities\batchfile.bat
and replace all the shortcuts with batchfile_exec.bat. If you double-click batchfile_exec.bat, the working directory will be the one containing batchfile_exec.bat.
I personally don't like Windows shortcuts that much, because they are hard to handle within a revision control system. As you also noticed, it is very time consuming if you want to modify a lot of them.
By the way: If batchfile.bat was designed/written to be always run from the direcory where it is located, you might also consider to modify batchfile.bat to force that behaviour:
setlocal
cd /D %0\..
REM your original content
endlocal
In %0 the path to the batchfile is stored.
The trick is to assume that %0 is a directory and then to change one level lower based on that directory. With /D also the drive letter is changed correctly.
The cd command doesn't care if %0 is really a directory. In fact %d doesn't even have to exist (%0\dummy\..\.. would also work).
The setlocal command is to have the working directory being restored when batchfile.bat has finished (this would be good if batchfile.bat was called form another batch file).
I noticed that the endlocal command is not really necessary in this context since it is applied implicitly when batchfile.bat finishes.

Permissions to protect file from being deleted or modified

I want to chmod a directory to prevent any files inside that directory from being deleted or modified without my permission.
How can I achieve that, my directory is set to 777 now which I think is a issue. Could other users access and delete my file without permission if I set the permissions to 777? What permission should I set so that?
I want to be the only one who can write to my own directory, others should only be able to read my file.
Yes, with 777, anybody could delete files from the directory.
You should run chmod 0755 yourdir or chmod og-w yourdir.
You can see the contents (read), add or remove files (write) and "pass through" the folder (execute)
Members of the owning group and other users can see the contents of the folder (read) and "pass through" to child folders (execute). They cannot add or remote files (write).
This guide is a good discussion of *nix directory permissions.
Rather than thinking about it in terms of numeric codes, perhaps it's easier to use the symbolic names for permissions. For example, to remove the ability for "others" to "write" your files:
chmod o-w FILE...
You may also want g-w if you do not want members of your Unix group to write your files.
The removal of write (w) permissions is the same as "clearing bit 2" in the mode, so 7 becomes 5, but this is hard for most normal people to remember, and you don't entirely need to.

How could you edit a specific group policy using a batch file

Im working on over 700 computers in a school district and have written a small program that i intend to write to a cd. The program is set to autorun when the disk is inserted and prompt the screen resolution of the computer and what computer the building is in (the different school buildings). Afterwards the program will run a batch file that copies a default desktop from the disk and into the windows\web\wallpaper directory. It also replaces other files that have been customized for the school district.
To finish changing the theme of the computer, i need to have the file make a few edits to the group policy and the registry. How would i be able to use the program to makes these changes? Would it all be written into the batch or would the batch have to initiate another file (like a registry file)?
All the group policy editor does is set registry keys. If you can identify what keys are being set for the policy you want, you can use reg.exe to set those keys.
reg.exe add HKCU\Software\path\to\regkey\ /v valuename /d newvalue
Registry will work for the first user, but after a new user logs in, GP will change those settings for the new user.
To make deployment gp, do this: Set one machine's GP to the way you want it. Once you are done, goto C:\windows\System32\GroupPolicy and copy the contents. (note: this is a hidden file). On the next machines you want, just paste back in the file.
If you do this in a batch, you will have to run the batch as administrator to touch the C:\windows\system32 folder. (UAC, the bane IT)

How to say no to all "do you want to overwrite" prompts in a batch file copy?

By default, copying from the command prompt will prompt you to overwrite files that already exist in the target location.
You can add "/Y" to say "Yes to all" replacements.
But how can you say "No to all" ?
In other words, I want to copy everything from one directory that does not already exist in the target.
The closest thing I see is the XCOPY argument to only copy things after a specific mod-datetime.
Unless there's a scenario where you'd not want to copy existing files in the source that have changed since the last copy, why not use XCOPY with /D without specifying a date?
echo "No" | copy/-Y c:\source c:\Dest\
You can make a text file with a single long line of "n" then run your command and put < nc.txt after it. I did this to copy over 145,000 instances where "No overwrite" was what I wanted and it worked fine this way.
Or you can just hold the n key down with something, but that takes longer than using the < to pipe it in.
Here's a workaround. If you want to copy everything from A that does not already exist in B:
Copy A to a new directory C.
Copy B to C, overwriting anything that overlaps with A.
Copy C to B.
I use XCOPY with the following parameters for copying .NET assemblies:
/D /Y /R /H
/D:m-d-y - Copies files changed on or after the specified date. If no date is given, copies only those files whose source time is newer than the destination time.
/Y - Suppresses prompting to confirm you want to overwrite an existing destination file.
/R - Overwrites read-only files.
/H - Copies hidden and system files also.
I know you all think /D: date is going to use date stuff, but just /D without the: does exactly what we want so...
xcopy {Source} {Destination} /E /D
Will copy without overwriting to pickup those files that are new or maybe failed before for some reason.
Just try it, it works.
I expect xxcopy has an option for that.
Bingo:
http://www.xxcopy.com/xxcopy27.htm#tag_231
2.3 By comparison with the file in destination
The switches in this group select files based on the
comparison between the files in the source and those in
the destination. They are often used for periodic backup
and directory synchronization purposes. These switches
were originally created as variations of directory backup.
They are also convenient for selecting files for deletion.
2.3.1 by Presence/Absence
The /BB and /U switches are the two switches which select
files by the pure presence or absence as the criteria.
Other switches in the this group (Group 2.3) are also
affected by the file in the destination, but for a
particular characteristics for comparison's sake.
/BB Selects files that are present in source but not in destination.
/U Selects files that are present in both source and destination.
-Adam
this works fine
no | cp -rf c:\source c:\Dest\
echo N | copy /-y $(SolutionDir)SomeDir $(OutDir)
Try this:
robocopy "source" "destination" /e /b /copyall /xo /it
Copy that line into notepad and save as a .bat file. Run the file and it will copy everything from the source to the destination. When you run it again it will not replace files that are identical. when you change or a file changes it will replace the file at the destination.
test it out. I created a .txt file with a few works, ran the script, change the wording on the .txt file and ran the script again, it replace only the change file from the source.
/e=Copies subdirectories. Note that this option includes empty directories
/b=Copies files in Backup mode
/copyall=Copies all file information
/xo=Excludes older files. (this is what prevents it from copy the same file over and over)
/it=Includes "tweaked" files. (this will allow the copy and replace of modified files)
Thanks for this. I am using the command line utility AzCopy (v 3.1.0.93) to move ~1 million files from my local PC to my Azure blob storage. I've got some duplicates and cannot babysit the copy to answer each prompt and don't want to re-upload the same file.
The AzCopy utility offers a /Y command to suppress the confirmation prompts but ends up telling it to overwrite the destination file. Going this route I was able to get it to NOT re-upload the file. However, it does seem like a bit of a hack since it is not actually answering the prompt with "No", instead I get the error "No input is received when user needed to make a choice among several given options." but does not upload the file.
Here is the command I used: echo n | AzCopy /Source:"{file path}" /Dest:"{blob storage URL}" /DestKey:{key}
Hope this helps the next guy.
Depending on the size and number of files being copied, you could copy the destination directory over the source first with "yes to all", then do the original copy you were doing, also with "yes to all" set. That should give you the same results.
We used "robocopy" through "invoke-command" to copy a huge amount of VMs in our environment. We've discovered that "robocopy" unexpectedly exits sometimes and the whole proccess goes to down. So we've decided to use "xcopy". Now we're checking it's work and to "create" "Not for all" option we use that function (powershell):
function gen_long_no([string]$path) {
$result = ""; Get-ChildItem $path -Recurse | ? { if ($_.PSIsContainer -eq $false) { $result += "n" } };
return $result
}
Maybe helps somebody.
Adding the switches for subdirectories and verification work just fine.
echo n | xcopy/-Y/s/e/v c:\source*.* c:\Dest\

Resources